Skip to content

Instantly share code, notes, and snippets.

@mbillingr
Created August 2, 2022 11:21
Show Gist options
  • Save mbillingr/af865c28eff77b1d8eaf957824458712 to your computer and use it in GitHub Desktop.
Save mbillingr/af865c28eff77b1d8eaf957824458712 to your computer and use it in GitHub Desktop.
Memory/Pointer simulation in Python
from abc import ABC, abstractmethod
from dataclasses import dataclass
from typing import Literal, Any
BYTEORDER: Literal["little", "big"] = "big"
class Type(ABC):
@abstractmethod
def load(self, offset, memory):
pass
@abstractmethod
def store(self, value, offset, memory):
pass
class U64(Type):
def load(self, offset, memory):
return memory.get_int(offset)
def store(self, value, offset, memory):
assert isinstance(value, int)
assert 0 <= value < 2**64
return memory.set_int(offset, value)
class U64List(Type):
def load(self, offset, memory):
car = memory.get_int(offset)
cdr = memory.get_int(offset + 8)
return (car, Pointer(cdr, self, memory))
def store(self, value, offset, memory):
assert isinstance(value, tuple)
assert len(value) == 2
assert isinstance(value[0], int)
assert isinstance(value[1], Pointer)
memory.set_int(offset, value[0])
memory.set_int(offset + 8, value[1].address)
class Memory(bytearray):
def __init__(self, n_bytes):
super().__init__(b"\x00" * n_bytes)
def set_int(self, offset, value: int, n_bytes=8):
self.set_bytes(offset, value.to_bytes(n_bytes, BYTEORDER))
def get_int(self, offset, n_bytes=8) -> int:
return int.from_bytes(self.get_bytes(offset, n_bytes), BYTEORDER)
def set_bytes(self, offset, data):
self[offset : offset + len(data)] = data
def get_bytes(self, offset, length) -> bytes:
return self[offset : offset + length]
@dataclass
class Pointer:
address: int
type: Type
mem: Memory
def read(self) -> Any:
return self.type.load(self.address, self.mem)
def write(self, value: Any):
return self.type.store(value, self.address, self.mem)
mem = Memory(50)
nil = Pointer(0, U64List(), mem)
p1 = Pointer(1, U64List(), mem)
p1.write((10, nil))
p2 = Pointer(17, U64List(), mem)
p2.write((20, p1))
print(mem)
print(p2.read())
print(p1.read())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment