Type Constraint Propagation

Using the techniques in Type Information Restoring during parsing, we can collect some traces of type information during parsing. These information makes up the initial type constraint.

Now, given the initial type constraint, we want to propagate them over all the variables & values while the C0VM is running.

Notation: Maybe<T> -> unknown | T.

Type from Native Function

Since native functions are implemented internally, we can know the return type of native function. Therefore, most of the native function have signature like this:

function native_function(arg1: C0Value<Maybe<C0Type.value>>): C0Value<Type.value> 
{...}

Given argument with arbitrary type, the function will return a value with type T.

native_function(Maybe<a>, Maybe<b>, ...) -> T

Type from Byte code Operations

Some byte code operations have very specific semantics - for instance, the ADD , SUB etc. operations means arithmetic operation.

Therefore, when we push the result on operand stack, we can explicitly set their type to int

[ADD | SUB | MUL | ... ](Maybe<int>, Maybe<int>) -> int

Some other operations, on the other hand, only modify the input parameter's type.

AMSTORE(*Maybe<*T>, *T) -> **T
IMSTORE(*Maybe<int>, int) -> *int
CMSTORE(*Maybe<bool | char>, bool | char) -> *(bool | char)

Last updated