From a880c1abfab992126a1a53d4b435150517bf654c Mon Sep 17 00:00:00 2001 From: Senthilnathan Date: Tue, 7 Jul 2026 14:30:59 +0530 Subject: [PATCH] Fix parser failing on comments inside if/when ternary --- core/odin/parser/parser.odin | 4 +++- src/parser.cpp | 4 +++- tests/core/odin/test_parser.odin | 39 +++++++++++++++++++++++++++++++- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/core/odin/parser/parser.odin b/core/odin/parser/parser.odin index 319c05836..2ad291aef 100644 --- a/core/odin/parser/parser.odin +++ b/core/odin/parser/parser.odin @@ -3625,7 +3625,9 @@ parse_binary_expr :: proc(p: ^Parser, lhs: bool, prec_in: int) -> ^ast.Expr { case .If, .When: if p.prev_tok.pos.line < op.pos.line { // NOTE(bill): Check to see if the `if` or `when` is on the same line of the `lhs` condition - break loop + if p.expr_level <= 0 { + break loop + } } } diff --git a/src/parser.cpp b/src/parser.cpp index c4dc2c0bc..0e7ec1d60 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -3585,7 +3585,9 @@ gb_internal Ast *parse_binary_expr(AstFile *f, bool lhs, i32 prec_in) { case Token_when: if (prev.pos.line < op.pos.line) { // NOTE(bill): Check to see if the `if` or `when` is on the same line of the `lhs` condition - goto loop_end; + if (f->expr_level <= 0) { + goto loop_end; + } } break; } diff --git a/tests/core/odin/test_parser.odin b/tests/core/odin/test_parser.odin index 4a1fdbfb4..e60a9f8f0 100644 --- a/tests/core/odin/test_parser.odin +++ b/tests/core/odin/test_parser.odin @@ -134,7 +134,7 @@ my_func :: proc (cond: bool, a: string, b: string) -> string { @test -test_parse_multiline_ternary_with_comment :: proc(t: ^testing.T) { +test_parse_multiline_ternary_infix_with_comment :: proc(t: ^testing.T) { context.allocator = context.temp_allocator runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() file := ast.File{ @@ -169,3 +169,40 @@ test_parse_multiline_ternary_with_comment :: proc(t: ^testing.T) { testing.expect(t, ok, "bad parse") testing.expect(t, file.syntax_error_count == 0, "should contain zero errors") } + +@test +test_parse_ternary_if_statements_with_comment :: proc(t: ^testing.T) { + context.allocator = context.temp_allocator + runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() + file := ast.File{ + fullpath = "test.odin", + src = ` + package main + + my_func :: proc (cond: bool, a: string, b: string) -> string { + out := ( + cond + if a // This is a comment! + else b + ) + return out + } + `, + } + + p := parser.default_parser() + + p.err = proc(pos: tokenizer.Pos, format: string, args: ..any) { + message := fmt.tprintf(format, ..args) + log.errorf("%s(%d:%d): %s", pos.file, pos.line, pos.column, message) + } + + p.warn = proc(pos: tokenizer.Pos, format: string, args: ..any) { + message := fmt.tprintf(format, ..args) + log.warnf("%s(%d:%d): %s", pos.file, pos.line, pos.column, message) + } + + ok := parser.parse_file(&p, &file) + testing.expect(t, ok, "bad parse") + testing.expect(t, file.syntax_error_count == 0, "should contain zero errors") +}