aboutsummaryrefslogtreecommitdiff
path: root/src/analyze.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/analyze.cpp')
-rw-r--r--src/analyze.cpp66
1 files changed, 35 insertions, 31 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp
index f5c9b5eba4..1bf0ca06ec 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -57,7 +57,7 @@ static AstNode *first_executing_node(AstNode *node) {
case NodeTypeBlock:
case NodeTypeDirective:
case NodeTypeReturnExpr:
- case NodeTypeDeferExpr:
+ case NodeTypeDefer:
case NodeTypeVariableDeclaration:
case NodeTypeTypeDecl:
case NodeTypeErrorValueDecl:
@@ -1456,7 +1456,7 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode
case NodeTypeParamDecl:
case NodeTypeFnDecl:
case NodeTypeReturnExpr:
- case NodeTypeDeferExpr:
+ case NodeTypeDefer:
case NodeTypeRoot:
case NodeTypeBlock:
case NodeTypeBinOpExpr:
@@ -4590,56 +4590,54 @@ static void validate_voided_expr(CodeGen *g, AstNode *source_node, TypeTableEntr
}
}
-static TypeTableEntry *analyze_defer_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
+static TypeTableEntry *analyze_defer(CodeGen *g, ImportTableEntry *import, BlockContext *parent_context,
TypeTableEntry *expected_type, AstNode *node)
{
- if (!context->fn_entry) {
+ if (!parent_context->fn_entry) {
add_node_error(g, node, buf_sprintf("defer expression outside function definition"));
return g->builtin_types.entry_invalid;
}
- if (!node->data.defer_expr.expr) {
+ if (!node->data.defer.expr) {
add_node_error(g, node, buf_sprintf("defer expects an expression"));
return g->builtin_types.entry_void;
}
+ node->data.defer.child_block = new_block_context(node, parent_context);
- switch (node->data.defer_expr.kind) {
+ switch (node->data.defer.kind) {
case ReturnKindUnconditional:
{
- TypeTableEntry *resolved_type = analyze_expression(g, import, context, nullptr,
- node->data.defer_expr.expr);
- validate_voided_expr(g, node->data.defer_expr.expr, resolved_type);
- zig_panic("TODO");
+ TypeTableEntry *resolved_type = analyze_expression(g, import, parent_context, nullptr,
+ node->data.defer.expr);
+ validate_voided_expr(g, node->data.defer.expr, resolved_type);
- //node->data.defer_expr.index_in_block = context->defer_list.length;
- //context->defer_list.append(node);
return g->builtin_types.entry_void;
}
case ReturnKindError:
{
- TypeTableEntry *resolved_type = analyze_expression(g, import, context, nullptr,
- node->data.defer_expr.expr);
+ TypeTableEntry *resolved_type = analyze_expression(g, import, parent_context, nullptr,
+ node->data.defer.expr);
if (resolved_type->id == TypeTableEntryIdInvalid) {
// OK
} else if (resolved_type->id == TypeTableEntryIdErrorUnion) {
// OK
} else {
- add_node_error(g, node->data.defer_expr.expr,
+ add_node_error(g, node->data.defer.expr,
buf_sprintf("expected error type, got '%s'", buf_ptr(&resolved_type->name)));
}
return g->builtin_types.entry_void;
}
case ReturnKindMaybe:
{
- TypeTableEntry *resolved_type = analyze_expression(g, import, context, nullptr,
- node->data.defer_expr.expr);
+ TypeTableEntry *resolved_type = analyze_expression(g, import, parent_context, nullptr,
+ node->data.defer.expr);
if (resolved_type->id == TypeTableEntryIdInvalid) {
// OK
} else if (resolved_type->id == TypeTableEntryIdMaybe) {
// OK
} else {
- add_node_error(g, node->data.defer_expr.expr,
+ add_node_error(g, node->data.defer.expr,
buf_sprintf("expected maybe type, got '%s'", buf_ptr(&resolved_type->name)));
}
return g->builtin_types.entry_void;
@@ -4657,11 +4655,11 @@ static TypeTableEntry *analyze_string_literal_expr(CodeGen *g, ImportTableEntry
}
}
-static TypeTableEntry *analyze_block_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
+static TypeTableEntry *analyze_block_expr(CodeGen *g, ImportTableEntry *import, BlockContext *parent_context,
TypeTableEntry *expected_type, AstNode *node)
{
- BlockContext *child_context = new_block_context(node, context);
- node->data.block.block_context = child_context;
+ BlockContext *child_context = new_block_context(node, parent_context);
+ node->data.block.child_block = child_context;
TypeTableEntry *return_type = g->builtin_types.entry_void;
for (int i = 0; i < node->data.block.statements.length; i += 1) {
@@ -4676,7 +4674,7 @@ static TypeTableEntry *analyze_block_expr(CodeGen *g, ImportTableEntry *import,
if (is_node_void_expr(child)) {
// {unreachable;void;void} is allowed.
// ignore void statements once we enter unreachable land.
- analyze_expression(g, import, context, g->builtin_types.entry_void, child);
+ analyze_expression(g, import, child_context, g->builtin_types.entry_void, child);
continue;
}
add_node_error(g, first_executing_node(child), buf_sprintf("unreachable code"));
@@ -4685,10 +4683,16 @@ static TypeTableEntry *analyze_block_expr(CodeGen *g, ImportTableEntry *import,
bool is_last = (i == node->data.block.statements.length - 1);
TypeTableEntry *passed_expected_type = is_last ? expected_type : nullptr;
return_type = analyze_expression(g, import, child_context, passed_expected_type, child);
+ if (child->type == NodeTypeDefer && return_type->id != TypeTableEntryIdInvalid) {
+ // defer starts a new block context
+ child_context = child->data.defer.child_block;
+ assert(child_context);
+ }
if (!is_last) {
validate_voided_expr(g, child, return_type);
}
}
+ node->data.block.nested_block = child_context;
return return_type;
}
@@ -4750,8 +4754,8 @@ static TypeTableEntry *analyze_expression(CodeGen *g, ImportTableEntry *import,
case NodeTypeReturnExpr:
return_type = analyze_return_expr(g, import, context, expected_type, node);
break;
- case NodeTypeDeferExpr:
- return_type = analyze_defer_expr(g, import, context, expected_type, node);
+ case NodeTypeDefer:
+ return_type = analyze_defer(g, import, context, expected_type, node);
break;
case NodeTypeVariableDeclaration:
analyze_variable_declaration(g, import, context, expected_type, node);
@@ -4956,7 +4960,7 @@ static void analyze_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode
case NodeTypeParamDecl:
case NodeTypeFnDecl:
case NodeTypeReturnExpr:
- case NodeTypeDeferExpr:
+ case NodeTypeDefer:
case NodeTypeRoot:
case NodeTypeBlock:
case NodeTypeBinOpExpr:
@@ -5039,8 +5043,8 @@ static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode
case NodeTypeReturnExpr:
collect_expr_decl_deps(g, import, node->data.return_expr.expr, decl_node);
break;
- case NodeTypeDeferExpr:
- collect_expr_decl_deps(g, import, node->data.defer_expr.expr, decl_node);
+ case NodeTypeDefer:
+ collect_expr_decl_deps(g, import, node->data.defer.expr, decl_node);
break;
case NodeTypePrefixOpExpr:
collect_expr_decl_deps(g, import, node->data.prefix_op_expr.primary_expr, decl_node);
@@ -5361,7 +5365,7 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
case NodeTypeParamDecl:
case NodeTypeFnDecl:
case NodeTypeReturnExpr:
- case NodeTypeDeferExpr:
+ case NodeTypeDefer:
case NodeTypeBlock:
case NodeTypeBinOpExpr:
case NodeTypeUnwrapErrorExpr:
@@ -5552,8 +5556,8 @@ Expr *get_resolved_expr(AstNode *node) {
switch (node->type) {
case NodeTypeReturnExpr:
return &node->data.return_expr.resolved_expr;
- case NodeTypeDeferExpr:
- return &node->data.defer_expr.resolved_expr;
+ case NodeTypeDefer:
+ return &node->data.defer.resolved_expr;
case NodeTypeBinOpExpr:
return &node->data.bin_op_expr.resolved_expr;
case NodeTypeUnwrapErrorExpr:
@@ -5652,7 +5656,7 @@ TopLevelDecl *get_resolved_top_level_decl(AstNode *node) {
return &node->data.type_decl.top_level_decl;
case NodeTypeNumberLiteral:
case NodeTypeReturnExpr:
- case NodeTypeDeferExpr:
+ case NodeTypeDefer:
case NodeTypeBinOpExpr:
case NodeTypeUnwrapErrorExpr:
case NodeTypePrefixOpExpr: