creating:evaluation

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
creating:evaluation [2025/04/27 17:32] – Removed infix conjunction & disjunction operators ahelwercreating:evaluation [2025/06/19 16:31] (current) – LEFT_BRACE interpretation splits out Object value = ahelwer
Line 65: Line 65:
 ==== Evaluating Unary Operators ==== ==== Evaluating Unary Operators ====
  
-Our first real difference is in the ''visitUnaryExpr()'' method.+Our first real difference from the book is in the ''visitUnaryExpr()'' method.
 Recall that since our ''Expr.Unary'' type represents both prefix and suffix operators, we don't call its parameter ''right'' as in the book. Recall that since our ''Expr.Unary'' type represents both prefix and suffix operators, we don't call its parameter ''right'' as in the book.
-Here's how we define the negative prefix operator, casting the parameter to an ''int'' instead of a ''double'' (highlighted lines differ from book): +We also don't pre-emptively evaluate the inner expression at the top of the method; this is important for when we later fully implement the prime and enabled operators. 
- +The method is structured as switch statement handling all possible unary operators
-<code java [highlight_lines_extra="3,7"]>+<code java>
   @Override   @Override
   public Object visitUnaryExpr(Expr.Unary expr) {   public Object visitUnaryExpr(Expr.Unary expr) {
-    Object operand = evaluate(expr.expr); 
- 
     switch (expr.operator.type) {     switch (expr.operator.type) {
-      case MINUS: +      case PRIME{
-        return -(int)operand; +
-    }+
  
-    // Unreachable. +      } case ENABLED: { 
-    return null;+ 
 +      } case NOT: { 
 + 
 +      } case MINUS: { 
 + 
 +      } default: { 
 +        // Unreachable. 
 +        return null; 
 +      } 
 +    }
   }   }
 +</code>
 +
 +Here's how we define the negative prefix operator; while the book casts the operand to a ''double'', here we cast it to an ''int'':
 +<code java [highlight_lines_extra="2,3"]>
 +      } case MINUS: {
 +        Object operand = evaluate(expr.expr);
 +        return -(int)operand;
 +      } default: {
 </code> </code>
  
Line 90: Line 103:
  
 Our logical-not prefix operator is denoted by the ''NOT'' token type instead of ''BANG'' as in Lox. Our logical-not prefix operator is denoted by the ''NOT'' token type instead of ''BANG'' as in Lox.
-We also have no use for the ''isTruthy()'' helper method, since TLA⁺ is quite strict: only Boolean values can be given to Boolean operators! +We also have no use for the ''isTruthy()'' helper method from the book, since TLA⁺ is quite strict: only Boolean values can be given to Boolean operators! 
-Add this code to the ''visitUnaryExpr()'' method: +Add this code to ''visitUnaryExpr()'':
 <code java [highlight_lines_extra="2,3"]> <code java [highlight_lines_extra="2,3"]>
-    switch (expr.operator.type+      } case NOT: { 
-      case NOT:+        Object operand = evaluate(expr.expr);
         return !(boolean)operand;         return !(boolean)operand;
-      case MINUS:+      case MINUS: {
 </code> </code>
  
 We still have two more unary operators to define: ''ENABLED'', and the prime operator. We still have two more unary operators to define: ''ENABLED'', and the prime operator.
 Both are trivial in this domain but will become much more complicated later on. Both are trivial in this domain but will become much more complicated later on.
-For constant expressions, ''ENABLED'' is true if and only if the expression itself is true+For constant expressions, ''ENABLED'' is always false and prime is just whatever the inner expression evaluates to
-Add the highlighted code to the ''visitUnaryExpr()'' method: +Add the highlighted code to ''visitUnaryExpr()'': 
- +<code java [highlight_lines_extra="2,4"]> 
-<code java [highlight_lines_extra="2,3"]> +      case PRIME{ 
-    switch (expr.operator.type) { +        return evaluate(expr.expr); 
-      case ENABLED+      case ENABLED: { 
-        return (boolean)operand+        return false
-      case NOT: +      case NOT{
-</code> +
- +
-Priming a constant expression has no effect on the value of that expression, so just return the operand's value: +
- +
-<code java [highlight_lines_extra="2,3"]> +
-    switch (expr.operator.type) { +
-      case PRIME: +
-        return operand+
-      case ENABLED:+
 </code> </code>
  
Line 124: Line 127:
  
 Unlike Lox, addition in TLA⁺ is only defined between two numbers (at least in its standard ''Integers'' module definition). Unlike Lox, addition in TLA⁺ is only defined between two numbers (at least in its standard ''Integers'' module definition).
-Here's how we define our basic binary arithmetic & comparison operators; add a ''visitBinaryExpr()'' method in the ''Interpreter'' class: +Here's how we define our basic binary arithmetic & comparison operators; add a ''visitBinaryExpr()'' method in the ''Interpreter'' class (highlighted code differs from the book):
 <code java [highlight_lines_extra="8,9,10,11,12,13,14"]> <code java [highlight_lines_extra="8,9,10,11,12,13,14"]>
   @Override   @Override
Line 226: Line 228:
         Set<Object> set = new HashSet<Object>();         Set<Object> set = new HashSet<Object>();
         for (Expr parameter : expr.parameters) {         for (Expr parameter : expr.parameters) {
-          set.add(evaluate(parameter));+          Object value = evaluate(parameter)
 +          set.add(value);
         }         }
         return set;         return set;
Line 240: Line 243:
 In [[https://craftinginterpreters.com/evaluating-expressions.html#runtime-errors|section 7.3]] we add some error detection & reporting to our interpreter code. In [[https://craftinginterpreters.com/evaluating-expressions.html#runtime-errors|section 7.3]] we add some error detection & reporting to our interpreter code.
  
-Here's our variant of the ''checkNumberOperand()'' and ''checkNumberOperands()'' methods given in the book, using ''Integer'' instead of ''Double''; put these in the ''Interpreter'' class:+Here's our variant of the ''checkNumberOperand()'' and ''checkNumberOperands()'' methods given in the book, using ''Integer'' instead of ''Double''; put these in the ''Interpreter'' class (highlighted code differs from the book):
  
 <code java [highlight_lines_extra="2,8"]> <code java [highlight_lines_extra="2,8"]>
Line 292: Line 295:
 Now add these checks to our interpreter code. Now add these checks to our interpreter code.
 Here's negative: Here's negative:
-<code java [highlight_lines_extra="2"]> +<code java [highlight_lines_extra="3"]> 
-      case MINUS:+      case MINUS: 
 +        Object operand = evaluate(expr.expr);
         checkNumberOperand(expr.operator, operand);         checkNumberOperand(expr.operator, operand);
         return -(int)operand;         return -(int)operand;
 +      } default: {
 </code> </code>
 Logical not: Logical not:
-<code java [highlight_lines_extra="2"]> +<code java [highlight_lines_extra="3"]> 
-      case NOT:+      case NOT: 
 +        Object operand = evaluate(expr.expr);
         checkBooleanOperand(expr.operator, operand);         checkBooleanOperand(expr.operator, operand);
         return !(boolean)operand;         return !(boolean)operand;
-</code> +      } case MINUS{
-Enabled: +
-<code java [highlight_lines_extra="2"]> +
-      case ENABLED: +
-        checkBooleanOperand(expr.operator, operand); +
-        return (boolean)operand;+
 </code> </code>
 Subtraction: Subtraction:
  • creating/evaluation.1745775154.txt.gz
  • Last modified: 2025/04/27 17:32
  • by ahelwer