about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBaitinq <[email protected]>2025-01-27 20:44:02 +0100
committerBaitinq <[email protected]>2025-01-27 23:44:02 +0100
commitca1823eda5b9ee3a186cddaf711d19a4016d03be (patch)
tree2308107fbde7e0bea2454a19d44c8481b31df740
parentCodegen: Start working on actual AST codegen (diff)
downloadpry-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.src5
-rw-r--r--src/codegen.zig85
-rw-r--r--src/main.zig4
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) {