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>
3.9 KiB
3.9 KiB
Nyash Quick Reference (MVP)
Purpose
- One‑page 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)- Default‑ON(P4): Known 受信者かつ関数が一意に存在する場合に正規化(userbox 限定)。
- それ以外(Unknown/core/user‑instance)は安全に BoxCall へフォールバック(挙動不変)。
- 環境で無効化:
NYASH_REWRITE_KNOWN_DEFAULT=0(開発時の切替用)。 - バックエンド(VM/LLVM/Ny)は統一形状の呼び出しを受け取る。
- Member:
obj.fieldorobj.m
Display & Conversion
- Human‑readable display:
x.toString()(推奨)- ユーザーBoxで表示をカスタムしたい場合は
str()またはstringify()(互換)を実装する。VMはtoString()をstr()/stringify()に再ルーティングする。
- ユーザーBoxで表示をカスタムしたい場合は
- Debug表示(構造的・安定):
repr(x)(将来導入、devのみ) - JSONシリアライズ:
toJson(x)(文字列)/toJsonNode(x)(構造)
Operators (precedence high→low)
- Unary:
! ~ - weak(weak <expr>produces aWeakRef;weak(expr)is invalid) - Multiplicative:
* / % - Additive:
+ - - Compare:
== != < <= > >= - Logical:
&& ||(short‑circuit, side‑effect 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.
- End of line, before
- Not allowed:
- Line break immediately after a binary operator (e.g.,
1 +\n2) - Ambiguous continuations; parser must Fail‑Fast with a clear message.
- Line break immediately after a binary operator (e.g.,
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 formmatch (expr) { case ... }— MVP (literals and simple type patterns)
Using / SSOT
- Dev/CI: file‑based
usingallowed for convenience. - Prod:
nyash.tomlonly. 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 resolverNYASH_ENTRY_ALLOW_TOPLEVEL_MAIN=1— allowmainas top‑level 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.