diff options
author | Thomas Voss <mail@thomasvoss.com> | 2024-06-19 20:16:49 +0200 |
---|---|---|
committer | Thomas Voss <mail@thomasvoss.com> | 2024-06-19 20:16:49 +0200 |
commit | cb358312c86c6fe13631fb4022cefccee8bba91e (patch) | |
tree | 6bec6a2a98a6df93084b39f6a2e51e163764e9fc /src/codegen.c | |
parent | 4486b6eccd96784cc9423b41e5b6dce7c9a3d740 (diff) |
Various parser fixes
Diffstat (limited to 'src/codegen.c')
-rw-r--r-- | src/codegen.c | 120 |
1 files changed, 87 insertions, 33 deletions
diff --git a/src/codegen.c b/src/codegen.c index 4253bd4..504291a 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -1,4 +1,5 @@ #include <assert.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> @@ -12,67 +13,120 @@ #include "parser.h" #include "types.h" -static size_t codegenexpr(LLVMBuilderRef, struct type *, struct ast, +struct cgctx { + LLVMModuleRef mod; + LLVMBuilderRef bob; + struct strview namespace; +}; + +static size_t codegendecl(struct cgctx, struct type *, struct ast, + struct lexemes, size_t) + __attribute__((nonnull)); +static size_t codegenexpr(struct cgctx, struct type *, struct ast, struct lexemes, size_t, LLVMValueRef *) __attribute__((nonnull)); static LLVMTypeRef type2llvm(struct type); +/* TODO: Don’t do this? */ +#define lengthof(xs) (sizeof(xs) / sizeof(*(xs))) +static struct { + struct strview key; + LLVMValueRef val; +} constants[1024]; +static size_t constcnt; + void codegen(const char *file, struct type *types, struct ast ast, struct lexemes toks) { - LLVMModuleRef mod = LLVMModuleCreateWithName("oryx"); - LLVMSetSourceFileName(mod, file, strlen(file)); - LLVMBuilderRef bob = LLVMCreateBuilder(); + struct cgctx ctx = {0}; + ctx.mod = LLVMModuleCreateWithName("oryx"); + ctx.bob = LLVMCreateBuilder(); + LLVMSetSourceFileName(ctx.mod, file, strlen(file)); for (size_t i = 0; i < ast.len;) { // LLVMValueRef val; assert(ast.kinds[i] == ASTDECL || ast.kinds[i] == ASTCDECL); - // if (ast.kids[i].rhs != AST_EMPTY && types[ast.kids[i].rhs] == - // TYPE_FN) codegenfn(builder, types, ast, toks, i, &val); else - // codegenexpr(builder, types, ast, toks, i, &val); + i = codegendecl(ctx, types, ast, toks, i); /* 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, init; - LLVMTypeRef vartype = type2llvm(types[i]); + // 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, init; + // LLVMTypeRef vartype = type2llvm(types[i]); + // + // globl = LLVMAddGlobal(mod, vartype, name); + // LLVMSetGlobalConstant(globl, ast.kinds[i] == ASTCDECL); + // + // if (ast.kids[i].rhs != AST_EMPTY) { + // i = codegenexpr(bob, types, ast, toks, ast.kids[i].rhs, &init); + // init = LLVMConstTrunc(init, vartype); + // } else { + // init = LLVMConstNull(vartype); + // i = fwdnode(ast, i); + // } + // + // LLVMSetInitializer(globl, init); + // LLVMSetLinkage(globl, LLVMPrivateLinkage); + // + // free(name); + } - globl = LLVMAddGlobal(mod, vartype, name); - LLVMSetGlobalConstant(globl, ast.kinds[i] == ASTCDECL); + LLVMDisposeBuilder(ctx.bob); - if (ast.kids[i].rhs != AST_EMPTY) { - i = codegenexpr(bob, types, ast, toks, ast.kids[i].rhs, &init); - init = LLVMConstTrunc(init, vartype); - } else { - init = LLVMConstNull(vartype); - i += 2; - } + char *error = NULL; + LLVMVerifyModule(ctx.mod, LLVMAbortProcessAction, &error); + LLVMDisposeMessage(error); - LLVMSetInitializer(globl, init); - LLVMSetLinkage(globl, LLVMPrivateLinkage); + LLVMDumpModule(ctx.mod); + LLVMDisposeModule(ctx.mod); +} - free(name); +size_t +codegendecl(struct cgctx ctx, struct type *types, struct ast ast, + struct lexemes toks, size_t i) +{ + struct strview ident = toks.strs[ast.lexemes[i]]; + + char *name; + if (ctx.namespace.len != 0) { + size_t namelen = ident.len + ctx.namespace.len + 1; + name = bufalloc(NULL, namelen + 1, 1); + sprintf(name, "%.*s.%.*s", (int)ctx.namespace.len, ctx.namespace.p, + (int)ident.len, ident.p); + } else { + name = bufalloc(NULL, ident.len + 1, 1); + memcpy(name, ident.p, ident.len); + name[ident.len] = 0; } - LLVMDisposeBuilder(bob); + LLVMValueRef val; + LLVMTypeRef vartype = type2llvm(types[i]); - char *error = NULL; - LLVMVerifyModule(mod, LLVMAbortProcessAction, &error); - LLVMDisposeMessage(error); + if (ast.kids[i].rhs != AST_EMPTY) { + i = codegenexpr(ctx, types, ast, toks, ast.kids[i].rhs, &val); + val = LLVMConstTrunc(val, vartype); + } else { + i = fwdnode(ast, i); + val = LLVMConstNull(vartype); + } + + LLVMValueRef globl = LLVMAddGlobal(ctx.mod, vartype, name); + LLVMSetInitializer(globl, val); + LLVMSetLinkage(globl, LLVMLinkerPrivateLinkage); - LLVMDumpModule(mod); - LLVMDisposeModule(mod); + free(name); + return i; } size_t -codegenexpr(LLVMBuilderRef builder, struct type *types, struct ast ast, +codegenexpr(struct cgctx ctx, struct type *types, struct ast ast, struct lexemes toks, size_t i, LLVMValueRef *v) { - (void)builder; + (void)ctx; switch (ast.kinds[i]) { case ASTNUMLIT: { /* TODO: Arbitrary precision? */ |