From 6a77fc4cdd35b2ecd1c32f7c5f2e249d6e225d91 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 21 Aug 2021 23:10:21 +0100 Subject: Add multi-pointer types `[^]T` --- src/parser.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src/parser.cpp') diff --git a/src/parser.cpp b/src/parser.cpp index 6184a62ab..898dd4da6 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -337,6 +337,9 @@ Ast *clone_ast(Ast *node) { case Ast_PointerType: n->PointerType.type = clone_ast(n->PointerType.type); break; + case Ast_MultiPointerType: + n->MultiPointerType.type = clone_ast(n->MultiPointerType.type); + break; case Ast_ArrayType: n->ArrayType.count = clone_ast(n->ArrayType.count); n->ArrayType.elem = clone_ast(n->ArrayType.elem); @@ -985,7 +988,12 @@ Ast *ast_pointer_type(AstFile *f, Token token, Ast *type) { result->PointerType.type = type; return result; } - +Ast *ast_multi_pointer_type(AstFile *f, Token token, Ast *type) { + Ast *result = alloc_ast_node(f, Ast_MultiPointerType); + result->MultiPointerType.token = token; + result->MultiPointerType.type = type; + return result; +} Ast *ast_array_type(AstFile *f, Token token, Ast *count, Ast *elem) { Ast *result = alloc_ast_node(f, Ast_ArrayType); result->ArrayType.token = token; @@ -2317,7 +2325,11 @@ Ast *parse_operand(AstFile *f, bool lhs) { case Token_OpenBracket: { Token token = expect_token(f, Token_OpenBracket); Ast *count_expr = nullptr; - if (f->curr_token.kind == Token_Question) { + if (f->curr_token.kind == Token_Pointer) { + expect_token(f, Token_Pointer); + expect_token(f, Token_CloseBracket); + return ast_multi_pointer_type(f, token, parse_type(f)); + } else if (f->curr_token.kind == Token_Question) { count_expr = ast_unary_expr(f, expect_token(f, Token_Question), nullptr); } else if (allow_token(f, Token_dynamic)) { expect_token(f, Token_CloseBracket); -- cgit v1.2.3 From 93b5befe45b6464f30f7a9404d1db2d84edf201f Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 22 Aug 2021 11:27:24 +0100 Subject: Improve error handling for missing semicolon separators in a `for` loop --- core/odin/parser/parser.odin | 24 ++++++++++++++++++------ src/parser.cpp | 26 ++++++++++++++++++-------- 2 files changed, 36 insertions(+), 14 deletions(-) (limited to 'src/parser.cpp') diff --git a/core/odin/parser/parser.odin b/core/odin/parser/parser.odin index 8bf159778..6bcb564fe 100644 --- a/core/odin/parser/parser.odin +++ b/core/odin/parser/parser.odin @@ -848,12 +848,24 @@ parse_for_stmt :: proc(p: ^Parser) -> ^ast.Stmt { if !is_range && parse_control_statement_semicolon_separator(p) { init = cond; cond = nil; - if p.curr_tok.kind != .Semicolon { - cond = parse_simple_stmt(p, nil); - } - expect_semicolon(p, cond); - if p.curr_tok.kind != .Open_Brace && p.curr_tok.kind != .Do { - post = parse_simple_stmt(p, nil); + + + if f.curr_tok.kind == .Open_Brace || f.curr_tok.kind == .Do { + error(p, f.curr_tok.pos, "Expected ';', followed by a condition expression and post statement, got %s", token.tokens[f.curr_tok.kind]); + } else { + if p.curr_tok.kind != .Semicolon { + cond = parse_simple_stmt(p, nil); + } + + if p.curr_tok.text != ";" { + error(p, p.curr_tok.pos, "Expected ';', got %s", tokenizer.token_to_string(p.curr_tok)); + } else { + expect_semicolon(p, nil); + } + + if p.curr_tok.kind != .Open_Brace && p.curr_tok.kind != .Do { + post = parse_simple_stmt(p, nil); + } } } } diff --git a/src/parser.cpp b/src/parser.cpp index 6184a62ab..e9efd989a 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -4133,16 +4133,26 @@ Ast *parse_for_stmt(AstFile *f) { if (!is_range && parse_control_statement_semicolon_separator(f)) { init = cond; cond = nullptr; - if (f->curr_token.kind != Token_Semicolon) { - cond = parse_simple_stmt(f, StmtAllowFlag_None); - } - expect_semicolon(f, cond); - if (f->curr_token.kind != Token_OpenBrace && - f->curr_token.kind != Token_do) { - post = parse_simple_stmt(f, StmtAllowFlag_None); + + if (f->curr_token.kind == Token_OpenBrace || f->curr_token.kind == Token_do) { + syntax_error(f->curr_token, "Expected ';', followed by a condition expression and post statement, got %.*s", LIT(token_strings[f->curr_token.kind])); + } else { + if (f->curr_token.kind != Token_Semicolon) { + cond = parse_simple_stmt(f, StmtAllowFlag_None); + } + + if (f->curr_token.string != ";") { + syntax_error(f->curr_token, "Expected ';', got %.*s", LIT(token_to_string(f->curr_token))); + } else { + expect_semicolon(f, nullptr); + } + + if (f->curr_token.kind != Token_OpenBrace && + f->curr_token.kind != Token_do) { + post = parse_simple_stmt(f, StmtAllowFlag_None); + } } } - } -- cgit v1.2.3