diff options
| author | Baitinq <[email protected]> | 2025-01-27 00:20:37 +0100 |
|---|---|---|
| committer | Baitinq <[email protected]> | 2025-01-27 00:20:37 +0100 |
| commit | 6cb8057e3ac6429a181804652fd33789a54b64c9 (patch) | |
| tree | 784bb3c3c8703ad0e9f623ff61b740a0f531757d | |
| parent | Misc: Update gitignore (diff) | |
| download | interpreter-6cb8057e3ac6429a181804652fd33789a54b64c9.tar.gz interpreter-6cb8057e3ac6429a181804652fd33789a54b64c9.tar.bz2 interpreter-6cb8057e3ac6429a181804652fd33789a54b64c9.zip | |
Codegen: Start working on actual AST codegen
Diffstat (limited to '')
| -rw-r--r-- | src/codegen.zig | 54 | ||||
| -rw-r--r-- | src/main.zig | 30 |
2 files changed, 70 insertions, 14 deletions
diff --git a/src/codegen.zig b/src/codegen.zig index 60512bb..648ceb4 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -8,6 +8,7 @@ const core = llvm.core; pub const CodeGen = struct { llvm_module: types.LLVMModuleRef, + builder: types.LLVMBuilderRef, pub fn init(arena: std.mem.Allocator) !*CodeGen { // Initialize LLVM @@ -16,10 +17,12 @@ pub const CodeGen = struct { _ = target.LLVMInitializeNativeAsmParser(); const module: types.LLVMModuleRef = core.LLVMModuleCreateWithName("module"); + const builder = core.LLVMCreateBuilder(); const self = try arena.create(CodeGen); self.* = .{ .llvm_module = module, + .builder = builder, }; return self; @@ -52,21 +55,56 @@ pub const CodeGen = struct { std.debug.print("Object file generated: {s}\n", .{filename}); // Clean up LLVM resources + defer core.LLVMDisposeBuilder(self.builder); core.LLVMDisposeModule(self.llvm_module); core.LLVMShutdown(); } - pub fn generate(self: *CodeGen) void { - const builder = core.LLVMCreateBuilder(); - defer core.LLVMDisposeBuilder(builder); + pub fn generate(self: *CodeGen, ast: *parser.Node) !void { + std.debug.assert(ast.* == parser.Node.PROGRAM); + + const program = ast.PROGRAM; + + for (program.statements) |stmt| { + _ = try self.generate_statement(stmt); + } + } + + fn generate_statement(self: *CodeGen, statement: *parser.Node) !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; + // }, + // .FUNCTION_CALL_STATEMENT => |*function_call_statement| { + // _ = try self.evaluate_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 null; + } + + 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; + + _ = core.LLVMBuildRet(self.builder, core.LLVMConstInt(core.LLVMInt32Type(), 12, 0)); + } + pub fn generate_poc(self: *CodeGen) void { const main_func_type = core.LLVMFunctionType(core.LLVMInt32Type(), null, 0, 0); const main_func = core.LLVMAddFunction(self.llvm_module, "_start", main_func_type); const main_entry = core.LLVMAppendBasicBlock(main_func, "entrypoint"); - core.LLVMPositionBuilderAtEnd(builder, main_entry); + core.LLVMPositionBuilderAtEnd(self.builder, main_entry); const format_str = "Hello, World!\n"; - const format_str_ptr = core.LLVMBuildGlobalStringPtr(builder, format_str, "format_str_ptr"); + const format_str_ptr = core.LLVMBuildGlobalStringPtr(self.builder, format_str, "format_str_ptr"); var print_function_params = [_]types.LLVMTypeRef{ core.LLVMPointerType(core.LLVMInt8Type(), 0), @@ -76,7 +114,7 @@ pub const CodeGen = struct { var print_func_args = [_]types.LLVMValueRef{ format_str_ptr, }; - _ = core.LLVMBuildCall2(builder, print_func_type, print_func, &print_func_args, print_func_args.len, "print_call"); + _ = core.LLVMBuildCall2(self.builder, print_func_type, print_func, &print_func_args, print_func_args.len, "print_call"); var exit_func_params = [_]types.LLVMTypeRef{ core.LLVMInt32Type(), @@ -87,7 +125,7 @@ pub const CodeGen = struct { var exit_func_args = [_]types.LLVMValueRef{ core.LLVMConstInt(core.LLVMInt32Type(), 7, 0), }; - const exit_func_ret = core.LLVMBuildCall2(builder, exit_func_type, exit_func, &exit_func_args, exit_func_args.len, "exit_call"); - _ = core.LLVMBuildRet(builder, exit_func_ret); + const exit_func_ret = core.LLVMBuildCall2(self.builder, exit_func_type, exit_func, &exit_func_args, exit_func_args.len, "exit_call"); + _ = core.LLVMBuildRet(self.builder, exit_func_ret); } }; diff --git a/src/main.zig b/src/main.zig index a8dd0b6..526b7e4 100644 --- a/src/main.zig +++ b/src/main.zig @@ -25,7 +25,7 @@ pub fn main() !void { const source_codegen = try codegen.CodeGen.init(arena.allocator()); defer source_codegen.deinit(); - source_codegen.generate(); + source_codegen.generate_poc(); if (std.mem.eql(u8, path, "-i")) { while (true) { @@ -34,7 +34,7 @@ pub fn main() !void { const buf = try stdin.readUntilDelimiterAlloc(allocator, '\n', 1024); defer allocator.free(buf); - process_buf(buf, allocator, arena.allocator(), source_evaluator) catch |err| { + process_buf(buf, allocator, arena.allocator(), source_evaluator, null) catch |err| { try stdout.print("Error processing line: {any}\n", .{err}); }; } @@ -43,11 +43,25 @@ pub fn main() !void { const file = try std.fs.cwd().openFile(path, .{}); const buf = try file.readToEndAlloc(allocator, 1 * 1024 * 1024); defer allocator.free(buf); - try process_buf(buf, allocator, arena.allocator(), source_evaluator); + if (std.os.argv.len < 3) { + try process_buf( + buf, + allocator, + arena.allocator(), + source_evaluator, + null, + ); + } else try process_buf( + buf, + allocator, + arena.allocator(), + source_evaluator, + source_codegen, + ); } } -fn process_buf(buf: []u8, allocator: std.mem.Allocator, arena: std.mem.Allocator, source_evaluator: *evaluator.Evaluator) !void { +fn process_buf(buf: []u8, allocator: std.mem.Allocator, arena: std.mem.Allocator, source_evaluator: *evaluator.Evaluator, source_codegen: ?*codegen.CodeGen) !void { std.debug.print("Buf:\n{s}\n", .{buf}); var token_list = std.ArrayList(tokenizer.Token).init(allocator); @@ -63,8 +77,12 @@ fn process_buf(buf: []u8, allocator: std.mem.Allocator, arena: std.mem.Allocator const ast = try source_parser.parse(); std.debug.print("AST: {any}\n", .{ast}); - const result = try source_evaluator.evaluate_ast(ast); - std.debug.print("Evaluation result: {any}\n", .{result}); + if (source_codegen != null) { + try source_codegen.?.generate(ast); + } else { + const result = try source_evaluator.evaluate_ast(ast); + std.debug.print("Evaluation result: {any}\n", .{result}); + } } test { |