Options
All
  • Public
  • Public/Protected
  • All
Menu

Class CESKM<Base>

The CESKM virtual machine.

The focal point is the transition step implementation, which a sub-class will use as a building-block in its evaluation algorithm.

remarks

The machine can only perform the operations it defines, so sub-classes will almost certainly override CESKM.op. If your machine is to manipulate values of types other than boolean or null, you will also need to override CESKM.literal to map term literals to primitive machine values.

example
type Base = boolean | null | string | number;
class VM extends CESKM<Base> {
public run(program: string): Value<Base> {
let result = this.step(this.inject(parse_cbpv(program)));
while (!result.done) {
result = this.step(result.value);
}
return result.value;
}
protected literal(v: Base): Value<Base> {
if ("number" === typeof v
|| "boolean" === typeof v
|| "string" === typeof v
|| null === v)
{ return scalar(v); }
throw new Error(`${v} not a primitive value`);
}
protected op(op_sym: string, args: Value<Base>[]): Value<Base> {
switch (op_sym) {
// ...
default: return super.op(op_sym,args);
}
}
}

Type parameters

  • Base = null | boolean

    The types which may be stored and operated on by your programs.

Hierarchy

  • CESKM

Index

Constructors

constructor

  • new CESKM<Base>(): CESKM<Base>
  • Type parameters

    • Base = null | boolean

    Returns CESKM<Base>

Properties

Protected gensym_count

gensym_count: number = 0

Monotonically increasing number used to generate unique identifiers.

internal

Evaluation Methods

Private continue

  • This method tries to apply the current continuation to a value, which we know is positive.

    remarks

    This is where the meta-stack plays its role: the machine only halts if the current continuation (argument 2) is and the meta-stack is empty. It becomes non-empty when the reset operator pushes to it.

    internal
    sealed

    Parameters

    • val: Value<Base>

      The Value which we are to annihilate with ...

    • kontinuation: Kont<Base>

      ... the given continuation.

    • store: Store<Base>

      A backing Value storage object.

    • meta: Kont<Base>[]

      A stack (LIFO) of continuations.

    Returns IteratorResult<State<Base>, Value<Base>>

    An IteratorResult: either Value<Base> if done, else State<Base>.

inject

literal

  • literal(v: Base): Value<Base>
  • remarks

    Sub-classes will need to override this method if they change the Base type.

    example
    class VM extends CESKM {
    // ...
    protected literal(v: null | boolean) {
    if ("number" === typeof v || "boolean" === typeof v) {
    return scalar(v);
    }
    throw new Error(`invalid literal: ${JSON.stringify(v)}`);
    }
    }
    virtual

    Parameters

    • v: Base

      A term intended to represent a literal value.

    Returns Value<Base>

    A value representation of the syntactic literal.

op

  • op(op_sym: string, args: Value<Base>[]): Value<Base>
  • Define the baseline operations which your machine is able to perform on data.

    example
    type Base = number | boolean | string | null;
    class VM extends CESKM<Base> {
    // ...
    protected op(op_sym: string, args: Value<Base>[]): Value<Base> {
    switch (op_sym) {
    case "op:add": {
    if (! ("v" in args[0]) || ! ("v" in args[1]))
    { throw new Error(`arguments must be values`); }
    if ("number" !== typeof args[0].v || "number" !== typeof args[1].v)
    { throw new Error(`arguments must be numbers`); }
    const result: unknown = args[0].v + args[1].v;
    return scalar(result as Base);
    }
    // ...
    default: return super.op(op_sym, args);
    }
    }
    }
    virtual

    Parameters

    • op_sym: string

      the symbol for the primitive operator.

    • args: Value<Base>[]

      the values passed to the operator.

    Returns Value<Base>

Private positive

  • Evaluates a positive expression to an irreducible Value.

    throws

    Error If the expression isn't positive.

    internal
    sealed

    Parameters

    • expr: Cbpv

      The positive expression we are evaluating.

    • env: Env

      A static environment to bind any free variables.

    • store: Store<Base>

      A backing Value storage.

    Returns Value<Base>

    The term as a positive Value, suspended if necessary.

step

  • Performs one transition "step" on a State, yielding either a terminal Value or another State from which to step again.

    remarks

    This method always terminates for well-formed input.

    The while-loop exists because 3 expression types (application, let-bindings, and letrec-bindings) do not by themselves constitute a complete step. Rather, each points to a successor term which must be evaluated.

    Seeing as how all input expected to terminate will be finite, it is reasonable to assume that the number of nested applications and bindings will be finite, and thus that the loop will eventually terminate.

    sealed

    Parameters

    • state: State<Base>

      The State from which we are starting.

    Returns IteratorResult<State<Base>, Value<Base>>

    An IteratorResult of either State<Base> (not done), or Value<Base> (done).

Other Methods

empty_env

  • empty_env(): Env
  • Provides a way to inject custom sub-classes of Env.

    virtual

    Returns Env

empty_store

  • empty_store(): Store<Base>

Protected gensym

  • gensym(): string
  • internal

    Returns string

    A freshly generated symbol. Multi-purpose.

Generated using TypeDoc