diff options
| author | Ginger Bill <bill@gingerbill.org> | 2016-12-30 15:45:10 +0000 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2016-12-30 15:45:10 +0000 |
| commit | 23d32f34e526cfb657a72e5b2dab86d1df765f0f (patch) | |
| tree | 7998bcf40ca9f581be6296bf4f68c102a5d234c8 /src/ssa.c | |
| parent | d714bece47ea058e482389452cd428dad9c28fd0 (diff) | |
Block Expressions and `give`
Diffstat (limited to 'src/ssa.c')
| -rw-r--r-- | src/ssa.c | 66 |
1 files changed, 65 insertions, 1 deletions
@@ -2571,7 +2571,7 @@ ssaValue *ssa_find_implicit_value_backing(ssaProcedure *proc, ImplicitValueId id return *value; } - +void ssa_build_stmt_list(ssaProcedure *proc, AstNodeArray stmts); ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue *tv) { expr = unparen_expr(expr); @@ -2626,6 +2626,70 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue return ssa_addr_load(proc, ssa_build_addr(proc, expr)); case_end; + case_ast_node(be, BlockExpr, expr); + ssa_emit_comment(proc, str_lit("BlockExpr")); + ssa_open_scope(proc); + + AstNodeArray stmts = be->stmts; + stmts.count--; + ssa_build_stmt_list(proc, stmts); + + 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); + ssaValue *value = ssa_build_expr(proc, give_expr); + + ssa_close_scope(proc, ssaDeferExit_Default, NULL); + + return value; + case_end; + + case_ast_node(ge, GiveExpr, expr); + ssa_emit_comment(proc, str_lit("GiveExpr")); + + ssaValue *v = NULL; + Type *give_type = type_of_expr(proc->module->info, expr); + GB_ASSERT(give_type != NULL); + if (give_type->kind != Type_Tuple) { + v = ssa_emit_conv(proc, ssa_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); + + ssaValueArray results; + array_init_reserve(&results, proc->module->tmp_allocator, tuple->variable_count); + + for_array(res_index, ge->results) { + ssaValue *res = ssa_build_expr(proc, ge->results.e[res_index]); + Type *t = ssa_type(res); + if (t->kind == Type_Tuple) { + for (isize i = 0; i < t->Tuple.variable_count; i++) { + Entity *e = t->Tuple.variables[i]; + ssaValue *v = ssa_emit_struct_ev(proc, res, i); + array_add(&results, v); + } + } else { + array_add(&results, res); + } + } + + v = ssa_add_local_generated(proc, give_type); + for_array(i, results) { + Entity *e = tuple->variables[i]; + ssaValue *res = ssa_emit_conv(proc, results.e[i], e->type); + ssaValue *field = ssa_emit_struct_ep(proc, v, i); + ssa_emit_store(proc, field, res); + } + + v = ssa_emit_load(proc, v); + + gb_temp_arena_memory_end(tmp); + } + + return v; + case_end; + case_ast_node(ue, UnaryExpr, expr); switch (ue->op.kind) { case Token_Pointer: |