aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.c
blob: 48c43ce2a64a89add2df7325fcfe46978bbb2edd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include <ctype.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include <llvm-c/Analysis.h>
#include <llvm-c/Core.h>
#include <llvm-c/ExecutionEngine.h>

#include "alloc.h"
#include "analyzer.h"
#include "common.h"
#include "errors.h"
#include "strview.h"

#define lengthof(xs) (sizeof(xs) / sizeof(*(xs)))

/* A context structure we can pass to all the codegen functions just so they
   have easy access to everything */
struct cgctx {
	arena a;
	LLVMContextRef ctx;
	LLVMModuleRef mod;
	LLVMBuilderRef bob;
	struct strview namespace;
};

// 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)));

void
codegen(const char *file, struct type *types, struct ast ast,
        struct lexemes toks)
{
	(void)types;
	(void)ast;
	(void)toks;
	char *triple = LLVMGetDefaultTargetTriple();

	struct cgctx ctx;
	ctx.a           = NULL;
	ctx.namespace.p = NULL;
	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);

	arena_free(&ctx.a);

	LLVMDisposeBuilder(ctx.bob);

	char *error = NULL;
	if (LLVMVerifyModule(ctx.mod, LLVMReturnStatusAction, &error) == 1)
		err("codegen: %s", error);

	LLVMDisposeMessage(error);
	LLVMDumpModule(ctx.mod);
	LLVMDisposeModule(ctx.mod);
	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();
// 	}
// }
//
// void
// str2val(mpq_t rop, struct strview sv)
// {
// 	mpq_init(rop);
// 	char *clean = bufalloc(NULL, sv.len + 1, 1);
// 	size_t len = 0;
//
// 	for (size_t i = 0; i < sv.len; i++) {
// 		if (isdigit(sv.p[i]))
// 			clean[len++] = sv.p[i];
// 	}
// 	clean[len] = 0;
//
// 	mpq_set_str(rop, clean, 10);
//
// 	free(clean);
// }
//
// struct val *
// cvmap_insert(cvmap **m, struct strview k, arena *a)
// {
// 	for (uint64_t h = strview_hash(k); *m; h <<= 2) {
// 		if (strview_eq(k, (*m)->key))
// 			return &(*m)->val;
// 		m = &(*m)->child[h >> 62];
// 	}
// 	if (a == NULL)
// 		return NULL;
// 	*m = arena_new(a, cvmap, 1);
// 	(*m)->key = k;
// 	return &(*m)->val;
// }