From 84f2bcd885296433a4ccf2188639b377293306e4 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 11 Aug 2016 22:05:09 +0100 Subject: [PATCH] Nested Procedures --- examples/main.ll | 6 +++--- examples/main.odin | 10 ++++++---- src/codegen/print_llvm.cpp | 3 +++ src/codegen/ssa.cpp | 25 +++++++++++++++++++++++-- 4 files changed, 35 insertions(+), 9 deletions(-) diff --git a/examples/main.ll b/examples/main.ll index fce46ccd9..d513bdfa8 100644 --- a/examples/main.ll +++ b/examples/main.ll @@ -4,7 +4,7 @@ declare void @llvm.memmove.p0i8.p0i8.i64(i8*, i8*, i64, i32, i1) -define void @thing(i64 ()* %p) { +define void @exec(i64 ()* %p) { "entry - 0": %0 = alloca i64 ()*, align 8 ; p store i64 ()* zeroinitializer, i64 ()** %0 @@ -26,11 +26,11 @@ define void @main() { call void @print_int(i64 %2) call void @print_rune(i32 128149) call void @print_rune(i32 10) - call void @thing(i64 ()* @main$0) + call void @exec(i64 ()* @main$cool_beans) ret void } -define i64 @main$0() { +define i64 @main$cool_beans() { "entry - 0": %0 = alloca i64, align 8 ; a store i64 zeroinitializer, i64* %0 diff --git a/examples/main.odin b/examples/main.odin index 1263a77eb..686e2884b 100644 --- a/examples/main.odin +++ b/examples/main.odin @@ -2,7 +2,7 @@ import "basic" TWO_HEARTS :: '💕'; -thing :: proc(p : proc() -> int) { +exec :: proc(p : proc() -> int) { print_int(p()); print_rune('\n'); } @@ -12,12 +12,14 @@ main :: proc() { print_int(cast(int)a); print_rune(TWO_HEARTS); print_rune('\n'); - thing(proc() -> int { + + cool_beans :: proc() -> int { a : int = 1337; - print_rune(TWO_HEARTS); + print_rune('💕'); print_rune('\n'); return a; - }); + } + exec(cool_beans); } /* diff --git a/src/codegen/print_llvm.cpp b/src/codegen/print_llvm.cpp index a9645cca1..71daf9851 100644 --- a/src/codegen/print_llvm.cpp +++ b/src/codegen/print_llvm.cpp @@ -595,6 +595,9 @@ void ssa_print_proc(gbFile *f, ssaModule *m, ssaProcedure *proc) { gb_for_array(i, proc->anon_procs) { ssa_print_proc(f, m, proc->anon_procs[i]); } + gb_for_array(i, proc->nested_procs) { + ssa_print_proc(f, m, proc->nested_procs[i]); + } } void ssa_print_llvm_ir(gbFile *f, ssaModule *m) { diff --git a/src/codegen/ssa.cpp b/src/codegen/ssa.cpp index a126ae5f2..f07fed9dc 100644 --- a/src/codegen/ssa.cpp +++ b/src/codegen/ssa.cpp @@ -40,7 +40,6 @@ struct ssaProcedure { ssaProcedure *parent; ssaModule * module; String name; - Entity * entity; Type * type; AstNode * type_expr; AstNode * body; @@ -50,6 +49,7 @@ struct ssaProcedure { ssaTargetList * target_list; gbArray(ssaProcedure *) anon_procs; + gbArray(ssaProcedure *) nested_procs; }; @@ -1256,6 +1256,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue return v; return ssa_emit_load(proc, v); } + return NULL; case_end; case_ast_node(pe, ParenExpr, expr); @@ -1481,7 +1482,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue case_end; } - GB_PANIC("Unexpected expression"); + GB_PANIC("Unexpected expression: %.*s", LIT(ast_node_strings[expr->kind])); return NULL; } @@ -1767,6 +1768,26 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { case_end; case_ast_node(pd, ProcDecl, node); + if (proc->nested_procs == NULL) { + // TODO(bill): Cleanup + gb_array_init(proc->nested_procs, gb_heap_allocator()); + } + // NOTE(bill): Generate a new name + // parent$name + String pd_name = pd->name->Ident.token.string; + isize name_len = proc->name.len + 1 + pd_name.len + 1; + u8 *name_text = gb_alloc_array(proc->module->allocator, u8, name_len); + name_len = gb_snprintf(cast(char *)name_text, name_len, "%.*s$%.*s", LIT(proc->name), LIT(pd_name)); + String name = make_string(name_text, name_len-1); + + Entity *e = *map_get(&proc->module->info->definitions, hash_pointer(pd->name)); + ssaValue *value = ssa_make_value_procedure(proc->module->allocator, + proc->module, e->type, pd->type, pd->body, name); + ssaProcedure *np = &value->proc; + gb_array_append(proc->nested_procs, np); + ssa_build_proc(value, proc); + + map_set(&proc->module->values, hash_pointer(e), value); case_end;