Ichor (Ichor v0.1.1)

Copy Markdown View Source

Ichor reads grammar definitions -- its own language Aether, plus ABNF, BNF, EBNF, and PEG importers -- and turns each one into a working Lexer + Parser + Executor for whatever language the grammar describes, via either an interpreted VM backend (Grammar.VM) or compile-time native codegen (__using__/1 below).

This top-level module holds evaluate_node/3: a general entry point for evaluating a Ichor.Capture.node_t() that didn't come from the original parse. Every other .eval thunk a Ichor.Actions implementation sees is tied to a specific position in the text that was actually parsed; a macro's expansion isn't -- it's new code, built by the macro body, that still needs to go through the same handle_rule/handle_token dispatch (or default fallback) as anything else. Not Lisp-specific in principle: any grammar with macro-like features would need this same re-entry point.

It also holds __using__/1, the native codegen backend's own entry point:

defmodule Calculator do
  use Ichor, grammar: "calculator.aether", actions: Calculator.Actions
end

Calculator.run("2 + 3 * 4")  #=> {:ok, 14}

grammar: is a path to a .aether file, resolved relative to the use-ing module's own source file (so a grammar file can live alongside the module that compiles it); grammar_source: takes literal grammar text directly instead, for callers that don't want a separate file on disk. Exactly one of the two is required. actions: bakes in a compile-time-known module reference -- parse/1, tokenize/1, and run/1,2 all get added directly to the use-ing module, via Grammar.Native.generate/2.

Summary

Functions

Evaluates a raw capture node (as found on any Ichor.Capture.node, or built directly by something like a macro's unreify) against actions_module, starting from context.

Functions

evaluate_node(arg, actions_module, context)

@spec evaluate_node(Ichor.Capture.node_t(), module(), Ichor.Actions.context()) ::
  {:ok, term(), Ichor.Actions.context()} | {:error, Ichor.Error.t()}

Evaluates a raw capture node (as found on any Ichor.Capture.node, or built directly by something like a macro's unreify) against actions_module, starting from context.