Tramaj.Eval
- Package
- purescript-tramaj-purs
- Repository
- lucasdicioccio/purescript-tramaj-purs
Evaluates a Tramaj.Ast Program against an input context, producing
either a Tramaj.Node document or an ordinary JSON value.
There is one evaluator. v1 had two — an expression evaluator and a
template-node evaluator — because it had two ASTs; now that documents
are expressions, evalExpr handles everything, and the only rule the
document side adds is how a child value becomes children
(childNodes).
Value is the language's full value domain, not JSON with extras
bolted on: an array or object may contain document nodes, which is what
makes the JSX-children pattern — passing a fragment to a component as
an ordinary parameter — work without a separate template-value
category. JSON is what you get at the boundaries (toJson), where a
node would be meaningless: an attribute value, an action payload, an
element's value slot.
Evaluation is eager and deterministic everywhere except Branch, which
evaluates only the arm it selects.
Kept in lockstep with ../tramaj-hs/src/Tramaj/Eval.hs.
#EvalError Source
data EvalErrorConstructors
UnboundName StringPathNotFound (Array String)TypeMismatch StringUnknownLibrary StringImportCycle StringConcatMismatch String StringInLibrary String EvalErrorWhatever went wrong inside an imported library, tagged with which library it was. Nests, so a failure three imports deep reads as the chain that reached it. This matters most for the parameter a library needs and the import never supplied: that surfaces as this library's own
PathNotFound ["ctx", ...], and without the tag there would be nothing on it to say whose context was short.NotConcrete StringA symbolic value where the language requires a concrete one (§1.5's table, and a symbol used as an allocation key).
AllocationInLibrary StringA program containing
?(k)is loaded as a library (§1.4): only the root may allocate, because the root runs exactly once and a library does not. Lexical, not data-flow — raised because the library's own source contains an allocation site, whether or not evaluation would ever reach it.TypeErr TypeErrorA static v4-types failure (v4-types §10), surfaced from either the erasure pass every entry point below runs before evaluating anything (§7, roadmap Phase 11) or from building the symbolic envelope's
"types"/"type-constraints"lists (§8, Phase 13). Not a new evaluation failure mode — nothing here is raised during evaluation — butTramaj.Types.TypeErrorstill needs a home in the one error type every entry point already returns.NotRepresentable StringAn arithmetic operation has no result in the type of its operands (reference.md §11, §12): an integer result outside the integer range, a zero divisor, a float result that is not finite. Nothing wraps, saturates or rounds instead.
Instances
#Mode Source
data ModeA host parameter, not a property of the program (v3-symbols §5): what an
interpreter is willing to read back out, not anything the template
itself declares. Concrete is reference.md exactly — Node JSON or a
plain value, byte for byte. Symbolic wraps the same evaluation in the
v3 envelope (§5.2); until §3/§4 land, that envelope's "symbols" and
"constraints" are always empty, because nothing yet produces either.
Constructors
Instances
#Options Source
type Options = { arithmetic :: Boolean, mode :: Mode }What a host chooses for one evaluation. Like Mode, each field is a
host parameter and not a property of the program.
arithmetic is reference.md §11's arithmetic profile, per evaluation:
with it on, the ten names of Tramaj.Analysis.arithmeticNames are in
the initial environment of the program and of every library it runs,
and a seeded term is accepted in symbolic mode (v3-symbols §5.4). With
it off they are unbound, so a program that uses one fails with
UnboundName, and every seeded term is refused. The two number types
and the reserved "$term" key do not depend on it.
#defaultOptions Source
defaultOptions :: OptionsConcrete mode, without the arithmetic profile. evalProgram and
runProgram run with these options and the mode they are given. The
profile is off unless a host asks for it, so that a host which has not
opted in never receives a term, and can refuse a program up front with
Tramaj.Analysis.deepArithmeticOps.
#LibraryTable Source
type LibraryTable = Map String ProgramHost-supplied library store. Where a library came from — a file, an
embedded string, a fetch — is entirely the host's business; the
evaluator only ever sees an already-parsed Program.
#evalProgram Source
evalProgram :: Mode -> LibraryTable -> Json -> Program -> Either EvalError OutputEvaluation now depends on the mode (v3-symbols §5): an allocation or an
unsupplied root demand mints a symbol in symbolic mode and raises
SymbolsUnavailable in concrete mode. There is no mode-independent
evaluation any more, so every entry point takes one.
#evalProgramWith Source
evalProgramWith :: Options -> LibraryTable -> Json -> Program -> Either EvalError OutputAs evalProgram, with every per-evaluation option given (Options).
#runProgram Source
runProgram :: Mode -> LibraryTable -> Json -> Program -> Either EvalError JsonThe mode-aware entry point: what a host actually serializes. Concrete
mode is evalProgram unchanged, projected down to plain JSON — Node
JSON for a document, the value itself for an expression, with any
emissions discarded (v3-symbols §5.1). Symbolic mode wraps the same
Output in the v3 envelope (§5.2), including the deduplicated symbol
table and constraint list.
#runProgramWith Source
runProgramWith :: Options -> LibraryTable -> Json -> Program -> Either EvalError JsonAs runProgram, with every per-evaluation option given (Options).
#builtinNames Source
builtinNames :: Array StringThe fixed builtin vocabulary of every profile; the arithmetic profile
adds Tramaj.Analysis.arithmeticNames to it. Builtins are ordinary values in the
initial environment rather than a separate call form, so
cardinality($xs), $f($x) and map($xs, $not) all go through
Call.
#emittedConstraintCount Source
emittedConstraintCount :: Options -> LibraryTable -> Json -> Program -> Either EvalError IntHow many constraints an evaluation emitted, counted before dedupe
makes equal ones one. No program and no output can tell this number:
it is here for tests, as the one way to count how many times a
function was applied, which reference.md §11 fixes for the key function
of a sort.
a <> bwhere the two sides are not the same concatenable type.