summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorBaitinq <manuelpalenzuelamerino@gmail.com>2025-01-19 16:04:08 +0100
committerBaitinq <manuelpalenzuelamerino@gmail.com>2025-01-19 16:43:59 +0100
commit44ec5d5de6a558fc20b8452a1ee743b64d56e5e5 (patch)
treee6b3f445aa8578b2bcaa5de2d2d91214755230b9 /src
parentFeature: Add support for boolean values (diff)
downloadinterpreter-44ec5d5de6a558fc20b8452a1ee743b64d56e5e5.tar.gz
interpreter-44ec5d5de6a558fc20b8452a1ee743b64d56e5e5.tar.bz2
interpreter-44ec5d5de6a558fc20b8452a1ee743b64d56e5e5.zip
Feature: Add basic support for equality expression
Diffstat (limited to 'src')
-rw-r--r--src/evaluator.zig12
-rw-r--r--src/parser.zig54
2 files changed, 47 insertions, 19 deletions
diff --git a/src/evaluator.zig b/src/evaluator.zig
index 39c7235..f35956a 100644
--- a/src/evaluator.zig
+++ b/src/evaluator.zig
@@ -141,10 +141,14 @@ pub const Evaluator = struct {
                 const lhs = try self.get_expression_value(x.lhs) orelse return EvaluatorError.EvaluationError;
                 const rhs = try self.get_expression_value(x.rhs) orelse return EvaluatorError.EvaluationError;
                 std.debug.assert(lhs.* == .NUMBER and rhs.* == .NUMBER);
-                var res: i64 = undefined;
-                if (x.addition) res = lhs.NUMBER + rhs.NUMBER;
-                res = lhs.NUMBER - rhs.NUMBER;
-                return try self.create_variable(.{ .NUMBER = res });
+                if (x.addition) return try self.create_variable(.{ .NUMBER = lhs.NUMBER + rhs.NUMBER });
+                return try self.create_variable(.{ .NUMBER = lhs.NUMBER - rhs.NUMBER });
+            },
+            .EQUALITY_EXPRESSION => |x| {
+                const lhs = try self.get_expression_value(x.lhs) orelse return EvaluatorError.EvaluationError;
+                const rhs = try self.get_expression_value(x.rhs) orelse return EvaluatorError.EvaluationError;
+                std.debug.assert(lhs.* == .NUMBER and rhs.* == .NUMBER); //TODO: Generic
+                return try self.create_variable(.{ .BOOLEAN = (lhs.NUMBER == rhs.NUMBER) });
             },
             .PRIMARY_EXPRESSION => |x| {
                 switch (x) {
diff --git a/src/parser.zig b/src/parser.zig
index ac66e5d..1014ba4 100644
--- a/src/parser.zig
+++ b/src/parser.zig
@@ -13,6 +13,7 @@ const NodeType = enum {
     FUNCTION_CALL_STATEMENT,
     IF_STATEMENT,
     EXPRESSION,
+    EQUALITY_EXPRESSION,
     ADDITIVE_EXPRESSION,
     PRIMARY_EXPRESSION,
     FUNCTION_DEFINITION,
@@ -40,6 +41,7 @@ pub const Node = union(NodeType) {
         statements: []*Node,
     },
     EXPRESSION: union(enum) {
+        //TODO: Why do we need this
         ADDITIVE_EXPRESSION: struct {
             expression: *Node,
         },
@@ -47,6 +49,10 @@ pub const Node = union(NodeType) {
             expression: *Node,
         },
     },
+    EQUALITY_EXPRESSION: struct {
+        lhs: *Node,
+        rhs: *Node,
+    },
     ADDITIVE_EXPRESSION: struct {
         addition: bool,
         lhs: *Node,
@@ -211,16 +217,34 @@ pub const Parser = struct {
         } });
     }
 
-    // Expression   ::= AdditiveExpression | FunctionDefinition
+    // Expression ::= EqualityExpression | AdditiveExpression | FunctionDefinition
     fn parse_expression(self: *Parser) ParserError!*Node {
         errdefer if (!self.try_context) std.debug.print("Error parsing expression\n", .{});
 
-        return self.accept_parse(parse_additive_expression) orelse
+        return self.accept_parse(parse_equality_expression) orelse
+            self.accept_parse(parse_additive_expression) orelse
             self.accept_parse(parse_function_definition) orelse
             return ParserError.ParsingError;
     }
 
-    // AdditiveExpression ::= PrimaryExpression (("+" | "-") AdditiveExpression)
+    // EqualityExpression ::= AdditiveExpression "==" AdditiveExpression
+    fn parse_equality_expression(self: *Parser) ParserError!*Node {
+        errdefer if (!self.try_context) std.debug.print("Error parsing equality expression\n", .{});
+
+        const lhs = try self.parse_additive_expression();
+
+        _ = try self.parse_token(tokenizer.TokenType.EQUALS);
+        _ = try self.parse_token(tokenizer.TokenType.EQUALS);
+
+        const rhs = try self.parse_additive_expression();
+
+        return self.create_node(.{ .EQUALITY_EXPRESSION = .{
+            .lhs = lhs,
+            .rhs = rhs,
+        } });
+    }
+
+    // AdditiveExpression ::= PrimaryExpression (("+" | "-") AdditiveExpression)?
     fn parse_additive_expression(self: *Parser) ParserError!*Node {
         errdefer if (!self.try_context) std.debug.print("Error parsing additive expression\n", .{});
 
@@ -339,6 +363,18 @@ pub const Parser = struct {
         });
     }
 
+    fn parse_token(self: *Parser, expected_token: tokenizer.TokenType) ParserError!tokenizer.Token {
+        errdefer if (!self.try_context) std.debug.print("Error accepting token: {any}\n", .{expected_token});
+        const token = self.peek_token() orelse return ParserError.ParsingError;
+
+        if (token != expected_token) {
+            if (!self.try_context) std.debug.print("Expected {any} - found {any}\n", .{ expected_token, token });
+            return ParserError.ParsingError;
+        }
+
+        return self.consume_token() orelse unreachable;
+    }
+
     fn accept_parse(self: *Parser, parsing_func: *const fn (_: *Parser) ParserError!*Node) ?*Node {
         const prev_offset = self.offset;
         self.try_context = true;
@@ -358,18 +394,6 @@ pub const Parser = struct {
         return null;
     }
 
-    fn parse_token(self: *Parser, expected_token: tokenizer.TokenType) ParserError!tokenizer.Token {
-        errdefer if (!self.try_context) std.debug.print("Error accepting token: {any}\n", .{expected_token});
-        const token = self.peek_token() orelse return ParserError.ParsingError;
-
-        if (token != expected_token) {
-            if (!self.try_context) std.debug.print("Expected {any} - found {any}\n", .{ expected_token, token });
-            return ParserError.ParsingError;
-        }
-
-        return self.consume_token() orelse unreachable;
-    }
-
     fn consume_token(self: *Parser) ?tokenizer.Token {
         if (self.offset >= self.tokens.len) return null;