diff options
| author | gingerBill <bill@gingerbill.org> | 2021-08-16 11:58:50 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2021-08-16 11:58:50 +0100 |
| commit | e3fef2dadef2b10342222f0314583f6f53e39ff4 (patch) | |
| tree | 8c9d02259b75be22736d65d4a595ee933a26a259 /src | |
| parent | 4c306a6f9958a01302cf09fdff8f7d4ff143c605 (diff) | |
Improve parsing for `or_return`; allow `#force_inline foo() or_return;`
Diffstat (limited to 'src')
| -rw-r--r-- | src/check_stmt.cpp | 15 | ||||
| -rw-r--r-- | src/parser.cpp | 27 |
2 files changed, 21 insertions, 21 deletions
diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 6c5da5197..504c23d53 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1456,21 +1456,6 @@ bool all_operands_valid(Array<Operand> const &operands) { return true; } -Ast *strip_or_return_expr(Ast *node) { - for (;;) { - if (node == nullptr) { - return node; - } - if (node->kind == Ast_OrReturnExpr) { - node = node->OrReturnExpr.expr; - } else if (node->kind == Ast_ParenExpr) { - node = node->ParenExpr.expr; - } else { - return node; - } - } -} - void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { u32 mod_flags = flags & (~Stmt_FallthroughAllowed); switch (node->kind) { diff --git a/src/parser.cpp b/src/parser.cpp index c00585f37..8f3ffb8cc 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1698,6 +1698,22 @@ Ast *unselector_expr(Ast *node) { return node; } +Ast *strip_or_return_expr(Ast *node) { + for (;;) { + if (node == nullptr) { + return node; + } + if (node->kind == Ast_OrReturnExpr) { + node = node->OrReturnExpr.expr; + } else if (node->kind == Ast_ParenExpr) { + node = node->ParenExpr.expr; + } else { + return node; + } + } +} + + Ast *parse_value(AstFile *f); Array<Ast *> parse_element_list(AstFile *f) { @@ -1916,7 +1932,7 @@ bool ast_on_same_line(Ast *x, Ast *y) { Ast *parse_force_inlining_operand(AstFile *f, Token token) { Ast *expr = parse_unary_expr(f, false); - Ast *e = unparen_expr(expr); + Ast *e = strip_or_return_expr(expr); if (e->kind != Ast_ProcLit && e->kind != Ast_CallExpr) { syntax_error(expr, "%.*s must be followed by a procedure literal or call, got %.*s", LIT(token.string), LIT(ast_strings[expr->kind])); return ast_bad_expr(f, token, f->curr_token); @@ -2801,6 +2817,10 @@ Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) { operand = ast_deref_expr(f, operand, expect_token(f, Token_Pointer)); break; + case Token_or_return: + operand = ast_or_return_expr(f, operand, expect_token(f, Token_or_return)); + break; + case Token_OpenBrace: if (!lhs && is_literal_type(operand) && f->expr_level >= 0) { operand = parse_literal_value(f, operand); @@ -2895,7 +2915,6 @@ i32 token_precedence(AstFile *f, TokenKind t) { case Token_if: case Token_when: case Token_or_else: - case Token_or_return: return 1; case Token_Ellipsis: case Token_RangeFull: @@ -2954,8 +2973,6 @@ Ast *parse_binary_expr(AstFile *f, bool lhs, i32 prec_in) { switch (op.kind) { case Token_if: case Token_when: - case Token_or_else: - case Token_or_return: 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; @@ -2989,8 +3006,6 @@ Ast *parse_binary_expr(AstFile *f, bool lhs, i32 prec_in) { Ast *x = expr; Ast *y = parse_expr(f, lhs); expr = ast_or_else_expr(f, x, op, y); - } else if (op.kind == Token_or_return) { - expr = ast_or_return_expr(f, expr, op); } else { Ast *right = parse_binary_expr(f, false, prec+1); if (right == nullptr) { |