A Seriously-Crafted Hobby Language
From Zero to Native Binary in 20 Days - The AI-Powered Language Revolution
๐ฏ๐ต ๆฅๆฌ่ช็ใฏใใกใ / Japanese Version
Execution Status (Feature Additions Pause)
- Active
--backend llvm(Python/llvmlite harness; AOT object emit)--backend vm(PyVM harness)
- Inactive/Sealed
--backend cranelift,--jit-direct(sealed; use LLVM harness)- AST interpreter (legacy) is gated by feature
interpreter-legacyand excluded from default builds (Rust VM + LLVM are the two main lines)
- Policy (clarification): No major feature additions during this phase. Bug fixes and correctness/FailโFast improvements are allowed and encouraged (bringing behavior in line with documented semantics). Any experimental additions must be guarded behind flags defaultโOFF and be reversible.
Quick pointers
- Emit object with harness: set
NYASH_LLVM_USE_HARNESS=1andNYASH_LLVM_OBJ_OUT=<path>(defaults in tools usetmp/). - Run PyVM:
NYASH_VM_USE_PY=1 ./target/release/nyash --backend vm apps/APP/main.nyash. - Root navigation map: see
ROOT_MAP.mdfor tight-mode paths.
Dev shortcuts (Operator Boxes & JSON smokes)
- Oneโshot JSON verification (dev, Operator Boxes ON):
./tools/opbox-json.sh - Run quick profile with Operator Boxes:
./tools/opbox-quick.sh - Details:
docs/guides/operator-boxes.md
Dev mode and defaults
nyash --dev script.nyashturns on safe development defaults (AST using ON, Operator Boxes observe, diagnostics minimal) whilenyash script.nyashstays productionโlike and quiet.- You can still use the dev shortcuts for a oneโcommand setup:
./tools/opbox-json.sh,./tools/opbox-quick.sh. - Using guard: duplicate
usingof the same file (or alias rebind to a different file) now errors with a line number hint to avoid ambiguous resolution.- Example error:
using: duplicate import of '<canon_path>' at file.nyash:12 (previous alias 'X' first seen at line 5) - Fix by removing the duplicate or consolidating aliases.
- Example error:
Phaseโ15 (2025โ09) update
- Parser newline/TokenCursor ็ตฑไธใฏ env ใฒใผใไธใง้ฒ่กไธญ๏ผ
NYASH_PARSER_TOKEN_CURSOR=1๏ผใ - if/else ใฎ PHI incoming ใฏๅฎ้ใฎ้ท็งปๅ ๏ผexit๏ผใธไฟฎๆญฃๆธใฟ๏ผVM/LLVM ใใชใใฃ็ท๏ผใ
- ่ชๅทฑใในใๆบๅใจใใฆ Nyash ่ฃฝ JSON ใฉใคใใฉใชใจ Ny Executor๏ผๆๅฐๅฝไปค๏ผใๆขๅฎOFFใฎใใฐใซใง่ฟฝๅ ไบๅฎใ
- ๆจๅฅจใใฐใซ:
NYASH_LLVM_USE_HARNESS=1,NYASH_PARSER_TOKEN_CURSOR=1,NYASH_JSON_PROVIDER=ny,NYASH_SELFHOST_EXEC=1ใ
Developer quickstart: see docs/guides/build/dev-quickstart.md. Changelog highlights: CHANGELOG.md.
User Macros (Phase 2): docs/guides/user-macros.md
Exceptions (postfix catch/cleanup): docs/guides/exception-handling.md
ScopeBox & MIR hints: docs/guides/scopebox.md
AST JSON v0 (macro/bridge): docs/reference/ir/ast-json-v0.md
MIR mode note: Default PHI behavior
- Phaseโ15 ships PHIโON by default. Builders emit SSA
Phinodes at merges for loops, break/continue, and structured control flow. - Legacy PHIโoff fallback: set
NYASH_MIR_NO_PHI=1(pair withNYASH_VERIFY_ALLOW_NO_PHI=1if you need relaxed verification). - See
docs/reference/mir/phi_policy.mdfor rationale and troubleshooting. Selfโhosting oneโpager:docs/how-to/self-hosting.md. ExternCall (env.*) and println normalization:docs/reference/runtime/externcall.md.
- VM: no extra environment needed for typical runs.
- Example:
./target/release/nyash --backend vm apps/tests/ternary_basic.nyash
- Example:
- LLVM harness: set three variables so the runner finds the harness and runtime.
NYASH_LLVM_USE_HARNESS=1NYASH_NY_LLVM_COMPILER=$NYASH_ROOT/target/release/ny-llvmcNYASH_EMIT_EXE_NYRT=$NYASH_ROOT/target/release- Example:
NYASH_LLVM_USE_HARNESS=1 NYASH_NY_LLVM_COMPILER=target/release/ny-llvmc NYASH_EMIT_EXE_NYRT=target/release ./target/release/nyash --backend llvm apps/ny-llvm-smoke/main.nyash
- Enable:
NYASH_DEBUG_ENABLE=1 - Select kinds:
NYASH_DEBUG_KINDS=resolve,ssa - Output file:
NYASH_DEBUG_SINK=/tmp/nyash_debug.jsonl - Use with smokes:
NYASH_DEBUG_ENABLE=1 NYASH_DEBUG_KINDS=resolve,ssa NYASH_DEBUG_SINK=/tmp/nyash.jsonl tools/smokes/v2/run.sh --profile quick --filter "userbox_*"
Diagnostics (builder; dev-only)
- See
docs/development/builder/DIAGNOSTICS.mdfor a compact list of flags likeNYASH_VARMAP_TRACE,NYASH_MAT_TRACE, and routing/SSA traces.
- Centralized call emission is enabled by default in development builds.
- Env toggle:
NYASH_MIR_UNIFIED_CALLโ default ON unless set to0|false|off. - Instance method calls are normalized in one place (
emit_unified_call):- Early mapping:
toString/stringify โ str equals/1: Known first โ unique-suffix fallback (user boxes only)- Knownโfunction rewrite:
obj.m(a) โ Class.m(me,obj,a)
- Early mapping:
- Env toggle:
- Disable legacy rewrite path (dev-only) to avoid duplicate behavior during migration:
NYASH_DEV_DISABLE_LEGACY_METHOD_REWRITE=1
- JSON emit follows unified format (v1) when unified is ON; legacy v0 otherwise.
- VM policy (Instance BoxCall): user instance dispatch is a development fallback only.
- Env:
NYASH_VM_USER_INSTANCE_BOXCALL={0|1}(default: dev/ci=true, prod=false) - Builder is responsible for InstanceโFunction rewrite on user boxes; production disallows instance BoxCall so rewrite leaks are detected early.
- Env:
Dev metrics (opt-in)
- Known-rate KPI for
resolve.choose:NYASH_DEBUG_KPI_KNOWN=1(enable)NYASH_DEBUG_SAMPLE_EVERY=<N>(print every N events)
Layer guard (one-way deps: originโobserveโrewrite)
- Check script:
tools/dev/check_builder_layers.sh - Ensures builder layering hygiene during refactors.
- stringify(Void) โ "null" for JSON-friendly printing (dev safety; prod behavior unchanged).
- JsonScanner defaults (guarded by
NYASH_VM_SCANNER_DEFAULTS=1) for missing numeric/text fields insideis_eof/current/advancecontexts only. - VoidBox common methods (length/size/get/push) are neutral no-ops in guarded paths to avoid dev-time hard stops.
Profiles (quick)
--profile devโ Macros ON (strict), PyVM devๅใ่จญๅฎใ้ฉ็จ๏ผๅฟ ่ฆใซๅฟใใฆ็ฐๅขใงไธๆธใๅฏ๏ผ--profile liteโ Macros OFF ใฎ่ปฝ้ๅฎ่ก- ไพ:
./target/release/nyash --profile dev --backend vm apps/tests/ternary_basic.nyash
- ไพ:
Specs & Constraints
- Invariants (must-hold):
docs/reference/invariants.md - Constraints (known/temporary/resolved):
docs/reference/constraints.md - PHI & SSA design:
docs/reference/architecture/phi-and-ssa.md - Testing matrix (spec โ tests):
docs/guides/testing-matrix.md - Comparison with other languages:
docs/guides/comparison/nyash-vs-others.md
- Guide:
docs/how-to/self-hosting.md - Minimal E2E:
./target/release/nyash --backend vm apps/selfhost-minimal/main.nyash - Smokes:
bash tools/jit_smoke.sh/bash tools/selfhost_vm_smoke.sh - JSON (Operator Boxes, dev):
./tools/opbox-json.sh/./tools/opbox-quick.sh - Makefile:
make run-minimal,make smoke-selfhost
MIR note: Coreโ13 minimal kernel is enforced by default (NYASH_MIR_CORE13=1). Legacy ops are normalized (Array/RefโBoxCall; TypeCheck/Cast/Barrier/WeakRef unified).
Pure mode: set NYASH_MIR_CORE13_PURE=1 to enable strict Coreโ13. The optimizer rewrites a few ops (Load/Store/NewBox/Unary) to Coreโ13 forms, and the compiler rejects any remaining nonโCoreโ13 ops. This may break execution temporarily by design to surface MIR violations early.
Note: JIT runtime execution is currently disabled to reduce debugging overhead. Use Interpreter/VM for running and AOT (Cranelift/LLVM) for distribution.
September 2, 2025 - ๐ฅ ABI as a Box! Nyash ABI itself implemented as TypeBox (C language) - path to self-hosting clear! September 1, 2025 - Revolutionary TypeBox ABI unification achieved! C ABI + Nyash ABI seamlessly integrated. August 29, 2025 - Just 20 days after inception, Nyash can now compile to native executables!
# From Nyash source to native binary (Cranelift required)
cargo build --release --features cranelift-jit
./tools/build_aot.sh program.nyash -o app # Native EXE
./app # Standalone execution!What we achieved in 24 days:
- โ Full programming language with interpreter
- โ VM with 13.5x performance boost
- โ JIT compiler (Cranelift integration)
- โ WebAssembly support
- โ Plugin system (C ABI + Nyash ABI unified)
- โ Native binary generation
- โ Python integration via plugins
- โ TypeBox ABI bridge (revolutionary plugin unification)
- โ Self-hosting path clear (Nyash ABI in C, no Rust dependency!)
// Traditional languages have complex type systems
// Nyash: One concept rules them all - Box
static box Main {
main() {
// Every value is a Box - unified, safe, simple
local name = new StringBox("Nyash")
local count = new IntegerBox(42)
local data = new MapBox()
// Even Python objects are Boxes!
local py = new PyRuntimeBox()
local math = py.import("math")
print("sqrt(9) = " + math.getattr("sqrt").call(9).str())
return 0
}
}
- Day 1: Basic interpreter working
- Day 4: Already planning JIT
- Day 13: VM achieving 13.5x speedup
- Day 20: Native executable generation!
// Any functionality can be a plugin Box
local file = new FileBox() // File I/O plugin
local http = new HttpClientBox() // Network plugin
local py = new PyRuntimeBox() // Python plugin
// Plugins compile to native code too!
Important: JIT runtime execution is sealed for now. Use PyVM/VM for running, and Cranelift AOT/LLVM AOT for native executables.
Phaseโ15 (SelfโHosting): Legacy VM/Interpreter are featureโgated
- Default build runs PyVM for
--backend vm(python3 +tools/pyvm_runner.pyrequired) - To enable legacy Rust VM/Interpreter, build with:
Then
cargo build --release --features vm-legacy,interpreter-legacy
--backend vm/--backend interpreteruse the legacy paths. - Note:
--benchmarkrequires the legacy VM. Build with--features vm-legacybefore running benchmarks.
./target/release/nyash program.nyash- Instant execution
- Full debug information
- Perfect for development
# Default: PyVM harness (requires python3)
./target/release/nyash --backend vm program.nyash
# Enable legacy Rust VM if needed
cargo build --release --features vm-legacy
./target/release/nyash --backend vm program.nyash- Default (vm-legacy OFF): PyVM executes MIR(JSON) via
tools/pyvm_runner.py - Legacy VM: 13.5x over interpreter (historical); kept for comparison and plugin tests
# Build once (Cranelift)
cargo build --release --features cranelift-jit
./tools/build_aot.sh program.nyash -o myapp
./myapp # Standalone executable!- Zero dependencies
- Maximum performance
- Easy distribution
# Build harness + CLI (no LLVM_SYS_180_PREFIX needed)
cargo build --release -p nyash-llvm-compiler && cargo build --release --features llvm
# Emit and run native executable via harness
NYASH_LLVM_USE_HARNESS=1 \
NYASH_NY_LLVM_COMPILER=target/release/ny-llvmc \
NYASH_EMIT_EXE_NYRT=target/release \
./target/release/nyash --backend llvm --emit-exe myapp program.nyash
./myapp
# Alternatively, emit an object file then link manually
NYASH_LLVM_USE_HARNESS=1 \
NYASH_NY_LLVM_COMPILER=target/release/ny-llvmc \
./target/release/nyash --backend llvm program.nyash \
-D NYASH_LLVM_OBJ_OUT=$PWD/nyash_llvm_temp.o
cc nyash_llvm_temp.o -L crates/nyrt/target/release -Wl,--whole-archive -lnyrt -Wl,--no-whole-archive -lpthread -ldl -lm -o myapp
./myappQuick smoke test (VM vs EXE):
tools/smoke_aot_vs_vm.sh examples/aot_min_string_len.nyashNYASH_LLVM_OBJ_OUT: Path to emit.owhen running--backend llvm.- Example:
NYASH_LLVM_OBJ_OUT=$PWD/nyash_llvm_temp.o ./target/release/nyash --backend llvm apps/ny-llvm-smoke/main.nyash
- Example:
- Previously available
NYASH_LLVM_ALLOW_BY_NAME=1: Removed - all plugin calls now use method_id by default.- The LLVM backend only supports method_id-based plugin calls for better performance and type safety.
The WASM/browser path is currently not maintained and is not part of CI. The older playground and guides are kept for historical reference only.
- Source (archived):
projects/nyash-wasm/(build not guaranteed) - Current focus: VM (Rust) and LLVM (llvmlite harness)
- If you experiment locally, see the project README and
projects/nyash-wasm/build.sh(wasm-pack required). No support guarantees.
Reads nyash.toml, builds plugins โ core โ emits AOT object โ links an executable in one shot.
Basic (Cranelift AOT)
./target/release/nyash --build nyash.toml \
--app apps/egui-hello-plugin/main.nyash \
--out app_eguiKey options (minimal)
--build <path>: path to nyash.toml--app <file>: entry.nyash--out <name>: output executable (default:app/app.exe)--build-aot cranelift|llvm(default: cranelift)--profile release|debug(default: release)--target <triple>(only when needed)
Notes
- LLVM AOT uses Python llvmlite harness. Ensure Python3 + llvmlite and
ny-llvmcare available (built viacargo build -p nyash-llvm-compiler). NoLLVM_SYS_180_PREFIXrequired. - Apps that open a GUI may show a window during AOT emission; close it to continue.
- On WSL if the window doesnโt show, see
docs/guides/cranelift_aot_egui_hello.md(WaylandโX11).
Real-world benchmark results (ny_bench.nyash):
Mode | Time | Relative Speed
---------------|-----------|---------------
Interpreter | 110.10ms | 1.0x (baseline)
VM | 8.14ms | 13.5x faster
Cranelift AOT | ~4โ6ms | ~20โ27x faster
Native (LLVM) | ~4ms | ~27x faster
box GameCharacter {
private { name, health, skills }
// Birth constructor - giving life to Boxes!
birth(characterName) {
me.name = characterName
me.health = 100
me.skills = new ArrayBox()
print("๐ " + characterName + " has been born!")
}
learnSkill(skill) {
me.skills.push(skill)
return me // Method chaining
}
}
// Usage
local hero = new GameCharacter("Neko")
hero.learnSkill("Fire Magic").learnSkill("Healing")
// Concurrent operations made simple
nowait task1 = fetchDataFromAPI()
nowait task2 = processLocalFiles()
// Do other work while waiting
updateUI()
// Collect results
local apiData = await task1
local files = await task2
// Composition over inheritance
box EnhancedArray from ArrayBox {
private { logger }
override push(item) {
me.logger.log("Adding: " + item)
from ArrayBox.push(item) // Delegate to parent
}
}
Just completed: Revolutionary unification of all property types into one elegant syntax!
box RevolutionaryBox {
// ๐ต stored: Traditional field storage
name: StringBox
// ๐ข computed: Calculated every access
size: IntegerBox { me.items.count() }
// ๐ก once: Lazy evaluation with caching
once cache: CacheBox { buildExpensiveCache() }
// ๐ด birth_once: Eager evaluation at object creation
birth_once config: ConfigBox { loadConfiguration() }
birth() {
me.name = "Example"
// birth_once properties already initialized!
}
}
The Property System enables revolutionary Python โ Nyash transpilation:
# Python side
class DataProcessor:
@property
def computed_result(self):
return self.value * 2
@functools.cached_property
def expensive_data(self):
return heavy_computation()// Auto-generated Nyash (1:1 mapping!)
box DataProcessor {
computed_result: IntegerBox { me.value * 2 } // computed
once expensive_data: ResultBox { heavy_computation() } // once
}
Result: Python code runs 10-50x faster as native Nyash binaries!
- Property System Specification - Complete syntax reference
- Python Integration Guide - Python โ Nyash transpilation
- Implementation Strategy - Technical details
"Everything is Box" Philosophy - Even ABI is a Box!
// TypeBox - Type information as a Box (enables cross-plugin creation)
typedef struct {
uint32_t abi_tag; // 'TYBX'
const char* name; // "ArrayBox"
void* (*create)(void); // Box creation function
} NyrtTypeBox;
// NEW: Nyash ABI itself as a TypeBox! (C implementation, no Rust)
typedef struct {
uint32_t abi_tag; // 'NABI'
const char* name; // "NyashABIProvider"
void* (*create)(void); // ABI provider creation
// ... Nyash operations (call, retain, release)
} NyashABITypeBox;Revolutionary Achievement: ABI implementation in pure C enables self-hosting!
# nyash.toml v3.0 - Unified plugin support
[plugins.map]
path = "plugins/map.so"
abi = "c" # Traditional C ABI
[plugins.advanced_map]
path = "plugins/adv_map.so"
abi = "nyash" # Type-safe Nyash ABI
[plugins.hybrid]
path = "plugins/hybrid.so"
abi = "unified" # Both ABIs supported!Key Innovation: TypeBox enables cross-plugin Box creation without circular dependencies. MapBox can now return ArrayBox seamlessly!
๐ Full TypeBox Documentation
# Clone and build
git clone https://github.com/moe-charm/nyash.git
cd nyash
cargo build --release --features cranelift-jit
# Run your first program
echo 'print("Hello Nyash!")' > hello.nyash
./target/release/nyash hello.nyash# Cross-compile for Windows
cargo install cargo-xwin
cargo xwin build --target x86_64-pc-windows-msvc --release
# Use target/x86_64-pc-windows-msvc/release/nyash.exe
# Native EXE (AOT) on Windows (requires Cranelift and MSYS2/WSL toolchain for linking)
cargo build --release --features cranelift-jit
powershell -ExecutionPolicy Bypass -File tools\build_aot.ps1 -Input examples\aot_min_string_len.nyash -Out app.exe
./app.exe- Developed with Claude, ChatGPT, and Codex collaboration
- 20-day journey from concept to native compilation
- Proves AI can accelerate language development by 30x
- Every optimization preserves the Box abstraction
- Plugins are Boxes, JIT preserves Boxes, even native code respects Boxes
- TypeBox: Even type information is a Box!
- Unprecedented consistency across all execution modes
- Built-in debugging and profiling
- JSON event streams for JIT compilation
- DOT graph visualization of optimizations
// Use Python libraries from Nyash!
local py = new PyRuntimeBox()
local np = py.import("numpy")
local array = np.getattr("array").call([1, 2, 3])
print("NumPy array: " + array.str())
local server = new HttpServerBox()
server.start(8080)
loop(true) {
local request = server.accept()
local response = new HttpResponseBox()
response.setStatus(200)
response.write("Hello from Nyash!")
request.respond(response)
}
box GameObject {
public { x, y, sprite }
update(deltaTime) {
// Physics simulation
me.y = me.y + gravity * deltaTime
}
render(canvas) {
canvas.drawImage(me.sprite, me.x, me.y)
}
}
Join the revolution! We welcome:
- ๐ Bug reports and fixes
- โจ New Box types via plugins
- ๐ Documentation improvements
- ๐ฎ Cool example programs
See also: Contributor guide in AGENTS.md (Repository Guidelines) for project layout, build/test commands, and PR expectations.
MIT License - Use freely in your projects!
charmpic - Hobby Language Developer
- ๐ฑ GitHub: @moe-charm
- ๐ Created with: Claude, ChatGPT, Codex collaboration
- August 9, 2025: First commit - "Hello Nyash!"
- August 13: JIT planning begins (day 4!)
- August 20: VM achieves 13.5x performance
- August 29: Native EXE compilation achieved!
- September 1: TypeBox ABI unification - C ABI + Nyash ABI seamless integration
- September 2: ๐ฅ Self-hosting path clear - Nyash ABI in C (no Rust dependency!)
- September 4: ๐ช Windows GUI displayed via JIT/native EXE (OS-native window)
24 days from zero to self-hosting capability - a new record in language development!
๐ Nyash - Where Everything is a Box, and Boxes Compile to Native Code!
Built with โค๏ธ, ๐ค AI collaboration, and the belief that programming languages can be created at the speed of thought