From cad753e3986183fa180abae480a85432b4b36af1 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 22 Feb 2022 22:53:13 +0000 Subject: Simplify `parse_binary_expr` --- src/parser.cpp | 157 +++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 109 insertions(+), 48 deletions(-) (limited to 'src/parser.cpp') diff --git a/src/parser.cpp b/src/parser.cpp index 8a7ab2d20..c214df782 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -3013,66 +3013,127 @@ i32 token_precedence(AstFile *f, TokenKind t) { return 0; } +// Ast *parse_binary_expr(AstFile *f, bool lhs, i32 prec_in) { +// Ast *expr = parse_unary_expr(f, lhs); +// for (i32 prec = token_precedence(f, f->curr_token.kind); prec >= prec_in; prec--) { +// for (;;) { +// Token op = f->curr_token; +// i32 op_prec = token_precedence(f, op.kind); +// if (op_prec != prec) { +// // NOTE(bill): This will also catch operators that are not valid "binary" operators +// break; +// } +// Token prev = f->prev_token; +// switch (op.kind) { +// case Token_if: +// 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; +// } +// break; +// } +// expect_operator(f); // NOTE(bill): error checks too + +// if (op.kind == Token_Question) { +// Ast *cond = expr; +// // Token_Question +// Ast *x = parse_expr(f, lhs); +// Token token_c = expect_token(f, Token_Colon); +// Ast *y = parse_expr(f, lhs); +// expr = ast_ternary_if_expr(f, x, cond, y); +// } else if (op.kind == Token_if || op.kind == Token_when) { +// Ast *x = expr; +// Ast *cond = parse_expr(f, lhs); +// Token tok_else = expect_token(f, Token_else); +// Ast *y = parse_expr(f, lhs); + +// switch (op.kind) { +// case Token_if: +// expr = ast_ternary_if_expr(f, x, cond, y); +// break; +// case Token_when: +// expr = ast_ternary_when_expr(f, x, cond, y); +// break; +// } +// } else { +// Ast *right = parse_binary_expr(f, false, prec+1); +// if (right == nullptr) { +// syntax_error(op, "Expected expression on the right-hand side of the binary operator '%.*s'", LIT(op.string)); +// } +// if (op.kind == Token_or_else) { +// // NOTE(bill): easier to handle its logic different with its own AST kind +// expr = ast_or_else_expr(f, expr, op, right); +// } else { +// expr = ast_binary_expr(f, op, expr, right); +// } +// } + +// lhs = false; +// } +// loop_end:; +// } +// return expr; +// } + Ast *parse_binary_expr(AstFile *f, bool lhs, i32 prec_in) { Ast *expr = parse_unary_expr(f, lhs); - for (i32 prec = token_precedence(f, f->curr_token.kind); prec >= prec_in; prec--) { - for (;;) { - Token op = f->curr_token; - i32 op_prec = token_precedence(f, op.kind); - if (op_prec != prec) { - // NOTE(bill): This will also catch operators that are not valid "binary" operators - break; + for (;;) { + Token op = f->curr_token; + i32 op_prec = token_precedence(f, op.kind); + if (op_prec < prec_in) { + // NOTE(bill): This will also catch operators that are not valid "binary" operators + break; + } + Token prev = f->prev_token; + switch (op.kind) { + case Token_if: + 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; } - Token prev = f->prev_token; + break; + } + expect_operator(f); // NOTE(bill): error checks too + + if (op.kind == Token_Question) { + Ast *cond = expr; + // Token_Question + Ast *x = parse_expr(f, lhs); + Token token_c = expect_token(f, Token_Colon); + Ast *y = parse_expr(f, lhs); + expr = ast_ternary_if_expr(f, x, cond, y); + } else if (op.kind == Token_if || op.kind == Token_when) { + Ast *x = expr; + Ast *cond = parse_expr(f, lhs); + Token tok_else = expect_token(f, Token_else); + Ast *y = parse_expr(f, lhs); + switch (op.kind) { case Token_if: + expr = ast_ternary_if_expr(f, x, cond, y); + break; 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; - } + expr = ast_ternary_when_expr(f, x, cond, y); break; } - expect_operator(f); // NOTE(bill): error checks too - - if (op.kind == Token_Question) { - Ast *cond = expr; - // Token_Question - Ast *x = parse_expr(f, lhs); - Token token_c = expect_token(f, Token_Colon); - Ast *y = parse_expr(f, lhs); - expr = ast_ternary_if_expr(f, x, cond, y); - } else if (op.kind == Token_if || op.kind == Token_when) { - Ast *x = expr; - Ast *cond = parse_expr(f, lhs); - Token tok_else = expect_token(f, Token_else); - Ast *y = parse_expr(f, lhs); - - switch (op.kind) { - case Token_if: - expr = ast_ternary_if_expr(f, x, cond, y); - break; - case Token_when: - expr = ast_ternary_when_expr(f, x, cond, y); - break; - } + } else { + Ast *right = parse_binary_expr(f, false, op_prec+1); + if (right == nullptr) { + syntax_error(op, "Expected expression on the right-hand side of the binary operator '%.*s'", LIT(op.string)); + } + if (op.kind == Token_or_else) { + // NOTE(bill): easier to handle its logic different with its own AST kind + expr = ast_or_else_expr(f, expr, op, right); } else { - Ast *right = parse_binary_expr(f, false, prec+1); - if (right == nullptr) { - syntax_error(op, "Expected expression on the right-hand side of the binary operator '%.*s'", LIT(op.string)); - } - if (op.kind == Token_or_else) { - // NOTE(bill): easier to handle its logic different with its own AST kind - expr = ast_or_else_expr(f, expr, op, right); - } else { - expr = ast_binary_expr(f, op, expr, right); - } + expr = ast_binary_expr(f, op, expr, right); } - - lhs = false; } - loop_end:; + + lhs = false; } + loop_end:; return expr; } -- cgit v1.2.3 From 62d232d798fff25597b6e3591c6a178c32fa440e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 22 Feb 2022 22:59:00 +0000 Subject: Correct `ExactValue_Pointer` --- src/exact_value.cpp | 17 ++++++++++++--- src/parser.cpp | 63 ----------------------------------------------------- 2 files changed, 14 insertions(+), 66 deletions(-) (limited to 'src/parser.cpp') diff --git a/src/exact_value.cpp b/src/exact_value.cpp index fd90278e5..3dae96853 100644 --- a/src/exact_value.cpp +++ b/src/exact_value.cpp @@ -630,6 +630,9 @@ void match_exact_values(ExactValue *x, ExactValue *y) { case ExactValue_Bool: case ExactValue_String: case ExactValue_Quaternion: + case ExactValue_Pointer: + case ExactValue_Procedure: + case ExactValue_Typeid: return; case ExactValue_Integer: @@ -671,9 +674,6 @@ void match_exact_values(ExactValue *x, ExactValue *y) { return; } break; - - case ExactValue_Procedure: - return; } compiler_error("match_exact_values: How'd you get here? Invalid ExactValueKind %d", x->kind); @@ -932,6 +932,17 @@ bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y) { break; } + case ExactValue_Pointer: { + switch (op) { + case Token_CmpEq: return x.value_pointer == y.value_pointer; + case Token_NotEq: return x.value_pointer != y.value_pointer; + case Token_Lt: return x.value_pointer < y.value_pointer; + case Token_LtEq: return x.value_pointer <= y.value_pointer; + case Token_Gt: return x.value_pointer > y.value_pointer; + case Token_GtEq: return x.value_pointer >= y.value_pointer; + } + } + case ExactValue_Typeid: switch (op) { case Token_CmpEq: return are_types_identical(x.value_typeid, y.value_typeid); diff --git a/src/parser.cpp b/src/parser.cpp index c214df782..9659e8c18 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -3013,69 +3013,6 @@ i32 token_precedence(AstFile *f, TokenKind t) { return 0; } -// Ast *parse_binary_expr(AstFile *f, bool lhs, i32 prec_in) { -// Ast *expr = parse_unary_expr(f, lhs); -// for (i32 prec = token_precedence(f, f->curr_token.kind); prec >= prec_in; prec--) { -// for (;;) { -// Token op = f->curr_token; -// i32 op_prec = token_precedence(f, op.kind); -// if (op_prec != prec) { -// // NOTE(bill): This will also catch operators that are not valid "binary" operators -// break; -// } -// Token prev = f->prev_token; -// switch (op.kind) { -// case Token_if: -// 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; -// } -// break; -// } -// expect_operator(f); // NOTE(bill): error checks too - -// if (op.kind == Token_Question) { -// Ast *cond = expr; -// // Token_Question -// Ast *x = parse_expr(f, lhs); -// Token token_c = expect_token(f, Token_Colon); -// Ast *y = parse_expr(f, lhs); -// expr = ast_ternary_if_expr(f, x, cond, y); -// } else if (op.kind == Token_if || op.kind == Token_when) { -// Ast *x = expr; -// Ast *cond = parse_expr(f, lhs); -// Token tok_else = expect_token(f, Token_else); -// Ast *y = parse_expr(f, lhs); - -// switch (op.kind) { -// case Token_if: -// expr = ast_ternary_if_expr(f, x, cond, y); -// break; -// case Token_when: -// expr = ast_ternary_when_expr(f, x, cond, y); -// break; -// } -// } else { -// Ast *right = parse_binary_expr(f, false, prec+1); -// if (right == nullptr) { -// syntax_error(op, "Expected expression on the right-hand side of the binary operator '%.*s'", LIT(op.string)); -// } -// if (op.kind == Token_or_else) { -// // NOTE(bill): easier to handle its logic different with its own AST kind -// expr = ast_or_else_expr(f, expr, op, right); -// } else { -// expr = ast_binary_expr(f, op, expr, right); -// } -// } - -// lhs = false; -// } -// loop_end:; -// } -// return expr; -// } - Ast *parse_binary_expr(AstFile *f, bool lhs, i32 prec_in) { Ast *expr = parse_unary_expr(f, lhs); for (;;) { -- cgit v1.2.3 From d4ccb69ccc56fb57cad48493a9e5e78ca3529a84 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 28 Feb 2022 21:49:19 +0000 Subject: Check if directory exists with the same target executable name when building a directory --- src/parser.cpp | 16 ++++++++++++++++ src/parser.hpp | 1 + 2 files changed, 17 insertions(+) (limited to 'src/parser.cpp') diff --git a/src/parser.cpp b/src/parser.cpp index 9659e8c18..f70afe346 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -5719,6 +5719,22 @@ ParseFileError parse_packages(Parser *p, String init_filename) { error_line("Expected either a directory or a .odin file, got '%.*s'\n", LIT(init_filename)); return ParseFile_WrongExtension; } + } else if (init_fullpath.len != 0) { + String path = init_fullpath; + if (path[path.len-1] == '/') { + path.len -= 1; + } + if ((build_context.command_kind & Command__does_build) && + build_context.build_mode == BuildMode_Executable) { + String short_path = filename_from_path(path); + char *cpath = alloc_cstring(heap_allocator(), short_path); + defer (gb_free(heap_allocator(), cpath)); + + if (gb_file_exists(cpath)) { + error_line("Please specify the executable name with -out: as a directory exists with the same name in the current working directory"); + return ParseFile_DirectoryAlreadyExists; + } + } } diff --git a/src/parser.hpp b/src/parser.hpp index f6791a291..c33d1520b 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -46,6 +46,7 @@ enum ParseFileError { ParseFile_InvalidToken, ParseFile_GeneralError, ParseFile_FileTooLarge, + ParseFile_DirectoryAlreadyExists, ParseFile_Count, }; -- cgit v1.2.3 From fad851d80c4d2ded5eba6b766ca00d90893c73aa Mon Sep 17 00:00:00 2001 From: Sébastien Marie Date: Thu, 3 Mar 2022 15:57:51 +0000 Subject: check for semi-colon before EOF too --- src/parser.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/parser.cpp') diff --git a/src/parser.cpp b/src/parser.cpp index f70afe346..94a585f35 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1538,7 +1538,7 @@ void fix_advance_to_next_stmt(AstFile *f) { Token expect_closing(AstFile *f, TokenKind kind, String context) { if (f->curr_token.kind != kind && f->curr_token.kind == Token_Semicolon && - f->curr_token.string == "\n") { + (f->curr_token.string == "\n" || f->curr_token.kind == Token_EOF)) { Token tok = f->prev_token; tok.pos.column += cast(i32)tok.string.len; syntax_error(tok, "Missing ',' before newline in %.*s", LIT(context)); @@ -1560,6 +1560,7 @@ void assign_removal_flag_to_semicolon(AstFile *f) { switch (curr_token->kind) { case Token_CloseBrace: case Token_CloseParen: + case Token_EOF: ok = true; break; } -- cgit v1.2.3