diff options
| author | Baitinq <[email protected]> | 2025-03-21 20:22:45 +0100 |
|---|---|---|
| committer | Baitinq <[email protected]> | 2025-03-22 20:30:56 +0100 |
| commit | 95999cb6a286871e245e8b9e20d79bc6cd22252c (patch) | |
| tree | b9ae565e1284fc58c255725fb78ee877a3bd960f | |
| parent | Misc: Improve error handling (diff) | |
| download | pry-lang-95999cb6a286871e245e8b9e20d79bc6cd22252c.tar.gz pry-lang-95999cb6a286871e245e8b9e20d79bc6cd22252c.tar.bz2 pry-lang-95999cb6a286871e245e8b9e20d79bc6cd22252c.zip | |
Feature: Add initial support for linking external symbols
| -rw-r--r-- | examples/15.src | 12 | ||||
| -rw-r--r-- | grammar.ebnf | 2 | ||||
| -rw-r--r-- | src/codegen.zig | 24 | ||||
| -rw-r--r-- | src/parser.zig | 12 |
4 files changed, 44 insertions, 6 deletions
diff --git a/examples/15.src b/examples/15.src index 7bd73d2..fd68961 100644 --- a/examples/15.src +++ b/examples/15.src @@ -1,7 +1,11 @@ -let putc = (i64) => i64; - -let main = () => i64 { - putc(52); +let putchar = (i64) => i64; +let main = (_: void) => i64 { + putchar(72); + putchar(101); + putchar(108); + putchar(108); + putchar(111); + putchar(10); return 0; }; diff --git a/grammar.ebnf b/grammar.ebnf index bbfe488..562f2f8 100644 --- a/grammar.ebnf +++ b/grammar.ebnf @@ -2,7 +2,7 @@ Program ::= Statement+ Statement ::= (AssignmentStatement | FunctionCallStatement | IfStatement | WhileStatement | ReturnStatement) SEMICOLON -AssignmentStatement ::= "let" IDENTIFIER EQUALS Expression +AssignmentStatement ::= "let" IDENTIFIER EQUALS (Type | Expression) FunctionCallStatement ::= (IDENTIFIER | FunctionDefinition) LPAREN FunctionArguments? RPAREN 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(.{ |