rpn-python/interpreter.py

66 lines
1.4 KiB
Python

from constants import (
NUMBER, EOF,
PLUS, MINUS, MUL, DIV, POW,
HEX, DEC, BIN,
)
class Interpreter:
def __init__(self):
self.stack = []
self.mode = DEC
self.mode_func = float
def init_lexer(self, lexer):
self.lexer = lexer
self.current_token = self.lexer.get_next_token()
def eat(self, type):
if self.current_token.type == type:
self.current_token = self.lexer.get_next_token()
else:
raise Exception('Wrong token eaten')
def get_from_stack(self, pop=True):
if pop:
value = self.stack.pop()
else:
value = self.stack[-1]
if type(value) is str:
return self.ariables[value]
return value
def evaluate_operator(self, token):
if len(self.stack) < 2:
raise Exception('Needs at least 2 values on the stack')
right = self.get_from_stack()
left = self.get_from_stack()
self.stack.append(token.value(left, right))
self.eat(token.type)
def set_mode(self, token):
self.mode = token.type
self.mode_func = token.value
def parse(self, lexer):
self.init_lexer(lexer)
token = self.current_token
while token.type is not EOF:
if token.type in (PLUS, MINUS, MUL, DIV, POW):
self.evaluate_operator(token)
elif token.type == NUMBER:
self.stack.append(token.value)
self.eat(NUMBER)
elif token.type in (HEX, DEC, BIN):
self.set_mode(token)
self.eat(token.type)
token = self.current_token
return self.stack