Metastatic. MetaAST
(Metastatic v0.33.0)
View Source
Shared, language-agnostic core for MetaAST-shaped trees.
Both Metastatic.AST (programming-language MetaAST) and
Metastatic.NL.AST (natural-language MetaAST) model their trees as the same
uniform 3-tuple:
{type_atom, keyword_meta, children_or_value}This module owns the operations that are identical for both:
- node accessors (
type/1,meta/1,children/1) - metadata access (
get_meta/3,put_meta/3,update_meta/2) - generic depth-first traversal (
traverse/4,prewalk/2,postwalk/2)
Metastatic.AST and Metastatic.NL.AST delegate here, so the two meta-ASTs
can no longer drift apart in their shared surface. Domain-specific behaviour
(conformance rules, type registries, builders, to_string/1, …) stays in the
respective modules.
Traversal contract
traverse/4 visits a node's metadata values as well as its children: any
metadata value that is itself a node (or a list/keyword containing one) is
traversed. This keeps subterms embedded in metadata — e.g. a :coreference
target or a :pattern — visible to walkers. See Metastatic.AST.traverse/4
for the precise invariant used by the programming-language side.
Summary
Functions
Returns the node's children list or leaf value.
Gets a metadata value by key, with an optional default.
Returns the node's metadata keyword list.
Returns the path from a matching node up to the root, or nil.
Post-order traversal (no accumulator).
Pre-order traversal (no accumulator).
Returns a lazy enumerable that walks the tree in depth-first pre-order.
Returns a lazy pre-order enumerable that threads an accumulator.
Puts a metadata value by key.
Depth-first traversal with pre- and post-visit callbacks.
Returns the node type atom.
Replaces a node's children/value.
Merges a keyword list of metadata updates into the node.
Updates a single metadata value with a function.
Types
Functions
Returns the node's children list or leaf value.
Gets a metadata value by key, with an optional default.
Returns the node's metadata keyword list.
@spec path(t(), (t() -> as_boolean(term()))) :: [t()] | nil
Returns the path from a matching node up to the root, or nil.
The path starts with the matched node, followed by its parents up to the
root. Mirrors Macro.path/2.
Examples
iex> ast = {:binary_op, [operator: :+],
...> [{:variable, [], "x"}, {:literal, [subtype: :integer], 42}]}
iex> path = Metastatic.MetaAST.path(ast, fn {:literal, _, 42} -> true; _ -> false end)
iex> Enum.map(path, &Metastatic.MetaAST.type/1)
[:literal, :binary_op]
Post-order traversal (no accumulator).
Pre-order traversal (no accumulator).
@spec prewalker(t()) :: Enumerable.t()
Returns a lazy enumerable that walks the tree in depth-first pre-order.
Mirrors Macro.prewalker/1: each node is yielded before its children.
@spec prewalker(t(), acc, (t(), acc -> {term(), acc})) :: Enumerable.t() when acc: term()
Returns a lazy pre-order enumerable that threads an accumulator.
Mirrors the Macro.prewalker/2 shape: the caller supplies
fun.(node, acc) -> {yielded, acc} which runs for each node in pre-order
and returns the value to yield together with the next accumulator.
Examples
iex> ast = {:binary_op, [operator: :+],
...> [{:literal, [subtype: :integer], 1}, {:literal, [subtype: :integer], 2}]}
iex> ast |> Metastatic.MetaAST.prewalker(0, fn _n, acc -> {acc, acc + 1} end) |> Enum.to_list()
[0, 1, 2]
Puts a metadata value by key.
@spec traverse(t() | term(), acc, pre_fun, post_fun) :: {t() | term(), acc} when acc: term(), pre_fun: (t() | term(), acc -> {t() | term(), acc}), post_fun: (t() | term(), acc -> {t() | term(), acc})
Depth-first traversal with pre- and post-visit callbacks.
pre runs before a node's descendants, post after. Both receive
{node, acc} and must return {node, acc}. Metadata values that contain
nodes are traversed too.
Returns the node type atom.
Replaces a node's children/value.
Merges a keyword list of metadata updates into the node.
Updates a single metadata value with a function.
The function receives the current value (or default when absent) and
returns the new value.