2025-09-15 01:21:37 +09:00
# Ny JSON IR v0 — Minimal Spec (Stage‑ 2)
Status: experimental but stable for Phase‑ 15 Stage‑ 2. Input to `--ny-parser-pipe` .
Version and root
- `version` : 0
- `kind` : "Program"
- `body` : array of statements
Statements (`StmtV0` )
- `Return { expr }`
- `Extern { iface, method, args[] }` (optional; passes through to `ExternCall` )
- `Expr { expr }` (expression statement; side effects only)
- `Local { name, expr }` (Stage‑ 2)
- `If { cond, then: Stmt[], else?: Stmt[] }` (Stage‑ 2)
- `Loop { cond, body: Stmt[] }` (Stage‑ 2; while(cond) body)
2025-09-16 23:49:36 +09:00
- `Break` (Stage‑ 3; exits current loop)
- `Continue` (Stage‑ 3; jumps to loop head)
2025-09-19 02:07:38 +09:00
- `Try { try: Stmt[], catches?: Catch[], finally?: Stmt[] }` (Stage‑ 3 skeleton; surface syntax uses `cleanup` , but the v0 field name remains `finally` for compatibility; currently lowered as sequential `try` body only when runtime support is absent)
2025-09-15 01:21:37 +09:00
Expressions (`ExprV0` )
- `Int { value }` where `value` is JSON number or digit string
- `Str { value: string }`
- `Bool { value: bool }`
- `Binary { op: "+"|"-"|"*"|"/", lhs, rhs }`
- `Compare { op: "=="|"!="|"<"|"<="|">"|">=", lhs, rhs }`
- `Logical { op: "&&"|"||", lhs, rhs }` (short‑ circuit)
- `Call { name: string, args[] }` (function by name)
- `Method { recv: Expr, method: string, args[] }` (box method)
- `New { class: string, args[] }` (construct Box)
- `Var { name: string }`
2025-09-16 23:49:36 +09:00
- `Throw { expr }` (Stage‑ 3; currently degrades to expression statement when runtime semantics are disabled)
2025-09-15 01:21:37 +09:00
CFG conventions (lowered by the bridge)
- If: create `then_bb` , `else_bb` , `merge_bb` . Both branches jump to merge if unterminated.
- Loop: `preheader -> cond_bb -> (body_bb or exit_bb)` , body jumps back to cond.
- Short‑ circuit Logical: create `rhs_bb` , `fall_bb` , `merge_bb` with constants on fall path.
- All blocks end with a terminator (branch/jump/return).
2025-09-16 23:49:36 +09:00
PHI merging( Phase‑ 15 終盤の方針)
- MIR 生成層は PHI を生成しない( MIR13 運用) 。If/Loop の合流は LLVM 層( llvmlite/Resolver) が PHI を合成。
- ループは既存 CFG( preheader→cond→{body|exit}; body→cond) の検出により、ヘッダ BB で搬送値の PHI を構築。
- 将来( LoopForm= MIR18) では LoopForm 占位命令から逆 Lowering で PHI を自動化予定。
2025-09-19 02:07:38 +09:00
- PHI‑ off 運用( Builder 側の規約): merge 内に copy を置かず、then/else の pred へ edge_copy のみを挿入( self‑ copy は No‑ Op) 。use‑ before‑ def と重複 copy を原理的に回避する。
2025-09-15 01:21:37 +09:00
Type meta (emitter/LLVM harness cooperation)
- `+` with any string operand → string concat path( handle固定) 。
- `==/!=` with both strings → string compare path。
Special notes
- `Var("me")` : Bridge 既定では未定義エラー。デバッグ用に `NYASH_BRIDGE_ME_DUMMY=1` でダミー `NewBox{class}` を注入可(`NYASH_BRIDGE_ME_CLASS` 省略時は `Main` )。
- `--ny-parser-pipe` は stdin の JSON v0 を受け取り、MIR→MIR‑ Interp 経由で実行する。
CLI/Env cheatsheet
- Pipe: `echo '{...}' | target/release/nyash --ny-parser-pipe`
- File: `target/release/nyash --json-file sample.json`
- Verbose MIR dump: `NYASH_CLI_VERBOSE=1`
- me dummy: `NYASH_BRIDGE_ME_DUMMY=1 NYASH_BRIDGE_ME_CLASS=ConsoleBox`
Examples
Arithmetic
```json
{"version":0,"kind":"Program","body":[
{"type":"Return","expr":{
"type":"Binary","op":"+",
"lhs":{"type":"Int","value":1},
"rhs":{"type":"Binary","op":"*","lhs":{"type":"Int","value":2},"rhs":{"type":"Int","value":3}}
}}
]}
```
If with local + PHI merge
```json
{"version":0,"kind":"Program","body":[
{"type":"Local","name":"x","expr":{"type":"Int","value":1}},
{"type":"If","cond":{"type":"Compare","op":"< ","lhs":{"type":"Int","value":1},"rhs":{"type":"Int","value":2}},
"then":[{"type":"Local","name":"x","expr":{"type":"Int","value":10}}],
"else":[{"type":"Local","name":"x","expr":{"type":"Int","value":20}}]
},
{"type":"Return","expr":{"type":"Var","name":"x"}}
]}
```
2025-09-16 23:49:36 +09:00
- `Break` / `Continue` are emitted when Stage‑ 3 gate is enabled. When the bridge is compiled without Stage‑ 3 lowering, frontends may degrade them into `Expr(Int(0))` as a safety fallback.
2025-09-19 02:07:38 +09:00
- `Try` nodes include optional `catches` entries of the form `{ param?: string, typeHint?: string, body: Stmt[] }` . Until runtime exception semantics land, downstream lowers only the `try` body and ignores handlers/`finally` .