From 144504a752ec1e002684123035ed8aa02c99aa86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rikard=20Petr=C3=A9?= Date: Sat, 20 Jan 2024 15:53:19 +0100 Subject: [PATCH 1/5] odin/parser: Fix parsing of struct literal/call expression when closing brace/paren is on a new line without a comma after the last argument. --- core/odin/parser/parser.odin | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/core/odin/parser/parser.odin b/core/odin/parser/parser.odin index f11d0eb73..cb4d2785b 100644 --- a/core/odin/parser/parser.odin +++ b/core/odin/parser/parser.odin @@ -416,24 +416,28 @@ end_of_line_pos :: proc(p: ^Parser, tok: tokenizer.Token) -> tokenizer.Pos { } expect_closing_brace_of_field_list :: proc(p: ^Parser) -> tokenizer.Token { + return expect_closing_token_of_field_list(p, .Close_Brace, "field list") +} + +expect_closing_token_of_field_list :: proc(p: ^Parser, closing_kind: tokenizer.Token_Kind, msg: string) -> tokenizer.Token { token := p.curr_tok - if allow_token(p, .Close_Brace) { + if allow_token(p, closing_kind) { return token } if allow_token(p, .Semicolon) && !tokenizer.is_newline(token) { str := tokenizer.token_to_string(token) error(p, end_of_line_pos(p, p.prev_tok), "expected a comma, got %s", str) } - expect_brace := expect_token(p, .Close_Brace) + expect_closing := expect_token_after(p, closing_kind, msg) - if expect_brace.kind != .Close_Brace { - for p.curr_tok.kind != .Close_Brace && p.curr_tok.kind != .EOF && !is_non_inserted_semicolon(p.curr_tok) { + if expect_closing.kind != closing_kind { + for p.curr_tok.kind != closing_kind && p.curr_tok.kind != .EOF && !is_non_inserted_semicolon(p.curr_tok) { advance_token(p) } return p.curr_tok } - return expect_brace + return expect_closing } is_non_inserted_semicolon :: proc(tok: tokenizer.Token) -> bool { @@ -2922,7 +2926,7 @@ parse_literal_value :: proc(p: ^Parser, type: ^ast.Expr) -> ^ast.Comp_Lit { } p.expr_level -= 1 - close := expect_token_after(p, .Close_Brace, "compound literal") + close := expect_closing_brace_of_field_list(p); pos := type.pos if type != nil else open.pos lit := ast.new(ast.Comp_Lit, pos, end_pos(close)) @@ -2985,7 +2989,7 @@ parse_call_expr :: proc(p: ^Parser, operand: ^ast.Expr) -> ^ast.Expr { allow_token(p, .Comma) or_break } - close := expect_token_after(p, .Close_Paren, "argument list") + close := expect_closing_token_of_field_list(p, .Close_Paren, "argument list") p.expr_level -= 1 ce := ast.new(ast.Call_Expr, operand.pos, end_pos(close)) From 99825a28d7357b7e884ce0387f7e5fabd3180148 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rikard=20Petr=C3=A9?= Date: Sat, 20 Jan 2024 16:00:41 +0100 Subject: [PATCH 2/5] odin/parser: Allow semicolon after return statement for the case: if x do return y; else do return z; --- core/odin/parser/parser.odin | 1 + 1 file changed, 1 insertion(+) diff --git a/core/odin/parser/parser.odin b/core/odin/parser/parser.odin index cb4d2785b..f9fef15a9 100644 --- a/core/odin/parser/parser.odin +++ b/core/odin/parser/parser.odin @@ -1340,6 +1340,7 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt { rs := ast.new(ast.Return_Stmt, tok.pos, end) rs.results = results[:] + expect_semicolon(p, rs) return rs case .Break, .Continue, .Fallthrough: From 239d4e10762a12e96280bd91003acbf2170cadf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rikard=20Petr=C3=A9?= Date: Sat, 20 Jan 2024 16:09:41 +0100 Subject: [PATCH 3/5] odin/tokenizer: Reset insert_semicolon to false in tokenizer.init to fix bug when tokenizing multiple files. --- core/odin/tokenizer/tokenizer.odin | 1 + 1 file changed, 1 insertion(+) diff --git a/core/odin/tokenizer/tokenizer.odin b/core/odin/tokenizer/tokenizer.odin index 41de3ac8b..62170aa10 100644 --- a/core/odin/tokenizer/tokenizer.odin +++ b/core/odin/tokenizer/tokenizer.odin @@ -39,6 +39,7 @@ init :: proc(t: ^Tokenizer, src: string, path: string, err: Error_Handler = defa t.read_offset = 0 t.line_offset = 0 t.line_count = len(src) > 0 ? 1 : 0 + t.insert_semicolon = false t.error_count = 0 t.path = path From 730f992bff01543082332dc5e4921ac44da087ca Mon Sep 17 00:00:00 2001 From: RilleP Date: Wed, 10 Apr 2024 19:16:38 +0200 Subject: [PATCH 4/5] fix indentation --- core/odin/parser/parser.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/odin/parser/parser.odin b/core/odin/parser/parser.odin index 415ec949d..24a44f60e 100644 --- a/core/odin/parser/parser.odin +++ b/core/odin/parser/parser.odin @@ -2995,7 +2995,7 @@ parse_literal_value :: proc(p: ^Parser, type: ^ast.Expr) -> ^ast.Comp_Lit { } p.expr_level -= 1 - skip_possible_newline(p) + skip_possible_newline(p) close := expect_closing_brace_of_field_list(p); pos := type.pos if type != nil else open.pos From 330c1616255e2f22b8c4dfde57d6a3b17d038a15 Mon Sep 17 00:00:00 2001 From: RilleP Date: Thu, 11 Apr 2024 09:36:28 +0200 Subject: [PATCH 5/5] remove semicolon --- core/odin/parser/parser.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/odin/parser/parser.odin b/core/odin/parser/parser.odin index 24a44f60e..b2ffd3888 100644 --- a/core/odin/parser/parser.odin +++ b/core/odin/parser/parser.odin @@ -2996,7 +2996,7 @@ parse_literal_value :: proc(p: ^Parser, type: ^ast.Expr) -> ^ast.Comp_Lit { p.expr_level -= 1 skip_possible_newline(p) - close := expect_closing_brace_of_field_list(p); + close := expect_closing_brace_of_field_list(p) pos := type.pos if type != nil else open.pos lit := ast.new(ast.Comp_Lit, pos, end_pos(close))