Files
hakorune/docs/reference/language/quick-reference.md
tomoaki c117a04035 fix(rewrite): toString normalization to BoxCall(slot #0) - Phase 287 P4
Root cause: toString/stringify/str were being rewritten to Global/Method calls
with class inference, causing Main.toString/0 to be called for primitives.

Fix (Box-First + Legacy Deletion):
1.  MIR Builder - toString normalization (special.rs)
   - ALWAYS emit BoxCall with method_id=0 for toString/stringify/str
   - Do NOT rewrite to Global(Class.str/0) or Method calls
   - DELETED 70+ lines of complex class inference logic
   - Primitive guard with method name filter (known.rs)

2.  JSON Serializer - method_id output (mir_json_emit.rs)
   - Include method_id field in BoxCall JSON for LLVM

3.  LLVM Backend - universal slot #0 support
   - Extract method_id from JSON (instruction_lower.py)
   - Box primitives via nyash.box.from_i64 (boxcall.py)
   - Invoke toString via plugin system with method_id=0
   - ⚠️ TODO: Add nyash.integer.tostring_h to kernel

Test Results:
 VM: local x = 1; print(x.toString()) → "1" (PASS)
 VM: array_length test (boxed Integer) → PASS
⚠️ LLVM: Compiles successfully, needs kernel function

SSOT: slot_registry - toString is ALWAYS universal slot #0

Legacy Deleted:
- special.rs: Complex class inference rewrite (~70 lines)
- special.rs: Unique suffix fallback for toString
- special.rs: Main box special handling

Files changed:
- src/mir/builder/rewrite/special.rs (try_early_str_like_to_dst)
- src/mir/builder/rewrite/known.rs (primitive guards x4)
- src/runner/mir_json_emit.rs (method_id serialization x2)
- src/llvm_py/builders/instruction_lower.py (method_id extraction)
- src/llvm_py/instructions/boxcall.py (slot #0 handler)
- docs/reference/language/quick-reference.md (toString SSOT)

🎊 Generated with Claude Code
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 11:38:05 +09:00

78 lines
3.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Nyash Quick Reference (MVP)
Purpose
- Onepage practical summary for writing and implementing Nyash.
- Keep grammar minimal; clarify rules that often cause confusion.
Keywords (reserved)
- control: `if`, `else`, `loop`, `match`, `case`, `break`, `continue`, `return`
- decl: `static`, `box`, `local`, `using`, `as`
- lit: `true`, `false`, `null`, `void`
Expressions and Calls
- Function call: `f(a, b)`
- Method call: `obj.m(a, b)` — internally normalized to function form: `Class.m(me: obj, a, b)`
- DefaultONP4: Known 受信者かつ関数が一意に存在する場合に正規化userbox 限定)。
- それ以外Unknown/core/userinstanceは安全に BoxCall へフォールバック(挙動不変)。
- 環境で無効化: `NYASH_REWRITE_KNOWN_DEFAULT=0`(開発時の切替用)。
- バックエンドVM/LLVM/Nyは統一形状の呼び出しを受け取る。
- Member: `obj.field` or `obj.m`
Display & Conversion
- Humanreadable display: `x.toString()`(推奨)
- ユーザーBoxで表示をカスタムしたい場合は `str()` または `stringify()`互換を実装する。VMは `toString()``str()/stringify()` に再ルーティングする。
- Debug表示構造的・安定: `repr(x)`将来導入、devのみ
- JSONシリアライズ: `toJson(x)`(文字列)/ `toJsonNode(x)`(構造)
Operators (precedence high→low)
- Unary: `! ~ - weak` (`weak <expr>` produces a `WeakRef`; `weak(expr)` is invalid)
- Multiplicative: `* / %`
- Additive: `+ -`
- Compare: `== != < <= > >=`
- Logical: `&& ||` (shortcircuit, sideeffect aware)
Semicolons and ASI (Automatic Semicolon Insertion)
- Allowed to omit semicolon at:
- End of line, before `}` or at EOF, when the statement is syntactically complete.
- Not allowed:
- Line break immediately after a binary operator (e.g., `1 +\n2`)
- Ambiguous continuations; parser must FailFast with a clear message.
Truthiness (boolean context)
- SSOT: `reference/language/types.md`runtime truthiness
- 実行上は `Bool/Integer/Float/String/Void` が中心。`BoxRef` は一部のコアBoxのみ許可され、その他は `TypeError`Fail-Fast
- `null``void` の別名(構文糖衣)。どちらも boolean context では `TypeError`
Equality and Comparison
- SSOT: `reference/language/types.md``==`/`!=``< <= > >=` の runtime 仕様)
- `==` の cross-kind は **`Integer↔Float` のみ**(精密ルール)。それ以外の mixed kinds は `false`(エラーではない)。
- `< <= > >=``Integer/Float/String` の **同型同士**のみ(異型は `TypeError`)。
String and Numeric `+`
- SSOT: `reference/language/types.md`runtime `+` 仕様)
- `Integer+Integer` は加算、`Float+Float` は加算、`Integer↔Float``Float` に昇格して加算。
- 文字列連結は **`String + String` のみ**。`"a"+1` / `1+"a"``TypeError`(暗黙 stringify なし)。
- 文字列化して連結したい場合は明示的に `x.toString()` を使う。
Blocks and Control
- `if (cond) { ... } [else { ... }]`
- `loop (cond) { ... }` — minimal loop form
- `match (expr) { case ... }` — MVP (literals and simple type patterns)
Using / SSOT
- Dev/CI: filebased `using` allowed for convenience.
- Prod: `nyash.toml` only. Duplicate imports or alias rebinding is an error.
Errors (format)
- Always: `Error at line X, column Y: <message>`
- For tokenizer errors, add the reason and show one nearby line if possible.
Dev/Prod toggles (indicative)
- `NYASH_DEV=1` — developer defaults (diagnostics, tracing; behavior unchanged)
- `NYASH_ENABLE_USING=1` — enable using resolver
- `NYASH_ENTRY_ALLOW_TOPLEVEL_MAIN=1` — allow `main` as toplevel entry
Notes
- Keep the language small. Prefer explicit conversions (`x.toInteger()`, `x.toString()`, `x.toBool()`) over implicit coercions.
- Builder rewrites method calls to keep runtime dispatch simple and consistent across backends.