diff options
| author | Baitinq <[email protected]> | 2025-03-29 11:22:13 +0100 |
|---|---|---|
| committer | Baitinq <[email protected]> | 2025-03-29 11:27:15 +0100 |
| commit | d74c6a363cf457a2197f3f10c0d567a77573e79c (patch) | |
| tree | b82cad7904e8493c28cfa1612de2e0e081484e0c /src/codegen.zig | |
| parent | Codegen: Support void type (diff) | |
| download | pry-lang-d74c6a363cf457a2197f3f10c0d567a77573e79c.tar.gz pry-lang-d74c6a363cf457a2197f3f10c0d567a77573e79c.tar.bz2 pry-lang-d74c6a363cf457a2197f3f10c0d567a77573e79c.zip | |
Feature: Add basic support for pointer references and dereferences
Diffstat (limited to 'src/codegen.zig')
| -rw-r--r-- | src/codegen.zig | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/src/codegen.zig b/src/codegen.zig index da1c8ca..a6f4b08 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -127,6 +127,7 @@ pub const CodeGen = struct { const assignment_statement = statement.ASSIGNMENT_STATEMENT; if (assignment_statement.is_declaration and self.environment.scope_stack.items.len > 1) { + std.debug.assert(assignment_statement.is_dereference == false); // TODO: vv Int64Type is a problem const alloca = llvm.LLVMBuildAlloca(self.builder, llvm.LLVMInt64Type(), try std.fmt.allocPrintZ(self.arena, "{s}", .{assignment_statement.name})); //TODO: Correct type try self.environment.add_variable(assignment_statement.name, try self.create_variable(.{ @@ -137,8 +138,26 @@ pub const CodeGen = struct { })); } + var undereferenced_variable: ?*Variable = null; + if (assignment_statement.is_dereference) { + const ptr = self.environment.get_variable(assignment_statement.name) orelse unreachable; + undereferenced_variable = ptr; + const x = llvm.LLVMBuildLoad2(self.builder, ptr.type, ptr.value, "") orelse return CodeGenError.CompilationError; + try self.environment.add_variable(assignment_statement.name, try self.create_variable(.{ + .value = x, + .type = ptr.type, + .stack_level = null, + .node = statement, + })); + } + const variable = try self.generate_expression_value(assignment_statement.expression, assignment_statement.name); - try self.environment.add_variable(assignment_statement.name, variable); + + if (!assignment_statement.is_dereference) { + try self.environment.add_variable(assignment_statement.name, variable); + } else { + try self.environment.add_variable(assignment_statement.name, undereferenced_variable.?); + } } fn generate_function_call_statement(self: *CodeGen, statement: *parser.Node) CodeGenError!*Variable { @@ -430,16 +449,20 @@ pub const CodeGen = struct { var r: llvm.LLVMValueRef = undefined; var t: llvm.LLVMTypeRef = undefined; - switch (exp.negation) { - true => { + switch (exp.typ) { + .NOT => { std.debug.assert(k.type == llvm.LLVMInt1Type()); r = llvm.LLVMBuildICmp(self.builder, llvm.LLVMIntEQ, k.value, llvm.LLVMConstInt(llvm.LLVMInt1Type(), 0, 0), ""); t = llvm.LLVMInt1Type(); }, - false => { + .MINUS => { r = llvm.LLVMBuildNeg(self.builder, k.value, ""); t = llvm.LLVMInt64Type(); }, + .STAR => { + r = llvm.LLVMBuildLoad2(self.builder, k.type, k.value, ""); + t = llvm.LLVMInt64Type(); + }, } return self.generate_literal(r, t, name, expression); |