about summary refs log tree commit diff
path: root/src/codegen.zig
diff options
context:
space:
mode:
authorBaitinq <[email protected]>2025-05-12 23:45:57 +0200
committerBaitinq <[email protected]>2025-05-12 23:45:57 +0200
commita1a1564a44a56fa9308c440e2e72f62af689e2d2 (patch)
treea228a968c7fc21a8398e8f7ead0596eb423f999d /src/codegen.zig
parentboostrap: tokenizer: clean (diff)
downloadinterpreter-a1a1564a44a56fa9308c440e2e72f62af689e2d2.tar.gz
interpreter-a1a1564a44a56fa9308c440e2e72f62af689e2d2.tar.bz2
interpreter-a1a1564a44a56fa9308c440e2e72f62af689e2d2.zip
Feature: Add support for break statement
Diffstat (limited to 'src/codegen.zig')
-rw-r--r--src/codegen.zig16
1 files changed, 16 insertions, 0 deletions
diff --git a/src/codegen.zig b/src/codegen.zig
index ab34ea8..6b8e310 100644
--- a/src/codegen.zig
+++ b/src/codegen.zig
@@ -22,6 +22,8 @@ pub const CodeGen = struct {
 
     arena: std.mem.Allocator,
 
+    while_loop_exit: ?llvm.LLVMBasicBlockRef,
+
     pub fn init(arena: std.mem.Allocator) !*CodeGen {
         // Initialize LLVM
         llvm.LLVMInitializeAllTargetInfos();
@@ -40,6 +42,8 @@ pub const CodeGen = struct {
             .environment = try Environment.init(arena),
 
             .arena = arena,
+
+            .while_loop_exit = null,
         };
 
         return self;
@@ -114,6 +118,7 @@ pub const CodeGen = struct {
                 _ = try self.generate_function_call_statement(@ptrCast(function_call_statement));
             },
             .RETURN_STATEMENT => |*return_statement| return try self.generate_return_statement(@ptrCast(return_statement)),
+            .BREAK_STATEMENT => |*break_statement| return try self.generate_break_statement(@ptrCast(@alignCast(break_statement))),
             .IF_STATEMENT => |*if_statement| return try self.generate_if_statement(@ptrCast(if_statement)),
             .WHILE_STATEMENT => |*while_statement| return try self.generate_while_statement(@ptrCast(while_statement)),
             .IMPORT_DECLARATION => |*import_declaration| return try self.generate_import_declaration(@ptrCast(import_declaration)),
@@ -246,6 +251,14 @@ pub const CodeGen = struct {
         _ = llvm.LLVMBuildRet(self.builder, val.value);
     }
 
+    fn generate_break_statement(self: *CodeGen, statement: *parser.Node) !void {
+        errdefer std.debug.print("Error generating break statement\n", .{});
+        std.debug.assert(statement.* == parser.Node.BREAK_STATEMENT);
+        std.debug.assert(self.while_loop_exit != null);
+
+        _ = llvm.LLVMBuildBr(self.builder, self.while_loop_exit.?);
+    }
+
     fn generate_if_statement(self: *CodeGen, statement: *parser.Node) !void {
         errdefer std.debug.print("Error generating if statement\n", .{});
         std.debug.assert(statement.* == parser.Node.IF_STATEMENT);
@@ -287,6 +300,9 @@ pub const CodeGen = struct {
         const outer_block = llvm.LLVMAppendBasicBlock(llvm.LLVMGetLastFunction(self.llvm_module), "outer_block");
         _ = llvm.LLVMBuildCondBr(self.builder, condition_value.value, inner_block, outer_block);
 
+        self.while_loop_exit = outer_block;
+        defer self.while_loop_exit = null;
+
         _ = llvm.LLVMPositionBuilderAtEnd(self.builder, inner_block);
         for (while_statement.statements) |stmt| {
             try self.generate_statement(stmt);