diff options
| author | Baitinq <[email protected]> | 2025-05-15 18:42:37 +0200 |
|---|---|---|
| committer | Baitinq <[email protected]> | 2025-05-15 18:42:41 +0200 |
| commit | c8439a069354cb526e02a76f52e978738ad8871c (patch) | |
| tree | e49d0eb7221431daee13965c90e724d2cba28cc0 /src | |
| parent | Bootstrap: Tokenizer: Tokenize keywords (diff) | |
| download | pry-lang-c8439a069354cb526e02a76f52e978738ad8871c.tar.gz pry-lang-c8439a069354cb526e02a76f52e978738ad8871c.tar.bz2 pry-lang-c8439a069354cb526e02a76f52e978738ad8871c.zip | |
Feature: Add support for null pointers
Diffstat (limited to 'src')
| -rw-r--r-- | src/codegen.zig | 13 | ||||
| -rw-r--r-- | src/parser.zig | 6 | ||||
| -rw-r--r-- | src/tokenizer.zig | 2 |
3 files changed, 20 insertions, 1 deletions
diff --git a/src/codegen.zig b/src/codegen.zig index 5733d5f..05cb877 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -426,6 +426,19 @@ pub const CodeGen = struct { return try self.generate_function_call_statement(@ptrCast(fn_call)); }, .PRIMARY_EXPRESSION => |primary_expression| switch (primary_expression) { + .NULL => { + return try self.generate_literal(llvm.LLVMConstNull(llvm.LLVMPointerType(llvm.LLVMInt8Type(), 0)), name, expression, try self.create_node(.{ + .TYPE = .{ + .POINTER_TYPE = .{ + .type = try self.create_node(.{ + .TYPE = .{ .SIMPLE_TYPE = .{ + .name = "i8", + } }, + }), + }, + }, + })); + }, .NUMBER => |n| { return try self.generate_literal(llvm.LLVMConstInt(llvm.LLVMInt64Type(), @intCast(n.value), 0), name, expression, try self.create_node(.{ .TYPE = .{ diff --git a/src/parser.zig b/src/parser.zig index 7e1b695..ce1e4cb 100644 --- a/src/parser.zig +++ b/src/parser.zig @@ -61,6 +61,7 @@ pub const Node = union(enum) { BOOLEAN: struct { value: bool, }, + NULL: void, CHAR: struct { value: u8, }, @@ -525,7 +526,7 @@ pub const Parser = struct { } }); } - // PrimaryExpression ::= NUMBER | BOOLEAN | CHAR | STRING | IDENTIFIER | FunctionCallStatement | FunctionDefinition | LPAREN Expression RPAREN + // PrimaryExpression ::= NULL | NUMBER | BOOLEAN | CHAR | STRING | IDENTIFIER | FunctionCallStatement | FunctionDefinition | LPAREN Expression RPAREN fn parse_primary_expression(self: *Parser) ParserError!*Node { errdefer if (!self.try_context) std.debug.print("Error parsing primary expression {any}\n", .{self.peek_token()}); @@ -542,6 +543,9 @@ pub const Parser = struct { const token = self.consume_token() orelse return ParserError.ParsingError; return switch (token.type) { + .NULL => try self.create_node(.{ + .PRIMARY_EXPRESSION = .{ .NULL = void{} }, + }), .NUMBER => |number_token| try self.create_node(.{ .PRIMARY_EXPRESSION = .{ .NUMBER = .{ diff --git a/src/tokenizer.zig b/src/tokenizer.zig index 7ccb871..3b0ae4e 100644 --- a/src/tokenizer.zig +++ b/src/tokenizer.zig @@ -21,6 +21,7 @@ pub const TokenType = union(enum) { // Literals NUMBER: i64, BOOLEAN: bool, + NULL: void, CHAR: u8, STRING: []u8, @@ -94,6 +95,7 @@ pub const Tokenizer = struct { if (self.accept_string("break")) return self.create_token(.{ .BREAK = void{} }); if (self.accept_string("true")) return self.create_token(.{ .BOOLEAN = true }); if (self.accept_string("false")) return self.create_token(.{ .BOOLEAN = false }); + if (self.accept_string("null")) return self.create_token(.{ .NULL = void{} }); if (self.accept_string("=>")) return self.create_token(.{ .ARROW = void{} }); if (self.accept_string(";")) return self.create_token(.{ .SEMICOLON = void{} }); |