about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--grammar.ebnf4
-rw-r--r--src/codegen.zig9
-rw-r--r--src/parser.zig40
-rw-r--r--src/tokenizer.zig2
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 {