Skip to content

Instantly share code, notes, and snippets.

@polynomialherder
Last active June 16, 2023 01:58
Show Gist options
  • Save polynomialherder/996820d80407027d10f390b21aa591dd to your computer and use it in GitHub Desktop.
Save polynomialherder/996820d80407027d10f390b21aa591dd to your computer and use it in GitHub Desktop.
A toy stack machine implementation in Python to illustrate match statements
from enum import Enum, auto
from collections import namedtuple
class Operation(Enum):
PUSH = auto()
STORE = auto()
LOAD = auto()
ADD = auto()
MUL = auto()
GOTO = auto()
PRINT = auto()
def __repr__(self):
return f"<{self.name}>"
class VM:
def __init__(self):
self.stack = []
self.environment = {}
self.program_pointer = 0
def push(self, value):
self.stack.append(value)
def print(self):
print(self.stack.pop())
def add(self):
self.stack.append(self.stack.pop() + self.stack.pop())
def divide(self):
self.stack.append(self.stack.pop() / self.stack.pop())
def multiply(self):
self.stack.append(self.stack.pop() * self.stack.pop())
def store(self, key):
self.environment[key] = self.stack.pop()
def load(self, key):
self.stack.append(self.environment[key])
@property
def current_instruction(self):
return self.current_program[self.program_pointer]
def advance_pointer(self):
self.program_pointer += 1
def reset_pointer(self):
self.program_pointer = 0
def interpret(self, program):
self.current_program = program
while self.program_pointer < len(program):
match self.current_instruction:
case Operation.PRINT, None:
self.print()
case Operation.PUSH, x:
self.push(x)
case Operation.STORE, x:
self.store(x)
case Operation.LOAD, x:
self.load(x)
case Operation.ADD, None:
self.add()
case Operation.MUL, None:
self.multiply()
self.advance_pointer()
self.reset_pointer()
if __name__ == "__main__":
# Define a program in our stack machine
program = [
(Operation.PUSH, 10),
(Operation.STORE, "x"),
(Operation.PUSH, 20),
(Operation.STORE, "y"),
(Operation.PUSH, 10),
(Operation.STORE, "z"),
(Operation.PUSH, "hello"),
(Operation.STORE, "a"),
(Operation.LOAD, "x"),
(Operation.LOAD, "y"),
(Operation.ADD, None),
(Operation.LOAD, "z"),
(Operation.ADD, None),
(Operation.STORE, "v"),
(Operation.PUSH, "world"),
(Operation.STORE, "b"),
(Operation.LOAD, "b"),
(Operation.LOAD, "a"),
(Operation.ADD, None),
(Operation.STORE, "c"),
(Operation.LOAD, "v"),
(Operation.PRINT, None),
(Operation.LOAD, "c"),
(Operation.PRINT, None),
(Operation.LOAD, "a"),
(Operation.PRINT, None)
]
vm = VM()
vm.interpret(program)
# The program above should be semantically equivalent to the following Python program
x = 10
y = 20
z = 10
a = "hello"
v = x + y + z
b = "world"
c = a + b
print(v)
print(c)
print(a)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment