What is running
lupin is the wolf reference interpreter. It is a separate
implementation from the compiler, written against the specification, and the
two share no code. The build in this page is that program, compiled to
WebAssembly from the revision this site was built from. Nothing is uploaded:
the source stays in the tab, and no request leaves the page after the module
and the samples have loaded.
The interpreter is not the compiler, and it reaches a different set of
programs. It runs the memory model as a dynamic machine, so every ownership
rule is a check at run time and every fault cites the clause it came from. It
has no type checker and no borrow checker, because those are the compiler's
half of the split, so a program that the compiler would reject at
typecheck can still run here. When a program is outside what
this implementation covers, the verdict is unsupported and the
reason says which tier declined.
What this build declines
Three tiers report unsupported here that work when you run
lupin at a terminal. Tasks and procs each need an operating
system thread, and a WebAssembly module in a page has none to spawn. The
time builtins need a clock the module cannot read. The
filesystem and network tiers are declined in every build of the interpreter,
including the terminal one, because it opens no files and no sockets by
design.
The verdict vocabulary
| verdict | what happened |
|---|---|
exit(N) | The program ran to completion and returned N. |
trap(kind) | A checked fault stopped it: overflow, a bad index, a use after move. Each kind is a closed vocabulary entry and cites a clause. |
fail(CODE) | The program was rejected before it ran, with that diagnostic code. |
ub(anchor) | The provenance oracle found undefined behavior, and names the row of the memory model that licenses it. |
unsupported | Outside this implementation's coverage. The reason names the tier. |
Mahler kept revising the Fifth's orchestration between performances, and the parts he left behind disagree with each other.