summary refs log tree commit diff
diff options
context:
space:
mode:
authorBaitinq <manuelpalenzuelamerino@gmail.com>2025-01-18 11:07:55 +0100
committerBaitinq <manuelpalenzuelamerino@gmail.com>2025-01-18 11:07:59 +0100
commit6ff305a75c1271ddfd337f8f3b1dfc7724a0dd6e (patch)
tree568a945af85b68f0e65da5468e02b665dc90062a
parentLang: Start introducing support for function arguments (diff)
downloadinterpreter-6ff305a75c1271ddfd337f8f3b1dfc7724a0dd6e.tar.gz
interpreter-6ff305a75c1271ddfd337f8f3b1dfc7724a0dd6e.tar.bz2
interpreter-6ff305a75c1271ddfd337f8f3b1dfc7724a0dd6e.zip
Misc: Implement print function as "native" function
-rw-r--r--grammar.ebnf4
-rw-r--r--src/evaluator.zig24
-rw-r--r--src/parser.zig28
-rw-r--r--src/tokenizer.zig3
4 files changed, 15 insertions, 44 deletions
diff --git a/grammar.ebnf b/grammar.ebnf
index 406c2d0..35a7079 100644
--- a/grammar.ebnf
+++ b/grammar.ebnf
@@ -1,11 +1,9 @@
 Program      ::= Statement+
 
-Statement    ::= (AssignmentStatement | PrintStatement | FunctionCallStatement) SEMICOLON
+Statement    ::= (AssignmentStatement | FunctionCallStatement) SEMICOLON
 
 AssignmentStatement ::= "let" IDENTIFIER EQUALS Expression
 
-PrintStatement ::= PRINT LPAREN Expression RPAREN -- TODO: this won't be needed once functions support arguments
-
 FunctionCallStatement ::= IDENTIFIER LPAREN FunctionArguments? RPAREN
 
 FunctionArguments ::= Expression ("," Expression)*
diff --git a/src/evaluator.zig b/src/evaluator.zig
index 4164f93..cc1e99e 100644
--- a/src/evaluator.zig
+++ b/src/evaluator.zig
@@ -44,7 +44,6 @@ pub const Evaluator = struct {
 
         return switch (statement.STATEMENT.statement.*) {
             .ASSIGNMENT_STATEMENT => |*assignment_statement| try self.evaluate_assignment_statement(@ptrCast(assignment_statement)),
-            .PRINT_STATEMENT => |*print_statement| try self.evaluate_print_statement(@ptrCast(print_statement)),
             .FUNCTION_CALL_STATEMENT => |*function_call_statement| _ = try self.evaluate_function_call_statement(@ptrCast(function_call_statement)),
             else => unreachable,
         };
@@ -71,20 +70,21 @@ pub const Evaluator = struct {
         try self.variables.put(assignment_statement.name, val);
     }
 
-    fn evaluate_print_statement(self: *Evaluator, print_statement: *parser.Node) !void {
-        errdefer std.debug.print("Error evaluating print statement\n", .{});
-        std.debug.assert(print_statement.* == parser.Node.PRINT_STATEMENT);
-
-        const print_value = try self.get_expression_value(print_statement.PRINT_STATEMENT.expression);
+    // TODO: I dont really see the use of this.
+    fn evaluate_function_call_statement(self: *Evaluator, node: *parser.Node) !i64 {
+        errdefer std.debug.print("Error evaluating function call statement\n", .{});
+        std.debug.assert(node.* == parser.Node.FUNCTION_CALL_STATEMENT);
 
-        std.debug.print("PRINT: {d}\n", .{print_value});
-    }
+        const function_call_statement = node.FUNCTION_CALL_STATEMENT;
 
-    fn evaluate_function_call_statement(self: *Evaluator, function_call_statement: *parser.Node) !i64 {
-        errdefer std.debug.print("Error evaluating function call statement\n", .{});
-        std.debug.assert(function_call_statement.* == parser.Node.FUNCTION_CALL_STATEMENT);
+        // Print function implementation
+        if (std.mem.eql(u8, function_call_statement.name, "print")) {
+            std.debug.assert(function_call_statement.arguments.len == 1);
+            std.debug.print("PRINT: {any}\n", .{try self.get_expression_value(function_call_statement.arguments[0])});
+            return 0;
+        }
 
-        const val = self.variables.get(function_call_statement.FUNCTION_CALL_STATEMENT.name) orelse return EvaluatorError.EvaluationError;
+        const val = self.variables.get(function_call_statement.name) orelse return EvaluatorError.EvaluationError;
 
         return val.?;
     }
diff --git a/src/parser.zig b/src/parser.zig
index e206403..e9a2908 100644
--- a/src/parser.zig
+++ b/src/parser.zig
@@ -10,7 +10,6 @@ const NodeType = enum {
     PROGRAM,
     STATEMENT,
     ASSIGNMENT_STATEMENT,
-    PRINT_STATEMENT,
     FUNCTION_CALL_STATEMENT,
     EXPRESSION,
     ADDITIVE_EXPRESSION,
@@ -31,9 +30,6 @@ pub const Node = union(NodeType) {
         name: []const u8,
         expression: *Node,
     },
-    PRINT_STATEMENT: struct {
-        expression: *Node,
-    },
     FUNCTION_CALL_STATEMENT: struct {
         name: []const u8,
         arguments: []*Node,
@@ -105,13 +101,11 @@ pub const Parser = struct {
         } });
     }
 
-    // Statement ::= (AssignmentStatement | PrintStatement | FunctionCallStatement) SEMICOLON
+    // Statement ::= (AssignmentStatement | FunctionCallStatement) SEMICOLON
     fn parse_statement(self: *Parser) ParserError!*Node {
         errdefer if (!self.try_context) std.debug.print("Error parsing statement\n", .{});
 
-        const statement =
-            self.accept_parse(parse_print_statement) orelse
-            self.accept_parse(parse_function_call_statement) orelse
+        const statement = self.accept_parse(parse_function_call_statement) orelse
             try self.parse_assignment_statement();
 
         _ = try self.accept_token(tokenizer.TokenType.SEMICOLON);
@@ -147,24 +141,6 @@ pub const Parser = struct {
         });
     }
 
-    // PrintStatement :== PRINT LPAREN Expression RPAREN
-    fn parse_print_statement(self: *Parser) ParserError!*Node {
-        errdefer if (!self.try_context) std.debug.print("Error parsing print statement\n", .{});
-        _ = try self.accept_token(tokenizer.TokenType.PRINT);
-
-        _ = try self.accept_token(tokenizer.TokenType.LPAREN);
-
-        const expression = try self.parse_expression();
-
-        _ = try self.accept_token(tokenizer.TokenType.RPAREN);
-
-        return self.create_node(.{
-            .PRINT_STATEMENT = .{
-                .expression = @constCast(expression),
-            },
-        });
-    }
-
     // FunctionCallStatement ::= IDENTIFIER LPAREN FunctionArguments? RPAREN
     fn parse_function_call_statement(self: *Parser) ParserError!*Node {
         errdefer if (!self.try_context) std.debug.print("Error parsing function call statement\n", .{});
diff --git a/src/tokenizer.zig b/src/tokenizer.zig
index b5634a2..c673f20 100644
--- a/src/tokenizer.zig
+++ b/src/tokenizer.zig
@@ -7,7 +7,6 @@ const TokenizerError = error{
 pub const TokenType = enum {
     // Keywords
     LET,
-    PRINT,
     RETURN,
     ARROW,
 
@@ -32,7 +31,6 @@ pub const TokenType = enum {
 
 pub const Token = union(TokenType) {
     LET: void,
-    PRINT: void,
     RETURN: void,
     ARROW: void,
     IDENTIFIER: []u8,
@@ -78,7 +76,6 @@ pub const Tokenizer = struct {
         if (string.len == 0) return TokenizerError.TokenizingError;
 
         if (std.mem.eql(u8, string, "let")) return Token{ .LET = void{} };
-        if (std.mem.eql(u8, string, "print")) return Token{ .PRINT = void{} };
         if (std.mem.eql(u8, string, "return")) return Token{ .RETURN = void{} };
 
         if (std.fmt.parseInt(i32, string, 10) catch null) |i| return Token{ .NUMBER = i };