|
@@ -1,5 +1,5 @@
|
|
-from .tokens import TokenType, Token
|
|
|
|
-from .lexer import Lexer
|
|
|
|
|
|
+from .node import Node,Number,BinOp
|
|
|
|
+from .tokens import TokenType
|
|
|
|
|
|
|
|
|
|
class InterpreterException(Exception):
|
|
class InterpreterException(Exception):
|
|
@@ -7,69 +7,30 @@ class InterpreterException(Exception):
|
|
|
|
|
|
|
|
|
|
class Interpreter():
|
|
class Interpreter():
|
|
- def __init__(self):
|
|
|
|
- self._current_token: Token = None
|
|
|
|
- self._lexer = Lexer()
|
|
|
|
|
|
|
|
- def _check_token_type(self, type_: TokenType):
|
|
|
|
- print(type_)
|
|
|
|
- if self._current_token.type_ == type_:
|
|
|
|
- self._current_token = self._lexer.next()
|
|
|
|
- else:
|
|
|
|
- raise InterpreterException("invalid token order")
|
|
|
|
-
|
|
|
|
- def _factor(self) -> float:
|
|
|
|
- token = self._current_token
|
|
|
|
- if token.type_ == TokenType.MINUS:
|
|
|
|
- self._check_token_type(TokenType.MINUS)
|
|
|
|
- val = self._factor()
|
|
|
|
- return float(-val)
|
|
|
|
- if token.type_ == TokenType.PLUS:
|
|
|
|
- self._check_token_type(TokenType.PLUS)
|
|
|
|
- val = self._factor()
|
|
|
|
- return float(val)
|
|
|
|
- if token.type_ == TokenType.INTEGER:
|
|
|
|
- self._check_token_type(TokenType.INTEGER)
|
|
|
|
- return float(token.value)
|
|
|
|
- if token.type_ == TokenType.LPAREN:
|
|
|
|
- self._check_token_type(TokenType.LPAREN)
|
|
|
|
- result = self._expr()
|
|
|
|
- self._check_token_type(TokenType.RPAREN)
|
|
|
|
- return result
|
|
|
|
- raise InterpreterException("invalid factor")
|
|
|
|
-
|
|
|
|
- def _term(self) -> float:
|
|
|
|
- result = self._factor()
|
|
|
|
- ops = [TokenType.MUL, TokenType.DIV]
|
|
|
|
- while self._current_token.type_ in ops:
|
|
|
|
- token = self._current_token
|
|
|
|
- if token.type_ == TokenType.MUL:
|
|
|
|
- self._check_token_type(TokenType.MUL)
|
|
|
|
- result *= self._factor()
|
|
|
|
- elif token.type_ == TokenType.DIV:
|
|
|
|
- self._check_token_type(TokenType.DIV)
|
|
|
|
- result /= self._factor()
|
|
|
|
- return result
|
|
|
|
-
|
|
|
|
- def _expr(self) -> int:
|
|
|
|
- ops = [TokenType.PLUS, TokenType.MINUS]
|
|
|
|
- result = self._term()
|
|
|
|
- while self._current_token.type_ in ops:
|
|
|
|
- token = self._current_token
|
|
|
|
- if token.type_ == TokenType.PLUS:
|
|
|
|
- self._check_token_type(TokenType.PLUS)
|
|
|
|
- result += self._term()
|
|
|
|
- elif token.type_ == TokenType.MINUS:
|
|
|
|
- self._check_token_type(TokenType.MINUS)
|
|
|
|
- result -= self._term()
|
|
|
|
- else:
|
|
|
|
- raise InterpreterException("bad operator")
|
|
|
|
- return result
|
|
|
|
-
|
|
|
|
- def __call__(self, text: str) -> int:
|
|
|
|
- return self.interpret(text)
|
|
|
|
-
|
|
|
|
- def interpret(self, text: str) -> int:
|
|
|
|
- self._lexer.init(text)
|
|
|
|
- self._current_token = self._lexer.next()
|
|
|
|
- return self._expr()
|
|
|
|
|
|
+ def interpret(self,tree:Node) -> float:
|
|
|
|
+ return self._visit(tree)
|
|
|
|
+
|
|
|
|
+ def _visit(self, node: Node) -> float:
|
|
|
|
+ if isinstance(node,Number):
|
|
|
|
+ return self._visit_number(node)
|
|
|
|
+ elif isinstance(node,BinOp):
|
|
|
|
+ return self._visit_binop(node)
|
|
|
|
+ raise InterpreterException("invalid node")
|
|
|
|
+
|
|
|
|
+ def _visit_number(self, node:Number) -> float:
|
|
|
|
+ return float(node.token.value)
|
|
|
|
+
|
|
|
|
+ def _visit_binop(self,node:BinOp) -> float:
|
|
|
|
+ op = node.op
|
|
|
|
+ if op.type_ == TokenType.PLUS:
|
|
|
|
+ return self._visit(node.left) + self._visit(node.right)
|
|
|
|
+ if op.type_ == TokenType.MINUS:
|
|
|
|
+ return self._visit(node.left) - self._visit(node.right)
|
|
|
|
+ if op.type_ == TokenType.MUL:
|
|
|
|
+ return self._visit(node.left) * self._visit(node.right)
|
|
|
|
+ if op.type_ == TokenType.DIV:
|
|
|
|
+ return self._visit(node.left) / self._visit(node.right)
|
|
|
|
+ if op.type_ == TokenType.POW:
|
|
|
|
+ return pow(self._visit(node.left), self._visit(node.right))
|
|
|
|
+ raise InterpreterException("invalid separator")
|