zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 56cdaff9e71c10eb9c4dd130ee2516acacc1c13f (tree)
parent afc5507b6469c9963db8e00efc5648f8e682cf02
Author: Andrew Kelley <superjoe30@gmail.com>
Date:   Sat, 29 Oct 2016 19:24:59 -0400

ir: support return expression

Diffstat:
Msrc/analyze.cpp | 11+----------
Msrc/ir.cpp | 41+++++++++++++++++++++++++++++++++--------
2 files changed, 34 insertions(+), 18 deletions(-)

diff --git a/src/analyze.cpp b/src/analyze.cpp @@ -4970,11 +4970,6 @@ static TypeTableEntry *analyze_switch_expr(CodeGen *g, ImportTableEntry *import, static TypeTableEntry *analyze_return_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, TypeTableEntry *expected_type, AstNode *node) { - if (!context->fn_entry) { - add_node_error(g, node, buf_sprintf("return expression outside function definition")); - return g->builtin_types.entry_invalid; - } - if (!node->data.return_expr.expr) { node->data.return_expr.expr = create_ast_void_node(g, import, node); normalize_parent_ptrs(node); @@ -4984,11 +4979,7 @@ static TypeTableEntry *analyze_return_expr(CodeGen *g, ImportTableEntry *import, switch (node->data.return_expr.kind) { case ReturnKindUnconditional: - { - analyze_expression(g, import, context, expected_return_type, node->data.return_expr.expr); - - return g->builtin_types.entry_unreachable; - } + zig_panic("TODO moved to ir.cpp"); case ReturnKindError: { TypeTableEntry *expected_err_type; diff --git a/src/ir.cpp b/src/ir.cpp @@ -594,6 +594,37 @@ static void ir_gen_defers_for_block(IrBuilder *irb, BlockContext *inner_block, B } } +static IrInstruction *ir_gen_return(IrBuilder *irb, AstNode *node) { + assert(node->type == NodeTypeReturnExpr); + + BlockContext *scope = node->block_context; + + if (!scope->fn_entry) { + add_node_error(irb->codegen, node, buf_sprintf("return expression outside function definition")); + return irb->codegen->invalid_instruction; + } + + AstNode *expr_node = node->data.return_expr.expr; + switch (node->data.return_expr.kind) { + case ReturnKindUnconditional: + { + IrInstruction *return_value; + if (expr_node) { + return_value = ir_gen_node(irb, expr_node, scope); + } else { + return_value = ir_build_const_void(irb, node); + } + + return ir_build_return(irb, node, return_value); + } + case ReturnKindError: + zig_panic("TODO %%return"); + case ReturnKindMaybe: + zig_panic("TODO ?return"); + } + zig_unreachable(); +} + //static IrInstruction *ir_gen_return(IrBuilder *irb, AstNode *source_node, IrInstruction *value, ReturnKnowledge rk) { // BlockContext *defer_inner_block = source_node->block_context; // BlockContext *defer_outer_block = irb->node->block_context; @@ -1230,15 +1261,9 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockCont return ir_gen_while_expr(irb, node); case NodeTypeArrayAccessExpr: return ir_gen_array_access(irb, node, lval); - case NodeTypeUnwrapErrorExpr: case NodeTypeReturnExpr: - // TODO - //if (!scope->fn_entry) { - // add_node_error(ira->codegen, source_node, - // buf_sprintf("return expression outside function definition")); - // return ira->codegen->builtin_types.entry_invalid; - //} - + return ir_gen_return(irb, node); + case NodeTypeUnwrapErrorExpr: case NodeTypeDefer: case NodeTypeSliceExpr: case NodeTypeFieldAccessExpr: