Tapping towards structs and variants
This commit is contained in:
parent
6bc9bb9b59
commit
34c550ba7f
3 changed files with 107 additions and 11 deletions
|
@ -236,7 +236,7 @@ class Interpreter(object):
|
||||||
if n + len(c.frag) != len(c.funref.args):
|
if n + len(c.frag) != len(c.funref.args):
|
||||||
_error("CALLC target vionation; argument count missmatch")
|
_error("CALLC target vionation; argument count missmatch")
|
||||||
if n > len(stack):
|
if n > len(stack):
|
||||||
_error("Stack size vionation")
|
_error("Stack size violation")
|
||||||
|
|
||||||
# Extract the function signature
|
# Extract the function signature
|
||||||
sig = c.funref
|
sig = c.funref
|
||||||
|
@ -253,6 +253,23 @@ class Interpreter(object):
|
||||||
stack = stack.call(sig, ip)
|
stack = stack.call(sig, ip)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
case Opcode.STRUCT(structref, n):
|
||||||
|
if not (t := module.types.get(structref)):
|
||||||
|
_error(f"STRUCT must reference a known type, {structref!r} is undefined")
|
||||||
|
if n > len(stack):
|
||||||
|
_error("Stack size violation")
|
||||||
|
|
||||||
|
args = stack[:n]
|
||||||
|
stack.drop(n)
|
||||||
|
|
||||||
|
# FIXME: typecheck
|
||||||
|
for arg, ftype in zip(args, t.children):
|
||||||
|
pass
|
||||||
|
|
||||||
|
inst = Struct(structref, [], dict(zip(t.field_names, args)))
|
||||||
|
|
||||||
|
stack.push(inst)
|
||||||
|
|
||||||
|
|
||||||
case _:
|
case _:
|
||||||
raise Exception(f"Unhandled interpreter state {op}")
|
raise Exception(f"Unhandled interpreter state {op}")
|
||||||
|
|
|
@ -175,19 +175,58 @@ class Opcode:
|
||||||
####################################################################################################
|
####################################################################################################
|
||||||
# Structures
|
# Structures
|
||||||
####################################################################################################
|
####################################################################################################
|
||||||
|
|
||||||
|
# FIXME: This lacks any sort of way to do dynamic field references
|
||||||
|
|
||||||
|
class IDENTIFIERC(t.NamedTuple):
|
||||||
|
"""() -> (CONST)
|
||||||
|
|
||||||
|
An inline constant which produces an identifier to the stack.
|
||||||
|
|
||||||
|
Identifiers name functions, fields and types but are not strings.
|
||||||
|
They are a VM-internal naming structure with reference to the module.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
val: str
|
||||||
|
|
||||||
|
class TYPEREF(t.NamedTuple):
|
||||||
|
"""(IDENTIFIER) -> (TYPEREF)
|
||||||
|
|
||||||
|
Produces a TYPEREF to the type named by the provided IDENTIFIER.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
class FIELDREF(t.NamedTuple):
|
||||||
|
"""(IDENTIFIER, TYPEREF) -> (FIELDREF)
|
||||||
|
|
||||||
|
|
||||||
|
Produces a FIELDREF to the field named by the provided IDENTIFIER.
|
||||||
|
The FIELDREF must be within and with reference to a sum type.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
class VARIANTREF(t.NamedTuple):
|
||||||
|
"""(IDENTIFIER, TYPEREF) -> (VARIANTREF)
|
||||||
|
|
||||||
|
Produce a VARIANTREF to an 'arm' of the given variant type.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
class STRUCT(t.NamedTuple):
|
class STRUCT(t.NamedTuple):
|
||||||
"""(*) -> (T)
|
"""(STRUCTREF<S>, ...) -> (S)
|
||||||
|
|
||||||
Consume the top N items of the stack, producing a struct of the type `structref`.
|
Consume the top N items of the stack, producing a struct of the type `structref`.
|
||||||
|
|
||||||
The name and module path of the current function MUST match the name and module path of `structref`.
|
The name and module path of the current function MUST match the name and module path of `structref`.
|
||||||
|
The arity of this opcode MUST match the arity of the struct.
|
||||||
|
The signature of the struct MUST match the signature fo the top N of the stack.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
structref: str
|
nargs: int = 0
|
||||||
nargs: int
|
|
||||||
|
|
||||||
class FLOAD(t.NamedTuple):
|
class FLOAD(t.NamedTuple):
|
||||||
"""(A) -> (B)
|
"""(FIELDREF<f ⊢ T ∈ S>, S) -> (T)
|
||||||
|
|
||||||
Consume the struct reference at the top of the stack, producing the value of the referenced field.
|
Consume the struct reference at the top of the stack, producing the value of the referenced field.
|
||||||
|
|
||||||
|
@ -196,7 +235,7 @@ class Opcode:
|
||||||
fieldref: str
|
fieldref: str
|
||||||
|
|
||||||
class FSTORE(t.NamedTuple):
|
class FSTORE(t.NamedTuple):
|
||||||
"""(A, B) -> (A)
|
"""(FIELDREF<f ⊢ T ∈ S>, S, T) -> (S)
|
||||||
|
|
||||||
Consume the struct reference at the top of the stack and a value, producing a new copy of the struct in which
|
Consume the struct reference at the top of the stack and a value, producing a new copy of the struct in which
|
||||||
that field has been updated to the new value.
|
that field has been updated to the new value.
|
||||||
|
@ -205,6 +244,35 @@ class Opcode:
|
||||||
|
|
||||||
fieldref: str
|
fieldref: str
|
||||||
|
|
||||||
|
class VARIANT(t.NamedTuple):
|
||||||
|
"""(VARIANTREF<a ⊢ A ⊂ B>, ...) -> (B)
|
||||||
|
|
||||||
|
Construct an instance of an 'arm' of a variant.
|
||||||
|
The type of the 'arm' is considered to be the type of the whole variant.
|
||||||
|
|
||||||
|
The name and module path of the current function MUST match the name and module path of `VARIANTREF`.
|
||||||
|
The arity of this opcode MUST match the arity of the arm.
|
||||||
|
The signature of the arm MUST match the signature fo the top N of the stack.
|
||||||
|
"""
|
||||||
|
|
||||||
|
nargs: int = 0
|
||||||
|
|
||||||
|
class VTEST(t.NamedTuple):
|
||||||
|
"""(VARIANTREF<a ⊢ A ⊂ B>, B) -> (bool)
|
||||||
|
|
||||||
|
Test whether B is a given arm of a variant A .
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
class VLOAD(t.NamedTuple):
|
||||||
|
"""(VARIANTREF<a ⊢ A ⊂ B>, B) -> (A)
|
||||||
|
|
||||||
|
Load the value of the variant arm.
|
||||||
|
VLOAD errors (undefined) if B is not within the variant.
|
||||||
|
VLOAD errors (undefined) if the value in B is not an A - use VTEST as needed.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
####################################################################################################
|
####################################################################################################
|
||||||
# Arrays
|
# Arrays
|
||||||
####################################################################################################
|
####################################################################################################
|
||||||
|
|
|
@ -22,6 +22,14 @@ class ProductExpr(t.NamedTuple):
|
||||||
children: t.Mapping[str, t.Any]
|
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]
|
||||||
|
|
||||||
|
|
||||||
####################################################################################################
|
####################################################################################################
|
||||||
####################################################################################################
|
####################################################################################################
|
||||||
####################################################################################################
|
####################################################################################################
|
||||||
|
@ -50,8 +58,10 @@ class FunctionRef(t.NamedTuple):
|
||||||
|
|
||||||
|
|
||||||
class Closure(t.NamedTuple):
|
class Closure(t.NamedTuple):
|
||||||
target: t.Union["Closure", FunctionRef]
|
# Note that a closure over a closure is equivalent to a single closure which extends the captured stack fragment, so
|
||||||
args: t.List[t.Any]
|
# 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):
|
class FunctionSignature(t.NamedTuple):
|
||||||
|
@ -77,6 +87,7 @@ class FunctionSignature(t.NamedTuple):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class Closure(t.NamedTuple):
|
class Struct(t.NamedTuple):
|
||||||
funref: FunctionRef
|
name: str
|
||||||
frag: t.List[t.Any]
|
type_params: list
|
||||||
|
children: t.Mapping[str, t.Any]
|
||||||
|
|
Loading…
Reference in a new issue