Get CLOSUREC working
This commit is contained in:
parent
aef6cc088d
commit
b439466887
4 changed files with 44 additions and 5 deletions
|
@ -11,12 +11,13 @@ def main():
|
||||||
vm = Interpreter(BOOTSTRAP)
|
vm = Interpreter(BOOTSTRAP)
|
||||||
ret = vm.run(
|
ret = vm.run(
|
||||||
[
|
[
|
||||||
Opcode.FUNREF(XOR2),
|
Opcode.FUNREF(XOR3),
|
||||||
Opcode.CLOSUREF(1),
|
Opcode.CLOSUREF(1),
|
||||||
|
Opcode.CLOSUREC(1),
|
||||||
Opcode.CALLC(1),
|
Opcode.CALLC(1),
|
||||||
Opcode.RETURN(1),
|
Opcode.RETURN(1),
|
||||||
],
|
],
|
||||||
stack = [True, False]
|
stack = [True, True, False]
|
||||||
)
|
)
|
||||||
print(ret)
|
print(ret)
|
||||||
|
|
||||||
|
|
|
@ -11,11 +11,12 @@ context (a virtual machine) which DOES have an easily introspected and serialize
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
||||||
assert sys.version_info > (3, 10, 0), "`match` support is required"
|
assert sys.version_info > (3, 10, 0), "`match` support is required"
|
||||||
|
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
|
|
||||||
from .isa import FunctionRef, Opcode, Closure
|
from .isa import Closure, FunctionRef, Opcode
|
||||||
|
|
||||||
|
|
||||||
def rotate(l):
|
def rotate(l):
|
||||||
|
@ -87,8 +88,9 @@ class Interpreter(object):
|
||||||
|
|
||||||
stack = Stackframe(stack=stack)
|
stack = Stackframe(stack=stack)
|
||||||
mod = self.bootstrap.copy()
|
mod = self.bootstrap.copy()
|
||||||
mod.define_function(";<entry>;;", opcodes)
|
stack.ip = mod.functions[mod.define_function(";<main>;;", opcodes)]
|
||||||
stack.ip = mod.functions[";<entry>;;"]
|
|
||||||
|
print(mod)
|
||||||
|
|
||||||
def _error(msg=None):
|
def _error(msg=None):
|
||||||
# Note this is pretty expensive because we have to snapshot the stack BEFORE we do anything
|
# Note this is pretty expensive because we have to snapshot the stack BEFORE we do anything
|
||||||
|
@ -211,6 +213,22 @@ class Interpreter(object):
|
||||||
stack.drop(n)
|
stack.drop(n)
|
||||||
stack.push(c)
|
stack.push(c)
|
||||||
|
|
||||||
|
case Opcode.CLOSUREC(n):
|
||||||
|
c = stack.pop()
|
||||||
|
if not isinstance(c, Closure):
|
||||||
|
_error("CLOSUREC requires a closure at top of stack")
|
||||||
|
if n + len(c.frag) > len(c.funref.args):
|
||||||
|
_error("CLOSUREC target violation; too many parameters provided")
|
||||||
|
if n > len(stack):
|
||||||
|
_error("Stack size violation")
|
||||||
|
|
||||||
|
c = Closure(
|
||||||
|
c.funref,
|
||||||
|
stack.stack[:n] + c.frag
|
||||||
|
)
|
||||||
|
stack.drop(n)
|
||||||
|
stack.push(c)
|
||||||
|
|
||||||
case Opcode.CALLC(n):
|
case Opcode.CALLC(n):
|
||||||
c = stack.pop()
|
c = stack.pop()
|
||||||
if not isinstance(c, Closure):
|
if not isinstance(c, Closure):
|
||||||
|
|
|
@ -129,6 +129,7 @@ class Opcode:
|
||||||
Further close over the closure at the top of the stack.
|
Further close over the closure at the top of the stack.
|
||||||
This may produce nullary closures.
|
This may produce nullary closures.
|
||||||
"""
|
"""
|
||||||
|
nargs: int = 0
|
||||||
|
|
||||||
class CALLC(t.NamedTuple):
|
class CALLC(t.NamedTuple):
|
||||||
"""(`CLOSURE<... A to ... B>`, ... A) -> (... B)
|
"""(`CLOSURE<... A to ... B>`, ... A) -> (... B)
|
||||||
|
|
|
@ -84,3 +84,22 @@ def test_callc(vm, stack, ret):
|
||||||
Opcode.CALLC(1),
|
Opcode.CALLC(1),
|
||||||
Opcode.RETURN(1),
|
Opcode.RETURN(1),
|
||||||
], stack = stack) == ret
|
], stack = stack) == ret
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("stack,ret", [
|
||||||
|
[[False, False, False], [False]],
|
||||||
|
[[True, False, False], [True]],
|
||||||
|
[[False, True, False], [True]],
|
||||||
|
[[True, True, False], [True]],
|
||||||
|
[[True, True, True], [False]],
|
||||||
|
[[False, True, True], [True]],
|
||||||
|
[[False, False, True], [True]],
|
||||||
|
])
|
||||||
|
def test_closurec(vm, stack, ret):
|
||||||
|
assert vm.run([
|
||||||
|
Opcode.FUNREF(XOR3),
|
||||||
|
Opcode.CLOSUREF(1),
|
||||||
|
Opcode.CLOSUREC(1),
|
||||||
|
Opcode.CALLC(1),
|
||||||
|
Opcode.RETURN(1),
|
||||||
|
], stack = stack) == ret
|
||||||
|
|
Loading…
Reference in a new issue