Skip to content

Commit

Permalink
Add ?? break/continue/return/throw.
Browse files Browse the repository at this point in the history
  • Loading branch information
schungx committed May 21, 2024
1 parent c014343 commit a191b6f
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 11 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Bug fixes
New features
------------

* The `break`, `continue`, `return` and `throw` statements can now follow the `??` operator to short-circuit operations where the value is `()`.
* A new symbol, `$func$`, is added to custom syntax to allow parsing of anonymous functions.


Expand Down
33 changes: 22 additions & 11 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2265,20 +2265,31 @@ impl Engine {

// Parse the RHS
let rhs = match op_token {
Token::DoubleQuestion
if matches!(
state.input.peek().unwrap().0,
Token::Break | Token::Continue | Token::Return | Token::Throw
) =>
{
let stmt = self.parse_stmt(state, settings)?;
let block: StmtBlock = stmt.into();
Expr::Stmt(block.into())
}
// [xxx..] | (xxx..) | {xxx..} | xxx.., | xxx..; | xxx.. =>
// [xxx..=] | (xxx..=) | {xxx..=} | xxx..=, | xxx..=; | xxx..= =>
Token::ExclusiveRange | Token::InclusiveRange => {
let (next_op, next_pos) = state.input.peek().unwrap();

match next_op {
Token::ExclusiveRange | Token::InclusiveRange
if matches!(
state.input.peek().unwrap().0,
Token::RightBracket
| Token::RightParen
| Token::RightBrace
| Token::Comma
| Token::SemiColon
| Token::DoubleArrow => Expr::Unit(*next_pos),
_ => self.parse_unary(state, settings)?,
}
| Token::RightParen
| Token::RightBrace
| Token::Comma
| Token::SemiColon
| Token::DoubleArrow
) =>
{
let (_, next_pos) = state.input.peek().unwrap();
Expr::Unit(*next_pos)
}
_ => self.parse_unary(state, settings)?,
};
Expand Down
14 changes: 14 additions & 0 deletions tests/looping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,20 @@ fn test_loop() {
21
);

assert_eq!(
engine
.eval::<INT>(
"
for n in 0..10 {
let x = if n <= 5 { n };
x ?? break 42;
}
"
)
.unwrap(),
42
);

assert_eq!(*engine.compile("let x = 0; break;").unwrap_err().err_type(), ParseErrorType::LoopBreak);

#[cfg(not(feature = "no_function"))]
Expand Down

0 comments on commit a191b6f

Please sign in to comment.