Thanks for considering a contribution. This document covers what you need to know before opening an issue or a pull request.
Getting started
git clone <this repository>
cd ichor
mix deps.get
mix test
That should complete with no failures on a clean checkout. If it doesn't, please open an issue before doing anything else — that's a bug in its own right.
Project layout
lib/aether/— the Aether lexer and parser (.aethersource ->Grammar.IR).lib/grammar/—Grammar.IRitself, the analysis pass, and both backends (Grammar.VM,Grammar.Native).lib/ichor/—Ichor.Actionsand the ABNF/BNF/EBNF/PEG format importers.priv/grammar/— the.aethersources the format importers compile from (read once, at compile time, viause Ichor).test/— one directory per worked-example grammar (test/lisp/,test/yaml/, ...), plustest/support/for shared test fixtures and Actions implementations.guides/— the documentation underguides/, published via ExDoc alongside the generated module docs.
Making a change
Tests first, or at least alongside. A grammar-level change should come with a test exercising the actual input/output behavior, not just "does this parse." Several bugs found during this project's own development only showed up once a worked example was actually run end-to-end, not merely checked for successful parsing.
Both backends, where it applies.
Grammar.VMandGrammar.Nativeare required to agree on every grammar's behavior. A change to shared semantics (an IR node's meaning, a compiler pass) needs verification against both, not just whichever one you happened to be testing against.Run the full verification pass before opening a PR:
mix format mix compile --warnings-as-errors --force mix test mix docsMatch the existing documentation style. Default to no comments; when one is warranted, explain a non-obvious why (a hidden constraint, a subtle invariant, the specific bug class it prevents), not what the code already makes obvious by being well-named. Moduledocs should be self-contained — don't cite an external design document or a numbered "phase," since neither exists in this repository; document the library as it actually is.
Adding a new grammar-format importer
If you're adding support for reading another external grammar notation
(along the lines of Ichor.ABNF/Ichor.BNF/Ichor.EBNF.ISO/
Ichor.EBNF.W3C/Ichor.PEG), the existing five are the template to
follow:
- Write an
.aethergrammar describing the target format's own syntax, underpriv/grammar/. - Write an
Ichor.Actionsimplementation whose target category isGrammar.IR— turning a parsed rule of the external format into the equivalentGrammar.IRexpression, the same wayIchor.ABNF.ActionsorIchor.PEG.Actionsdo. - Compile the pair via
use Ichor, nested underIchor.*(not a bare top-level module name), matching the existing five. - Verify the importer fails informatively (a normal
Ichor.Error, not a crash) on syntax that isn't valid in your target format, not just that it succeeds on syntax that is.
Reporting bugs
Please include: the grammar (or a minimal excerpt reproducing the
issue), the input, what you expected, and what actually happened
(including the full Ichor.Error, if one was raised). "Doesn't parse"
and "doesn't work" are much harder to act on than a specific
input/expected/actual triple.
License
By contributing, you agree that your contributions will be licensed under the project's MIT license.