Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func WHNF ¶
WHNF forces a value to weak head normal form. An already-forced thunk is followed cheaply; anything that still needs work — an unforced thunk (code thunk, stdin cell, or pattern-binding indirection) or a pending application from a composition — is handed to the full reducer, which pushes the right update frames and memoises. It is the re-entrant entry point used by show, DeepEqual, FullNormalForm, and the primitive kernels (installed as value.Force); routing every force through the same reducer keeps update-frame handling and memoisation in one place.
Types ¶
type Capture ¶
type Capture struct {
FromUpvalue bool
Slot int
Name string // debug: source name of the captured variable; never read by the machine
}
A Capture says where MakeClosure reads one captured free variable: from the enclosing activation's own captured env (FromUpvalue) or from its local frame.
type ClosureTemplate ¶
type ClosureTemplate struct {
Code PC // entry point: the first case's Case instruction
Capture []Capture // minimal free-variable capture (closures escape, so this is worth computing)
Frame int // slots to allocate for the matched case's bindings and lets
NoMatch source.SourcePos // span of the whole pattern set, for "no pattern matched"
}
A ClosureTemplate is the compile-time description of a lambda. MakeClosure instantiates it into a *Closure, reading Capture to copy the minimal set of free variables from the enclosing activation's frames. Frame is the largest case frame, allocated once per application and reused across the cases tried.
type Instr ¶
Instr is one instruction. The two operands are small integers (pool indices, slots, arities, jump targets), never pointers, so Code stays dense. Each opcode's use of A and B is documented on the constant.
type Machine ¶
type Machine struct {
Prog *Program
// contains filtered or unexported fields
}
Machine is the STG-style push/enter reducer. It executes the flat bytecode produced by compile.go and keeps an explicit, heap-allocated reduction stack. Every strict point — forcing a thunk, applying an argument, forcing a builtin's operand or a match scrutinee — is a frame on that stack rather than a Go recursive call, so it forces values of arbitrary depth in bounded Go stack.
func NewMachine ¶
type ModuleBinding ¶
A ModuleBinding is one public binding of a module, compiled as its own activation (its right-hand side run in a fresh frame, memoised in the module environment). Order matches the module's PublicBindings so environment slots line up.
type Op ¶
type Op uint8
const ( // Build (push a value; never force). The head of a body is whatever these // leave on the operand stack when Enter is reached. PushConst Op = iota // push Consts[A] PushLocal // push Locals[A] PushUpvalue // push Upvalues[A] PushModule // push ModuleEnvironments[ModuleNames[A]][B] PushStdin // push the lazy stdin code-point stream PushBstdin // push the lazy stdin byte stream MakeCons // pop tail, head; push Cons{head, tail} MakeTuple // pop A operands; push Tuple of arity A (A ≠ 2) MakeCompose // pop second, first; push Composition{first, second} MakeClosure // push a closure from Closures[A], capturing the current frames MakeThunk // push a (memoising) thunk from Thunks[A] over the current frames StoreLet // Locals[A] = a (memoising) thunk from Thunks[B] over the current frames // Apply / tail position (push/enter: push arguments, then enter the head). PushArg // pop an operand; push it as an argument frame (with Posns[A]) onto the reduction stack Enter // terminator: the operand stack's top is this body's head — hand control back to the reducer // Match (force the subject, test, and bind). These run before a case's body; // a failed test jumps to B, the next case's Case instruction. Case // reset the subject stack to hold only the closure's argument (case entry / retry point) MatchNumber // pop subject; force to a number; jump B unless it equals Consts[A] MatchTuple // pop subject; force; if a tuple/cons of arity A push its elements, else jump B MatchString // pop subject; match the code-point spine against Consts[A]; jump B on mismatch Bind // pop subject; Locals[A] = a named thunk over it (no force) NoMatch // no case matched: raise the located "no pattern matched" error // Saturated primitive call (the strict arithmetic/comparison builtins). The // kernel forces and pops its operands and pushes the result; see prims.go. Prim // run primitive PrimOp(A); B = Posns index for error location )
type PC ¶
PC is re-exported from the value package, where Thunk and Closure store entry points; the two definitions are the same int32 alias.
type Program ¶
type Program struct {
Code []Instr
Consts []value.Value
Posns []source.SourcePos
Names []string
ModuleNames []string
Closures []ClosureTemplate
Thunks []ThunkTemplate
Entry PC
EntryFrame int
Modules map[string][]ModuleBinding
ModuleOrder []string // stable iteration order for startup and disassembly
}
Program is the whole compiled unit: one flat instruction array plus the pools its instructions index, the closure/thunk templates, the program-body entry, and the per-module binding entries.
func Compile ¶
func Compile(mainCore core.Expr, modCores map[string][]core.Bind, sourceProgram *syntax.Program, modules map[string]*syntax.Module) *Program
Compile translates the Core IR (program body + module bindings) into a flat Program. Bodies referenced out of line (lambdas, thunks) are queued and drained after the top-level bodies, so the layout never lets one span fall into another.
type StackFrame ¶
type StackFrame struct {
Kind StackFrameKind
Arg value.Value // valid when Kind == argFrame
Pos source.SourcePos // valid when Kind == argFrame
Thunk *value.Thunk // valid when Kind == updateFrame
Cont *contState // valid when Kind == runFrame
Prim *primArgs // valid when Kind == primArgsFrame
}
StackFrame is one entry of the reduction stack.
type StackFrameKind ¶
type StackFrameKind uint8
StackFrameKind distinguishes the five entries the reduction stack can hold.
type ThunkTemplate ¶
type ThunkTemplate struct {
Code PC
Name int // index into Names; the binding name for let/module thunks, -1 (→ "") for anonymous
Pos source.SourcePos // debug: definition site; never read by the machine
}
A ThunkTemplate is the compile-time description of a thunk body. The thunk captures the whole enclosing activation by reference (Locals + Upvalues), so no capture list is needed; it addresses them with the enclosing slot numbers.