Files
python/exercises/forth/example.py
Nathan Parsons f53e2ef08b Implement checks for raising messages with exceptions (#1113)
* Implement checks for messages being raised with exceptions
(Fixes #1080)

* Add self.assertRaisesWithMessage method to relevant exercise tests
    - Uses self.assertRaisesRegex
    - Checks only for the presence of a message, not content
* Add meaningful messages to failing examples
* octal: Switch to using a context manager for exception tests

* Add note regarding error messages to the insert

* simple-linked-list: Move hints.md to correct location

* simple-cipher: Remove extra whitespace from lines

* collatz-conjecture: Update hints.md

* Regenerate README to include exceptions section
2017-12-12 12:11:43 -06:00

59 lines
1.8 KiB
Python

class StackUnderflowError(Exception):
pass
def is_integer(string):
try:
int(string)
return True
except ValueError:
return False
def evaluate(input_data):
if not input_data:
return []
defines = {}
while input_data[0][:1] == ':':
values = input_data.pop(0).split()
values.pop()
values.pop(0)
key = values.pop(0)
if is_integer(key):
raise ValueError("Integers cannot be redefined")
defines[key] = values
stack = []
input_data = input_data[-1].split()
while any(input_data):
word = input_data.pop(0).lower()
try:
if is_integer(word):
stack.append(int(word))
elif word in defines:
input_data = defines[word] + input_data
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 == '/':
divisor = stack.pop()
if divisor == 0:
raise ZeroDivisionError("Attempted to divide by zero")
stack.append(int(stack.pop() / divisor))
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:
raise ValueError("{} has not been defined".format(word))
except IndexError:
raise StackUnderflowError("Insufficient number of items in stack")
return stack