diff options
Diffstat (limited to 'src/codegen.c')
-rw-r--r-- | src/codegen.c | 110 |
1 files changed, 83 insertions, 27 deletions
diff --git a/src/codegen.c b/src/codegen.c index 48c43ce..5b883b5 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -1,8 +1,12 @@ #include <ctype.h> +#include <stdbool.h> #include <stdint.h> #include <stdlib.h> #include <string.h> +#include <stdio.h> + +#include <gmp.h> #include <llvm-c/Analysis.h> #include <llvm-c/Core.h> #include <llvm-c/ExecutionEngine.h> @@ -25,30 +29,37 @@ struct cgctx { struct strview namespace; }; -// static LLVMTypeRef type2llvm(struct cgctx, struct type); +static LLVMTypeRef type2llvm(struct cgctx, struct type); // static void str2val(mpq_t, struct strview); // static struct val *cvmap_insert(cvmap **, struct strview, arena *) // __attribute__((nonnull(1))); +static void codegenast(struct cgctx, mpq_t *, struct type *, struct ast, + struct lexemes) + __attribute__((nonnull)); + void -codegen(const char *file, struct type *types, struct ast ast, - struct lexemes toks) +codegen(const char *file, mpq_t *folds, struct scope *scps, struct type *types, + struct ast ast, struct lexemes toks) { (void)types; + (void)scps; (void)ast; (void)toks; char *triple = LLVMGetDefaultTargetTriple(); struct cgctx ctx; - ctx.a = NULL; + ctx.a = NULL; ctx.namespace.p = NULL; - ctx.ctx = LLVMContextCreate(); - ctx.mod = LLVMModuleCreateWithNameInContext("oryx", ctx.ctx); - ctx.bob = LLVMCreateBuilderInContext(ctx.ctx); + ctx.ctx = LLVMContextCreate(); + ctx.mod = LLVMModuleCreateWithNameInContext("oryx", ctx.ctx); + ctx.bob = LLVMCreateBuilderInContext(ctx.ctx); LLVMSetSourceFileName(ctx.mod, file, strlen(file)); LLVMSetTarget(ctx.mod, triple); LLVMDisposeMessage(triple); + codegenast(ctx, folds, types, ast, toks); + arena_free(&ctx.a); LLVMDisposeBuilder(ctx.bob); @@ -63,26 +74,71 @@ codegen(const char *file, struct type *types, struct ast ast, LLVMContextDispose(ctx.ctx); } -// LLVMTypeRef -// type2llvm(struct cgctx ctx, struct type t) -// { -// switch (t.kind) { -// case TYPE_FN: -// err("codegen: %s: Not implemented for function types", __func__); -// case TYPE_NUM: -// /* TODO: Floats */ -// if (t.isfloat) -// err("codegen: %s: Not implemented for floats", __func__); -// /* TODO: Arbitrary precision */ -// if (t.size == 0) -// return LLVMInt64TypeInContext(ctx.ctx); -// assert((unsigned)t.size * 8 <= UINT8_MAX); -// return LLVMIntTypeInContext(ctx.ctx, t.size * 8); -// default: -// __builtin_unreachable(); -// } -// } -// +idx_t_ +codegendecl(struct cgctx ctx, mpq_t *folds, struct type *types, struct ast ast, + struct lexemes toks, idx_t_ i) +{ + /* Constants are purely a compiler concept; they aren’t generated + into anything */ + if ((ast.kinds[i] | 1) == ASTPCDECL) + return fwdnode(ast, i); + + struct pair p = ast.kids[i]; + switch (ast.kinds[p.rhs]) { + case ASTFN: + err("%s():%d: TODO", __func__, __LINE__); + default: { + struct strview sv = toks.strs[ast.lexemes[i]]; + /* TODO: Namespace the name */ + /* TODO: Temporary allocator */ + char *name = bufalloc(NULL, sv.len + 1, 1); + LLVMTypeRef t = type2llvm(ctx, types[i]); + LLVMValueRef globl = LLVMAddGlobal(ctx.mod, t, svtocstr(name, sv)); + free(name); + + /* TODO: Assert that the fold is an integer */ + + /* The max value of a u128 is length 39 */ + char buf[40]; + mpq_get_str(buf, 10, folds[p.rhs]); + + LLVMSetInitializer(globl, LLVMConstIntOfString(t, buf, 10)); + LLVMSetLinkage(globl, LLVMInternalLinkage); + + return fwdnode(ast, i); + } + } +} + +void +codegenast(struct cgctx ctx, mpq_t *folds, struct type *types, struct ast ast, + struct lexemes toks) +{ + for (idx_t_ i = 0; i < ast.len; + i = codegendecl(ctx, folds, types, ast, toks, i)) + ; +} + +LLVMTypeRef +type2llvm(struct cgctx ctx, struct type t) +{ + switch (t.kind) { + case TYPE_FN: + err("codegen: %s: Not implemented for function types", __func__); + case TYPE_NUM: + /* TODO: Floats */ + if (t.isfloat) + err("codegen: %s: Not implemented for floats", __func__); + /* TODO: Arbitrary precision */ + if (t.size == 0) + return LLVMInt64TypeInContext(ctx.ctx); + assert((unsigned)t.size * 8 <= UINT8_MAX); + return LLVMIntTypeInContext(ctx.ctx, t.size * 8); + default: + __builtin_unreachable(); + } +} + // void // str2val(mpq_t rop, struct strview sv) // { |