mirror of
https://github.com/odin-lang/Odin.git
synced 2026-02-27 21:34:59 +00:00
Make or_else and or_return operators (binary and suffix respectively)
This commit is contained in:
@@ -685,6 +685,21 @@ Ast *ast_ternary_when_expr(AstFile *f, Ast *x, Ast *cond, Ast *y) {
|
||||
return result;
|
||||
}
|
||||
|
||||
Ast *ast_or_else_expr(AstFile *f, Ast *x, Token const &token, Ast *y) {
|
||||
Ast *result = alloc_ast_node(f, Ast_OrElseExpr);
|
||||
result->OrElseExpr.x = x;
|
||||
result->OrElseExpr.token = token;
|
||||
result->OrElseExpr.y = y;
|
||||
return result;
|
||||
}
|
||||
|
||||
Ast *ast_or_return_expr(AstFile *f, Ast *expr, Token const &token) {
|
||||
Ast *result = alloc_ast_node(f, Ast_OrReturnExpr);
|
||||
result->OrReturnExpr.expr = expr;
|
||||
result->OrReturnExpr.token = token;
|
||||
return result;
|
||||
}
|
||||
|
||||
Ast *ast_type_assertion(AstFile *f, Ast *expr, Token dot, Ast *type) {
|
||||
Ast *result = alloc_ast_node(f, Ast_TypeAssertion);
|
||||
result->TypeAssertion.expr = expr;
|
||||
@@ -1340,6 +1355,8 @@ Token expect_operator(AstFile *f) {
|
||||
// okay
|
||||
} else if (prev.kind == Token_if || prev.kind == Token_when) {
|
||||
// okay
|
||||
} else if (prev.kind == Token_or_else || prev.kind == Token_or_return) {
|
||||
// okay
|
||||
} else if (!gb_is_between(prev.kind, Token__OperatorBegin+1, Token__OperatorEnd-1)) {
|
||||
String p = token_to_string(prev);
|
||||
syntax_error(f->curr_token, "Expected an operator, got '%.*s'",
|
||||
@@ -2870,6 +2887,8 @@ i32 token_precedence(AstFile *f, TokenKind t) {
|
||||
case Token_Question:
|
||||
case Token_if:
|
||||
case Token_when:
|
||||
case Token_or_else:
|
||||
case Token_or_return:
|
||||
return 1;
|
||||
case Token_Ellipsis:
|
||||
case Token_RangeFull:
|
||||
@@ -2924,14 +2943,18 @@ Ast *parse_binary_expr(AstFile *f, bool lhs, i32 prec_in) {
|
||||
// NOTE(bill): This will also catch operators that are not valid "binary" operators
|
||||
break;
|
||||
}
|
||||
if (op.kind == Token_if || op.kind == Token_when) {
|
||||
Token prev = f->prev_token;
|
||||
Token prev = f->prev_token;
|
||||
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
|
||||
break;
|
||||
goto loop_end;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
expect_operator(f); // NOTE(bill): error checks too
|
||||
|
||||
if (op.kind == Token_Question) {
|
||||
@@ -2955,6 +2978,12 @@ Ast *parse_binary_expr(AstFile *f, bool lhs, i32 prec_in) {
|
||||
Token tok_else = expect_token(f, Token_else);
|
||||
Ast *y = parse_expr(f, lhs);
|
||||
expr = ast_ternary_when_expr(f, x, cond, y);
|
||||
} else if (op.kind == Token_or_else) {
|
||||
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) {
|
||||
@@ -2965,6 +2994,7 @@ Ast *parse_binary_expr(AstFile *f, bool lhs, i32 prec_in) {
|
||||
|
||||
lhs = false;
|
||||
}
|
||||
loop_end:;
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user