From 48958afe4e187ce496d3445ee622ec3bc7bc8453 Mon Sep 17 00:00:00 2001 From: Baitinq Date: Wed, 28 May 2025 00:11:06 +0200 Subject: Feature: Add sizeof builtin function --- src/parser.zig | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) (limited to 'src/parser.zig') 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()}); -- cgit 1.4.1