diff options
| author | Baitinq <[email protected]> | 2025-01-27 20:44:02 +0100 |
|---|---|---|
| committer | Baitinq <[email protected]> | 2025-01-27 23:44:02 +0100 |
| commit | ca1823eda5b9ee3a186cddaf711d19a4016d03be (patch) | |
| tree | 2308107fbde7e0bea2454a19d44c8481b31df740 | |
| parent | Codegen: Start working on actual AST codegen (diff) | |
| download | pry-lang-ca1823eda5b9ee3a186cddaf711d19a4016d03be.tar.gz pry-lang-ca1823eda5b9ee3a186cddaf711d19a4016d03be.tar.bz2 pry-lang-ca1823eda5b9ee3a186cddaf711d19a4016d03be.zip | |
Codegen: Get the most basic ever example compiling
Diffstat (limited to '')
| -rw-r--r-- | examples/-1.src | 5 | ||||
| -rw-r--r-- | src/codegen.zig | 85 | ||||
| -rw-r--r-- | src/main.zig | 4 |
3 files changed, 78 insertions, 16 deletions
diff --git a/examples/-1.src b/examples/-1.src new file mode 100644 index 0000000..874d7ad --- /dev/null +++ b/examples/-1.src @@ -0,0 +1,5 @@ +/* HELLO! Welcome to the unnamed language */ + +let main = () => { + return 7; +}; diff --git a/src/codegen.zig b/src/codegen.zig index 648ceb4..1f4bb46 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -6,10 +6,17 @@ const target = llvm.target; const types = llvm.types; const core = llvm.core; +pub const CodeGenError = error{ + CompilationError, + OutOfMemory, +}; + pub const CodeGen = struct { llvm_module: types.LLVMModuleRef, builder: types.LLVMBuilderRef, + arena: std.mem.Allocator, + pub fn init(arena: std.mem.Allocator) !*CodeGen { // Initialize LLVM _ = target.LLVMInitializeNativeTarget(); @@ -23,12 +30,19 @@ pub const CodeGen = struct { self.* = .{ .llvm_module = module, .builder = builder, + + .arena = arena, }; return self; } - pub fn deinit(self: *CodeGen) void { + pub fn deinit(self: *CodeGen) !void { + try self.create_entrypoint(); + + // Dump module + core.LLVMDumpModule(self.llvm_module); + // Generate code const triple = target_m.LLVMGetDefaultTargetTriple(); var target_ref: types.LLVMTargetRef = undefined; @@ -36,7 +50,7 @@ pub const CodeGen = struct { const target_machine = target_m.LLVMCreateTargetMachine( target_ref, triple, - "generic", + "", "", types.LLVMCodeGenOptLevel.LLVMCodeGenLevelDefault, types.LLVMRelocMode.LLVMRelocDefault, @@ -60,7 +74,7 @@ pub const CodeGen = struct { core.LLVMShutdown(); } - pub fn generate(self: *CodeGen, ast: *parser.Node) !void { + pub fn generate(self: *CodeGen, ast: *parser.Node) CodeGenError!void { std.debug.assert(ast.* == parser.Node.PROGRAM); const program = ast.PROGRAM; @@ -70,31 +84,74 @@ pub const CodeGen = struct { } } - fn generate_statement(self: *CodeGen, statement: *parser.Node) !void { + fn generate_statement(self: *CodeGen, statement: *parser.Node) CodeGenError!void { std.debug.assert(statement.* == parser.Node.STATEMENT); switch (statement.STATEMENT.statement.*) { - // .ASSIGNMENT_STATEMENT => |*assignment_statement| { - // try self.evaluate_assignment_statement(@ptrCast(assignment_statement)); - // return null; - // }, + .ASSIGNMENT_STATEMENT => |*assignment_statement| { + try self.generate_assignment_statement(@ptrCast(assignment_statement)); + return; + }, // .FUNCTION_CALL_STATEMENT => |*function_call_statement| { - // _ = try self.evaluate_function_call_statement(@ptrCast(function_call_statement)); + // _ = try self.generate_function_call_statement(@ptrCast(function_call_statement)); // return null; // }, - .RETURN_STATEMENT => |*return_statement| return try self.generate_return_statement(@ptrCast(return_statement)), - else => unreachable, + // .RETURN_STATEMENT => |*return_statement| return try self.generate_return_statement(@ptrCast(return_statement)), + else => {}, } + } - return null; + fn generate_assignment_statement(self: *CodeGen, statement: *parser.Node) CodeGenError!void { + std.debug.assert(statement.* == parser.Node.ASSIGNMENT_STATEMENT); + + const assignment_statement = statement.ASSIGNMENT_STATEMENT; + + //tmp + std.debug.assert(assignment_statement.is_declaration == true); + std.debug.assert(assignment_statement.expression.* == parser.Node.FUNCTION_DEFINITION); + + const function_name = try std.fmt.allocPrintZ(self.arena, "{s}", .{assignment_statement.name}); + + const function_type = core.LLVMFunctionType(core.LLVMInt64Type(), &[_]types.LLVMTypeRef{}, 0, 0) orelse return CodeGenError.CompilationError; + const function = core.LLVMAddFunction(self.llvm_module, function_name, function_type) orelse return CodeGenError.CompilationError; + const function_entry = core.LLVMAppendBasicBlock(function, "entrypoint") orelse return CodeGenError.CompilationError; + core.LLVMPositionBuilderAtEnd(self.builder, function_entry); + + //tmp + std.debug.assert(assignment_statement.expression.* == parser.Node.FUNCTION_DEFINITION); + const function_defintion = assignment_statement.expression.FUNCTION_DEFINITION; + std.debug.print("XD: {any}\n", .{function_defintion.statements[0]}); + std.debug.assert(function_defintion.statements[0].* == parser.Node.STATEMENT); + const xd = function_defintion.statements[0]; + std.debug.assert(xd.STATEMENT.statement.* == parser.Node.RETURN_STATEMENT); + try self.generate_return_statement(xd.STATEMENT.statement); } fn generate_return_statement(self: *CodeGen, statement: *parser.Node) !void { std.debug.assert(statement.* == parser.Node.RETURN_STATEMENT); - // const return_value = statement.RETURN_STATEMENT.return_value; + const expression = statement.RETURN_STATEMENT.expression; + std.debug.assert(expression.* == parser.Node.PRIMARY_EXPRESSION); + const primary_expr = expression.PRIMARY_EXPRESSION.NUMBER.value; + // std.debug.assert(primary_expr == parser.Node.PRIMARY_EXPRESSION.NUMBER); - _ = core.LLVMBuildRet(self.builder, core.LLVMConstInt(core.LLVMInt32Type(), 12, 0)); + _ = core.LLVMBuildRet(self.builder, core.LLVMConstInt(core.LLVMInt64Type(), @intCast(primary_expr), 0)); + } + + pub fn create_entrypoint(self: *CodeGen) CodeGenError!void { + const start_function_type = core.LLVMFunctionType(core.LLVMInt8Type(), &[_]types.LLVMTypeRef{}, 0, 0) orelse return CodeGenError.CompilationError; + const start_function = core.LLVMAddFunction(self.llvm_module, "_start", start_function_type) orelse return CodeGenError.CompilationError; + const start_function_entry = core.LLVMAppendBasicBlock(start_function, "entrypoint") orelse return CodeGenError.CompilationError; + core.LLVMPositionBuilderAtEnd(self.builder, start_function_entry); + + const main_function_type = core.LLVMFunctionType(core.LLVMInt8Type(), &[_]types.LLVMTypeRef{}, 0, 0) orelse return CodeGenError.CompilationError; + const main_function = core.LLVMGetNamedFunction(self.llvm_module, "main") orelse return CodeGenError.CompilationError; + const main_function_return = core.LLVMBuildCall2(self.builder, main_function_type, main_function, &[_]types.LLVMTypeRef{}, 0, "main_call") orelse return CodeGenError.CompilationError; + + const exit_func_type = core.LLVMFunctionType(core.LLVMInt8Type(), @constCast(&[_]types.LLVMTypeRef{core.LLVMInt8Type()}), 1, 0); + const exit_func = core.LLVMAddFunction(self.llvm_module, "exit", exit_func_type); + const exit_func_return = core.LLVMBuildCall2(self.builder, exit_func_type, exit_func, @constCast(&[_]types.LLVMValueRef{main_function_return}), 1, "exit_call"); + _ = core.LLVMBuildRet(self.builder, exit_func_return); } pub fn generate_poc(self: *CodeGen) void { diff --git a/src/main.zig b/src/main.zig index 526b7e4..115c1b8 100644 --- a/src/main.zig +++ b/src/main.zig @@ -23,9 +23,9 @@ pub fn main() !void { const source_evaluator = try evaluator.Evaluator.init(arena.allocator()); const source_codegen = try codegen.CodeGen.init(arena.allocator()); - defer source_codegen.deinit(); + defer source_codegen.deinit() catch {}; - source_codegen.generate_poc(); + // source_codegen.generate_poc(); if (std.mem.eql(u8, path, "-i")) { while (true) { |