diff options
| author | Baitinq <[email protected]> | 2025-05-20 22:54:16 +0200 |
|---|---|---|
| committer | Baitinq <[email protected]> | 2025-05-20 22:54:16 +0200 |
| commit | 7b4fba9ae9c65fc5fc341d73446bde1eab4329f5 (patch) | |
| tree | d4b235726eb2da92536e71e22a026e3285adc355 | |
| parent | Codegen: Implement proper type comparisons (diff) | |
| download | interpreter-7b4fba9ae9c65fc5fc341d73446bde1eab4329f5.tar.gz interpreter-7b4fba9ae9c65fc5fc341d73446bde1eab4329f5.tar.bz2 interpreter-7b4fba9ae9c65fc5fc341d73446bde1eab4329f5.zip | |
Feature: Add support for casting types
| -rw-r--r-- | grammar.ebnf | 4 | ||||
| -rw-r--r-- | src/codegen.zig | 9 | ||||
| -rw-r--r-- | src/parser.zig | 40 | ||||
| -rw-r--r-- | src/tokenizer.zig | 2 |
4 files changed, 50 insertions, 5 deletions
diff --git a/grammar.ebnf b/grammar.ebnf index bd38952..3806ee6 100644 --- a/grammar.ebnf +++ b/grammar.ebnf @@ -18,7 +18,9 @@ ReturnStatement ::= RETURN (Expression)? FunctionArguments ::= Expression ("," Expression)* -Expression ::= EqualityExpression | AdditiveExpression +Expression ::= EqualityExpression | AdditiveExpression | CastExpression + +CastExpression ::= "cast" LPAREN TYPE "," Expression RPAREN EqualityExpression ::= AdditiveExpression ("==" | "!=" | "<=" | ">=" | "<" | ">") AdditiveExpression diff --git a/src/codegen.zig b/src/codegen.zig index 66db412..d6415cf 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -654,6 +654,15 @@ pub const CodeGen = struct { .node_type = expression, }); }, + .CAST_STATEMENT => |exp| { + const val = try self.generate_expression_value(exp.expression, ""); + return try self.create_variable(.{ + .value = val.value, //TODO: do real casting + .stack_level = null, + .node = expression, + .node_type = exp.typ, + }); + }, else => unreachable, }; } diff --git a/src/parser.zig b/src/parser.zig index 510726f..1e130f8 100644 --- a/src/parser.zig +++ b/src/parser.zig @@ -93,6 +93,10 @@ pub const Node = union(enum) { RETURN_STATEMENT: struct { expression: ?*Node, }, + CAST_STATEMENT: struct { + typ: *Node, + expression: *Node, + }, BREAK_STATEMENT: void, CONTINUE_STATEMENT: void, }; @@ -154,7 +158,8 @@ pub const Parser = struct { 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_function_call_statement) orelse + const statement = + self.accept_parse(parse_function_call_statement) orelse self.accept_parse(parse_if_statement) orelse self.accept_parse(parse_while_statement) orelse self.accept_parse(parse_return_statement) orelse @@ -401,11 +406,12 @@ pub const Parser = struct { } }); } - // Expression ::= EqualityExpression | AdditiveExpression + // Expression ::= EqualityExpression | AdditiveExpression | CastExpression fn parse_expression(self: *Parser) ParserError!*Node { errdefer if (!self.try_context) std.debug.print("Error parsing expression {any}\n", .{self.peek_token()}); - return self.accept_parse(parse_equality_expression) orelse + return self.accept_parse(parse_cast_expression) orelse + self.accept_parse(parse_equality_expression) orelse self.accept_parse(parse_additive_expression) orelse return ParserError.ParsingError; } @@ -678,6 +684,34 @@ pub const Parser = struct { }); } + // CastExpression ::= "cast" LPAREN TYPE "," Expression RPAREN + fn parse_cast_expression(self: *Parser) ParserError!*Node { + errdefer if (!self.try_context) std.debug.print("Error parsing cast statement {any}\n", .{self.peek_token()}); + + const ident = try self.parse_token(tokenizer.TokenType.IDENTIFIER); + + if (!std.mem.eql(u8, "cast", 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.COMMA); + + const expression = try self.parse_expression(); + + _ = try self.parse_token(tokenizer.TokenType.RPAREN); + + return self.create_node(.{ + .CAST_STATEMENT = .{ + .typ = typ, + .expression = expression, + }, + }); + } + // 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()}); diff --git a/src/tokenizer.zig b/src/tokenizer.zig index 32bdb19..d150058 100644 --- a/src/tokenizer.zig +++ b/src/tokenizer.zig @@ -177,7 +177,7 @@ pub const Tokenizer = struct { res.append(c) catch unreachable; } - return res; + return res.items; } fn accept_string(self: *Tokenizer, substr: []const u8) bool { |