import operator import readline from typing import Callable class FifthStack: def __init__(self): self.stack: list[int] = [] self.commands: dict[str, Callable] = { "push": self.push, "pop": self.pop, "swap": self.swap, "dup": self.dup, } self.binary_ops: dict[str, Callable[[int, int], int]] = { "+": operator.add, "-": operator.sub, "*": operator.mul, "/": operator.floordiv, } def _require(self, number, message): if len(self.stack) < number: print(f"ERROR: {message}") return False return True def _get_binary_op(self, command): return self.binary_ops.get(command) def _binary_op(self, operator): if not self._require(2, "two numbers required"): return b, a = self.stack.pop(), self.stack.pop() try: self.stack.append(operator(a, b)) except ZeroDivisionError as e: print(f"ERROR: division by zero") self.stack.extend([a, b]) def push(self, value): try: self.stack.append(int(value)) except ValueError: print("ERROR: integer required") def pop(self): if not self.stack: print("ERROR: stack empty") return self.stack.pop() def swap(self): if not self._require(2, "two numbers required"): return self.stack[-1], self.stack[-2] = self.stack[-2], self.stack[-1] def dup(self): if self._require(1, "stack empty"): self.stack.append(self.stack[-1]) def execute(self, command: str): tokens = command.lower().strip().split() if not tokens: return command, argument = tokens[0], tokens[1] if len(tokens) > 1 else None function = self.commands.get(command) if function: if command == "push": function(argument) else: function() elif command in self.binary_ops: self._binary_op(self._get_binary_op(command)) else: print("ERROR: unknown command") def main(): fifth = FifthStack() while True: print(f"stack is {fifth.stack}") try: if (command := input().strip().lower()) == "exit": break if command: fifth.execute(command) except (EOFError, KeyboardInterrupt): break if __name__ == "__main__": main()