diff --git a/src/compiler/parser/mod.rs b/src/compiler/parser/mod.rs index 12c2063..20527a9 100644 --- a/src/compiler/parser/mod.rs +++ b/src/compiler/parser/mod.rs @@ -156,10 +156,21 @@ fn parse_block<'source>(pos: &mut usize, tokens: &[Token<'source>]) -> Expressio loop { expressions.push(parse_block_level_expressions(pos, tokens)); + // Last expression left as return expression, if no semicolon is present if peek(pos, tokens).text == "}" { break; } - consume_string(pos, tokens, ";"); + + // Blocks don't need to be followed by a semicolon, but can be + if peek(&mut (*pos - 1), tokens).text == "}" { + if peek(pos, tokens).text == ";" { + consume_string(pos, tokens, ";"); + } + } else { + consume_string(pos, tokens, ";"); + } + + // If the last expression of the block ended in a semicolon, empty return if peek(pos, tokens).text == "}" { expressions.push(EmptyLiteral()); break; diff --git a/src/compiler/parser/tests.rs b/src/compiler/parser/tests.rs index 3332905..67e4b1d 100644 --- a/src/compiler/parser/tests.rs +++ b/src/compiler/parser/tests.rs @@ -450,7 +450,7 @@ fn test_omitting_semicolons() { Box::new(Block(vec![Identifier("a")])), None ), - Block(vec![Identifier("b")]), + Identifier("b"), ]) ); @@ -463,7 +463,7 @@ fn test_omitting_semicolons() { Box::new(Block(vec![Identifier("a")])), None ), - Block(vec![Identifier("b")]), + Identifier("b"), ]) ); @@ -476,7 +476,7 @@ fn test_omitting_semicolons() { Box::new(Block(vec![Identifier("a")])), Some(Box::new(Block(vec![Identifier("b")]))) ), - Block(vec![Identifier("c")]), + Identifier("c"), ]) );