about summary refs log tree commit diff
path: root/src/parser.zig
diff options
context:
space:
mode:
authorBaitinq <[email protected]>2025-05-28 00:11:06 +0200
committerBaitinq <[email protected]>2025-05-28 00:11:06 +0200
commit48958afe4e187ce496d3445ee622ec3bc7bc8453 (patch)
treebf6c0ead8240a27e150e9e81dd9207cee4dbe211 /src/parser.zig
parentFeature: Finish adding struct support :^) (diff)
downloadpry-lang-48958afe4e187ce496d3445ee622ec3bc7bc8453.tar.gz
pry-lang-48958afe4e187ce496d3445ee622ec3bc7bc8453.tar.bz2
pry-lang-48958afe4e187ce496d3445ee622ec3bc7bc8453.zip
Feature: Add sizeof builtin function
Diffstat (limited to 'src/parser.zig')
-rw-r--r--src/parser.zig35
1 files changed, 32 insertions, 3 deletions
diff --git a/src/parser.zig b/src/parser.zig
index 95b4bf2..5db8fa8 100644
--- a/src/parser.zig
+++ b/src/parser.zig
@@ -111,6 +111,9 @@ pub const Node = union(enum) {
         typ: *Node,
         expression: *Node,
     },
+    SIZEOF_STATEMENT: struct {
+        typ: *Node,
+    },
     BREAK_STATEMENT: void,
     CONTINUE_STATEMENT: void,
 };
@@ -168,12 +171,13 @@ pub const Parser = struct {
         } });
     }
 
-    // Statement    ::= (AssignmentStatement | ImportDeclaration | ExternDeclaration | CastStatement | FunctionCallStatement | IfStatement | WhileStatement | ReturnStatement | "break" | "continue") SEMICOLON
+    // Statement    ::= (AssignmentStatement | ImportDeclaration | ExternDeclaration | CastStatement | SizeOfStatement | FunctionCallStatement | IfStatement | WhileStatement | ReturnStatement | "break" | "continue") SEMICOLON
     fn parse_statement(self: *Parser) ParserError!*Node {
         errdefer if (!self.try_context) std.debug.print("Error parsing statement {any}\n", .{self.peek_token()});
 
         const statement =
-            self.accept_parse(parse_cast_statement) orelse
+            self.accept_parse(parse_cast_statement) orelse //TODO: Can we not deal with cast / sizeof in parser?
+            self.accept_parse(parse_sizeof_statement) orelse
             self.accept_parse(parse_function_call_statement) orelse
             self.accept_parse(parse_if_statement) orelse
             self.accept_parse(parse_while_statement) orelse
@@ -567,12 +571,14 @@ pub const Parser = struct {
         } });
     }
 
-    // PostfixExpression ::= PrimaryExpression (FunctionCallStatement | FieldAccess )*
+    // PostfixExpression ::= PrimaryExpression (CastStatement | SizeOfStatement | FunctionCallStatement | FieldAccess )*
     fn parse_postfix_expression(self: *Parser) ParserError!*Node {
         errdefer if (!self.try_context) std.debug.print("Error parsing postfix expression {any}\n", .{self.peek_token()});
 
         if (self.accept_parse(parse_cast_statement)) |stmt| {
             return stmt;
+        } else if (self.accept_parse(parse_sizeof_statement)) |stmt| {
+            return stmt;
         } else if (self.accept_parse(parse_function_call_statement)) |stmt| {
             return stmt;
         } else if (self.accept_parse(parse_field_access)) |stmt| {
@@ -814,6 +820,29 @@ pub const Parser = struct {
         });
     }
 
+    // SizeOfStatement ::= "sizeof" LPAREN TYPE RPAREN
+    fn parse_sizeof_statement(self: *Parser) ParserError!*Node {
+        errdefer if (!self.try_context) std.debug.print("Error parsing sizeof statement {any}\n", .{self.peek_token()});
+
+        const ident = try self.parse_token(tokenizer.TokenType.IDENTIFIER);
+
+        if (!std.mem.eql(u8, "sizeof", ident.type.IDENTIFIER)) {
+            return ParserError.ParsingError;
+        }
+
+        _ = try self.parse_token(tokenizer.TokenType.LPAREN);
+
+        const typ = try self.parse_type();
+
+        _ = try self.parse_token(tokenizer.TokenType.RPAREN);
+
+        return self.create_node(.{
+            .SIZEOF_STATEMENT = .{
+                .typ = typ,
+            },
+        });
+    }
+
     // Type ::= IDENTIFIER | FunctionType
     fn parse_type(self: *Parser) ParserError!*Node {
         errdefer if (!self.try_context) std.debug.print("Error parsing type annotation {any}\n", .{self.peek_token()});