summary refs log tree commit diff
diff options
context:
space:
mode:
authorBaitinq <manuelpalenzuelamerino@gmail.com>2025-01-22 00:30:28 +0100
committerBaitinq <manuelpalenzuelamerino@gmail.com>2025-01-22 00:30:59 +0100
commit596cfe8b9d7319085465bbd134247e2967652f6f (patch)
tree106c0926321316cac67d57ea94df8444fd0b3f8f
parentFeature: Add support for division and multiplication (diff)
downloadinterpreter-master.tar.gz
interpreter-master.tar.bz2
interpreter-master.zip
Feature: Add support for negation HEAD master
-rw-r--r--examples/7.src2
-rw-r--r--grammar.ebnf2
-rw-r--r--src/evaluator.zig5
-rw-r--r--src/parser.zig9
4 files changed, 11 insertions, 7 deletions
diff --git a/examples/7.src b/examples/7.src
index 9bb3c73..9846af5 100644
--- a/examples/7.src
+++ b/examples/7.src
@@ -1,7 +1,7 @@
 let main = () => {
 	let i = 4;
 	
-	if (1 - 1 * 2) == 5 - (10 / 2) - 1 {
+	if (1 - -1 * 2) == 5 - (10 / 2) + 3 {
 		print(i);
 		return i;
 	};
diff --git a/grammar.ebnf b/grammar.ebnf
index 700147e..af2d9ec 100644
--- a/grammar.ebnf
+++ b/grammar.ebnf
@@ -22,7 +22,7 @@ AdditiveExpression ::= MultiplicativeExpression (("+" | "-") MultiplicativeExpre
 
 MultiplicativeExpression ::= UnaryExpression (("*" | "/") UnaryExpression)*
 
-UnaryExpression ::= "!" UnaryExpression | PrimaryExpression
+UnaryExpression ::= ("!" | "-") UnaryExpression | PrimaryExpression
 
 PrimaryExpression ::= NUMBER | BOOLEAN | IDENTIFIER | FunctionCallStatement | LPAREN Expression RPAREN
 
diff --git a/src/evaluator.zig b/src/evaluator.zig
index 9f8b61f..798d66c 100644
--- a/src/evaluator.zig
+++ b/src/evaluator.zig
@@ -174,6 +174,10 @@ pub const Evaluator = struct {
             },
             .UNARY_EXPRESSION => |x| {
                 const val = try self.get_expression_value(x.expression) orelse return EvaluatorError.EvaluationError;
+                if (!x.negation) {
+                    std.debug.assert(val.* == .NUMBER);
+                    return try self.create_variable(.{ .NUMBER = -val.NUMBER });
+                }
                 std.debug.assert(val.* == .BOOLEAN);
                 return try self.create_variable(.{ .BOOLEAN = !val.BOOLEAN });
             },
@@ -268,7 +272,6 @@ const Environment = struct {
             .allocator = allocator,
         };
 
-        //TODO: Add more scopes when evaluating functions
         // Create global scope
         try self.create_scope();
 
diff --git a/src/parser.zig b/src/parser.zig
index 966cad3..b407c42 100644
--- a/src/parser.zig
+++ b/src/parser.zig
@@ -322,18 +322,19 @@ pub const Parser = struct {
         return lhs;
     }
 
-    // UnaryExpression ::= "!" UnaryExpression | PrimaryExpression
+    // UnaryExpression ::= ("!" | "-") UnaryExpression | PrimaryExpression
     fn parse_unary_expression(self: *Parser) ParserError!*Node {
         errdefer if (!self.try_context) std.debug.print("Error parsing unary expression\n", .{});
 
-        const negation = self.accept_token(tokenizer.TokenType.BANG) != null;
+        const not = self.accept_token(tokenizer.TokenType.BANG) != null;
+        const minus = self.accept_token(tokenizer.TokenType.MINUS) != null;
 
-        if (!negation) {
+        if (!not and !minus) {
             return try self.parse_primary_expression();
         }
 
         return self.create_node(.{ .UNARY_EXPRESSION = .{
-            .negation = negation,
+            .negation = not,
             .expression = try self.parse_unary_expression(),
         } });
     }