about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorBaitinq <[email protected]>2025-03-21 20:22:45 +0100
committerBaitinq <[email protected]>2025-03-22 20:30:56 +0100
commit95999cb6a286871e245e8b9e20d79bc6cd22252c (patch)
treeb9ae565e1284fc58c255725fb78ee877a3bd960f /src
parentMisc: Improve error handling (diff)
downloadinterpreter-95999cb6a286871e245e8b9e20d79bc6cd22252c.tar.gz
interpreter-95999cb6a286871e245e8b9e20d79bc6cd22252c.tar.bz2
interpreter-95999cb6a286871e245e8b9e20d79bc6cd22252c.zip
Feature: Add initial support for linking external symbols
Diffstat (limited to 'src')
-rw-r--r--src/codegen.zig24
-rw-r--r--src/parser.zig12
2 files changed, 35 insertions, 1 deletions
diff --git a/src/codegen.zig b/src/codegen.zig
index c16fa34..4e2d897 100644
--- a/src/codegen.zig
+++ b/src/codegen.zig
@@ -196,6 +196,7 @@ pub const CodeGen = struct {
         const function_return_type = switch (function.node.?.*) {
             .FUNCTION_DEFINITION => |x| x.return_type,
             .PRIMARY_EXPRESSION => |x| x.IDENTIFIER.type.?,
+            .TYPE => |x| x.FUNCTION_TYPE.return_type,
             else => unreachable,
         };
 
@@ -458,6 +459,28 @@ pub const CodeGen = struct {
 
                 return self.generate_literal(cmp, llvm.LLVMInt1Type(), name);
             },
+            .TYPE => |typ| {
+                std.debug.assert(typ == .FUNCTION_TYPE);
+                const function_type = try self.get_llvm_type(expression);
+                const function = llvm.LLVMAddFunction(self.llvm_module, try std.fmt.allocPrintZ(self.arena, "{s}", .{name.?}), function_type);
+
+                // Global functions
+                if (self.environment.scope_stack.items.len == 1) {
+                    return try self.create_variable(.{
+                        .value = function,
+                        .type = function_type,
+                        .stack_level = null,
+                        .node = expression,
+                    });
+                }
+
+                const ptr = self.environment.get_variable(name.?);
+                _ = llvm.LLVMBuildStore(self.builder, function, ptr.?.value) orelse return CodeGenError.CompilationError;
+                ptr.?.type = function_type;
+                ptr.?.node = expression;
+
+                return ptr.?;
+            },
             else => unreachable,
         };
     }
@@ -496,6 +519,7 @@ pub const CodeGen = struct {
             .SIMPLE_TYPE => |t| {
                 if (std.mem.eql(u8, t.name, "i64")) return llvm.LLVMInt64Type();
                 if (std.mem.eql(u8, t.name, "bool")) return llvm.LLVMInt1Type();
+                if (std.mem.eql(u8, t.name, "void")) return llvm.LLVMInt1Type(); //TODO:
                 unreachable;
             },
             // TODO: Properly handle this vv
diff --git a/src/parser.zig b/src/parser.zig
index b0a469c..d2067a1 100644
--- a/src/parser.zig
+++ b/src/parser.zig
@@ -142,7 +142,7 @@ pub const Parser = struct {
         });
     }
 
-    // AssignmentStatement ::= "let" IDENTIFIER EQUALS Expression
+    // AssignmentStatement ::= "let" IDENTIFIER EQUALS (Type | Expression)
     fn parse_assignment_statement(self: *Parser) ParserError!*Node {
         errdefer if (!self.try_context) std.debug.print("Error parsing assignment statement {any}\n", .{self.peek_token()});
 
@@ -155,6 +155,16 @@ pub const Parser = struct {
 
         _ = try self.parse_token(tokenizer.TokenType.EQUALS);
 
+        if (self.accept_parse(parse_type)) |typ| {
+            return self.create_node(.{
+                .ASSIGNMENT_STATEMENT = .{
+                    .is_declaration = is_declaration,
+                    .name = try self.arena.dupe(u8, identifier.type.IDENTIFIER),
+                    .expression = @constCast(typ),
+                },
+            });
+        }
+
         const expression = try self.parse_expression();
 
         return self.create_node(.{