No description
  • C++ 85.9%
  • Nix 5.9%
  • Shell 4.8%
  • Just 1.7%
  • CMake 1.7%
Find a file
NotAShelf da9be4b014
docs: document binary format; add testing instructions
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I2cb3440f97b4add57860b212a60442336a6a6964
2026-02-22 00:07:46 +03:00
src plugin: integrate evaluator for runtime comp 2026-02-22 00:07:43 +03:00
tests tests: initial test suite for IR compiler 2026-02-22 00:07:44 +03:00
.envrc meta: add direnv support 2026-02-22 00:07:36 +03:00
.gitignore chore: update gitignore for build artifacts 2026-02-22 00:07:45 +03:00
CMakeLists.txt evaulator: implement IR evaluation engine 2026-02-22 00:07:42 +03:00
flake.lock initial commit 2026-02-22 00:07:30 +03:00
flake.nix nix: add libblake to buildInputs; split off nativeBuildInputs 2026-02-22 00:07:37 +03:00
README.md docs: document binary format; add testing instructions 2026-02-22 00:07:46 +03:00

Nixir - Import-Resolving IR Plugin

Nixir, for the lack of a more imaginative name, is a Nix plugin with a fancy hybrid compilation architecture for optimized evaluation. We provide two complementary paths for Nix evaluator. It is either On-the-fly compilation where the plugin parses and compiles Nix code at runtime, or; ahead-of-time compilation where the nix-irc tool pre-compiles .nix files into .nixir files.

The plugin automatically chooses the fastest path based on file availability.

Supported Nix Constructs

  • Literals: integers, strings, booleans, null, paths
  • Attrsets: { name: value; }
  • Recursive attrsets: rec { ... }
  • Let bindings: let x: 1; in x
  • Recursion let: let rec x: y; y: x; in x
  • Conditionals: if cond then a else b
  • Lambdas: (basic support, patterns coming in Phase 5)
  • Applications: function calls
  • Selections: attrset.attribute
  • Assertions: assert condition; expr
  • With expressions: with attrs; expr
  • Operators:
    • Binary: +, -, *, /, ++, ==, !=, <, >, <=, >=, &&, ||, ->
    • Unary: -, !

Usage

Building

# Configure
$ cmake -B build

# Build
$ make

# The nix-irc executable will be in the project root
$ ./nix-irc --help

Compiling Nix to IR

# Basic compilation
$ nix-irc input.nix output.nixir

# With import search paths
$ nix-irc -I ./lib -I /nix/store/... input.nix output.nixir

# Disable import resolution
$ nix-irc --no-imports input.nix output.nixir

Runtime Evaluation (Plugin)

# Load the plugin and evaluate IR
$ nix --plugin-files ./nix-ir-plugin.so eval --expr 'builtins.nixIR_loadIR "output.nixir"'

# On-the-fly compilation and evaluation
$ nix --plugin-files ./nix-ir-plugin.so eval --expr 'builtins.nixIR_compile "1 + 2 * 3"'

# Get plugin info
$ nix --plugin-files ./nix-ir-plugin.so eval --expr 'builtins.nixIR_info'

Running Tests

# Test all sample files
for f in tests/*.nix; do
    ./nix-irc "$f" "${f%.nix}.nixir"
done

# Verify IR format
$ hexdump -C tests/simple.nixir | head -3

IR Format

The .nixir files use a versioned binary format:

Header:
  - Magic: 0x4E495258 ("NIRX")
  - Version: 1 (uint32)
  - Source count: uint32
  - Import count: uint32
  - String table size: uint32

String Table:
  - Interned strings for efficient storage

Nodes:
  - Binary encoding of IR nodes
  - Each node has type tag + inline data

Entry:
  - Main expression node index

Contributing

This is a research/experimental project. Contributions welcome!

Areas where help is needed:

  • Expanding parser to handle more Nix syntax
  • Performance optimization
  • Test coverage
  • Documentation improvements