add the basics of llvm codegen

This commit is contained in:
Luna 2019-09-20 23:40:21 -03:00
parent 250631ff41
commit 6c3d20bbbb
5 changed files with 121 additions and 4 deletions

View file

@ -6,6 +6,8 @@ pub fn build(b: *Builder) void {
exe.setBuildMode(mode);
exe.install();
exe.linkSystemLibrary("LLVM-8");
const run_cmd = exe.run();
run_cmd.step.dependOn(b.getInstallStep());

View file

@ -5,7 +5,7 @@ fn add(a: i32, b: i32) i32 {
}
// type is void by default
fn main() {
std.fmt.print("piss\n");
std.fmt.print("2 + 2 = %d\n", add(1, 2));
}
//fn main() {
// print("piss\n");
// // print("2 + 2 = %d\n", add(1, 2));
//}

85
src/codegen.zig Normal file
View file

@ -0,0 +1,85 @@
const std = @import("std");
const ast = @import("ast.zig");
const llvm = @import("llvm.zig");
pub const Codegen = struct {
allocator: *std.mem.Allocator,
pub fn init(allocator: *std.mem.Allocator) Codegen {
return Codegen{ .allocator = allocator };
}
fn genNode(
self: *Codegen,
mod: llvm.LLVMModuleRef,
node: *const ast.Node,
) !void {
switch (node.*) {
.Root => @panic("Should not have gotten Root"),
.FnDecl => |decl| {
const name = decl.func_name.lexeme;
const name_cstr = try std.cstr.addNullByte(self.allocator, name);
errdefer self.allocator.free(name_cstr);
//const ret_type = decl.return_type.lexeme;
var param_types = llvm.LLVMTypeList.init(self.allocator);
errdefer param_types.deinit();
for (decl.params.toSlice()) |param| {
try param_types.append(llvm.LLVMInt32Type());
}
var ret_type = llvm.LLVMFunctionType(
llvm.LLVMInt32Type(),
param_types.toSlice().ptr,
@intCast(c_uint, param_types.len),
0,
);
var func = llvm.LLVMAddFunction(mod, name_cstr.ptr, ret_type);
var entry = llvm.LLVMAppendBasicBlock(func, c"entry");
var builder = llvm.LLVMCreateBuilder();
llvm.LLVMPositionBuilderAtEnd(builder, entry);
// TODO codegen decl.body
var tmp = llvm.LLVMBuildAdd(
builder,
llvm.LLVMGetParam(func, 0),
llvm.LLVMGetParam(func, 1),
c"tmp",
);
_ = llvm.LLVMBuildRet(builder, tmp);
std.debug.warn("cgen: fn decl done\n");
},
else => {
std.debug.warn("got unhandled Node {}\n", node.*);
unreachable;
},
}
}
pub fn gen(self: *Codegen, root: *ast.Node) !void {
std.debug.warn("cgen: start gen\n");
var mod = llvm.LLVMModuleCreateWithName(c"awoo");
defer llvm.LLVMDisposeModule(mod);
std.debug.warn("cgen: got mod\n");
for (root.Root.toSlice()) |child| {
std.debug.warn("cgen: gen child {}\n", child);
try self.genNode(mod, &child);
}
std.debug.warn("cgen: done\n");
var err: ?[*]u8 = null;
_ = llvm.LLVMVerifyModule(
mod,
llvm.LLVMVerifierFailureAction.LLVMAbortProcessAction,
&err,
);
llvm.LLVMDisposeMessage(err);
}
};

26
src/llvm.zig Normal file
View file

@ -0,0 +1,26 @@
const std = @import("std");
pub const llvm = @cImport({
@cInclude("llvm-c/Core.h");
@cInclude("llvm-c/ExecutionEngine.h");
@cInclude("llvm-c/Target.h");
@cInclude("llvm-c/Analysis.h");
@cInclude("llvm-c/BitWriter.h");
});
usingnamespace llvm;
//pub const LLVMModuleRef = llvm.LLVMModuleRef;
//pub const LLVMInt32Type = llvm.LLVMInt32Type;
//pub const LLVMModuleCreateWithName = llvm.LLVMModuleCreateWithName;
//pub const LLVMFunctionType = llvm.LLVMFunctionType;
//pub const LLVMAddFunction = llvm.LLVMAddFunction;
//
//pub const LLVMBasicBlockRef = llvm.LLVMBasicBlockRef;
//pub const LLVMAppendBasicBlock = llvm.LLVMAppendBasicBlock;
//
//pub const LLVMBuilderRef = llvm.LLVMBuilderRef;
//pub const LLVMCreateBuilder = llvm.LLVMCreateBuilder;
//pub const LLVMPositionBuilderAtEnd = llvm.LLVMPositionBuilderAtEnd;
pub const LLVMTypeList = std.ArrayList(llvm.LLVMTypeRef);

View file

@ -3,6 +3,7 @@ const std = @import("std");
const scanners = @import("scanners.zig");
const parsers = @import("parsers.zig");
const printer = @import("ast_printer.zig");
const codegen = @import("codegen.zig");
pub const Result = enum {
Ok,
@ -45,6 +46,9 @@ pub fn run(allocator: *std.mem.Allocator, slice: []const u8) !Result {
std.debug.warn("parse tree\n");
printer.printNode(root.?, 0);
var cgen = codegen.Codegen.init(allocator);
try cgen.gen(root.?);
return Result.Ok;
}