diff options
| author | Baitinq <[email protected]> | 2025-05-25 22:49:18 +0200 |
|---|---|---|
| committer | Baitinq <[email protected]> | 2025-05-25 22:49:53 +0200 |
| commit | f5904b62012ca475c14ad55b7f2c0b0c5c48b362 (patch) | |
| tree | 890b3f1274b8dab2e7e2a2052d7d452fa3ca6db2 /src/parser.zig | |
| parent | Examples: Fix example 21 (diff) | |
| download | interpreter-f5904b62012ca475c14ad55b7f2c0b0c5c48b362.tar.gz interpreter-f5904b62012ca475c14ad55b7f2c0b0c5c48b362.tar.bz2 interpreter-f5904b62012ca475c14ad55b7f2c0b0c5c48b362.zip | |
Feature: Start adding structs support
Diffstat (limited to 'src/parser.zig')
| -rw-r--r-- | src/parser.zig | 89 |
1 files changed, 88 insertions, 1 deletions
diff --git a/src/parser.zig b/src/parser.zig index 25ab6aa..f92f0c5 100644 --- a/src/parser.zig +++ b/src/parser.zig @@ -78,6 +78,13 @@ pub const Node = union(enum) { parameters: []*Node, return_type: *Node, }, + STRUCT_INSTANCIATION: struct { + typ: []const u8, + }, + FIELD_ACCESS: struct { + expression: *Node, + name: []const u8, + }, TYPE: union(enum) { SIMPLE_TYPE: struct { name: []const u8, @@ -89,6 +96,9 @@ pub const Node = union(enum) { POINTER_TYPE: struct { type: *Node, }, + STRUCT_TYPE: struct { + fields: []*Node, + }, }, RETURN_STATEMENT: struct { expression: ?*Node, @@ -553,13 +563,15 @@ pub const Parser = struct { } }); } - // PrimaryExpression ::= NULL | NUMBER | BOOLEAN | CHAR | STRING | IDENTIFIER | CastStatement | FunctionCallStatement | FunctionDefinition | LPAREN Expression RPAREN + // PrimaryExpression ::= NULL | NUMBER | BOOLEAN | CHAR | STRING | IDENTIFIER | CastStatement | FunctionCallStatement | FunctionDefinition | StructDefinition | StructInstantiation | FieldAccess | 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()}); if (self.accept_parse(parse_cast_statement)) |stmt| return stmt; if (self.accept_parse(parse_function_call_statement)) |stmt| return stmt; if (self.accept_parse(parse_function_definition)) |stmt| return stmt; + if (self.accept_parse(parse_struct_definition)) |stmt| return stmt; + if (self.accept_parse(parse_struct_instanciation)) |stmt| return stmt; // LPAREN (Expression) RPAREN if (self.accept_token(tokenizer.TokenType.LPAREN)) |_| { @@ -571,6 +583,7 @@ pub const Parser = struct { const token = self.consume_token() orelse return ParserError.ParsingError; return switch (token.type) { + .DOT => try self.parse_field_access(), .NULL => try self.create_node(.{ .PRIMARY_EXPRESSION = .{ .NULL = void{} }, }), @@ -670,6 +683,80 @@ pub const Parser = struct { return node_list.items; } + // StructDefinition ::= "struct" LBRACE StructFields? RBRACE + fn parse_struct_definition(self: *Parser) ParserError!*Node { + errdefer if (!self.try_context) std.debug.print("Error parsing struct definition {any}\n", .{self.peek_token()}); + + // StructField ::= IDENTIFIER ":" Type + const parse_struct_field = struct { + fn call(iself: *Parser) ParserError!*Node { + const ident = try iself.parse_token(tokenizer.TokenType.IDENTIFIER); + _ = try iself.parse_token(tokenizer.TokenType.COLON); + const type_annotation = try iself.parse_type(); + + return iself.create_node(.{ + .PRIMARY_EXPRESSION = .{ + .IDENTIFIER = .{ + .name = try iself.arena.dupe(u8, ident.type.IDENTIFIER), + .type = type_annotation, + }, + }, + }); + } + }; + + _ = try self.parse_token(tokenizer.TokenType.STRUCT); + _ = try self.parse_token(tokenizer.TokenType.LBRACE); + + var fields = std.ArrayList(*Node).init(self.arena); + while (self.accept_parse(parse_struct_field.call)) |field| { + _ = self.accept_token(tokenizer.TokenType.COMMA); + try fields.append(field); + } + _ = try self.parse_token(tokenizer.TokenType.RBRACE); + + return self.create_node(.{ + .TYPE = .{ + .STRUCT_TYPE = .{ + .fields = fields.items, + }, + }, + }); + } + + // StructInstantiation ::= IDENTIFIER LBRACE RBRACE + fn parse_struct_instanciation(self: *Parser) ParserError!*Node { + errdefer if (!self.try_context) std.debug.print("Error parsing struct instanciation {any}\n", .{self.peek_token()}); + + const typ = try self.parse_token(tokenizer.TokenType.IDENTIFIER); + _ = try self.parse_token(tokenizer.TokenType.LBRACE); + _ = try self.parse_token(tokenizer.TokenType.RBRACE); + + return self.create_node(.{ + .STRUCT_INSTANCIATION = .{ + .typ = try self.arena.dupe(u8, typ.type.IDENTIFIER), + }, + }); + } + + // FieldAccess ::= Expression DOT IDENTIFIER + fn parse_field_access(self: *Parser) ParserError!*Node { + errdefer if (!self.try_context) std.debug.print("Error parsing field access {any}\n", .{self.peek_token()}); + + const expression = try self.parse_expression(); + + _ = try self.parse_token(tokenizer.TokenType.DOT); + + const ident = try self.parse_token(tokenizer.TokenType.IDENTIFIER); + + return self.create_node(.{ + .FIELD_ACCESS = .{ + .expression = expression, + .name = try self.arena.dupe(u8, ident.type.IDENTIFIER), + }, + }); + } + // ReturnStatement ::= RETURN (Expression)? fn parse_return_statement(self: *Parser) ParserError!*Node { errdefer if (!self.try_context) std.debug.print("Error parsing return statement {any}\n", .{self.peek_token()}); |