We greatly appreciate all contributions from the open source community. They're part of what keep Zirco possible.
If you have a suggestion for something that could improve the Zirco compiler or language, please create an issue. This can also be used for bug reports.
If you have a change you would like to make, please make a corresponding issue (unless it is trivial) and receive public feedback before beginning work on it. Then, fork our repository and make your changes — we appreciate them all. You may then create a Pull Request and the corresponding maintainer will provide feedback before possibly merging your PR!
- General Guidelines
- Proposing New Language Features
- Implementing Language Features
- Code Style and Quality
- Testing Requirements
- Documentation Requirements
- Search for existing issues to avoid duplicate work
- Discuss major changes in an issue before implementing
- Follow the Code of Conduct at all times
- Keep changes focused - one feature or fix per PR
- Write clear commit messages using Semantic Commit Messages
feat:for new featuresfix:for bug fixesdocs:for documentation changesrefactor:for code refactoringtest:for test additions/changeschore:for maintenance tasks
New language features require careful consideration as they become part of Zirco's long-term design. Follow this process:
Use the feature request template and include:
- Clear motivation: Explain the problem your feature solves
- Use cases: Provide concrete examples of how it would be used
- Syntax proposal: Show what the feature would look like in Zirco code
- Ecosystem benefits: Describe how this helps the broader community
- Potential drawbacks: Consider downsides and compatibility concerns
- Alternatives: What other approaches did you consider?
When proposing a feature, consider:
- Parser compatibility: Will it work with LALR(1) parsing? (See the
newkeyword example in struct construction) - Type system impact: How does it interact with Zirco's strong type system?
- LLVM codegen: Can it be efficiently mapped to LLVM IR?
- C-like semantics: Does it align with Zirco's C-like semantic model?
- Rust-inspired syntax: Does it fit Zirco's modern syntax goals?
- Future compatibility: Does it leave room for planned features like generics, pattern matching, or modules?
Study similar implemented features for guidance:
- Struct construction (
examples/struct_construction/) - Shows thenewkeyword syntax - Pointers (
examples/pointer_swap/) - Low-level memory operations - Control flow (
examples/loop_example/) - Statement-level features
Refer to the Language Specification for:
- Current syntax and semantics
- Type system rules
- Expression precedence
- Future directions (Section 8.9)
- Engage with feedback on your proposal issue
- Be open to alternative designs
- Consider backwards compatibility (though note: Zirco is pre-1.0 with no stability guarantees)
- Wait for maintainer approval before starting implementation
Language features typically require changes across three compiler stages. Here's the recommended workflow:
Location: compiler/zrc_parser/
-
Update the grammar (
src/parser.lalrpop):- Add new tokens to the lexer if needed (
src/lexer.rs) - Define grammar rules for your syntax
- Ensure the grammar remains LALR(1) compatible
- Add new tokens to the lexer if needed (
-
Extend the AST (
src/ast/):- Add new AST node types for your feature
- Implement
Displaytrait for pretty-printing - Add
Debugimplementations
-
Build and test:
cargo build -p zrc_parser cargo test -p zrc_parser
Example: The new keyword for struct construction required adding both a keyword token and grammar rules for struct initialization expressions.
Location: compiler/zrc_typeck/
-
Extend the TAST (
src/tast/):- Create typed versions of your AST nodes
- Include type information in the nodes
-
Implement type checking (
src/typeck/):- Add type checking logic for your feature
- Validate type correctness
- Provide helpful error messages via
zrc_diagnostics - Handle type inference if applicable
-
Build and test:
cargo build -p zrc_typeck cargo test -p zrc_typeck
Important: Ensure your type checking catches all semantic errors early.
Location: compiler/zrc_codegen/
-
Implement LLVM IR generation:
- Add codegen logic in appropriate files (
src/stmt.rs,src/expr.rs, etc.) - Use
inkwellbindings to generate LLVM IR - Handle all type variants
- Add codegen logic in appropriate files (
-
Add snapshot tests:
- Create tests that verify generated IR
- Use
instafor snapshot testing - Review snapshots with
cargo insta review
-
Build and test:
cargo build -p zrc_codegen cargo test -p zrc_codegen
-
Create a complete example in
examples/:- Create a new directory with a descriptive name
- Include a
Makefilefollowing existing patterns - Add example
.zrsource files - Write a comprehensive
README.mdexplaining:- What the feature does
- Syntax demonstration
- Implementation status
- How to build and run
-
Test the full pipeline:
cargo build cargo test make -C examples/<your-example> test
-
Update the specification (
docs/SPEC.md):- Document the syntax
- Explain semantics and behavior
- Add to the appropriate section
- Include grammar rules
- Provide examples
All code must pass these checks before submission:
# Build
cargo build
# Tests
cargo test
# Linting (requires nightly toolchain)
cargo +nightly clippy --all-targets -- -D warnings
# Formatting (requires nightly toolchain)
cargo +nightly fmtZirco uses extremely strict clippy lints:
- All items (public and private) require documentation comments
- No
.unwrap()- handle errors properly withResultor? - No
todo!()orunimplemented!()in committed code - Follow all
clippy::pedanticandclippy::nurserylints
- Use
///for item documentation - Use
//!for module documentation - Document all parameters with
# Arguments - Document return values
- Document panics with
# Panics - Document safety with
# Safetyfor unsafe code - Use examples in doc comments where helpful
- Add tests inline with
#[cfg(test)] mod tests { ... } - Test edge cases and error conditions
- Use descriptive test names
- Use
instacrate for IR verification - Review snapshots carefully with
cargo insta review - Commit snapshots with your changes
- Create full example programs in
examples/ - Include
make testtargets - Test compilation and execution
- Aim for comprehensive coverage of new code
- The project uses
cargo-tarpaulinfor coverage tracking - CI will report coverage changes
- Update relevant documentation when changing behavior
- Add code comments for complex logic (matching existing style)
- Update
README.mdif user-facing behavior changes
-
Update
docs/SPEC.md:- Add to the appropriate section
- Follow the existing structure
- Include grammar, semantics, and examples
- Update the Table of Contents
-
Create an example in
examples/:- Full working code demonstrating the feature
- Comprehensive README explaining the feature
- Makefile for building and testing
- Clear documentation of implementation status
-
Update compiler help text if adding CLI options
- Use clear, concise language
- Provide code examples
- Link to related features
- Explain the "why" not just the "what"
Important: Zirco is pre-1.0 with NO STABILITY GUARANTEES.
- Internal compiler APIs may change without warning
- Language syntax and semantics may evolve
- Breaking changes are expected
- All crates are version
0.1.0until stability is maintained
This allows rapid iteration and improvement. Your contributions help shape Zirco's future!
We use the all-contributors specification to recognize all contributions.
To add yourself as a contributor, please comment on an issue or PR with the following syntax:
@all-contributors please add @your-github-username for code, doc
See also: https://allcontributors.org/docs/en/bot/usage
- Questions? Open a GitHub Discussion
- Stuck? Comment on your PR or issue
- Found a bug? Open a bug report
Thank you for contributing to Zirco! Your efforts help make the language better for everyone.