Declarative rewrite phases with verified termination.
A language's syntactic phases — parsing, desugaring, lowering — expressed as declarative rewrite rules. Rule sets compose with verified termination. Towers of languages collapse into flat pipelines.
Self-contained: pattern matching, substitution, rewriting, head analysis, phases, pipelines, languages. No external dependencies beyond clojure.set.
Three layers: phase — a set of rules with a computed signature (consumed/produced heads) pipeline — a sequence of phases, validated: no phase raises earlier heads language — a pipeline + a target backend
Head-eliminating phases (consumed ∩ produced = ∅) terminate by construction. Non-head-eliminating phases run with bounded iteration.
Declarative rewrite phases with verified termination. A language's syntactic phases — parsing, desugaring, lowering — expressed as declarative rewrite rules. Rule sets compose with verified termination. Towers of languages collapse into flat pipelines. Self-contained: pattern matching, substitution, rewriting, head analysis, phases, pipelines, languages. No external dependencies beyond clojure.set. Three layers: phase — a set of rules with a computed signature (consumed/produced heads) pipeline — a sequence of phases, validated: no phase raises earlier heads language — a pipeline + a target backend Head-eliminating phases (consumed ∩ produced = ∅) terminate by construction. Non-head-eliminating phases run with bounded iteration.
(apply-rule rule expr)Try to apply a single rule. Returns the rewritten expression, or nil.
Try to apply a single rule. Returns the rewritten expression, or nil.
(apply-rules rules expr)Try each rule in order. Returns the first successful rewrite, or nil.
Try each rule in order. Returns the first successful rewrite, or nil.
(collapse name & pipelines)Collapse a tower of pipelines into a single flat pipeline. Concatenates phases, validates the result. Throws if invalid.
Collapse a tower of pipelines into a single flat pipeline. Concatenates phases, validates the result. Throws if invalid.
(expr-size expr)Count nodes in an expression tree. Useful as a decreasing measure.
Count nodes in an expression tree. Useful as a decreasing measure.
(head-eliminating? rules)Is this set of rules head-eliminating? consumed ∩ produced = ∅.
Is this set of rules head-eliminating? consumed ∩ produced = ∅.
(inspect-phase phase)Describe a phase: signature, verification, warnings.
Describe a phase: signature, verification, warnings.
(inspect-pipeline pipeline)Describe a pipeline: phases, signatures, validity.
Describe a pipeline: phases, signatures, validity.
(make-language lang-name pipeline target)Create a language: a named pipeline with a target backend. The target is a function (expr -> result) — eval, codegen, emission.
Create a language: a named pipeline with a target backend. The target is a function (expr -> result) — eval, codegen, emission.
(make-phase phase-name rules)(make-phase phase-name rules opts)Create a phase with computed signature and verification.
opts: :max-iters — iteration bound for non-head-eliminating phases (default 100) :strategy — :bottom-up (default) or :top-only :measure — optional (fn [expr] -> number), checked to decrease each pass
Create a phase with computed signature and verification. opts: :max-iters — iteration bound for non-head-eliminating phases (default 100) :strategy — :bottom-up (default) or :top-only :measure — optional (fn [expr] -> number), checked to decrease each pass
(make-pipeline pipeline-name phases)Create a validated pipeline. Throws if any phase raises earlier heads.
Create a validated pipeline. Throws if any phase raises earlier heads.
(match-pattern pattern expr)(match-pattern pattern expr bindings)Match a pattern against an expression. Returns a bindings map {symbol value} on success, nil on failure. Same variable must match the same value (consistency).
Match a pattern against an expression.
Returns a bindings map {symbol value} on success, nil on failure.
Same variable must match the same value (consistency).(named-rule rule-name pattern replacement)(named-rule rule-name pattern replacement guard)Create a named rule.
Create a named rule.
(pattern-head pattern)Extract the consumed head symbol from a rule's pattern. Returns the head symbol if the pattern is a list with a literal symbol head. Returns nil for variable heads, non-list patterns, or empty lists.
Extract the consumed head symbol from a rule's pattern. Returns the head symbol if the pattern is a list with a literal symbol head. Returns nil for variable heads, non-list patterns, or empty lists.
(pattern-var? x)Is x a pattern variable like ?x — matches one expression, binds to name.
Is x a pattern variable like ?x — matches one expression, binds to name.
(phase-signature rules)Compute the aggregate signature of a phase (set of rules).
Compute the aggregate signature of a phase (set of rules).
(procedural-phase phase-name f)Create a procedural phase — an opaque transformation function. Invisible to head analysis. Use for semantic phases that can't be expressed as rewrite rules.
Create a procedural phase — an opaque transformation function. Invisible to head analysis. Use for semantic phases that can't be expressed as rewrite rules.
(replacement-heads replacement)Extract all statically-known produced head symbols from a replacement.
Extract all statically-known produced head symbols from a replacement.
(rewrite rules expr)(rewrite rules expr max-iters)Apply rules bottom-up to fixed point, with iteration cap.
Apply rules bottom-up to fixed point, with iteration cap.
(rewrite-once rules expr)One bottom-up pass: rewrite each node, innermost first. Returns [changed? result].
One bottom-up pass: rewrite each node, innermost first. Returns [changed? result].
(rewrite-top rules expr)(rewrite-top rules expr max-iters)Apply rules at top level only, to fixed point.
Apply rules at top level only, to fixed point.
(rewrite-trace pipeline expr)Trace an expression through a pipeline, returning intermediate results.
Trace an expression through a pipeline, returning intermediate results.
(rule pattern replacement)(rule pattern replacement guard)(rule rule-name pattern replacement guard)Create a rule: pattern => replacement. Optional guard predicate on bindings.
Create a rule: pattern => replacement. Optional guard predicate on bindings.
(rule-signature rule)Compute the signature of a single rule. Returns {:consumes #{...} :produces #{...} :dynamic-produces? bool}
Compute the signature of a single rule.
Returns {:consumes #{...} :produces #{...} :dynamic-produces? bool}(run-language lang expr)(run-language lang expr opts)Run an expression through a language: pipeline then target. With {:trace true}, returns full trace.
Run an expression through a language: pipeline then target.
With {:trace true}, returns full trace.(run-phase phase expr)Execute a phase to fixed point. Head-eliminating phases get a high safety cap (1000). Non-head-eliminating phases use :max-iters (default 100). If :measure is set, verifies it decreases each iteration.
Execute a phase to fixed point. Head-eliminating phases get a high safety cap (1000). Non-head-eliminating phases use :max-iters (default 100). If :measure is set, verifies it decreases each iteration.
(run-pipeline pipeline expr)(run-pipeline pipeline expr opts)Execute a pipeline: each phase to fixed point in sequence. With {:trace true}, returns {:result expr :trace [...]}.
Execute a pipeline: each phase to fixed point in sequence.
With {:trace true}, returns {:result expr :trace [...]}.(splice-var? x)Is x a splice variable like ??xs — matches zero or more, binds to name.
Is x a splice variable like ??xs — matches zero or more, binds to name.
(substitute template bindings)Replace pattern variables in template with values from bindings. Splice variables (??xs) are spliced into the parent sequence.
Replace pattern variables in template with values from bindings. Splice variables (??xs) are spliced into the parent sequence.
(valid-pipeline? phases)Does this sequence of phases form a valid pipeline?
Does this sequence of phases form a valid pipeline?
(wildcard? x)Is x the wildcard _ — matches anything, no binding.
Is x the wildcard _ — matches anything, no binding.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |