66 lines
1.4 KiB
Python
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
|
|
|