Typing tweaks
This commit is contained in:
parent
c59034383c
commit
f3791adee8
5 changed files with 146 additions and 79 deletions
|
@ -17,7 +17,7 @@ def main():
|
|||
Opcode.CALLC(1),
|
||||
Opcode.RETURN(1),
|
||||
],
|
||||
stack = [True, True, False]
|
||||
stackframe = [True, True, False]
|
||||
)
|
||||
print(ret)
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ context (a virtual machine) which DOES have an easily introspected and serialize
|
|||
from copy import deepcopy
|
||||
|
||||
from ichor.isa import Opcode
|
||||
from ichor.typing import Closure, FunctionRef, Identifier
|
||||
from ichor.state import Closure, FunctionRef, Identifier, Module
|
||||
|
||||
|
||||
def rotate(l):
|
||||
|
@ -76,7 +76,7 @@ class InterpreterError(Exception):
|
|||
|
||||
class Interpreter(object):
|
||||
"""A shit simple instruction pointer based interpreter."""
|
||||
def __init__(self, bootstrap_module):
|
||||
def __init__(self, bootstrap_module: Module):
|
||||
self.bootstrap = bootstrap_module
|
||||
|
||||
def run(self, opcodes, stack=[]):
|
||||
|
@ -94,7 +94,7 @@ class Interpreter(object):
|
|||
raise InterpreterError(mod, deepcopy(stackframe), msg)
|
||||
|
||||
while True:
|
||||
op = mod.opcodes[stackframe.ip]
|
||||
op = mod.codepage[stackframe.ip]
|
||||
print("{0}{1: <50} {2}: {3}".format(" " * stackframe.depth, str(stackframe.stack), stackframe.ip, op))
|
||||
|
||||
match op:
|
||||
|
|
139
projects/shoggoth/src/python/ichor/state.py
Normal file
139
projects/shoggoth/src/python/ichor/state.py
Normal file
|
@ -0,0 +1,139 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
"""The core VM/interpreter model."""
|
||||
|
||||
|
||||
import typing as t
|
||||
|
||||
from ichor.isa import Opcode
|
||||
|
||||
|
||||
class Identifier(t.NamedTuple):
|
||||
name: str
|
||||
|
||||
|
||||
class FunctionSignature(t.NamedTuple):
|
||||
raw: str
|
||||
type_params: list
|
||||
name: str
|
||||
args: list
|
||||
ret: list
|
||||
|
||||
@staticmethod
|
||||
def parse_list(l):
|
||||
return [e for e in l.split(",") if e]
|
||||
|
||||
@classmethod
|
||||
def parse(cls, raw: str):
|
||||
vars, name, args, ret = raw.split(";")
|
||||
return cls(
|
||||
raw,
|
||||
cls.parse_list(vars),
|
||||
name,
|
||||
cls.parse_list(args),
|
||||
cls.parse_list(ret)
|
||||
)
|
||||
|
||||
|
||||
class FunctionRef(t.NamedTuple):
|
||||
raw: str
|
||||
type_params: list
|
||||
name: str
|
||||
args: list
|
||||
ret: list
|
||||
|
||||
@staticmethod
|
||||
def parse_list(l):
|
||||
return [e for e in l.split(",") if e]
|
||||
|
||||
@classmethod
|
||||
def parse(cls, raw: str):
|
||||
vars, name, args, ret = raw.split(";")
|
||||
return cls(
|
||||
raw,
|
||||
cls.parse_list(vars),
|
||||
name,
|
||||
cls.parse_list(args),
|
||||
cls.parse_list(ret)
|
||||
)
|
||||
|
||||
|
||||
class Function(t.NamedTuple):
|
||||
name: str
|
||||
|
||||
|
||||
class Closure(t.NamedTuple):
|
||||
# Note that a closure over a closure is equivalent to a single closure which extends the captured stack fragment, so
|
||||
# there's no need for a union here as we can simply convert nested closures.
|
||||
funref: FunctionRef
|
||||
frag: t.List[t.Any]
|
||||
|
||||
|
||||
class Struct(t.NamedTuple):
|
||||
name: str
|
||||
type_params: list
|
||||
children: t.Mapping[str, t.Any]
|
||||
|
||||
|
||||
class Module(t.NamedTuple):
|
||||
codepage: list = []
|
||||
functions: dict = {}
|
||||
types: dict = {}
|
||||
constants: dict = {}
|
||||
|
||||
def copy(self) -> "Module":
|
||||
return Module(
|
||||
self.codepage.copy(),
|
||||
self.functions.copy(),
|
||||
self.types.copy(),
|
||||
self.constants.copy(),
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def translate(start: int, end: int, i: Opcode):
|
||||
# FIXME: Consolidate bounds checks somehow
|
||||
match i:
|
||||
case Opcode.IF(t):
|
||||
d = t + start
|
||||
assert start <= d < end
|
||||
return Opcode.IF(d)
|
||||
|
||||
case Opcode.GOTO(t):
|
||||
d = t + start
|
||||
assert start <= d < end
|
||||
return Opcode.GOTO(d)
|
||||
|
||||
case _:
|
||||
return i
|
||||
|
||||
def define_function(self, name, opcodes):
|
||||
"""Enter a function into module.
|
||||
|
||||
Side-effects the codepage and name table.
|
||||
|
||||
"""
|
||||
|
||||
try:
|
||||
sig = FunctionRef.parse(name)
|
||||
assert sig.name
|
||||
except:
|
||||
raise ValueError("Illegal name provided")
|
||||
|
||||
start = len(self.codepage)
|
||||
self.functions[name] = start
|
||||
for op in opcodes:
|
||||
self.codepage.append(self.translate(start, start + len(opcodes), op))
|
||||
return name
|
||||
|
||||
def define_type(self, name, signature):
|
||||
self.types[name] = signature
|
||||
return name
|
||||
|
||||
def __str__(self):
|
||||
b = []
|
||||
marks = {v: k for k, v in self.functions.items()}
|
||||
for i, o in zip(range(1<<64), self.codepage):
|
||||
if(i in marks):
|
||||
b.append(f"{marks[i]}:")
|
||||
b.append(f"{i: >10}: {o}")
|
||||
return "\n".join(b)
|
|
@ -1,3 +1,5 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
"""The public interface for shoggoth's baked-in types."""
|
||||
|
||||
|
||||
|
@ -20,78 +22,3 @@ class SumExpr(t.NamedTuple):
|
|||
|
||||
class ProductExpr(t.NamedTuple):
|
||||
children: t.Mapping[str, t.Any]
|
||||
|
||||
|
||||
# FIXME: How exactly
|
||||
class StructExpr(t.NamedTuple):
|
||||
name: str
|
||||
type_params: list
|
||||
field_names: t.List[str]
|
||||
children: t.List[t.Any]
|
||||
|
||||
|
||||
####################################################################################################
|
||||
####################################################################################################
|
||||
####################################################################################################
|
||||
|
||||
class FunctionRef(t.NamedTuple):
|
||||
raw: str
|
||||
type_params: list
|
||||
name: str
|
||||
args: list
|
||||
ret: list
|
||||
|
||||
@staticmethod
|
||||
def parse_list(l):
|
||||
return [e for e in l.split(",") if e]
|
||||
|
||||
@classmethod
|
||||
def parse(cls, raw: str):
|
||||
vars, name, args, ret = raw.split(";")
|
||||
return cls(
|
||||
raw,
|
||||
cls.parse_list(vars),
|
||||
name,
|
||||
cls.parse_list(args),
|
||||
cls.parse_list(ret)
|
||||
)
|
||||
|
||||
|
||||
class Closure(t.NamedTuple):
|
||||
# Note that a closure over a closure is equivalent to a single closure which extends the captured stack fragment, so
|
||||
# there's no need for a union here as we can simply convert nested closures.
|
||||
funref: FunctionRef
|
||||
frag: t.List[t.Any]
|
||||
|
||||
|
||||
class FunctionSignature(t.NamedTuple):
|
||||
raw: str
|
||||
type_params: list
|
||||
name: str
|
||||
args: list
|
||||
ret: list
|
||||
|
||||
@staticmethod
|
||||
def parse_list(l):
|
||||
return [e for e in l.split(",") if e]
|
||||
|
||||
@classmethod
|
||||
def parse(cls, raw: str):
|
||||
vars, name, args, ret = raw.split(";")
|
||||
return cls(
|
||||
raw,
|
||||
cls.parse_list(vars),
|
||||
name,
|
||||
cls.parse_list(args),
|
||||
cls.parse_list(ret)
|
||||
)
|
||||
|
||||
|
||||
class Struct(t.NamedTuple):
|
||||
name: str
|
||||
type_params: list
|
||||
children: t.Mapping[str, t.Any]
|
||||
|
||||
|
||||
class Identifier(t.NamedTuple):
|
||||
name: str
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from ichor import Interpreter, BOOTSTRAP
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue