From 95999cb6a286871e245e8b9e20d79bc6cd22252c Mon Sep 17 00:00:00 2001 From: Baitinq Date: Fri, 21 Mar 2025 20:22:45 +0100 Subject: Feature: Add initial support for linking external symbols --- src/codegen.zig | 24 ++++++++++++++++++++++++ src/parser.zig | 12 +++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) (limited to 'src') 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(.{ -- cgit 1.4.1