diff --git a/examples/hello.ry b/examples/hello.ry index 43b93a2..4b651a7 100644 --- a/examples/hello.ry +++ b/examples/hello.ry @@ -1,5 +1,14 @@ // 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 { return 69 + 69; } diff --git a/src/codegen.zig b/src/codegen.zig index 384fd9a..485ef4e 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -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 { allocator: *std.mem.Allocator, @@ -56,11 +64,7 @@ pub const Codegen = struct { break :blk2 llvm.LLVMConstRealOfString(llvm.LLVMDoubleType(), val_cstr.ptr); }, .Bool => |val| blk2: { - if (val) { - break :blk2 llvm.LLVMConstInt(llvm.LLVMInt1Type(), 1, 1); - } else { - break :blk2 llvm.LLVMConstInt(llvm.LLVMInt1Type(), 0, 1); - } + break :blk2 mkLLVMBool(val); }, else => unreachable, }; @@ -97,10 +101,18 @@ pub const Codegen = struct { fn emitStmt(self: *Codegen, builder: var, stmt: *const ast.Stmt) !void { switch (stmt.*) { .Expr => |expr| _ = try self.emitExpr(builder, expr), + .Return => |ret| { var ret_expr = try self.emitExpr(builder, ret.value); _ = 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 => { std.debug.warn("Got unexpected statement {}\n", stmt.*); return CompileError.EmitError; @@ -138,7 +150,11 @@ pub const Codegen = struct { ); 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(); llvm.LLVMPositionBuilderAtEnd(builder, entry); @@ -155,8 +171,7 @@ pub const Codegen = struct { // c"tmp", //); - //_ = llvm.LLVMBuildRet(builder, tmp); - std.debug.warn("cgen: fn decl done\n"); + std.debug.warn("cgen: generated function '{}'\n", name); }, else => { std.debug.warn("got unhandled Node {}\n", node.*); diff --git a/src/parsers.zig b/src/parsers.zig index 0a192e1..900a1d1 100644 --- a/src/parsers.zig +++ b/src/parsers.zig @@ -688,7 +688,8 @@ pub const Parser = struct { while (self.peek().typ != .RightBrace) { var stmt = try self.parseStmt(); printer.printNode(try self.mkStmt(stmt), 0); - _ = try self.consumeSingle(.Semicolon); + if (self.check(.Semicolon)) + _ = try self.consumeSingle(.Semicolon); try stmts.append(stmt.*); } @@ -722,7 +723,9 @@ pub const Parser = struct { fn parseIfStmt(self: *@This()) !*Stmt { _ = try self.consumeSingle(.If); + _ = try self.consumeSingle(.LeftParen); var condition = try self.parseExpr(); + _ = try self.consumeSingle(.RightParen); const then_branch = try self.parseStmtBlock();