aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/analyzer.c20
-rw-r--r--src/codegen.c110
-rw-r--r--src/codegen.h4
-rw-r--r--src/main.c7
4 files changed, 109 insertions, 32 deletions
diff --git a/src/analyzer.c b/src/analyzer.c
index eaf0ab2..798b34c 100644
--- a/src/analyzer.c
+++ b/src/analyzer.c
@@ -108,6 +108,7 @@ analyzeprog(struct ast ast, struct lexemes toks, arena *a, struct type **types,
analyzeast(*scps, *types, ast, toks, a);
*folds = bufalloc(NULL, ast.len, sizeof(**folds));
+ memset(*folds, 0, ast.len * sizeof(**folds));
constfold(*folds, *scps, *types, ast, toks, a);
}
@@ -401,7 +402,8 @@ constfoldexpr(struct cfctx ctx, mpq_t *folds, struct scope *scps,
}
buf[len] = 0;
- (void)mpq_set_str(folds[i], buf, 10);
+ int ret = mpq_set_str(folds[i], buf, 10);
+ assert(ret == 0);
free(buf);
return fwdnode(ast, i);
@@ -427,12 +429,24 @@ constfoldexpr(struct cfctx ctx, mpq_t *folds, struct scope *scps,
break;
case ASTCDECL:
case ASTPCDECL: {
- *folds[i] = *folds[*ip];
+ idx_t_ expr = ast.kids[*ip].rhs;
+ assert(expr != AST_EMPTY);
+#if DEBUG
+ mpq_init(folds[i]);
+ mpq_set(folds[i], folds[expr]);
+#else
+ *folds[i] = *folds[expr];
+#endif
if ((*folds[i])._mp_den._mp_d == NULL) {
ctx.si = lvl;
(void)constfolddecl(ctx, folds, scps, types, ast, toks,
*ip);
- *folds[i] = *folds[*ip];
+#if DEBUG
+ mpq_init(folds[i]);
+ mpq_set(folds[i], folds[expr]);
+#else
+ *folds[i] = *folds[expr];
+#endif
assert((*folds[i])._mp_den._mp_d != NULL);
}
break;
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)
// {
diff --git a/src/codegen.h b/src/codegen.h
index eda799d..6f4af7a 100644
--- a/src/codegen.h
+++ b/src/codegen.h
@@ -1,11 +1,13 @@
#ifndef ORYX_CODEGEN_H
#define ORYX_CODEGEN_H
+#include <gmp.h>
+
#include "analyzer.h"
#include "lexer.h"
#include "parser.h"
-void codegen(const char *, struct scope *, struct type *, struct ast,
+void codegen(const char *, mpq_t *, struct scope *, struct type *, struct ast,
struct lexemes)
__attribute__((nonnull));
diff --git a/src/main.c b/src/main.c
index 5f36a75..5bd30fe 100644
--- a/src/main.c
+++ b/src/main.c
@@ -37,9 +37,14 @@ main(int argc, char **argv)
struct lexemes toks = lexstring(src, srclen);
struct ast ast = parsetoks(toks);
analyzeprog(ast, toks, &a, &types, &scps, &folds);
- codegen(argv[1], scps, types, ast, toks);
+ codegen(argv[1], folds, scps, types, ast, toks);
#if DEBUG
+ for (size_t i = 0; i < ast.len; i++) {
+ if ((*folds[i])._mp_den._mp_d != NULL)
+ mpq_clear(folds[i]);
+ }
+
free(folds);
free(scps);
free(src);