add basics of if statement emitting
- add util mkLLVMBool - add left/right paren to if statements - lowkey fix for statements' semicolon
This commit is contained in:
parent
1ac63cdbef
commit
1bb1fb813d
3 changed files with 36 additions and 9 deletions
|
@ -1,5 +1,14 @@
|
||||||
// import std;
|
// import std;
|
||||||
|
|
||||||
|
fn multwo(num: i32, double_flag: bool) i32 {
|
||||||
|
// TODO resolve expr variables
|
||||||
|
if (true) {
|
||||||
|
return 1 * 2;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn add(a: i32, b: i32) i32 {
|
fn add(a: i32, b: i32) i32 {
|
||||||
return 69 + 69;
|
return 69 + 69;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,14 @@ fn basicTypeToLLVM(ret_type: []const u8) !llvm.LLVMTypeRef {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mkLLVMBool(val: bool) llvm.LLVMValueRef {
|
||||||
|
if (val) {
|
||||||
|
return llvm.LLVMConstInt(llvm.LLVMInt1Type(), 1, 1);
|
||||||
|
} else {
|
||||||
|
return llvm.LLVMConstInt(llvm.LLVMInt1Type(), 0, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub const Codegen = struct {
|
pub const Codegen = struct {
|
||||||
allocator: *std.mem.Allocator,
|
allocator: *std.mem.Allocator,
|
||||||
|
|
||||||
|
@ -56,11 +64,7 @@ pub const Codegen = struct {
|
||||||
break :blk2 llvm.LLVMConstRealOfString(llvm.LLVMDoubleType(), val_cstr.ptr);
|
break :blk2 llvm.LLVMConstRealOfString(llvm.LLVMDoubleType(), val_cstr.ptr);
|
||||||
},
|
},
|
||||||
.Bool => |val| blk2: {
|
.Bool => |val| blk2: {
|
||||||
if (val) {
|
break :blk2 mkLLVMBool(val);
|
||||||
break :blk2 llvm.LLVMConstInt(llvm.LLVMInt1Type(), 1, 1);
|
|
||||||
} else {
|
|
||||||
break :blk2 llvm.LLVMConstInt(llvm.LLVMInt1Type(), 0, 1);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
|
@ -97,10 +101,18 @@ pub const Codegen = struct {
|
||||||
fn emitStmt(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.emitExpr(builder, expr),
|
.Expr => |expr| _ = try self.emitExpr(builder, expr),
|
||||||
|
|
||||||
.Return => |ret| {
|
.Return => |ret| {
|
||||||
var ret_expr = try self.emitExpr(builder, ret.value);
|
var ret_expr = try self.emitExpr(builder, ret.value);
|
||||||
_ = llvm.LLVMBuildRet(builder, ret_expr);
|
_ = llvm.LLVMBuildRet(builder, ret_expr);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
.If => |ifstmt| {
|
||||||
|
var cond = try self.emitExpr(builder, ifstmt.condition);
|
||||||
|
var zero = mkLLVMBool(false);
|
||||||
|
var icmp = llvm.LLVMBuildICmp(builder, llvm.LLVMIntPredicate.LLVMIntNE, cond, zero, c"ifcond");
|
||||||
|
},
|
||||||
|
|
||||||
else => {
|
else => {
|
||||||
std.debug.warn("Got unexpected statement {}\n", stmt.*);
|
std.debug.warn("Got unexpected statement {}\n", stmt.*);
|
||||||
return CompileError.EmitError;
|
return CompileError.EmitError;
|
||||||
|
@ -138,7 +150,11 @@ pub const Codegen = struct {
|
||||||
);
|
);
|
||||||
|
|
||||||
var func = llvm.LLVMAddFunction(mod, name_cstr.ptr, llvm_ret_type);
|
var func = llvm.LLVMAddFunction(mod, name_cstr.ptr, llvm_ret_type);
|
||||||
var entry = llvm.LLVMAppendBasicBlock(func, c"entry");
|
|
||||||
|
var buf = try self.allocator.alloc(u8, 512);
|
||||||
|
var entry_lbl = try std.fmt.bufPrint(buf, "fn_{}_entry", name);
|
||||||
|
var entry_lbl_cstr = try std.cstr.addNullByte(self.allocator, entry_lbl);
|
||||||
|
var entry = llvm.LLVMAppendBasicBlock(func, entry_lbl_cstr.ptr);
|
||||||
|
|
||||||
var builder = llvm.LLVMCreateBuilder();
|
var builder = llvm.LLVMCreateBuilder();
|
||||||
llvm.LLVMPositionBuilderAtEnd(builder, entry);
|
llvm.LLVMPositionBuilderAtEnd(builder, entry);
|
||||||
|
@ -155,8 +171,7 @@ pub const Codegen = struct {
|
||||||
// c"tmp",
|
// c"tmp",
|
||||||
//);
|
//);
|
||||||
|
|
||||||
//_ = llvm.LLVMBuildRet(builder, tmp);
|
std.debug.warn("cgen: generated function '{}'\n", name);
|
||||||
std.debug.warn("cgen: fn decl done\n");
|
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
std.debug.warn("got unhandled Node {}\n", node.*);
|
std.debug.warn("got unhandled Node {}\n", node.*);
|
||||||
|
|
|
@ -688,6 +688,7 @@ pub const Parser = struct {
|
||||||
while (self.peek().typ != .RightBrace) {
|
while (self.peek().typ != .RightBrace) {
|
||||||
var stmt = try self.parseStmt();
|
var stmt = try self.parseStmt();
|
||||||
printer.printNode(try self.mkStmt(stmt), 0);
|
printer.printNode(try self.mkStmt(stmt), 0);
|
||||||
|
if (self.check(.Semicolon))
|
||||||
_ = try self.consumeSingle(.Semicolon);
|
_ = try self.consumeSingle(.Semicolon);
|
||||||
try stmts.append(stmt.*);
|
try stmts.append(stmt.*);
|
||||||
}
|
}
|
||||||
|
@ -722,7 +723,9 @@ pub const Parser = struct {
|
||||||
|
|
||||||
fn parseIfStmt(self: *@This()) !*Stmt {
|
fn parseIfStmt(self: *@This()) !*Stmt {
|
||||||
_ = try self.consumeSingle(.If);
|
_ = try self.consumeSingle(.If);
|
||||||
|
_ = try self.consumeSingle(.LeftParen);
|
||||||
var condition = try self.parseExpr();
|
var condition = try self.parseExpr();
|
||||||
|
_ = try self.consumeSingle(.RightParen);
|
||||||
|
|
||||||
const then_branch = try self.parseStmtBlock();
|
const then_branch = try self.parseStmtBlock();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue