about summary refs log tree commit diff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/codegen.zig23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/codegen.zig b/src/codegen.zig
index c6b259e..3f2b564 100644
--- a/src/codegen.zig
+++ b/src/codegen.zig
@@ -124,6 +124,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)),
+            .IF_STATEMENT => |*if_statement| return try self.generate_if_statement(@ptrCast(if_statement)),
             else => unreachable,
         }
     }
@@ -170,6 +171,28 @@ pub const CodeGen = struct {
         _ = core.LLVMBuildRet(self.builder, (try self.generate_expression_value(expression)).value);
     }
 
+    fn generate_if_statement(self: *CodeGen, statement: *parser.Node) !void {
+        std.debug.assert(statement.* == parser.Node.IF_STATEMENT);
+
+        const if_statement = statement.IF_STATEMENT;
+
+        const condition_value = try self.generate_expression_value(if_statement.condition);
+
+        const current_block = core.LLVMGetInsertBlock(self.builder);
+
+        const then_block = core.LLVMAppendBasicBlock(core.LLVMGetLastFunction(self.llvm_module), "then_block");
+        _ = core.LLVMPositionBuilderAtEnd(self.builder, then_block);
+        for (if_statement.statements) |stmt| {
+            try self.generate_statement(stmt);
+        }
+        const merge_block = core.LLVMAppendBasicBlock(core.LLVMGetLastFunction(self.llvm_module), "else_block");
+        _ = core.LLVMBuildBr(self.builder, merge_block);
+        core.LLVMPositionBuilderAtEnd(self.builder, current_block);
+
+        _ = core.LLVMBuildCondBr(self.builder, condition_value.value, then_block, merge_block);
+        core.LLVMPositionBuilderAtEnd(self.builder, merge_block);
+    }
+
     fn generate_expression_value(self: *CodeGen, expression: *parser.Node) !*Variable {
         return switch (expression.*) {
             .FUNCTION_DEFINITION => |function_definition| {