2017-10-09 14:23:21 -05:00
|
|
|
class StackUnderflowError(Exception):
|
2021-10-25 14:05:13 -07:00
|
|
|
"""Exception raised when Stack is not full.
|
|
|
|
|
message: explanation of the error.
|
|
|
|
|
"""
|
|
|
|
|
def __init__(self, message):
|
|
|
|
|
self.message = message
|
2017-10-09 11:27:43 -05:00
|
|
|
|
|
|
|
|
|
2017-10-06 16:43:57 -05:00
|
|
|
def is_integer(string):
|
|
|
|
|
try:
|
|
|
|
|
int(string)
|
|
|
|
|
return True
|
2017-10-09 11:27:43 -05:00
|
|
|
except ValueError:
|
2017-10-06 16:43:57 -05:00
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
2017-10-09 09:10:33 -05:00
|
|
|
def evaluate(input_data):
|
2017-10-27 16:46:37 +01:00
|
|
|
if not input_data:
|
|
|
|
|
return []
|
2017-10-06 16:43:57 -05:00
|
|
|
defines = {}
|
2017-10-27 16:46:37 +01:00
|
|
|
while input_data[0][:1] == ':':
|
2017-10-09 09:10:33 -05:00
|
|
|
values = input_data.pop(0).split()
|
2017-10-06 16:47:16 -05:00
|
|
|
values.pop()
|
|
|
|
|
values.pop(0)
|
2018-01-26 22:29:22 +08:00
|
|
|
key = values.pop(0).lower()
|
2017-10-06 16:43:57 -05:00
|
|
|
if is_integer(key):
|
2021-10-25 14:05:13 -07:00
|
|
|
raise ValueError("illegal operation")
|
2018-07-20 14:33:17 -04:00
|
|
|
defines[key] = [
|
2021-10-25 14:05:13 -07:00
|
|
|
x
|
|
|
|
|
for v in values
|
|
|
|
|
for x in defines.get(v, [v])
|
2018-07-20 14:33:17 -04:00
|
|
|
]
|
2017-10-06 16:43:57 -05:00
|
|
|
stack = []
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = input_data[-1].split()
|
|
|
|
|
while any(input_data):
|
|
|
|
|
word = input_data.pop(0).lower()
|
2017-10-06 16:43:57 -05:00
|
|
|
try:
|
|
|
|
|
if is_integer(word):
|
|
|
|
|
stack.append(int(word))
|
|
|
|
|
elif word in defines:
|
2017-10-09 09:10:33 -05:00
|
|
|
input_data = defines[word] + input_data
|
2017-10-06 16:43:57 -05:00
|
|
|
elif word == '+':
|
|
|
|
|
stack.append(stack.pop() + stack.pop())
|
|
|
|
|
elif word == '-':
|
|
|
|
|
stack.append(-stack.pop() + stack.pop())
|
|
|
|
|
elif word == '*':
|
|
|
|
|
stack.append(stack.pop() * stack.pop())
|
|
|
|
|
elif word == '/':
|
2017-12-12 18:11:43 +00:00
|
|
|
divisor = stack.pop()
|
|
|
|
|
if divisor == 0:
|
2021-10-25 14:05:13 -07:00
|
|
|
raise ZeroDivisionError("divide by zero")
|
2017-12-12 18:11:43 +00:00
|
|
|
stack.append(int(stack.pop() / divisor))
|
2017-10-06 16:43:57 -05:00
|
|
|
elif word == 'dup':
|
|
|
|
|
stack.append(stack[-1])
|
|
|
|
|
elif word == 'drop':
|
|
|
|
|
stack.pop()
|
|
|
|
|
elif word == 'swap':
|
|
|
|
|
stack.append(stack[-2])
|
|
|
|
|
del stack[-3]
|
|
|
|
|
elif word == 'over':
|
|
|
|
|
stack.append(stack[-2])
|
|
|
|
|
else:
|
2021-10-25 14:05:13 -07:00
|
|
|
raise ValueError("undefined operation")
|
2017-10-09 11:27:43 -05:00
|
|
|
except IndexError:
|
2017-12-12 18:11:43 +00:00
|
|
|
raise StackUnderflowError("Insufficient number of items in stack")
|
2017-10-06 16:43:57 -05:00
|
|
|
return stack
|