nixir/README.md
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

2.7 KiB

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