aboutsummaryrefslogtreecommitdiff
path: root/src/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser.c')
-rw-r--r--src/parser.c276
1 files changed, 127 insertions, 149 deletions
diff --git a/src/parser.c b/src/parser.c
index 987022068..52343b649 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -168,24 +168,9 @@ AST_NODE_KIND(_ExprBegin, "", i32) \
Token open; \
Token close; \
}) \
- AST_NODE_KIND(CastExpr, "cast expression", struct { Token token; AstNode *type, *expr; Token open, close; }) \
- AST_NODE_KIND(FieldValue, "field value", struct { Token eq; AstNode *field, *value; }) \
- AST_NODE_KIND(BlockExpr, "block expr", struct { \
- AstNodeArray stmts; \
- Token open, close; \
- AstNode *give_node; \
- }) \
- AST_NODE_KIND(GiveExpr, "give expression", struct { \
- Token token; \
- AstNodeArray results; \
- }) \
- AST_NODE_KIND(IfExpr, "if expression", struct { \
- Token token; \
- AstNode *init; \
- AstNode *cond; \
- AstNode *body; \
- AstNode *else_expr; \
- }) \
+ AST_NODE_KIND(CastExpr, "cast expression", struct { Token token; AstNode *type, *expr; Token open, close; }) \
+ AST_NODE_KIND(FieldValue, "field value", struct { Token eq; AstNode *field, *value; }) \
+ AST_NODE_KIND(TernaryExpr, "ternary expression", struct { AstNode *cond, *x, *y; }) \
AST_NODE_KIND(IntervalExpr, "interval expression", struct { Token op; AstNode *left, *right; }) \
AST_NODE_KIND(_ExprEnd, "", i32) \
AST_NODE_KIND(_StmtBegin, "", i32) \
@@ -465,9 +450,7 @@ Token ast_node_token(AstNode *node) {
case AstNode_CastExpr: return node->CastExpr.token;
case AstNode_FieldValue: return node->FieldValue.eq;
case AstNode_DerefExpr: return node->DerefExpr.op;
- case AstNode_BlockExpr: return node->BlockExpr.open;
- case AstNode_GiveExpr: return node->GiveExpr.token;
- case AstNode_IfExpr: return node->IfExpr.token;
+ case AstNode_TernaryExpr: return ast_node_token(node->TernaryExpr.cond);
case AstNode_IntervalExpr: return ast_node_token(node->IntervalExpr.left);
case AstNode_BadStmt: return node->BadStmt.begin;
@@ -768,29 +751,11 @@ AstNode *ast_compound_lit(AstFile *f, AstNode *type, AstNodeArray elems, Token o
return result;
}
-
-AstNode *ast_block_expr(AstFile *f, AstNodeArray stmts, Token open, Token close) {
- AstNode *result = make_ast_node(f, AstNode_BlockExpr);
- result->BlockExpr.stmts = stmts;
- result->BlockExpr.open = open;
- result->BlockExpr.close = close;
- return result;
-}
-
-AstNode *ast_give_expr(AstFile *f, Token token, AstNodeArray results) {
- AstNode *result = make_ast_node(f, AstNode_GiveExpr);
- result->GiveExpr.token = token;
- result->GiveExpr.results = results;
- return result;
-}
-
-AstNode *ast_if_expr(AstFile *f, Token token, AstNode *init, AstNode *cond, AstNode *body, AstNode *else_expr) {
- AstNode *result = make_ast_node(f, AstNode_IfExpr);
- result->IfExpr.token = token;
- result->IfExpr.init = init;
- result->IfExpr.cond = cond;
- result->IfExpr.body = body;
- result->IfExpr.else_expr = else_expr;
+AstNode *ast_ternary_expr(AstFile *f, AstNode *cond, AstNode *x, AstNode *y) {
+ AstNode *result = make_ast_node(f, AstNode_TernaryExpr);
+ result->TernaryExpr.cond = cond;
+ result->TernaryExpr.x = x;
+ result->TernaryExpr.y = y;
return result;
}
@@ -1321,13 +1286,13 @@ void expect_semicolon(AstFile *f, AstNode *s) {
return;
}
} else {
- switch (s->kind) {
- case AstNode_GiveExpr:
- if (f->curr_token.kind == Token_CloseBrace) {
- return;
- }
- break;
- }
+ // switch (s->kind) {
+ // case AstNode_GiveExpr:
+ // if (f->curr_token.kind == Token_CloseBrace) {
+ // return;
+ // }
+ // break;
+ // }
}
syntax_error(prev_token, "Expected `;` after %.*s, got %.*s",
LIT(ast_node_strings[s->kind]), LIT(token_strings[prev_token.kind]));
@@ -1612,72 +1577,72 @@ AstNode *convert_stmt_to_expr(AstFile *f, AstNode *statement, String kind) {
-AstNode *parse_block_expr(AstFile *f) {
- AstNodeArray stmts = {0};
- Token open, close;
- open = expect_token(f, Token_OpenBrace);
- f->expr_level++;
- stmts = parse_stmt_list(f);
- f->expr_level--;
- close = expect_token(f, Token_CloseBrace);
- return ast_block_expr(f, stmts, open, close);
-}
-
-AstNode *parse_if_expr(AstFile *f) {
- if (f->curr_proc == NULL) {
- syntax_error(f->curr_token, "You cannot use an if expression in the file scope");
- return ast_bad_stmt(f, f->curr_token, f->curr_token);
- }
-
- Token token = expect_token(f, Token_if);
- AstNode *init = NULL;
- AstNode *cond = NULL;
- AstNode *body = NULL;
- AstNode *else_expr = NULL;
-
- isize prev_level = f->expr_level;
- f->expr_level = -1;
-
- if (allow_token(f, Token_Semicolon)) {
- cond = parse_expr(f, false);
- } else {
- init = parse_simple_stmt(f, false);
- if (allow_token(f, Token_Semicolon)) {
- cond = parse_expr(f, false);
- } else {
- cond = convert_stmt_to_expr(f, init, str_lit("boolean expression"));
- init = NULL;
- }
- }
-
- f->expr_level = prev_level;
-
- if (cond == NULL) {
- syntax_error(f->curr_token, "Expected condition for if statement");
- }
-
- body = parse_block_expr(f);
-
- if (allow_token(f, Token_else)) {
- switch (f->curr_token.kind) {
- case Token_if:
- else_expr = parse_if_expr(f);
- break;
- case Token_OpenBrace:
- else_expr = parse_block_expr(f);
- break;
- default:
- syntax_error(f->curr_token, "Expected if expression block statement");
- else_expr = ast_bad_expr(f, f->curr_token, f->tokens.e[f->curr_token_index+1]);
- break;
- }
- } else {
- syntax_error(f->curr_token, "An if expression must have an else clause");
- return ast_bad_stmt(f, f->curr_token, f->tokens.e[f->curr_token_index+1]);
- }
-
- return ast_if_expr(f, token, init, cond, body, else_expr);
-}
+// AstNode *parse_block_expr(AstFile *f) {
+// AstNodeArray stmts = {0};
+// Token open, close;
+// open = expect_token(f, Token_OpenBrace);
+// f->expr_level++;
+// stmts = parse_stmt_list(f);
+// f->expr_level--;
+// close = expect_token(f, Token_CloseBrace);
+// return ast_block_expr(f, stmts, open, close);
+// }
+
+// AstNode *parse_if_expr(AstFile *f) {
+// if (f->curr_proc == NULL) {
+// syntax_error(f->curr_token, "You cannot use an if expression in the file scope");
+// return ast_bad_stmt(f, f->curr_token, f->curr_token);
+// }
+
+// Token token = expect_token(f, Token_if);
+// AstNode *init = NULL;
+// AstNode *cond = NULL;
+// AstNode *body = NULL;
+// AstNode *else_expr = NULL;
+
+// isize prev_level = f->expr_level;
+// f->expr_level = -1;
+
+// if (allow_token(f, Token_Semicolon)) {
+// cond = parse_expr(f, false);
+// } else {
+// init = parse_simple_stmt(f, false);
+// if (allow_token(f, Token_Semicolon)) {
+// cond = parse_expr(f, false);
+// } else {
+// cond = convert_stmt_to_expr(f, init, str_lit("boolean expression"));
+// init = NULL;
+// }
+// }
+
+// f->expr_level = prev_level;
+
+// if (cond == NULL) {
+// syntax_error(f->curr_token, "Expected condition for if statement");
+// }
+
+// body = parse_block_expr(f);
+
+// if (allow_token(f, Token_else)) {
+// switch (f->curr_token.kind) {
+// case Token_if:
+// else_expr = parse_if_expr(f);
+// break;
+// case Token_OpenBrace:
+// else_expr = parse_block_expr(f);
+// break;
+// default:
+// syntax_error(f->curr_token, "Expected if expression block statement");
+// else_expr = ast_bad_expr(f, f->curr_token, f->tokens.e[f->curr_token_index+1]);
+// break;
+// }
+// } else {
+// syntax_error(f->curr_token, "An if expression must have an else clause");
+// return ast_bad_stmt(f, f->curr_token, f->tokens.e[f->curr_token_index+1]);
+// }
+
+// return ast_if_expr(f, token, init, cond, body, else_expr);
+// }
AstNode *parse_operand(AstFile *f, bool lhs) {
AstNode *operand = NULL; // Operand
@@ -1791,16 +1756,16 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
return type;
}
- case Token_if:
- if (!lhs && f->expr_level >= 0) {
- return parse_if_expr(f);
- }
- break;
- case Token_OpenBrace:
- if (!lhs && f->expr_level >= 0) {
- return parse_block_expr(f);
- }
- break;
+ // case Token_if:
+ // if (!lhs && f->expr_level >= 0) {
+ // return parse_if_expr(f);
+ // }
+ // break;
+ // case Token_OpenBrace:
+ // if (!lhs && f->expr_level >= 0) {
+ // return parse_block_expr(f);
+ // }
+ // break;
default: {
AstNode *type = parse_type_or_ident(f);
@@ -1984,6 +1949,19 @@ AstNode *parse_atom_expr(AstFile *f, bool lhs) {
}
break;
+ case Token_Question:
+ if (!lhs && operand != NULL && f->expr_level >= 0) {
+ AstNode *cond = operand;
+ Token token_q = expect_token(f, Token_Question);
+ AstNode *x = parse_expr(f, false);
+ Token token_c = expect_token(f, Token_Colon);
+ AstNode *y = parse_expr(f, false);
+ operand = ast_ternary_expr(f, cond, x, y);
+ } else {
+ loop = false;
+ }
+ break;
+
default:
loop = false;
break;
@@ -2925,27 +2903,27 @@ AstNode *parse_return_stmt(AstFile *f) {
}
-AstNode *parse_give_stmt(AstFile *f) {
- if (f->curr_proc == NULL) {
- syntax_error(f->curr_token, "You cannot use a give statement in the file scope");
- return ast_bad_stmt(f, f->curr_token, f->curr_token);
- }
- if (f->expr_level == 0) {
- syntax_error(f->curr_token, "A give statement must be used within an expression");
- return ast_bad_stmt(f, f->curr_token, f->curr_token);
- }
-
- Token token = expect_token(f, Token_give);
- AstNodeArray results;
- if (f->curr_token.kind != Token_Semicolon && f->curr_token.kind != Token_CloseBrace) {
- results = parse_rhs_expr_list(f);
- } else {
- results = make_ast_node_array(f);
- }
- AstNode *ge = ast_give_expr(f, token, results);
- expect_semicolon(f, ge);
- return ast_expr_stmt(f, ge);
-}
+// AstNode *parse_give_stmt(AstFile *f) {
+// if (f->curr_proc == NULL) {
+// syntax_error(f->curr_token, "You cannot use a give statement in the file scope");
+// return ast_bad_stmt(f, f->curr_token, f->curr_token);
+// }
+// if (f->expr_level == 0) {
+// syntax_error(f->curr_token, "A give statement must be used within an expression");
+// return ast_bad_stmt(f, f->curr_token, f->curr_token);
+// }
+
+// Token token = expect_token(f, Token_give);
+// AstNodeArray results;
+// if (f->curr_token.kind != Token_Semicolon && f->curr_token.kind != Token_CloseBrace) {
+// results = parse_rhs_expr_list(f);
+// } else {
+// results = make_ast_node_array(f);
+// }
+// AstNode *ge = ast_give_expr(f, token, results);
+// expect_semicolon(f, ge);
+// return ast_expr_stmt(f, ge);
+// }
AstNode *parse_for_stmt(AstFile *f) {
if (f->curr_proc == NULL) {
@@ -3227,7 +3205,7 @@ AstNode *parse_stmt(AstFile *f) {
case Token_defer: return parse_defer_stmt(f);
case Token_asm: return parse_asm_stmt(f);
case Token_return: return parse_return_stmt(f);
- case Token_give: return parse_give_stmt(f);
+ // case Token_give: return parse_give_stmt(f);
case Token_break:
case Token_continue: