All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

0.2.0 - 2026-08-03

Fixed

  • Ichor.Actions.eval_all/2 could evaluate sibling captures in the wrong order (and, for an Actions module implementing custom special-form logic that assumes a particular evaluation order, thread context incorrectly) because it relied on a plain Elixir map's own iteration order, which Elixir/Erlang make no guarantee about -- observed to actually differ between Erlang/OTP versions for the exact same code and input.

Changed

  • Breaking: raw capture data (Ichor.Capture.node_t/0's :rule variant, Ichor.Actions.evaluate/5's raw_captures argument, Grammar.LRTable.Captures.build/3's return value, and Grammar.Native.Runtime.Parser.merge_captures/2's accumulator) is now an ordered list of {name, value} pairs (Ichor.Capture.raw_captures/0) instead of a plain map, preserving true first-occurrence RHS/source order end to end -- the fix for the ordering bug above. A grammar's generated Actions module, or any hand-written code that pattern-matches or constructs raw_captures/node_t() values directly (e.g. for macro-expansion via Ichor.Actions.evaluate_node/3), needs updating from %{name: value} to [{name, value}]/[name: value]. The already- evaluated Ichor.Actions.captures/0 map handed to handle_rule/3 callbacks is unchanged (still a plain map, keyed for ergonomic access).
  • Ichor.Capture gained a position field (defaults to 0) recording a capture's index among its siblings; eval_all/2 now sorts by it before folding, instead of trusting captures' own map order.

0.1.0 - 2026-07-29

Added