if expression

This commit is contained in:
Ginger Bill
2016-12-30 16:21:45 +00:00
parent 23d32f34e5
commit 2ecafda1d3
6 changed files with 222 additions and 43 deletions
+2 -1
View File
@@ -379,7 +379,8 @@ void check_open_scope(Checker *c, AstNode *node) {
GB_ASSERT(node->kind == AstNode_Invalid ||
is_ast_node_stmt(node) ||
is_ast_node_type(node) ||
node->kind == AstNode_BlockExpr);
node->kind == AstNode_BlockExpr ||
node->kind == AstNode_IfExpr );
Scope *scope = make_scope(c->context.scope, c->allocator);
add_scope(c, node, scope);
if (node->kind == AstNode_ProcType) {
+61 -2
View File
@@ -3744,7 +3744,7 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
case_ast_node(be, BlockExpr, node);
if (c->proc_stack.count == 0) {
error_node(node, "A block expression is only allowed withing a procedure");
error_node(node, "A block expression is only allowed within a procedure");
goto error;
}
@@ -3777,9 +3777,68 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
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);
if (operand.mode != Addressing_Invalid && !is_type_boolean(operand.type)) {
error_node(ie->cond, "Non-boolean condition in if expression");
}
Type *if_type = NULL;
Type *else_type = NULL;
check_expr(c, &operand, ie->body);
if_type = operand.type;
if (ie->else_expr != NULL) {
switch (ie->else_expr->kind) {
case AstNode_IfExpr:
case AstNode_BlockExpr:
check_expr(c, &operand, ie->else_expr);
else_type = operand.type;
break;
default:
error_node(ie->else_expr, "Invalid else expression in if expression");
break;
}
} else {
error_node(ie->else_expr, "An if expression must have an else expression");
check_close_scope(c);
goto error;
}
check_close_scope(c);
GB_ASSERT(if_type != NULL &&
else_type != NULL);
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, "if expression type and else expression type do not match, %s != %s", its, ets);
gb_string_free(ets);
gb_string_free(its);
goto error;
}
o->type = if_type;
o->mode = Addressing_Value;
case_end;
case_ast_node(ye, GiveExpr, node);
if (c->proc_stack.count == 0) {
error_node(node, "A give expression is only allowed withing a procedure");
error_node(node, "A give expression is only allowed within a procedure");
goto error;
}
+1 -1
View File
@@ -504,7 +504,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
check_stmt(c, is->body, mod_flags);
if (is->else_stmt) {
if (is->else_stmt != NULL) {
switch (is->else_stmt->kind) {
case AstNode_IfStmt:
case AstNode_BlockStmt: