diff options
author | Baitinq <manuelpalenzuelamerino@gmail.com> | 2025-01-18 11:07:55 +0100 |
---|---|---|
committer | Baitinq <manuelpalenzuelamerino@gmail.com> | 2025-01-18 11:07:59 +0100 |
commit | 6ff305a75c1271ddfd337f8f3b1dfc7724a0dd6e (patch) | |
tree | 568a945af85b68f0e65da5468e02b665dc90062a | |
parent | Lang: Start introducing support for function arguments (diff) | |
download | interpreter-6ff305a75c1271ddfd337f8f3b1dfc7724a0dd6e.tar.gz interpreter-6ff305a75c1271ddfd337f8f3b1dfc7724a0dd6e.tar.bz2 interpreter-6ff305a75c1271ddfd337f8f3b1dfc7724a0dd6e.zip |
Misc: Implement print function as "native" function
-rw-r--r-- | grammar.ebnf | 4 | ||||
-rw-r--r-- | src/evaluator.zig | 24 | ||||
-rw-r--r-- | src/parser.zig | 28 | ||||
-rw-r--r-- | src/tokenizer.zig | 3 |
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 }; |