Trait libunseemly::runtime::reify::Reifiable [−][src]
pub trait Reifiable {
fn ty_name() -> Name;
fn reify(&self) -> Value;
fn reflect(_: &Value) -> Self;
fn ty() -> Ast { ... }
fn ty_invocation() -> Ast { ... }
fn concrete_arguments() -> Option<Vec<Ast>> { ... }
}
Expand description
This is for parts of this compiler that need to be represented as object-level values. Almost all of it, turns out!
Since this language is extensible, we need to connect the Rust code in the compiler with the Unseemly code that actually gets evaluated. This is where the magic happens.
Suppose that T
is a two-argument generic type.
Generally, we plan on executing code in an environment in which
T::<Irr,Irr>::name()
is bound to T::<Irr,Irr>::ty()
.
(The type arguments do not affect name
and ty
; ()
is convention.)
Then, we can use T::<SomeActualArg, OtherActualArg>::ty_invocation()
in that environment.
This is also where ICPs can happen, so make sure that ::ty() is consistent with ::reify().
Required methods
A name for that type, so that recursive types are okay.
Ignore the type parameters of Self
; invoke like Self::<Irr,Irr>::ty_name()
.
e.g. WithInteger
Provided methods
The Unseemly type that corresponds to to the Reifiable
type.
This leaves abstract the type parameters of Self
; invoke like Self::<Irr,Irr>::ty()
.
e.g. ∀ A. Pair<A int>
TODO: rename to generic_ty
fn ty_invocation() -> Ast
fn ty_invocation() -> Ast
How to refer to this type, given an environment in which
ty_name()
is defined to be ty()
.
Parameters will be concrete.
e.g. WithInteger<Float>
(Types using this type will use this, rather than ty
)
Don’t override this.