Tapping towards structs and variants
This commit is contained in:
parent
dc71833082
commit
50f4a4cdb1
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):
|
||||
_error("CALLC target vionation; argument count missmatch")
|
||||
if n > len(stack):
|
||||
_error("Stack size vionation")
|
||||
_error("Stack size violation")
|
||||
|
||||
# Extract the function signature
|
||||
sig = c.funref
|
||||
|
@ -253,6 +253,23 @@ class Interpreter(object):
|
|||
stack = stack.call(sig, ip)
|
||||
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 _:
|
||||
raise Exception(f"Unhandled interpreter state {op}")
|
||||
|
|
|
@ -175,19 +175,58 @@ class Opcode:
|
|||
####################################################################################################
|
||||
# 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):
|
||||
"""(*) -> (T)
|
||||
"""(STRUCTREF<S>, ...) -> (S)
|
||||
|
||||
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 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
|
||||
nargs: int = 0
|
||||
|
||||
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.
|
||||
|
||||
|
@ -196,7 +235,7 @@ class Opcode:
|
|||
fieldref: str
|
||||
|
||||
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
|
||||
that field has been updated to the new value.
|
||||
|
@ -205,6 +244,35 @@ class Opcode:
|
|||
|
||||
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
|
||||
####################################################################################################
|
||||
|
|
|
@ -22,6 +22,14 @@ 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]
|
||||
|
||||
|
||||
####################################################################################################
|
||||
####################################################################################################
|
||||
####################################################################################################
|
||||
|
@ -50,8 +58,10 @@ class FunctionRef(t.NamedTuple):
|
|||
|
||||
|
||||
class Closure(t.NamedTuple):
|
||||
target: t.Union["Closure", FunctionRef]
|
||||
args: t.List[t.Any]
|
||||
# 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):
|
||||
|
@ -77,6 +87,7 @@ class FunctionSignature(t.NamedTuple):
|
|||
)
|
||||
|
||||
|
||||
class Closure(t.NamedTuple):
|
||||
funref: FunctionRef
|
||||
frag: t.List[t.Any]
|
||||
class Struct(t.NamedTuple):
|
||||
name: str
|
||||
type_params: list
|
||||
children: t.Mapping[str, t.Any]
|
||||
|
|
Loading…
Reference in a new issue