aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgingerBill <bill+github@gingerbill.org>2016-08-11 22:05:09 +0100
committergingerBill <bill+github@gingerbill.org>2016-08-11 22:05:09 +0100
commit84f2bcd885296433a4ccf2188639b377293306e4 (patch)
treec3ab2164e35ba5a0639de4cad5141447df88ed90
parent19cc77dad301225754bdc797e2bd55f580775048 (diff)
Nested Procedures
-rw-r--r--examples/main.ll6
-rw-r--r--examples/main.odin10
-rw-r--r--src/codegen/print_llvm.cpp3
-rw-r--r--src/codegen/ssa.cpp25
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;