From fa732617fbc01b16a6d3c561858bd2a95467c074 Mon Sep 17 00:00:00 2001 From: Taylor Holliday Date: Sat, 8 Aug 2026 14:46:42 -0700 Subject: [PATCH] Allow semicolons to separate statements Statements in a block could only be separated by newlines. Accept `;` as an alternate separator so multiple statements can share a line. The lexer already produced Token::Semi for array types (`[T; N]`) and array repeat literals (`[x; n]`); those are distinct contexts and are unaffected. A semicolon is now accepted anywhere a newline was, including trailing before the closing brace. Since parse_block is shared, this covers function bodies, while/for bodies, if/else branches, and block expressions. The semicolon is purely a separator: unlike Rust, a trailing one does not void the block's value, so `{ a; b; }` still evaluates to `b`. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01QL98e281ffpSW7JKQyS87C --- src/parser.rs | 10 +++++++++- tests/cases/semicolons.lyte | 25 +++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 tests/cases/semicolons.lyte diff --git a/src/parser.rs b/src/parser.rs index 34fa005..878725b 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -853,7 +853,9 @@ fn parse_block(arena: &mut ExprArena, typevars: &[Name], cx: &mut ParseContext) r.push(parse_stmt(arena, typevars, cx)); - if cx.lex.tok != Token::Endl { + // Statements are separated by newlines or semicolons. Semicolons let + // multiple statements share a line. + if cx.lex.tok != Token::Endl && cx.lex.tok != Token::Semi { break; } @@ -1461,6 +1463,12 @@ mod tests { "{ x = y\n z = w }", "{ f(x)\n g(y) }", "{ var x = y\n var z = w }", + "{ x; y }", + "{ x; }", + "{ x;\n y }", + "{ x = y; z = w }", + "{ var x = y; var z = w; f(x) }", + "{ while x { y; z }; w }", ], ); } diff --git a/tests/cases/semicolons.lyte b/tests/cases/semicolons.lyte new file mode 100644 index 0000000..2927880 --- /dev/null +++ b/tests/cases/semicolons.lyte @@ -0,0 +1,25 @@ +// expected stdout: +// compilation successful +// assert(true) +// assert(true) +// assert(true) +// assert(true) + +sum_three(a: i32, b: i32, c: i32) -> i32 { + var t = 0; t = t + a; t = t + b + t = t + c + return t +} + +main { + var x = 1; var y = 2; var z = x + y + assert(z == 3) + + // Trailing semicolon before the closing brace. + assert(sum_three(1, 2, 3) == 6); + + var i = 0 + while i < 3 { i = i + 1; x = x + i } + assert(i == 3) + assert(x == 7) +}