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
|
import "llvm.src";
let codegen = struct {
llvm_module: LLVMModuleRef,
llvm_context: LLVMContextRef,
builder: LLVMBuilderRef,
arena: *arena,
};
let codegen_init = (alloc: *arena) => *codegen {
LLVMInitializeAllTargetInfos();
LLVMInitializeAllTargetMCs();
LLVMInitializeAllTargets();
LLVMInitializeAllAsmPrinters();
LLVMInitializeAllAsmParsers();
let module = LLVMModuleCreateWithName("module");
let context = LLVMGetGlobalContext();
let builder = LLVMCreateBuilder();
let c = cast(*codegen, arena_alloc(alloc, sizeof(codegen)));
(*c).llvm_module = module;
(*c).llvm_context = context;
(*c).builder = builder;
(*c).arena = alloc;
return c;
};
let codegen_generate_assignment_statement = (c: *codegen, stmt: *NODE_ASSIGNMENT_STATEMENT_DATA) => i64 {
println("HOLA");
return 0;
};
let codegen_generate_statement = (c: *codegen, statement: *Node) => i64 {
let stmt = *statement;
assert(stmt.type == NODE_ASSIGNMENT_STATEMENT); /* TODO: generate other node types */
let res = codegen_generate_assignment_statement(c, cast(*NODE_ASSIGNMENT_STATEMENT_DATA, stmt.data));
if res != 0 {
return 1;
};
println("STMT: %d", stmt.type);
return 0;
};
let codegen_generate = (c: *codegen, ast: *Node) => i64 {
assert((*ast).type == NODE_PROGRAM);
let program = *cast(*NODE_PROGRAM_DATA, (*ast).data);
let i = 0;
while i < program.statements_len {
let stmt = *(program.statements + cast(**Node, i));
let res = codegen_generate_statement(c, stmt);
if res != 0 {
return 1;
};
i = i + 1;
};
return 0;
};
let codegen_compile = (c: *codegen) => i64 {
/* Dump module */
LLVMDumpModule((*c).llvm_module);
/* Generate code */
let triple = LLVMGetDefaultTargetTriple();
let target_ref = cast(*LLVMTargetRef, arena_alloc((*c).arena, sizeof(*LLVMTargetRef)));
let message = cast(**i8, null);
let result = LLVMGetTargetFromTriple(triple, target_ref, message);
if result != 0 {
println("Target output: %s", *message);
LLVMDisposeMessage(*message);
};
let target_machine = LLVMCreateTargetMachine(
*target_ref,
triple,
"",
"",
LLVMCodeGenLevelDefault,
LLVMRelocDefault,
LLVMCodeModelDefault,
);
LLVMDisposeMessage(triple);
result = LLVMVerifyModule((*c).llvm_module, LLVMAbortProcessAction, message);
if result != 0 {
println("Verification output: %s", *message);
LLVMDisposeMessage(*message);
};
/* Generate the object file */
let filename = "bootstrap_output.o";
LLVMTargetMachineEmitToFile(
target_machine,
(*c).llvm_module,
filename,
LLVMObjectFile,
cast(**i8, null),
);
LLVMDisposeTargetMachine(target_machine);
println("Object file generated: %s", filename);
return 0;
};
let codegen_deinit = (c: *codegen) => void {
LLVMDisposeModule((*c).llvm_module);
LLVMShutdown();
LLVMDisposeBuilder((*c).builder);
return;
};
|