py-calc/interpeter.py
2026-04-10 16:39:57 +02:00

66 lines
No EOL
2.1 KiB
Python

from nodes import *
from values import Number
class Interpeter:
def visit(self, node):
method_name = f'visit_{type(node).__name__}'
method = getattr(self, method_name)
return method(node)
def visit_NumberNode(self, node) -> Number:
return Number(node.value)
def visit_AddNode(self, node) -> Number:
return Number(self.visit(node.node_a).value + self.visit(node.node_b).value)
def visit_SubtractNode(self, node) -> Number:
return Number(self.visit(node.node_a).value - self.visit(node.node_b).value)
def visit_MultiplyNode(self, node) -> Number:
return Number(self.visit(node.node_a).value * self.visit(node.node_b).value)
def visit_DivideNode(self, node) -> Number:
try:
return Number(self.visit(node.node_a).value / self.visit(node.node_b).value)
except Exception:
raise Exception("Runtime Math error (division)")
def visit_PlusNode(self, node) -> Number:
return self.visit(node.node)
def visit_MinusNode(self, node) -> Number:
return Number(-self.visit(node.node).value)
def visit_FactorialNode(self, node) -> Number:
fact = lambda x: 1 if x == 0 else x * fact(x-1)
try:
return Number(fact(self.visit(node.node).value))
except Exception:
raise Exception("Runtime Math error (Factorial)")
def visit_PowerNode(self, node) -> Number:
return Number(pow(self.visit(node.node_a).value, self.visit(node.node_b).value))
def visit_ModuleNode(self, node) -> Number:
return Number(self.visit(node.node_a).value % self.visit(node.node_b).value)
def visit_AverageNode(self, node) -> Number:
return Number((self.visit(node.node_a).value + self.visit(node.node_b).value) / 2.0 )
def visit_MaximumNode(self, node) -> Number:
return Number(max(self.visit(node.node_a).value, self.visit(node.node_b).value) )
def visit_MinimumNode(self, node) -> Number:
return Number(min(self.visit(node.node_a).value, self.visit(node.node_b).value) )
def visit_NegateNode(self, node) -> Number:
if not self.visit(node.node).value.is_integer():
raise Exception("Runtime Math error (Negate)")
return Number(~int(self.visit(node.node).value))