Predicator.Visitors.InstructionsVisitor (predicator v3.7.0)
View SourceVisitor that converts AST nodes to stack machine instructions.
This visitor implements post-order traversal to generate instruction lists that can be executed by the stack-based evaluator. Instructions are generated in the correct order for stack-based evaluation.
Source positions
Internally the traversal pairs every instruction with the source position of
the AST node that emitted it. visit/2 discards those positions and returns
the plain instruction list; visit_with_positions/2 returns both. The
instruction list is identical either way - positions never enter the
instruction format itself, so cross-language interchange and stored compiled
artifacts are unaffected (ADR-0001).
Both entry points accept either a positioned AST or the position-free shape
Predicator 3.6 produced, normalizing with Predicator.Parser.ensure_positions/1
on the way in.
Examples
iex> ast = {:literal, 42}
iex> Predicator.Visitors.InstructionsVisitor.visit(ast, [])
[["lit", 42]]
iex> ast = {:identifier, "score"}
iex> Predicator.Visitors.InstructionsVisitor.visit(ast, [])
[["load", "score"]]
iex> ast = {:comparison, :gt, {:identifier, "score"}, {:literal, 85}}
iex> Predicator.Visitors.InstructionsVisitor.visit(ast, [])
[["load", "score"], ["lit", 85], ["compare", "GT"]]
iex> ast = {:logical_and, {:literal, true}, {:literal, false}}
iex> Predicator.Visitors.InstructionsVisitor.visit(ast, [])
[["lit", true], ["jump_if_falsy_or_pop", 2], ["lit", false]]
iex> ast = {:function_call, "len", [{:identifier, "name"}]}
iex> Predicator.Visitors.InstructionsVisitor.visit(ast, [])
[["load", "name"], ["call", "len", 1]]
Summary
Types
One instruction paired with the source position of the node that emitted it.
Functions
Visits an AST node and returns stack machine instructions.
Returns the instruction list and a side table mapping each instruction's 0-based index to the source position of the AST node that emitted it.
Types
@type annotated() :: {[binary() | term()], Predicator.Types.position() | nil}
One instruction paired with the source position of the node that emitted it.
Functions
@spec visit( Predicator.Parser.ast() | Predicator.Parser.bare_ast(), keyword() ) :: [[binary() | term()]]
Visits an AST node and returns stack machine instructions.
Uses post-order traversal to ensure operands are pushed onto the stack before operators are applied.
Parameters
ast_node- The AST node to convert to instructionsopts- Optional visitor options (currently unused)
Returns
List of instructions in the format [["operation", ...args]]
@spec visit_with_positions( Predicator.Parser.ast() | Predicator.Parser.bare_ast(), keyword() ) :: {[[binary() | term()]], Predicator.Types.position_table()}
Returns the instruction list and a side table mapping each instruction's 0-based index to the source position of the AST node that emitted it.
Nodes carrying a nil position contribute no entry, so a position-free AST
yields an empty table. The instruction list is identical to visit/2's.
Examples
iex> ast = {:comparison, :gt, {:identifier, "score", {1, 1}}, {:literal, 85, {1, 9}}, {1, 7}}
iex> Predicator.Visitors.InstructionsVisitor.visit_with_positions(ast)
{[["load", "score"], ["lit", 85], ["compare", "GT"]],
%{0 => {1, 1}, 1 => {1, 9}, 2 => {1, 7}}}
iex> Predicator.Visitors.InstructionsVisitor.visit_with_positions({:literal, 42})
{[["lit", 42]], %{}}