aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2017-02-14 19:26:32 +0000
committerGinger Bill <bill@gingerbill.org>2017-02-14 19:26:32 +0000
commit71100ed427ee2eec8d8a9d4d9616102738097e80 (patch)
tree913d12b69a404635d0b2442262a300c7084b55bf /src
parent3ecf3505fd62c6aa10190a0be97e8572476e8c8b (diff)
Ternary expression (removed if and block expression)
Diffstat (limited to 'src')
-rw-r--r--src/check_expr.c230
-rw-r--r--src/check_stmt.c11
-rw-r--r--src/checker.c4
-rw-r--r--src/ir.c84
-rw-r--r--src/parser.c276
5 files changed, 181 insertions, 424 deletions
diff --git a/src/check_expr.c b/src/check_expr.c
index 4461a4def..687f4ebea 100644
--- a/src/check_expr.c
+++ b/src/check_expr.c
@@ -1114,11 +1114,12 @@ i64 check_array_or_map_count(Checker *c, AstNode *e, bool is_map) {
}
Type *make_optional_ok_type(gbAllocator a, Type *value) {
+ bool typed = true;
Type *t = make_type_tuple(a);
t->Tuple.variables = gb_alloc_array(a, Entity *, 2);
t->Tuple.variable_count = 2;
t->Tuple.variables[0] = make_entity_field(a, NULL, blank_token, value, false, 0);
- t->Tuple.variables[1] = make_entity_field(a, NULL, blank_token, t_bool, false, 1);
+ t->Tuple.variables[1] = make_entity_field(a, NULL, blank_token, typed ? t_bool : t_untyped_bool, false, 1);
return t;
}
@@ -2113,6 +2114,7 @@ void check_cast(Checker *c, Operand *x, Type *type) {
gb_string_free(from_type);
gb_string_free(to_type);
gb_string_free(expr_str);
+
x->mode = Addressing_Invalid;
return;
}
@@ -3831,7 +3833,8 @@ int valid_proc_and_score_cmp(void const *a, void const *b) {
typedef Array(Operand) ArrayOperand;
-void check_unpack_arguments(Checker *c, isize lhs_count, ArrayOperand *operands, AstNodeArray rhs, bool allow_ok) {
+bool check_unpack_arguments(Checker *c, isize lhs_count, ArrayOperand *operands, AstNodeArray rhs, bool allow_ok) {
+ bool optional_ok = false;
for_array(i, rhs) {
Operand o = {0};
check_multi_expr(c, &o, rhs.e[i]);
@@ -3849,6 +3852,8 @@ void check_unpack_arguments(Checker *c, isize lhs_count, ArrayOperand *operands,
ok.type = t_bool;
array_add(operands, val);
array_add(operands, ok);
+
+ optional_ok = true;
} else {
array_add(operands, o);
}
@@ -3860,6 +3865,8 @@ void check_unpack_arguments(Checker *c, isize lhs_count, ArrayOperand *operands,
}
}
}
+
+ return optional_ok;
}
Type *check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode *call) {
@@ -4162,40 +4169,6 @@ bool check_set_index_data(Operand *o, Type *type, bool indirection, i64 *max_cou
return false;
}
-
-bool check_is_giving(AstNode *node, AstNode **give_expr) {
- switch (node->kind) {
- case_ast_node(es, ExprStmt, node);
- if (es->expr->kind == AstNode_GiveExpr) {
- if (give_expr) *give_expr = es->expr;
- return true;
- }
- case_end;
-
- case_ast_node(ge, GiveExpr, node);
- if (give_expr) *give_expr = node;
- return true;
- case_end;
-
- case_ast_node(be, BlockExpr, node);
- // Iterate backwards
- for (isize n = be->stmts.count-1; n >= 0; n--) {
- AstNode *stmt = be->stmts.e[n];
- if (stmt->kind == AstNode_EmptyStmt) {
- continue;
- }
- if (stmt->kind == AstNode_ExprStmt && stmt->ExprStmt.expr->kind == AstNode_GiveExpr) {
- if (give_expr) *give_expr = stmt->ExprStmt.expr;
- return true;
- }
- }
- case_end;
- }
-
- if (give_expr) *give_expr = NULL;
- return false;
-}
-
ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint) {
ExprKind kind = Expr_Stmt;
@@ -4297,177 +4270,30 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
o->type = type;
case_end;
- case_ast_node(ge, GiveExpr, node);
+ case_ast_node(te, TernaryExpr, node);
if (c->proc_stack.count == 0) {
- error_node(node, "A give expression is only allowed within a procedure");
+ error_node(node, "A ternary expression is only allowed within a procedure");
goto error;
}
-
- if (ge->results.count == 0) {
- error_node(node, "`give` has no results");
- goto error;
- }
-
- gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
-
- Array(Operand) operands;
- array_init_reserve(&operands, c->tmp_allocator, 2*ge->results.count);
-
- for_array(i, ge->results) {
- AstNode *rhs = ge->results.e[i];
- Operand o = {0};
- check_multi_expr(c, &o, rhs);
- if (!is_operand_value(o)) {
- error_node(rhs, "Expected a value for a `give`");
- continue;
- }
- if (o.type->kind != Type_Tuple) {
- array_add(&operands, o);
- } else {
- TypeTuple *tuple = &o.type->Tuple;
- for (isize j = 0; j < tuple->variable_count; j++) {
- o.type = tuple->variables[j]->type;
- array_add(&operands, o);
- }
- }
- }
-
- if (operands.count == 0) {
- error_node(node, "`give` has no value");
- gb_temp_arena_memory_end(tmp);
- goto error;
- } else if (operands.count == 1) {
- Operand operand = operands.e[0];
- Type *th = type_hint != NULL ? type_hint : c->context.type_hint;
- if (th != NULL) {
- convert_to_typed(c, &operand, th, 0);
- }
- // IMPORTANT NOTE(bill): This type could be untyped!!!
- o->type = default_type(operand.type);
- o->mode = Addressing_Value;
- } else {
- Type *tuple = make_type_tuple(c->allocator);
-
- Entity **variables = gb_alloc_array(c->allocator, Entity *, operands.count);
- isize variable_index = 0;
- for_array(i, operands) {
- Operand operand = operands.e[i];
- // Type *type = default_type(operand.type);
- Type *type = operand.type;
- switch (operand.mode) {
- case Addressing_Constant:
- variables[variable_index++] = make_entity_constant(c->allocator, NULL, empty_token, type, operand.value);
- break;
- default:
- variables[variable_index++] = make_entity_param(c->allocator, NULL, empty_token, type, false, true);
- break;
- }
- }
- tuple->Tuple.variables = variables;
- tuple->Tuple.variable_count = operands.count;
-
- o->type = tuple;
- o->mode = Addressing_Value;
- }
- gb_temp_arena_memory_end(tmp);
- case_end;
-
- case_ast_node(be, BlockExpr, node);
- if (c->proc_stack.count == 0) {
- error_node(node, "A block expression is only allowed within a procedure");
- goto error;
- }
-
- for (isize i = be->stmts.count-1; i >= 0; i--) {
- if (be->stmts.e[i]->kind != AstNode_EmptyStmt) {
- break;
- }
- be->stmts.count--;
- }
-
- if (be->stmts.count == 0) {
- error_node(node, "Empty block expression");
- goto error;
- }
-
- CheckerContext prev_context = c->context;
- c->context.type_hint = type_hint;
- check_open_scope(c, node);
- check_stmt_list(c, be->stmts, Stmt_GiveAllowed);
- check_close_scope(c);
-
- c->context = prev_context;
-
- AstNode *give_node = NULL;
- if (!check_is_giving(node, &give_node) || give_node == NULL) {
- error_node(node, "Missing give statement at end of block expression");
- goto error;
- }
-
- GB_ASSERT(give_node != NULL && give_node->kind == AstNode_GiveExpr);
- be->give_node = give_node;
-
- Type *type = type_of_expr(&c->info, give_node);
- if (type == NULL) {
- goto error;
- } else if (type == t_invalid) {
- o->type = t_invalid;
- o->mode = Addressing_Invalid;
- } else {
- o->type = type;
- o->mode = Addressing_Value;
- }
- case_end;
-
- case_ast_node(ie, IfExpr, node);
- if (c->proc_stack.count == 0) {
- error_node(node, "An if expression is only allowed within a procedure");
- goto error;
- }
-
- check_open_scope(c, node);
-
- if (ie->init != NULL) {
- check_stmt(c, ie->init, 0);
- }
-
Operand operand = {Addressing_Invalid};
- check_expr(c, &operand, ie->cond);
+ check_expr(c, &operand, te->cond);
if (operand.mode != Addressing_Invalid && !is_type_boolean(operand.type)) {
- error_node(ie->cond, "Non-boolean condition in if expression");
+ error_node(te->cond, "Non-boolean condition in if expression");
}
Operand x = {Addressing_Invalid};
Operand y = {Addressing_Invalid};
- Type *if_type = NULL;
- Type *else_type = NULL;
- if (type_hint) {
- gb_printf_err("here\n");
- }
- check_expr_with_type_hint(c, &x, ie->body, type_hint);
- if_type = x.type;
-
- if (ie->else_expr != NULL) {
- switch (ie->else_expr->kind) {
- case AstNode_IfExpr:
- case AstNode_BlockExpr:
- check_expr_with_type_hint(c, &y, ie->else_expr, if_type);
- else_type = y.type;
- break;
- default:
- error_node(ie->else_expr, "Invalid else expression in if expression");
- break;
- }
+ check_expr_with_type_hint(c, &x, te->x, type_hint);
+
+ if (te->y != NULL) {
+ check_expr_with_type_hint(c, &y, te->y, type_hint);
} else {
- error_node(ie->else_expr, "An if expression must have an else expression");
- check_close_scope(c);
+ error_node(node, "A ternary expression must have an else clause");
goto error;
}
- check_close_scope(c);
-
- if (if_type == NULL || if_type == t_invalid ||
- else_type == NULL || else_type == t_invalid) {
+ if (x.type == NULL || x.type == t_invalid ||
+ y.type == NULL || y.type == t_invalid) {
goto error;
}
@@ -4482,16 +4308,16 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
}
- if (!are_types_identical(if_type, else_type)) {
- gbString its = type_to_string(if_type);
- gbString ets = type_to_string(else_type);
- error_node(node, "Mismatched types in if expression, %s vs %s", its, ets);
+ if (!are_types_identical(x.type, y.type)) {
+ gbString its = type_to_string(x.type);
+ gbString ets = type_to_string(y.type);
+ error_node(node, "Mismatched types in ternary expression, %s vs %s", its, ets);
gb_string_free(ets);
gb_string_free(its);
goto error;
}
- o->type = if_type;
+ o->type = x.type;
o->mode = Addressing_Value;
case_end;
@@ -5371,12 +5197,6 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
str = gb_string_appendc(str, "}");
case_end;
- case_ast_node(be, BlockExpr, node);
- str = gb_string_appendc(str, "block expression");
- case_end;
- case_ast_node(ie, IfExpr, node);
- str = gb_string_appendc(str, "if expression");
- case_end;
case_ast_node(te, TagExpr, node);
str = gb_string_appendc(str, "#");
diff --git a/src/check_stmt.c b/src/check_stmt.c
index 138e1277e..7315f80ee 100644
--- a/src/check_stmt.c
+++ b/src/check_stmt.c
@@ -30,11 +30,6 @@ void check_stmt_list(Checker *c, AstNodeArray stmts, u32 flags) {
case AstNode_ReturnStmt:
error_node(n, "Statements after this `return` are never executed");
break;
- case AstNode_ExprStmt:
- if (n->ExprStmt.expr->kind == AstNode_GiveExpr) {
- error_node(n, "A `give` must be the last statement in a block");
- }
- break;
}
}
@@ -413,12 +408,6 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
if (operand.expr->kind == AstNode_CallExpr) {
return;
}
- if (operand.expr->kind == AstNode_GiveExpr) {
- if ((flags&Stmt_GiveAllowed) != 0) {
- return;
- }
- error_node(node, "Illegal use of `give`");
- }
gbString expr_str = expr_to_string(operand.expr);
error_node(node, "Expression is not used: `%s`", expr_str);
gb_string_free(expr_str);
diff --git a/src/checker.c b/src/checker.c
index 9fbf3d36d..0b3c66166 100644
--- a/src/checker.c
+++ b/src/checker.c
@@ -400,9 +400,7 @@ void check_open_scope(Checker *c, AstNode *node) {
node = unparen_expr(node);
GB_ASSERT(node->kind == AstNode_Invalid ||
is_ast_node_stmt(node) ||
- is_ast_node_type(node) ||
- node->kind == AstNode_BlockExpr ||
- node->kind == AstNode_IfExpr );
+ is_ast_node_type(node));
Scope *scope = make_scope(c->context.scope, c->allocator);
add_scope(c, node, scope);
if (node->kind == AstNode_ProcType) {
diff --git a/src/ir.c b/src/ir.c
index e6bf588de..ad6f65fea 100644
--- a/src/ir.c
+++ b/src/ir.c
@@ -2851,25 +2851,40 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
return ir_addr_load(proc, ir_build_addr(proc, expr));
case_end;
- case_ast_node(be, BlockExpr, expr);
- ir_emit_comment(proc, str_lit("BlockExpr"));
- ir_open_scope(proc);
+ case_ast_node(te, TernaryExpr, expr);
+ ir_emit_comment(proc, str_lit("TernaryExpr"));
- AstNodeArray stmts = be->stmts;
- stmts.count--;
- ir_build_stmt_list(proc, stmts);
+ irValueArray edges = {0};
+ array_init_reserve(&edges, proc->module->allocator, 2);
- AstNode *give_stmt = be->stmts.e[be->stmts.count-1];
- GB_ASSERT(give_stmt->kind == AstNode_ExprStmt);
- AstNode *give_expr = give_stmt->ExprStmt.expr;
- GB_ASSERT(give_expr->kind == AstNode_GiveExpr);
- irValue *value = ir_build_expr(proc, give_expr);
+ GB_ASSERT(te->y != NULL);
+ irBlock *then = ir_new_block(proc, NULL, "if.then");
+ irBlock *done = ir_new_block(proc, NULL, "if.done"); // NOTE(bill): Append later
+ irBlock *else_ = ir_new_block(proc, NULL, "if.else");
+ irValue *cond = ir_build_cond(proc, te->cond, then, else_);
+ ir_start_block(proc, then);
+
+ ir_open_scope(proc);
+ array_add(&edges, ir_build_expr(proc, te->x));
ir_close_scope(proc, irDeferExit_Default, NULL);
- return value;
+ ir_emit_jump(proc, done);
+ ir_start_block(proc, else_);
+
+ ir_open_scope(proc);
+ array_add(&edges, ir_build_expr(proc, te->y));
+ ir_close_scope(proc, irDeferExit_Default, NULL);
+
+ ir_emit_jump(proc, done);
+ ir_start_block(proc, done);
+
+ Type *type = type_of_expr(proc->module->info, expr);
+
+ return ir_emit(proc, ir_make_instr_phi(proc, edges, type));
case_end;
+#if 0
case_ast_node(ie, IfExpr, expr);
ir_emit_comment(proc, str_lit("IfExpr"));
if (ie->init != NULL) {
@@ -2908,50 +2923,7 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
return ir_emit(proc, ir_make_instr_phi(proc, edges, type));
case_end;
-
- case_ast_node(ge, GiveExpr, expr);
- ir_emit_comment(proc, str_lit("GiveExpr"));
-
- irValue *v = NULL;
- Type *give_type = type_of_expr(proc->module->info, expr);
- GB_ASSERT(give_type != NULL);
- if (give_type->kind != Type_Tuple) {
- v = ir_emit_conv(proc, ir_build_expr(proc, ge->results.e[0]), give_type);
- } else {
- TypeTuple *tuple = &give_type->Tuple;
- gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&proc->module->tmp_arena);
-
- irValueArray results;
- array_init_reserve(&results, proc->module->tmp_allocator, tuple->variable_count);
-
- for_array(res_index, ge->results) {
- irValue *res = ir_build_expr(proc, ge->results.e[res_index]);
- Type *t = ir_type(res);
- if (t->kind == Type_Tuple) {
- for (isize i = 0; i < t->Tuple.variable_count; i++) {
- Entity *e = t->Tuple.variables[i];
- irValue *v = ir_emit_struct_ev(proc, res, i);
- array_add(&results, v);
- }
- } else {
- array_add(&results, res);
- }
- }
-
- v = ir_add_local_generated(proc, give_type);
- for_array(i, results) {
- Entity *e = tuple->variables[i];
- irValue *res = ir_emit_conv(proc, results.e[i], e->type);
- irValue *field = ir_emit_struct_ep(proc, v, i);
- ir_emit_store(proc, field, res);
- }
- v = ir_emit_load(proc, v);
-
- gb_temp_arena_memory_end(tmp);
- }
-
- return v;
- case_end;
+#endif
case_ast_node(ce, CastExpr, expr);
Type *type = tv->type;
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: