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;
|
// import std;
|
||||||
|
|
||||||
fn add(a: i32, b: i32) i32 {
|
fn add() i32 {
|
||||||
return a + b;
|
return 1 + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// type is void by default
|
// 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.?)];
|
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 {
|
pub const Codegen = struct {
|
||||||
allocator: *std.mem.Allocator,
|
allocator: *std.mem.Allocator,
|
||||||
|
@ -16,7 +19,7 @@ pub const Codegen = struct {
|
||||||
return Codegen{ .allocator = allocator };
|
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
|
// TODO if expr is Variable, we should do a variable lookup
|
||||||
// in a symbol table, going up in scope, etc.
|
// in a symbol table, going up in scope, etc.
|
||||||
|
|
||||||
|
@ -24,32 +27,58 @@ pub const Codegen = struct {
|
||||||
// TODO Assign modify symbol table
|
// TODO Assign modify symbol table
|
||||||
|
|
||||||
// TODO Calls fetch symbol table, check arity of it at codegen level
|
// 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
|
// 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| {
|
.Binary => |binary| {
|
||||||
var left = try self.genExpr(builder, binary.left);
|
var left = try self.emitExpr(builder, binary.left);
|
||||||
var right = try self.genExpr(builder, binary.right);
|
var right = try self.emitExpr(builder, binary.right);
|
||||||
|
|
||||||
return switch (binary.op.lexeme[0]) {
|
return switch (binary.op.lexeme[0]) {
|
||||||
// TODO other operators
|
// TODO other operators
|
||||||
'+' => llvm.LLVMBuildAdd(builder, left, right, c"addtmp"),
|
'+' => llvm.LLVMBuildAdd(builder, left, right, c"addtmp"),
|
||||||
|
|
||||||
// TODO codegen errors
|
// 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
|
// 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.*) {
|
switch (stmt.*) {
|
||||||
.Expr => |expr| try self.genExpr(builder, expr),
|
.Expr => |expr| _ = try self.emitExpr(builder, expr),
|
||||||
else => unreachable,
|
.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| {
|
for (decl.body.toSlice()) |stmt| {
|
||||||
// TODO custom function context for us
|
// TODO custom function context for us
|
||||||
try self.genFuncStmt(builder, stmt);
|
try self.emitStmt(builder, &stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO codegen decl.body
|
//var tmp = llvm.LLVMBuildAdd(
|
||||||
var tmp = llvm.LLVMBuildAdd(
|
// builder,
|
||||||
builder,
|
// llvm.LLVMGetParam(func, 0),
|
||||||
llvm.LLVMGetParam(func, 0),
|
// llvm.LLVMGetParam(func, 1),
|
||||||
llvm.LLVMGetParam(func, 1),
|
// c"tmp",
|
||||||
c"tmp",
|
//);
|
||||||
);
|
|
||||||
|
|
||||||
_ = llvm.LLVMBuildRet(builder, tmp);
|
//_ = llvm.LLVMBuildRet(builder, tmp);
|
||||||
std.debug.warn("cgen: fn decl done\n");
|
std.debug.warn("cgen: fn decl done\n");
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
|
@ -156,11 +184,9 @@ pub const Codegen = struct {
|
||||||
var data_layout = llvm.LLVMCopyStringRepOfTargetData(target_data);
|
var data_layout = llvm.LLVMCopyStringRepOfTargetData(target_data);
|
||||||
llvm.LLVMSetDataLayout(mod, data_layout);
|
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.o");
|
||||||
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, "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);
|
||||||
|
|
Loading…
Reference in a new issue