One error struct, reused across every stage -- Lexer, Parser, analysis
pass, and Ichor.Actions -- so errors look the same regardless of
origin.
context_lines is pre-rendered at construction time, not lazily
computed on access: cheap to do once, and keeps every stage's error
output visually consistent.
data is whatever a stage wants to hand through with its error --
most often an action failing with its own domain error, wrapped here
so the parser's result stays an Ichor.Error and its caller unwraps
it. Ichor itself never sets or reads it, and format/1 ignores it.
Summary
Functions
Renders the full human-readable error: location, message, and the caret-annotated snippet, in that order.
Builds a Ichor.Error, pre-rendering context_lines immediately.
Types
@type stage() :: :lexer | :parser | :analysis | :action
@type t() :: %Ichor.Error{ column: pos_integer() | nil, context_lines: String.t() | nil, data: term(), expected: term(), file: String.t() | nil, found: term(), line: pos_integer() | nil, message: String.t(), stage: stage() | nil }
Functions
Renders the full human-readable error: location, message, and the caret-annotated snippet, in that order.
Examples
iex> error = Ichor.Error.new(
...> message: "expected ')'",
...> stage: :parser,
...> file: "calc.aether",
...> line: 1,
...> column: 8,
...> source: "(2 + 3"
...> )
iex> Ichor.Error.format(error)
"calc.aether:1:8: expected ')'\n1 | (2 + 3\n | ^"
Builds a Ichor.Error, pre-rendering context_lines immediately.
Accepts :message (required), :stage, :line, :column, :file,
:expected, :found, :data, and either :source (the full source text, used
to render a caret-annotated snippet at :line/:column) or a
pre-rendered :context_lines directly, for callers that already have
one (e.g. re-wrapping an error from another stage).
Examples
iex> error = Ichor.Error.new(
...> message: "expected ')'",
...> stage: :parser,
...> line: 1,
...> column: 8,
...> expected: ")",
...> found: :eof,
...> source: "(2 + 3"
...> )
iex> error.context_lines
"1 | (2 + 3\n | ^"
iex> Ichor.Error.new(message: "boom", source: nil, line: nil).context_lines
nil