aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/codegen.c')
-rw-r--r--src/codegen.c110
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)
// {