aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Voss <mail@thomasvoss.com> 2024-06-17 19:06:58 +0200
committerThomas Voss <mail@thomasvoss.com> 2024-06-17 19:06:58 +0200
commitcc8060636ee0a341f68db9ad8fda4ebaabaf49cf (patch)
treedd5ad764d9da79d936c1e7afd31714b99a653888
parent97c386b7cd2d3074e8609513ef85218268635cb3 (diff)
Codegen global variables
-rw-r--r--src/codegen.c97
1 files changed, 57 insertions, 40 deletions
diff --git a/src/codegen.c b/src/codegen.c
index 1db5625..a3a1b87 100644
--- a/src/codegen.c
+++ b/src/codegen.c
@@ -10,6 +10,7 @@
#include "common.h"
#include "errors.h"
#include "parser.h"
+#include "types.h"
static size_t codegenstmt(LLVMBuilderRef, struct ast, struct lexemes,
size_t);
@@ -24,48 +25,64 @@ codegen(struct ast ast, struct lexemes toks)
LLVMBuilderRef builder = LLVMCreateBuilder();
for (size_t i = 0; i < ast.len;) {
- if (ast.kinds[i] != ASTCDECL)
- err("codegen: Expected constant declaration");
-
- size_t expr = ast.kids[i].rhs;
- if (ast.kinds[expr] != ASTFN) {
- assert(!"not implemented");
- __builtin_unreachable();
+ switch (ast.kinds[i]) {
+ case ASTDECL: {
+ /* TODO: Temporary allocator */
+ struct strview sv = toks.strs[ast.lexemes[i]];
+ char *name = bufalloc(NULL, sv.len + 1, 1);
+ ((uchar *)memcpy(name, sv.p, sv.len))[sv.len] = 0;
+
+ LLVMValueRef globl, val;
+ globl = LLVMAddGlobal(mod, LLVMInt64Type(), name);
+ i = codegenexpr(builder, ast, toks, ast.kids[i].rhs, &val);
+ LLVMSetInitializer(globl, val);
+ free(name);
+ break;
}
-
- size_t proto = ast.kids[expr].lhs, body = ast.kids[expr].rhs;
-
- LLVMTypeRef ret;
- LLVMTypeRef params[] = {0};
-
- if (ast.kids[proto].rhs == AST_EMPTY)
- ret = LLVMVoidType();
- else {
- size_t type = ast.kids[proto].rhs;
- struct strview sv = toks.strs[ast.lexemes[type]];
-
- /* TODO: Make int 32bit on 32bit platforms */
- if (strncmp("int", sv.p, sv.len) == 0)
- ret = LLVMInt64Type();
- else
- err("codegen: Unknown type: %.*s", (int)sv.len, sv.p);
+ case ASTCDECL: {
+ idx_t_ expr = ast.kids[i].rhs;
+ if (ast.kinds[expr] != ASTFN) {
+ assert(!"not implemented");
+ __builtin_unreachable();
+ }
+
+ idx_t_ proto = ast.kids[expr].lhs, body = ast.kids[expr].rhs;
+
+ LLVMTypeRef ret;
+ LLVMTypeRef params[] = {0};
+
+ if (ast.kids[proto].rhs == AST_EMPTY)
+ ret = LLVMVoidType();
+ else {
+ size_t type = ast.kids[proto].rhs;
+ struct strview sv = toks.strs[ast.lexemes[type]];
+
+ /* TODO: Make int 32bit on 32bit platforms */
+ if (strncmp("int", sv.p, sv.len) == 0)
+ ret = LLVMInt64Type();
+ else
+ err("codegen: Unknown type: %.*s", (int)sv.len, sv.p);
+ }
+
+ LLVMTypeRef fnproto = LLVMFunctionType(ret, params, 0, false);
+
+ struct strview sv = toks.strs[ast.lexemes[i]];
+ char *fnname = bufalloc(NULL, sv.len + 1, 1);
+ ((char *)memcpy(fnname, sv.p, sv.len))[sv.len] = 0;
+
+ LLVMValueRef fn = LLVMAddFunction(mod, fnname, fnproto);
+ LLVMBasicBlockRef entry = LLVMAppendBasicBlock(fn, "entry");
+ LLVMPositionBuilderAtEnd(builder, entry);
+
+ free(fnname);
+
+ for (i = ast.kids[body].lhs; i <= ast.kids[body].rhs;)
+ i = codegenstmt(builder, ast, toks, i);
+ break;
+ }
+ default:
+ err("codegen: Expected declaration");
}
-
- LLVMTypeRef fnproto = LLVMFunctionType(ret, params, 0, false);
-
- struct strview sv = toks.strs[ast.lexemes[i]];
- char *fnname = bufalloc(NULL, sv.len + 1, 1);
- ((char *)memcpy(fnname, sv.p, sv.len))[sv.len] = 0;
-
- LLVMValueRef fn = LLVMAddFunction(mod, fnname, fnproto);
- LLVMBasicBlockRef entry = LLVMAppendBasicBlock(fn, "entry");
- LLVMPositionBuilderAtEnd(builder, entry);
-
- free(fnname);
-
- for (i = ast.kids[body].lhs; i <= ast.kids[body].rhs;)
- i = codegenstmt(builder, ast, toks, i);
-
}
LLVMDisposeBuilder(builder);