Compare commits
3 commits
4a2cc4b524
...
4c1bdb5f91
Author | SHA1 | Date | |
---|---|---|---|
4c1bdb5f91 | |||
05c480c364 | |||
469625d32a |
2 changed files with 69 additions and 14 deletions
|
@ -7,6 +7,8 @@ fn sliceify(non_slice: ?[*]const u8) []const u8 {
|
||||||
return non_slice.?[0..std.mem.len(u8, non_slice.?)];
|
return non_slice.?[0..std.mem.len(u8, non_slice.?)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const CompileError = error{LLVMError};
|
||||||
|
|
||||||
pub const Codegen = struct {
|
pub const Codegen = struct {
|
||||||
allocator: *std.mem.Allocator,
|
allocator: *std.mem.Allocator,
|
||||||
|
|
||||||
|
@ -14,6 +16,43 @@ pub const Codegen = struct {
|
||||||
return Codegen{ .allocator = allocator };
|
return Codegen{ .allocator = allocator };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn genExpr(self: *Codegen, builder: var, expr: *const ast.Expr) !llvm.LLVMValueRef {
|
||||||
|
// TODO if expr is Variable, we should do a variable lookup
|
||||||
|
// in a symbol table, going up in scope, etc.
|
||||||
|
|
||||||
|
// TODO VarDecl add things to the symbol table
|
||||||
|
// TODO Assign modify symbol table
|
||||||
|
|
||||||
|
// TODO Calls fetch symbol table, check arity of it at codegen level
|
||||||
|
switch (expr.*) {
|
||||||
|
|
||||||
|
// TODO handle all literals, construct llvm values for them
|
||||||
|
.Literal => |literal| {},
|
||||||
|
.Binary => |binary| {
|
||||||
|
var left = try self.genExpr(builder, binary.left);
|
||||||
|
var right = try self.genExpr(builder, binary.right);
|
||||||
|
|
||||||
|
return switch (binary.op.lexeme[0]) {
|
||||||
|
// TODO other operators
|
||||||
|
'+' => llvm.LLVMBuildAdd(builder, left, right, c"addtmp"),
|
||||||
|
|
||||||
|
// TODO codegen errors
|
||||||
|
else => @panic("invalid binary operator"),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
// TODO codegen errors
|
||||||
|
else => @panic("invalid expr"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn genFuncStmt(self: *Codegen, builder: var, stmt: *const ast.Stmt) !void {
|
||||||
|
switch (stmt.*) {
|
||||||
|
.Expr => |expr| try self.genExpr(builder, expr),
|
||||||
|
else => unreachable,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn genNode(
|
fn genNode(
|
||||||
self: *Codegen,
|
self: *Codegen,
|
||||||
mod: llvm.LLVMModuleRef,
|
mod: llvm.LLVMModuleRef,
|
||||||
|
@ -48,6 +87,11 @@ pub const Codegen = struct {
|
||||||
var builder = llvm.LLVMCreateBuilder();
|
var builder = llvm.LLVMCreateBuilder();
|
||||||
llvm.LLVMPositionBuilderAtEnd(builder, entry);
|
llvm.LLVMPositionBuilderAtEnd(builder, entry);
|
||||||
|
|
||||||
|
for (decl.body.toSlice()) |stmt| {
|
||||||
|
// TODO custom function context for us
|
||||||
|
try self.genFuncStmt(builder, stmt);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO codegen decl.body
|
// TODO codegen decl.body
|
||||||
var tmp = llvm.LLVMBuildAdd(
|
var tmp = llvm.LLVMBuildAdd(
|
||||||
builder,
|
builder,
|
||||||
|
@ -89,23 +133,19 @@ pub const Codegen = struct {
|
||||||
|
|
||||||
if (llvm.LLVMWriteBitcodeToFile(mod, c"awoo.bc") != 0) {
|
if (llvm.LLVMWriteBitcodeToFile(mod, c"awoo.bc") != 0) {
|
||||||
std.debug.warn("error writing bitcode to file: {}\n", sliceify(err));
|
std.debug.warn("error writing bitcode to file: {}\n", sliceify(err));
|
||||||
|
return CompileError.LLVMError;
|
||||||
// TODO return error value
|
|
||||||
@panic("compile error");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//llvm.InitializeAllTargetInfos();
|
llvm.LLVMInitializeAllTargetInfos();
|
||||||
//llvm.InitializeAllTargets();
|
llvm.LLVMInitializeAllTargets();
|
||||||
//llvm.InitializeAllTargetMCs();
|
llvm.LLVMInitializeAllTargetMCs();
|
||||||
//llvm.InitializeAllAsmParsers();
|
llvm.LLVMInitializeAllAsmParsers();
|
||||||
//llvm.InitializeAllAsmPrinters();
|
llvm.LLVMInitializeAllAsmPrinters();
|
||||||
|
|
||||||
var engine: llvm.LLVMExecutionEngineRef = undefined;
|
var engine: llvm.LLVMExecutionEngineRef = undefined;
|
||||||
if (llvm.LLVMCreateExecutionEngineForModule(&engine, mod, &err) != 0) {
|
if (llvm.LLVMCreateExecutionEngineForModule(&engine, mod, &err) != 0) {
|
||||||
std.debug.warn("failed to create execution engine: {}\n", sliceify(err));
|
std.debug.warn("failed to create execution engine: {}\n", sliceify(err));
|
||||||
|
return CompileError.LLVMError;
|
||||||
// TODO return error value
|
|
||||||
@panic("compile error");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var machine = llvm.LLVMGetExecutionEngineTargetMachine(engine);
|
var machine = llvm.LLVMGetExecutionEngineTargetMachine(engine);
|
||||||
|
@ -119,6 +159,9 @@ pub const Codegen = struct {
|
||||||
var outpath = try std.mem.dupe(self.allocator, u8, "output.o");
|
var outpath = try std.mem.dupe(self.allocator, u8, "output.o");
|
||||||
var outpath_cstr = try std.cstr.addNullByte(self.allocator, outpath);
|
var outpath_cstr = try std.cstr.addNullByte(self.allocator, outpath);
|
||||||
|
|
||||||
|
//var asmpath = try std.mem.dupe(self.allocator, u8, "output.S");
|
||||||
|
//var asmpath_cstr = try std.cstr.addNullByte(self.allocator, asmpath);
|
||||||
|
|
||||||
var desc = llvm.LLVMGetTargetDescription(target);
|
var desc = llvm.LLVMGetTargetDescription(target);
|
||||||
var features = llvm.LLVMGetTargetMachineFeatureString(machine);
|
var features = llvm.LLVMGetTargetMachineFeatureString(machine);
|
||||||
var triple = llvm.LLVMGetTargetMachineTriple(machine);
|
var triple = llvm.LLVMGetTargetMachineTriple(machine);
|
||||||
|
@ -127,6 +170,17 @@ pub const Codegen = struct {
|
||||||
std.debug.warn("triple: {}\n", sliceify(triple));
|
std.debug.warn("triple: {}\n", sliceify(triple));
|
||||||
std.debug.warn("features: {}\n", sliceify(features));
|
std.debug.warn("features: {}\n", sliceify(features));
|
||||||
|
|
||||||
|
//if (llvm.LLVMTargetMachineEmitToFile(
|
||||||
|
// machine,
|
||||||
|
// mod,
|
||||||
|
// asmpath_cstr.ptr,
|
||||||
|
// llvm.LLVMCodeGenFileType.LLVMAssemblyFile,
|
||||||
|
// &err,
|
||||||
|
//) != 0) {
|
||||||
|
// std.debug.warn("failed to emit to assembly file: {}\n", sliceify(err));
|
||||||
|
// return CompileError.LLVMError;
|
||||||
|
//}
|
||||||
|
|
||||||
if (llvm.LLVMTargetMachineEmitToFile(
|
if (llvm.LLVMTargetMachineEmitToFile(
|
||||||
machine,
|
machine,
|
||||||
mod,
|
mod,
|
||||||
|
@ -135,9 +189,7 @@ pub const Codegen = struct {
|
||||||
&err,
|
&err,
|
||||||
) != 0) {
|
) != 0) {
|
||||||
std.debug.warn("failed to emit to file: {}\n", sliceify(err));
|
std.debug.warn("failed to emit to file: {}\n", sliceify(err));
|
||||||
|
return CompileError.LLVMError;
|
||||||
// TODO return error value
|
|
||||||
@panic("compile error");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -46,6 +46,9 @@ pub fn run(allocator: *std.mem.Allocator, slice: []const u8) !Result {
|
||||||
std.debug.warn("parse tree\n");
|
std.debug.warn("parse tree\n");
|
||||||
printer.printNode(root.?, 0);
|
printer.printNode(root.?, 0);
|
||||||
|
|
||||||
|
// TODO type pass
|
||||||
|
// TODO variable pass
|
||||||
|
|
||||||
var cgen = codegen.Codegen.init(allocator);
|
var cgen = codegen.Codegen.init(allocator);
|
||||||
try cgen.gen(root.?);
|
try cgen.gen(root.?);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue