# Nyar Assembler
A modern, high-performance assembler and binary format manipulation library for the Nyar Virtual Machine. It provides a fluent API for building Nyar programs, managing constant pools, and generating optimized bytecode in the `.nyarc` (Nyar Archive) format.
## 🏛️ Architecture
```mermaid
graph TB
subgraph "Nyar Assembler Pipeline"
A[High-level Instructions] --> B[Nyar Builder]
B --> C[Constant Pool Management]
C --> D[Bytecode Encoder]
D --> E[Nyarc Binary Output]
subgraph "Core Modules"
F[program::builder]
G[program::instructions]
H[program::pool]
I[formats::nyarc]
end
B --> F
D --> G
C --> H
E --> I
end
```
## 🚀 Features
### Core Capabilities
- **Fluent Builder API**: Chainable methods to construct modules, functions (chunks), and control flow.
- **Instruction Set Support**: Comprehensive coverage of the Nyar VM instruction set, including stack manipulation, upvalues, and closure creation.
- **Constant Pool Deduplication**: Automatically manages and deduplicates constants (integers, floats, strings, etc.) to minimize binary size.
- **Metadata Management**: Handles imports, exports, and module-level metadata for dynamic linking and execution.
### Advanced Features
- **Flexible Binary Encoding**: Leverages `gaia-binary` with Leb128 variable-length encoding for compact instruction streams.
- **Closure Support**: Built-in support for capturing upvalues and creating closures at runtime.
- **Type Safety**: Strongly-typed instruction operands and program structures enforced by Rust's type system.
- **Zero-Dependency Core**: Designed to be lightweight and portable, with minimal external dependencies.
## 💻 Usage
### Generating a "Hello Nyar" Module
The following example demonstrates how to use `NyarBuilder` to create a simple program that pushes a string and returns.
```rust
use nyar_assembler::program::{
NyarBuilder, NyarInstruction, NyarConstant,
};
use nyar_assembler::formats::nyarc::NyarcWriter;
use std::io::Cursor;
fn main() {
let mut builder = NyarBuilder::new();
// 1. Add a string constant
let hello_idx = builder.add_constant(NyarConstant::String("Hello, Nyar!".to_string()));
// 2. Build a code chunk
builder.begin_chunk();
builder.emit(NyarInstruction::Push(hello_idx as u16)).unwrap();
builder.emit(NyarInstruction::Return).unwrap();
builder.set_chunk_meta(0, 0, 1);
// 3. Export the entry point
builder.add_export("main".into(), 0);
// 4. Finalize and write to binary
let program = builder.finish();
let mut buffer = Cursor::new(Vec::new());
let mut writer = NyarcWriter::new(&mut buffer);
writer.write(&program).expect("Failed to write .nyarc binary");
let binary_data = buffer.into_inner();
println!("Generated {} bytes of Nyar bytecode", binary_data.len());
}
```
## 🛠️ Support Status
| Core Instructions | ✅ |
| Upvalues / Closures | ✅ |
| Constant Pool | ✅ |
| Import / Export | ✅ |
| Binary (.nyarc) | ✅ |
| Disassembler | 🚧 |