I’m stuck on the first evaluating Stage #IZ6.
The evaluator does evaluate using the whole tokens thing. However, somewhere in the process of being passed from the parser to the evaluator, true gets converted to True implictly through what I assume is Python evaluation. I just can’t get a handle on where exactly.
Here are my logs:
I added a debug print (this is inside the evaluator):
def evaluate(self):
print(f"Evaluating Literal: {self.expression.value} (type: {type(self.expression.value)})")
return self.evaluate_expr(self.expression)
and received stdout which verifies that Python is converting itself:
Evaluating Literal: True (type: <class 'bool'>)
True
And here’s a snippet of my code:
include relevant code here (please make sure to keep the backticks around this!)
The parser itself correctly displays true, so it must be somewhere in the passing to the evaluator that Python coils around it and changes it to a Python Bool
Here’s a snippet of my evaluator being called in main():
elif command == "evaluate":
tokens, lex_errors = scanner.scan_tokens()
if lex_errors:
sys.exit(65)
parser = Parser(tokens)
expression = parser.parse()
if parser.had_error or not expression:
sys.exit(65)
evaluator = Evaluate(expression)
result = evaluator.evaluate()
print(result)
sys.exit(0)
Additional testing:
Added in some debugging output for evaluating !true:
<__main__.Unary object at 0x10d4ecc90>
Evaluating Unary: TokenType.BANG ! None true
<__main__.Literal object at 0x10d4eccd0>
Evaluating Literal: True (type: <class 'bool'>)
False
And I’m just going to give my entire Evaluate Class:
class Evaluate:
def __init__(self, expression):
self.expression = expression
def evaluate(self):
return self.evaluate_expr(self.expression)
def evaluate_expr(self, expr):
# DEBUGGING PRINTING IS IN
if isinstance(expr, Binary):
print(repr(expr))
print(f"Evaluating Binary: {expr.left} {expr.operator} {expr.right}")
return self.evaluate_binary(expr)
elif isinstance(expr, Grouping):
print(repr(expr))
print(repr(expr.expression))
print(f"Evaluating Grouping: {expr.expression}")
return self.evaluate_expr(expr.expression)
elif isinstance(expr, Literal):
print(repr(expr))
print(f"Evaluating Literal: {expr.value} (type: {type(expr.value)})")
return expr.value
elif isinstance(expr, Unary):
print(repr(expr))
print(f"Evaluating Unary: {expr.operator} {expr.right}")
return self.evaluate_unary(expr)
else:
raise Exception(f"Unexpected expression type: {type(expr)}")
def evaluate_binary(self, expr):
left = self.evaluate_expr(expr.left)
right = self.evaluate_expr(expr.right)
operator = expr.operator.type
if operator == TokenType.PLUS:
return left + right
elif operator == TokenType.MINUS:
return left - right
elif operator == TokenType.STAR:
return left * right
elif operator == TokenType.SLASH:
return left / right
elif operator == TokenType.GREATER:
return left > right
elif operator == TokenType.GREATER_EQUAL:
return left >= right
elif operator == TokenType.LESS:
return left < right
elif operator == TokenType.LESS_EQUAL:
return left <= right
elif operator == TokenType.EQUAL_EQUAL:
return left == right
elif operator == TokenType.BANG_EQUAL:
return left != right
else:
raise Exception(f"Unexpected operator: {operator}")
def evaluate_unary(self, expr):
right = self.evaluate_expr(expr.right)
operator = expr.operator.type
if operator == TokenType.MINUS:
return -right
elif operator == TokenType.BANG:
return not right
else:
raise Exception(f"Unexpected operator: {operator}")