add emitting of integer and float literals
- remove panics - add emitting for return statements - remove default emitting of return a+b;
This commit is contained in:
parent
4c1bdb5f91
commit
013aafa8a4
2 changed files with 53 additions and 27 deletions
|
@ -1,7 +1,7 @@
|
|||
// import std;
|
||||
|
||||
fn add(a: i32, b: i32) i32 {
|
||||
return a + b;
|
||||
fn add() i32 {
|
||||
return 1 + 1;
|
||||
}
|
||||
|
||||
// type is void by default
|
||||
|
|
|
@ -7,7 +7,10 @@ fn sliceify(non_slice: ?[*]const u8) []const u8 {
|
|||
return non_slice.?[0..std.mem.len(u8, non_slice.?)];
|
||||
}
|
||||
|
||||
pub const CompileError = error{LLVMError};
|
||||
pub const CompileError = error{
|
||||
LLVMError,
|
||||
EmitError,
|
||||
};
|
||||
|
||||
pub const Codegen = struct {
|
||||
allocator: *std.mem.Allocator,
|
||||
|
@ -16,7 +19,7 @@ pub const Codegen = struct {
|
|||
return Codegen{ .allocator = allocator };
|
||||
}
|
||||
|
||||
fn genExpr(self: *Codegen, builder: var, expr: *const ast.Expr) !llvm.LLVMValueRef {
|
||||
fn emitExpr(self: *Codegen, builder: var, expr: *const ast.Expr) anyerror!llvm.LLVMValueRef {
|
||||
// TODO if expr is Variable, we should do a variable lookup
|
||||
// in a symbol table, going up in scope, etc.
|
||||
|
||||
|
@ -24,32 +27,58 @@ pub const Codegen = struct {
|
|||
// TODO Assign modify symbol table
|
||||
|
||||
// TODO Calls fetch symbol table, check arity of it at codegen level
|
||||
switch (expr.*) {
|
||||
return switch (expr.*) {
|
||||
|
||||
// TODO handle all literals, construct llvm values for them
|
||||
.Literal => |literal| {},
|
||||
.Literal => |literal| blk: {
|
||||
break :blk switch (literal) {
|
||||
// TODO other literals
|
||||
.Integer => |val| blk2: {
|
||||
var val_cstr = try std.cstr.addNullByte(self.allocator, val);
|
||||
break :blk2 llvm.LLVMConstIntOfString(llvm.LLVMInt32Type(), val_cstr.ptr, 10);
|
||||
},
|
||||
.Float => |val| blk2: {
|
||||
var val_cstr = try std.cstr.addNullByte(self.allocator, val);
|
||||
break :blk2 llvm.LLVMConstRealOfString(llvm.LLVMDoubleType(), val_cstr.ptr);
|
||||
},
|
||||
else => unreachable,
|
||||
};
|
||||
},
|
||||
.Binary => |binary| {
|
||||
var left = try self.genExpr(builder, binary.left);
|
||||
var right = try self.genExpr(builder, binary.right);
|
||||
var left = try self.emitExpr(builder, binary.left);
|
||||
var right = try self.emitExpr(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"),
|
||||
else => {
|
||||
std.debug.warn("Unexpected binary operator: '{}'\n", binary.op.lexeme);
|
||||
return CompileError.EmitError;
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
// TODO codegen errors
|
||||
else => @panic("invalid expr"),
|
||||
}
|
||||
else => {
|
||||
std.debug.warn("Got unexpected expr {}\n", expr.*);
|
||||
return CompileError.EmitError;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
fn genFuncStmt(self: *Codegen, builder: var, stmt: *const ast.Stmt) !void {
|
||||
fn emitStmt(self: *Codegen, builder: var, stmt: *const ast.Stmt) !void {
|
||||
switch (stmt.*) {
|
||||
.Expr => |expr| try self.genExpr(builder, expr),
|
||||
else => unreachable,
|
||||
.Expr => |expr| _ = try self.emitExpr(builder, expr),
|
||||
.Return => |ret| {
|
||||
var ret_expr = try self.emitExpr(builder, ret.value);
|
||||
_ = llvm.LLVMBuildRet(builder, ret_expr);
|
||||
},
|
||||
else => {
|
||||
std.debug.warn("Got unexpected statement {}\n", stmt.*);
|
||||
return CompileError.EmitError;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,18 +118,17 @@ pub const Codegen = struct {
|
|||
|
||||
for (decl.body.toSlice()) |stmt| {
|
||||
// TODO custom function context for us
|
||||
try self.genFuncStmt(builder, stmt);
|
||||
try self.emitStmt(builder, &stmt);
|
||||
}
|
||||
|
||||
// TODO codegen decl.body
|
||||
var tmp = llvm.LLVMBuildAdd(
|
||||
builder,
|
||||
llvm.LLVMGetParam(func, 0),
|
||||
llvm.LLVMGetParam(func, 1),
|
||||
c"tmp",
|
||||
);
|
||||
//var tmp = llvm.LLVMBuildAdd(
|
||||
// builder,
|
||||
// llvm.LLVMGetParam(func, 0),
|
||||
// llvm.LLVMGetParam(func, 1),
|
||||
// c"tmp",
|
||||
//);
|
||||
|
||||
_ = llvm.LLVMBuildRet(builder, tmp);
|
||||
//_ = llvm.LLVMBuildRet(builder, tmp);
|
||||
std.debug.warn("cgen: fn decl done\n");
|
||||
},
|
||||
else => {
|
||||
|
@ -156,11 +184,9 @@ pub const Codegen = struct {
|
|||
var data_layout = llvm.LLVMCopyStringRepOfTargetData(target_data);
|
||||
llvm.LLVMSetDataLayout(mod, data_layout);
|
||||
|
||||
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.o");
|
||||
|
||||
//var asmpath = try std.mem.dupe(self.allocator, u8, "output.S");
|
||||
//var asmpath_cstr = try std.cstr.addNullByte(self.allocator, asmpath);
|
||||
//var asmpath_cstr = try std.cstr.addNullByte(self.allocator, "output.S");
|
||||
|
||||
var desc = llvm.LLVMGetTargetDescription(target);
|
||||
var features = llvm.LLVMGetTargetMachineFeatureString(machine);
|
||||
|
|
Loading…
Reference in a new issue