Block Expressions and give

This commit is contained in:
Ginger Bill
2016-12-30 15:45:10 +00:00
parent d714bece47
commit 23d32f34e5
12 changed files with 605 additions and 106 deletions
+65 -1
View File
@@ -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: