diff options
Diffstat (limited to 'src/codegen.c')
-rw-r--r-- | src/codegen.c | 64 |
1 files changed, 50 insertions, 14 deletions
diff --git a/src/codegen.c b/src/codegen.c index 9a59476..8218bc3 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -35,6 +35,7 @@ struct cgctx { LLVMBuilderRef bob; LLVMValueRef func; + idx_t scpi; strview_t namespace; }; @@ -126,7 +127,12 @@ codegentypedexpr(struct cgctx ctx, idx_t i, type_t type, LLVMValueRef *outv) } assert(ctx.ast.kinds[i] == ASTIDENT); - err("%s():%d: not implemented", __func__, __LINE__); + + strview_t sv = ctx.toks.strs[ctx.ast.lexemes[i]]; + LLVMTypeRef t = type2llvm(ctx, ctx.types[i]); + LLVMValueRef ptrval = symtab_insert(&ctx.scps[ctx.scpi].map, sv, NULL)->v; + *outv = LLVMBuildLoad2(ctx.bob, t, ptrval, "loadtmp"); + return fwdnode(ctx.ast, i); } idx_t @@ -157,12 +163,39 @@ idx_t codegenblk(struct cgctx ctx, idx_t i) { pair_t p = ctx.ast.kids[i]; + while (ctx.scps[ctx.scpi].i != p.lhs) + ctx.scpi++; for (i = p.lhs; i <= p.rhs; i = codegenstmt(ctx, i)) ; return i; } idx_t +codegenalloca(struct cgctx ctx, idx_t i) +{ + pair_t p = ctx.ast.kids[i]; + while (ctx.scps[ctx.scpi].i != p.lhs) + ctx.scpi++; + for (i = p.lhs; i <= p.rhs;) { + switch (ctx.ast.kinds[i]) { + case ASTBLK: + i = codegenalloca(ctx, i); + break; + case ASTDECL: { + strview_t sv = ctx.toks.strs[ctx.ast.lexemes[i]]; + uchar *name = tmpalloc(ctx.s, sv.len + 1, 1); + LLVMTypeRef t = type2llvm(ctx, ctx.types[i]); + symtab_insert(&ctx.scps[ctx.scpi].map, sv, NULL)->v = + LLVMBuildAlloca(ctx.bob, t, svtocstr(name, sv)); + } /* fallthrough */ + default: + i = fwdnode(ctx.ast, i); + } + } + return i; +} + +idx_t codegenfunc(struct cgctx ctx, idx_t i, const char *name) { LLVMTypeRef ret = ctx.types[i].ret == NULL @@ -171,13 +204,19 @@ codegenfunc(struct cgctx ctx, idx_t i, const char *name) LLVMTypeRef ft = LLVMFunctionType(ret, NULL, 0, false); ctx.func = LLVMAddFunction(ctx.mod, name, ft); - LLVMBasicBlockRef entry = LLVMAppendBasicBlockInContext(ctx.ctx, ctx.func, - "entry"); + LLVMBasicBlockRef entry = + LLVMAppendBasicBlockInContext(ctx.ctx, ctx.func, "entry"); LLVMPositionBuilderAtEnd(ctx.bob, entry); - pair_t p = ctx.ast.kids[i]; - i = codegenblk(ctx, p.rhs); - if (ctx.ast.kids[p.lhs].rhs == AST_EMPTY) + idx_t proto = ctx.ast.kids[i].lhs; + idx_t blk = ctx.ast.kids[i].rhs; + + snapshot_t snap = arena_snapshot_create(*ctx.a); + (void)codegenalloca(ctx, blk); + arena_snapshot_restore(ctx.a, snap); + + i = codegenblk(ctx, blk); + if (ctx.ast.kids[proto].rhs == AST_EMPTY) LLVMBuildRetVoid(ctx.bob); return i; } @@ -193,11 +232,10 @@ codegendecl(struct cgctx ctx, idx_t i) if (ctx.ast.kinds[p.rhs] != ASTFN) return fwdnode(ctx.ast, i); - strview_t sv = ctx.toks.strs[ctx.ast.lexemes[i]]; /* TODO: Namespace the name */ + strview_t sv = ctx.toks.strs[ctx.ast.lexemes[i]]; char *name = tmpalloc(ctx.s, sv.len + 1, 1); - svtocstr(name, sv); - return codegenfunc(ctx, p.rhs, name); + return codegenfunc(ctx, p.rhs, svtocstr(name, sv)); } assert(ctx.ast.kinds[i] == ASTDECL); @@ -216,12 +254,10 @@ codegendecl(struct cgctx ctx, idx_t i) return i; } if (!ctx.types[i].isfloat /* && !aux.buf[p.lhs].decl.isstatic */) { - strview_t sv = ctx.toks.strs[ctx.ast.lexemes[i]]; - /* TODO: Namespace the name */ - char *name = tmpalloc(ctx.s, sv.len + 1, 1); - LLVMTypeRef t = type2llvm(ctx, ctx.types[i]); LLVMValueRef var, val; - var = LLVMBuildAlloca(ctx.bob, t, svtocstr(name, sv)); + /* TODO: Namespace the name */ + strview_t sv = ctx.toks.strs[ctx.ast.lexemes[i]]; + var = symtab_insert(&ctx.scps[ctx.scpi].map, sv, NULL)->v; i = codegentypedexpr(ctx, p.rhs, ctx.types[i], &val); LLVMBuildStore(ctx.bob, val, var); return i; |