From 71100ed427ee2eec8d8a9d4d9616102738097e80 Mon Sep 17 00:00:00 2001 From: Ginger Bill Date: Tue, 14 Feb 2017 19:26:32 +0000 Subject: Ternary expression (removed if and block expression) --- src/parser.c | 276 +++++++++++++++++++++++++++-------------------------------- 1 file changed, 127 insertions(+), 149 deletions(-) (limited to 'src/parser.c') 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: -- cgit v1.2.3