Token-stream term rewriting system.
Three stages:
Rules are pure data — patterns and replacements that the engine interprets. No lambdas in rule definitions.
Pattern language (matches consecutive sibling nodes): {:bind :name} — match any node, bind {:bind :name :pred fn} — match node satisfying fn, bind {:bind :name :paren-group true :adj true} — match adjacent paren group, bind
Replacement language (produces sibling nodes): {:ref :name} — emit bound node {:ref :name :strip-ws true} — emit bound node, strip :ws {:paren-group [...] :ws-from :name} — build paren group from parts {:body-of :name} — emit inner children of bound group {:body-of :name :ensure-ws str} — emit inner children, ensure :ws on first
Token-stream term rewriting system.
Three stages:
1. Nest: group balanced delimiters into nested vectors
2. Rewrite: apply declarative rules on nested structure
3. Flatten: unnest back to flat token vector for emission
Rules are pure data — patterns and replacements that the engine
interprets. No lambdas in rule definitions.
Pattern language (matches consecutive sibling nodes):
{:bind :name} — match any node, bind
{:bind :name :pred fn} — match node satisfying fn, bind
{:bind :name :paren-group true :adj true} — match adjacent paren group, bind
Replacement language (produces sibling nodes):
{:ref :name} — emit bound node
{:ref :name :strip-ws true} — emit bound node, strip :ws
{:paren-group [...] :ws-from :name} — build paren group from parts
{:body-of :name} — emit inner children of bound group
{:body-of :name :ensure-ws str} — emit inner children, ensure :ws on firstDefault rule set for M-expression → S-expression rewriting.
Default rule set for M-expression → S-expression rewriting.
M-expression call: valid head followed by adjacent paren-group. head(args...) → (head args...) x → ([x] args...)
M-expression call: valid head followed by adjacent paren-group. head(args...) → (head args...) [x](args...) → ([x] args...)
(meme->clj-text source)Convert meme source to Clojure source text via token-stream rewriting.
Convert meme source to Clojure source text via token-stream rewriting.
(nest-tokens tokens)Group balanced delimiters into nested vectors. Each delimited group becomes [opener-tok ...children closer-tok]. Children may themselves be nested groups or atom tokens.
Group balanced delimiters into nested vectors. Each delimited group becomes [opener-tok ...children closer-tok]. Children may themselves be nested groups or atom tokens.
(rewrite-level rules children)Rewrite one level of nested children. Recurses into sub-groups first (bottom-up), then scans left-to-right applying rules at this level. After a match, re-checks the same position to support chained calls: f(x)(y) → ((f x) y).
Rewrite one level of nested children. Recurses into sub-groups first (bottom-up), then scans left-to-right applying rules at this level. After a match, re-checks the same position to support chained calls: f(x)(y) → ((f x) y).
(rewrite-meme->sexp tokens)(rewrite-meme->sexp tokens rules)Rewrite a meme token stream to S-expression token structure. Nest → rewrite → flatten.
Rewrite a meme token stream to S-expression token structure. Nest → rewrite → flatten.
(rule pattern replacement)Create a rewrite rule from pattern and replacement data.
Create a rewrite rule from pattern and replacement data.
(tokenize-and-rewrite source)Tokenize meme source and rewrite to S-expression token structure.
Tokenize meme source and rewrite to S-expression token structure.
(tokens->text tokens)Reconstruct source text from a token vector, preserving whitespace.
Reconstruct source text from a token vector, preserving whitespace.
(valid-head? node)Can this node be the head of an M-expression call?
Can this node be the head of an M-expression call?
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 |