feat(parser): Phase 285A1.4 & A1.5 - Weak field sugar + Parser hang fix

A1.4: Add sugar syntax `public weak parent` ≡ `public { weak parent }`
A1.5: Fix parser hang on unsupported `param: Type` syntax

Key changes:
- A1.4: Extend visibility parser to handle weak modifier (fields.rs)
- A1.5: Shared helper `parse_param_name_list()` with progress-zero detection
- A1.5: Fix 6 vulnerable parameter parsing loops (methods, constructors, functions)
- Tests: Sugar syntax (OK/NG), parser hang (timeout-based)
- Docs: lifecycle.md, EBNF.md, phase-285a1-boxification.md

Additional changes:
- weak() builtin implementation (handlers/weak.rs)
- Leak tracking improvements (leak_tracker.rs)
- Documentation updates (lifecycle, types, memory-finalization, etc.)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-24 07:44:50 +09:00
parent a47f850d02
commit ab76e39036
60 changed files with 2099 additions and 454 deletions

View File

@ -5,6 +5,10 @@
Nyashの核心哲学「**Everything is Box**」に関する完全な設計ドキュメント集。
言語設計の根幹から実装詳細まで、Boxシステムのすべてを網羅しています。
注(`init { ... }` について):
- `init { a, b, c }` は legacy のフィールド宣言slotです互換のために残っています
- 新規コードでは、可能なら Unified Membersstored/computed/once/birth_onceでの宣言を推奨しますSSOT: `docs/reference/language/EBNF.md` / ライフサイクルSSOT: `docs/reference/language/lifecycle.md`)。
## 📚 ドキュメント構成
### 🌟 コア哲学
@ -51,4 +55,4 @@ Nyashの核心哲学「Everything is Box」の解説。なぜすべてをBoxに
---
**最終更新**: 2025年8月19日 - boxes-system統合整理完了
**Phase 9.75g-0成果**: プラグインシステムとの完全統合
**Phase 9.75g-0成果**: プラグインシステムとの完全統合

View File

@ -5,6 +5,8 @@
Nyashは継承の代わりに「完全明示デリゲーション」を採用しています。
これは「Everything is Box」哲学に基づく、より安全で明確な設計アプローチです。
注: `init { ... }` は legacy のフィールド宣言slotです互換のために残っています。新しい宣言モデルUnified Members`docs/reference/language/EBNF.md` を参照してください。
## 🎯 なぜデリゲーションか
### 継承の問題点
@ -387,4 +389,4 @@ box Proxy delegates * to target {
関連ドキュメント:
- [Everything is Box](everything-is-box.md)
- [override/from構文詳細](../override-delegation-syntax.md)
- [言語リファレンス](../language-reference.md)
- [言語リファレンス](../language-reference.md)

View File

@ -112,7 +112,7 @@ local result = "Hello" + 42.toString() // OK: "Hello42"
### 特殊Box型
- **FutureBox** - 非同期処理
- **WeakBox** - 弱参照
- **WeakRefWeakBox** - 弱参照(観測は `weak_to_strong()`。言語SSOT: `docs/reference/language/lifecycle.md`
- **ExternBox** - 外部ライブラリ統合
## 🔄 Boxの生成と利用
@ -130,6 +130,7 @@ local num = 42 // 自動的にIntegerBox
### ユーザー定義Box
```nyash
// 注: `init { ... }` は legacy のフィールド宣言slotです互換のために残っています
box Point {
init { x, y }
@ -195,4 +196,4 @@ Everything is Box哲学により、Nyashは
関連ドキュメント:
- [Box型カタログ](box-types-catalog.md)
- [デリゲーションシステム](delegation-system.md)
- [メモリ管理](memory-management.md)
- [メモリ管理](memory-management.md)

View File

@ -2,6 +2,8 @@
**最終更新: 2025年8月19日 - 統合仕様書**
注: 言語レベルの SSOT は `docs/reference/language/lifecycle.md`。本書は設計ートであり、SSOT と矛盾する記述があれば SSOT を優先する。
## 📋 概要
Nyashは「Everything is Box」哲学のもと、統一的なメモリ管理と予測可能なリソース解放を実現しています。
@ -72,20 +74,23 @@ box MyResource {
**重要**: `fini()`は「このオブジェクトをもう使わない」という宣言であり、物理的な即時破棄ではありません。
### 実行順序(確定仕様
### 実行順序(設計SSOTへの案内
最終的な順序・禁止事項の SSOT は `docs/reference/language/lifecycle.md` に集約する。
本セクションの箇条書きは “目標像/設計メモ” として読む。
#### 自動カスケード解放
```nyash
box Pipeline {
init { r1, r2, r3, weak monitor }
init { r1, r2, r3, monitor_weak }
fini() {
// 1) ユーザー定義処理(柔軟な順序制御可能)
me.r3.fini() // 依存関係でr3→r2の順
me.r2.fini()
// 2) 自動カスケード: 残りのr1がinit宣言順で自動解放
// 3) weakフィールドは対象外lazy nil化
// 2) 自動カスケード: 残りのr1が自動解放weak参照は対象外
// 3) weak参照は weak_to_strong() で観測し、失効時は null=void/noneを返す
}
}
```
@ -94,7 +99,7 @@ box Pipeline {
1. **finalized チェック** - 既に解放済みなら何もしないidempotent
2. **再入防止** - `in_finalization`フラグで再帰呼び出し防止
3. **ユーザー定義fini()実行** - カスタムクリーンアップ処理
4. **自動カスケード** - `init`宣言順で未処理フィールドを解放
4. **自動カスケード** - strong-owned フィールドを決定的順序で解放weakはスキップ
5. **フィールドクリア** - 全フィールドを無効化
6. **finalized設定** - 以後の使用を禁止
@ -102,25 +107,26 @@ box Pipeline {
```nyash
box Node {
init { id, weak next } // 'next'は弱参照
init { id, next_weak } // 弱参照は値として保持する(`weak(x)`
}
local node1 = new Node("A", null)
local node2 = new Node("B", node1) // node2はnode1への弱参照を持つ
node1.next = node2 // node1はnode2への強参照を持つ
local node2 = new Node("B", null)
node2.next_weak = weak(node1)
node1.next_weak = weak(node2)
// 循環参照を回避し、安全に解放される
```
#### weak参照の特性
- **所有権なし**: オブジェクトの生存期間に影響しない
- **自動nil化**: 参照先が解放されると自動的に`null`になる
- **観測はweak_to_strong**: 参照先が Dead/Freed の場合、`weak_to_strong()``null` を返す
- **fini()対象外**: 弱参照フィールドはfini()カスケードでスキップ
### 不変条件(重要)
- **weak参照**: `weak`フィールドに対して`fini()`を直接呼ぶことはできません
- **finalized後禁止**: `fini()`呼び出し後は、そのオブジェクトの使用はすべて禁止
- **カスケード順序**: `init`宣言順の**逆順**で実行、`weak`フィールドはスキップ
- **カスケード順序**: strong-owned フィールドに対して決定的に実行`weak`フィールドはスキップ順序のSSOTは `docs/reference/language/lifecycle.md`)。
## 🌟 実用例
@ -130,7 +136,7 @@ box FileHandler {
init { file, buffer }
fini() {
// オブジェクト削除時に自動呼び出し
// 終了時に資源を解放(必要なら明示的に呼ぶ)
if me.file != null {
me.file.close()
console.log("File closed automatically")
@ -177,4 +183,4 @@ box PluginResource {
**関連ドキュメント**:
- [Box型リファレンス](box-reference.md)
- [プラグインシステム](../plugin-system/)
- [BID-FFI仕様](../plugin-system/ffi-abi-specification.md)
- [BID-FFI仕様](../plugin-system/ffi-abi-specification.md)

View File

@ -11,7 +11,7 @@
- `design-philosophy.md` - Nyashの設計哲学
- `override-delegation-syntax.md` - オーバーライド・デリゲーション構文の詳細
- `portability-contract.md` - 移植性に関する契約
- `portability-contract.md` - 移植性に関する契約(アーカイブ。参照先: `docs/archive/core-language/portability-contract.md`
## 📦 アーカイブ

View File

@ -1,295 +1,8 @@
# 🤝 Nyash Portability Contract v0
# Portability Contract v0 (Archived)
*ChatGPT5アドバイス・全バックエンド互換性保証仕様*
This document has been archived. The canonical copy is:
- `docs/archive/core-language/portability-contract.md`
## 🎯 目的
**「nyash --target= interp / vm / wasm / aot-rust / jit-cranelift」で同一プログラムが同一結果を保証**
全バックエンドでNyashプログラムが確実に動作し、最適化レベルに関係なく**決定的で予測可能な実行**を実現。
## 🔧 **Contract v0 仕様**
### 1⃣ **決定的破棄Deterministic Finalization**
#### **強参照のみ伝播保証**
```rust
// ✅ 保証される動作
box Parent {
child_strong: ChildBox // 強参照→破棄連鎖
}
parent.fini() // 必ずchild_strong.fini()も呼ばれる
```
#### **破棄順序の決定性**
```nyash
// 破棄順序: 最新→最古(スタック順序)
box Child from Parent {
init { data }
pack() {
from Parent.pack() // 1. Parent初期化
me.data = "child" // 2. Child初期化
}
// fini順序: 2→1逆順破棄
}
```
#### **例外安全性**
```rust
pub enum FinalizationGuarantee {
AlwaysExecuted, // fini()は例外時も必ず実行
NoDoubleDestroy, // 同一オブジェクトの二重破棄禁止
OrderPreserved, // 初期化と逆順での破棄保証
}
```
### 2⃣ **weak参照の非伝播生存チェック**
#### **非伝播保証**
```nyash
box Parent {
init { child_weak }
pack() {
local child = new Child()
me.child_weak = weak(child) // weak参照生成
// child がfini()されても Parent は影響なし
}
}
```
#### **生存チェック必須**
```mir
// MIR レベルでの生存チェック
%alive = weak_load %weak_ref
br %alive -> %use_bb, %null_bb
%use_bb:
// weak参照が有効な場合の処理
%value = /* weak_refの値使用 */
jmp %continue_bb
%null_bb:
// weak参照が無効な場合の処理
%value = const null
jmp %continue_bb
%continue_bb:
// 合流地点Phi必須
%result = phi [%value from %use_bb, %value from %null_bb]
```
#### **自動null化契約**
```rust
pub struct WeakContract {
auto_nullification: true, // 参照先fini()時に自動null
no_dangling_pointers: true, // ダングリングポインタ禁止
thread_safe_access: true, // マルチスレッド安全アクセス
}
```
### 3⃣ **Effect意味論最適化可能性**
#### **Effect分類契約**
```rust
pub enum EffectLevel {
Pure, // 副作用なし→並び替え・除去・重複実行可能
Mut, // メモリ変更→順序保証必要・並列化制限
Io, // I/O操作→実行順序厳密保証・キャッシュ禁止
Bus, // 分散通信→elision対象・ネットワーク最適化可能
}
```
#### **最適化契約**
```mir
// Pure関数→最適化可能
%result1 = call @pure_function(%arg) effects=[PURE]
%result2 = call @pure_function(%arg) effects=[PURE]
// → 最適化: %result2 = copy %result1
// Mut操作→順序保証
store %value1 -> %ptr effects=[MUT]
store %value2 -> %ptr effects=[MUT]
// → 順序維持必須
// Bus操作→elision対象
send %bus, %message effects=[BUS]
// → ネットワーク最適化・バッチ化可能
```
### 4⃣ **Bus-elision基盤契約**
#### **elision ON/OFF同一結果保証**
```bash
# 最適化ON→高速実行
nyash --elide-bus --target wasm program.hako
# 最適化OFF→完全分散実行
nyash --no-elide-bus --target vm program.hako
# 結果は必ず同一(契約保証)
```
#### **Bus操作の意味保証**
```mir
// Bus送信の意味論
send %bus, %message effects=[BUS] {
// elision OFF: 実際のネットワーク送信
// elision ON: ローカル最適化(結果同一)
}
// Bus受信の意味論
%msg = recv %bus effects=[BUS] {
// elision OFF: ネットワーク受信待ち
// elision ON: ローカル値返却(結果同一)
}
```
## 🧪 **Contract検証システム**
### **互換テストスイート**
```rust
// tests/portability_contract_tests.rs
#[test]
fn test_deterministic_finalization() {
let program = "/* fini順序テスト */";
let interp_result = run_interpreter(program);
let vm_result = run_vm(program);
let wasm_result = run_wasm(program);
// 破棄順序・タイミングが全バックエンドで同一
assert_eq!(interp_result.finalization_order, vm_result.finalization_order);
assert_eq!(vm_result.finalization_order, wasm_result.finalization_order);
}
#[test]
fn test_weak_reference_semantics() {
let program = "/* weak参照テスト */";
// 生存チェック・null化が全バックエンドで同一動作
let results = run_all_backends(program);
assert_all_equal(results.map(|r| r.weak_behavior));
}
#[test]
fn test_effect_optimization_equivalence() {
let program = "/* Effect最適化テスト */";
// PURE関数の最適化結果が同一
let optimized = run_with_optimization(program);
let reference = run_without_optimization(program);
assert_eq!(optimized.output, reference.output);
}
#[test]
fn test_bus_elision_equivalence() {
let program = "/* Bus通信テスト */";
let elision_on = run_with_flag(program, "--elide-bus");
let elision_off = run_with_flag(program, "--no-elide-bus");
// Bus最適化ON/OFFで結果同一
assert_eq!(elision_on.output, elision_off.output);
}
```
### **Golden Dump検証**
```bash
#!/bin/bash
# scripts/verify_portability_contract.sh
echo "🧪 Portability Contract v0 検証中..."
# 1. MIR出力一致検証
nyash --dump-mir test.hako > golden.mir
nyash --dump-mir test.hako > current.mir
if ! diff golden.mir current.mir; then
echo "❌ MIR回帰エラー検出"
exit 1
fi
# 2. 全バックエンド同一出力
declare -a backends=("interp" "vm" "wasm")
for backend in "${backends[@]}"; do
nyash --target $backend test.hako > ${backend}.out
done
# 出力一致確認
if diff interp.out vm.out && diff vm.out wasm.out; then
echo "✅ 全バックエンド出力一致"
else
echo "❌ バックエンド出力差異検出"
exit 1
fi
# 3. Bus-elision検証
nyash --elide-bus test.hako > elision_on.out
nyash --no-elide-bus test.hako > elision_off.out
if diff elision_on.out elision_off.out; then
echo "✅ Bus-elision同一結果"
else
echo "❌ Bus-elision結果差異"
exit 1
fi
echo "🎉 Portability Contract v0 検証完了"
```
## 📊 **Contract適合レベル**
### **Tier-0: 基本互換性**
- [ ] **決定的破棄**: fini()順序がバックエンド間で同一
- [ ] **weak非伝播**: weak参照が親破棄に影響しない
- [ ] **基本Effect**: PURE/MUT/IO の意味論統一
- [ ] **出力一致**: 同一プログラム→同一標準出力
### **Tier-1: 最適化互換性**
- [ ] **PURE最適化**: 純粋関数の除去・移動がバックエンド間で同等
- [ ] **weak生存チェック**: 全バックエンドで同一タイミング
- [ ] **Bus-elision**: ON/OFF切り替えで結果同一
- [ ] **性能予測**: 最適化レベル差が定量的
### **Tier-2: 高度互換性**
- [ ] **メモリレイアウト**: Box構造がバックエンド間で互換
- [ ] **エラー処理**: 例外・パニックが同一動作
- [ ] **並行性**: Future/awaitが同一意味論
- [ ] **デバッグ**: スタックトレース・診断情報が同等
## ⚡ **実装優先順位**
### **Phase 8.4(今すぐ)**
1. **Tier-0契約実装**: 基本互換性確保
2. **Golden dump自動化**: CI/CDで回帰検出
3. **Bus命令設計**: elision基盤構築
### **Phase 8.5(短期)**
1. **Tier-1契約実装**: 最適化互換性
2. **性能ベンチマーク**: 契約準拠性測定
3. **エラー契約**: 例外処理統一
### **Phase 9+(中長期)**
1. **Tier-2契約実装**: 高度互換性
2. **形式検証**: 契約の数学的証明
3. **認証システム**: 契約適合認定
---
## 🎯 **期待効果**
### **開発者体験**
- **予測可能性**: どのバックエンドでも同一動作保証
- **デバッグ容易性**: バックエンド切り替えで問題切り分け
- **最適化信頼性**: 高速化しても結果不変保証
### **Nyash言語価値**
- **差別化**: 「全バックエンド互換」言語として独自性
- **信頼性**: エンタープライズ採用の技術的根拠
- **拡張性**: 新バックエンド追加時の品質保証
---
*最終更新: 2025-08-14 - ChatGPT5アドバイス完全実装*
*「Everything is Box」×「全バックエンド互換」= Nyashの技術的優位性*
Language SSOT:
- `docs/reference/language/lifecycle.md`
- `docs/reference/language/types.md`

View File

@ -251,6 +251,7 @@ NYASH_CLI_VERBOSE=2 \
| `NYASH_GC_METRICS=1` | OFF | Any | GC メトリクス (text) |
| `NYASH_GC_METRICS_JSON=1` | OFF | Any | GC メトリクス (JSON) |
| `NYASH_VM_TRACE=1` | OFF | Any | VM 実行トレース |
| `NYASH_LEAK_LOG={1\|2}` | OFF | Any | Exit-time leak report (Phase 285)。`1`=summary counts, `2`=verbose (names/entries) |
---

View File

@ -72,13 +72,25 @@ This section adds a minimal grammar for Box members (a unified member model) wit
```
box_decl := 'box' IDENT '{' member* '}'
member := stored
member := visibility_block
| weak_stored
| stored
| computed
| once_decl
| birth_once_decl
| method_decl
| block_as_role ; nyash-mode (block-first) equivalent
visibility_block := ( 'public' | 'private' ) '{' member* '}'
; member visibility grouping (Phase 285A1.3). `weak` is allowed inside.
weak_stored := 'weak' IDENT ( ':' TYPE )?
; weak field declaration (Phase 285A1.2). Enforces WeakRef type at compile-time.
visibility_weak_sugar := ('public'|'private') 'weak' IDENT ( ':' TYPE )?
; sugar syntax (Phase 285A1.4). Equivalent to visibility block form.
; e.g., `public weak parent` ≡ `public { weak parent }`
stored := IDENT ':' TYPE ( '=' expr )?
; stored property (read/write). No handlers supported.
@ -93,6 +105,10 @@ birth_once_decl:= 'birth_once' IDENT ':' TYPE ( '=>' expr | block ) handler_tail
method_decl := IDENT '(' params? ')' ( ':' TYPE )? block handler_tail?
params := IDENT (',' IDENT)*
; parameter name list (Phase 285A1.5)
; Note: Parameter type annotations (e.g., `name: Type`) are not supported.
; nyash-mode (block-first) variant — gated with NYASH_ENABLE_UNIFIED_MEMBERS=1
block_as_role := block 'as' ( 'once' | 'birth_once' )? IDENT ':' TYPE
@ -101,7 +117,7 @@ catch_block := 'catch' ( '(' ( IDENT IDENT | IDENT )? ')' )? block
cleanup_block := 'cleanup' block
; Stage3 (Phase 1 via normalization gate NYASH_CATCH_NEW=1)
; Postfix handlers for expressions and calls
; Postfix handlers for expressions and calls (cleanup may appear without catch)
postfix_catch := primary_expr 'catch' ( '(' ( IDENT IDENT | IDENT )? ')' )? block
postfix_cleanup := primary_expr 'cleanup' block
```
@ -120,12 +136,23 @@ Lowering (no JSON v0 change)
- birth_once → add `__name: T` and insert initialization just before user `birth` in declaration order; handlers apply to each initializer
- method → existing method forms; optional postfix handlers lower to try/catch/finally
## Legacy: `init { ... }` field list (compatibility)
Some docs and older code use an `init { a, b, c }` list inside a `box` body. This is a legacy compatibility form to declare stored slots.
Semantics (SSOT):
- `init { a, b, c }` declares **untyped stored slots** named `a`, `b`, `c` (equivalent to writing `a` / `b` / `c` as stored members without type).
- `init { weak x, weak y }` declares **weak fields** (equivalent to writing `weak x` / `weak y` as members).
- It does not execute code. Initialization logic belongs in `birth(...) { ... }` and assignments.
- **New code** should prefer the direct syntax: `weak field_name` (Phase 285A1.2) or the unified member model (`stored/computed/once/birth_once`).
- Legacy `init { weak field }` syntax still works for backward compatibility but is superseded by `weak field`.
## Stage3 (Gated) Additions
Enabled when `NYASH_PARSER_STAGE3=1` for the Rust parser (and via `--stage3`/`NYASH_NY_COMPILER_STAGE3=1` for the selfhost parser):
- try/catch/cleanup
- `try_stmt := 'try' block ('catch' '(' (IDENT IDENT | IDENT | ε) ')' block) ('cleanup' block)?`
- `try_stmt := 'try' block ('catch' '(' (IDENT IDENT | IDENT | ε) ')' block)? ('cleanup' block)?`
- MVP policy: single `catch` per `try`
- `(Type var)` or `(var)` or `()` are accepted for the catch parameter。

View File

@ -38,18 +38,18 @@ Rust製インタープリターによる高性能実行と、直感的な構文
| `override` | 明示的オーバーライド | `override speak() { }` |
| `break` | ループ脱出 | `break` |
| `catch` | 例外処理 | `catch (e) { }`(式/呼び出しの後置も可・Stage3 |
| `cleanup` | 最終処理finally の後継) | `cleanup { }`(式/呼び出しの後置も可・Stage3 |
| `cleanup` | 最終処理finally の後継) | `cleanup { }`(式/呼び出しの後置・Stage3`catch` があればその後に実行 |
| `throw` | 例外発生 | `throw error` |
| `nowait` | 非同期実行 | `nowait future = task()` |
| `await` | 待機・結果取得 | `result = await future` |
| `include` | ファイル取り込み | `include "math.hako"` |
| `print` | 出力(デバッグ用) | `print("Hello")` |
| `function`/`fn` | 関数定義 | `fn add(a,b) { }` |
| `init` | 初期化ブロック | `init { field1, field2 }` |
| `init` | legacy/互換フィールド宣言slot | `init { field1, field2 }` |
| `pack` | 旧コンストラクタ(互換性) | `pack(param) { }` |
| `outbox` | 所有権移転変数 | `outbox result = compute()` |
| `global` | グローバル変数 | `global CONFIG = "dev"` |
| `weak` | 弱参照修飾子 | `weak reference` |
| `weak` | 弱参照(生成) | `weak(x)` |
| `using` | 名前空間インポート | `using namespace` |
### **演算子・論理**
@ -95,6 +95,16 @@ box ClassName {
}
```
注: `fini()` / strong・weak / スコープ終了 / GC の方針cycle の扱い含む)の SSOT は `docs/reference/language/lifecycle.md`
注(`init { ... }` について):
- `init { a, b, c }` は **互換のために残っているフィールド宣言slot**です(コード実行の「初期化ブロック」ではありません)。
- これは「untyped な stored slot を宣言する糖衣」として扱います(例: `a` / `b` / `c` の stored を追加する)。
- `init { weak field }` は弱フィールド宣言ですPhase 285A1.2 の直接構文 `weak field` に統一されました)。
- 新規コードでは、可能なら以下を推奨します:
- **弱フィールド**: 直接構文 `weak field_name`Phase 285A1.2
- **その他**: `docs/reference/language/EBNF.md` の Unified Membersstored/computed/once/birth_once
#### **デリゲーションBox**
```nyash
box Child from Parent interface Comparable {
@ -739,6 +749,8 @@ array.map(fn(x) { x * x })
- Rust所有権システムによる完全なメモリ安全性
- Arc<Mutex>によるスレッドセーフな共有状態管理
- 自動参照カウント + 明示的デストラクタfini
- SSOT: `docs/reference/language/lifecycle.md`
- GCtracing/cycle collectionは意味論ではなく補助。OFFでも非循環は解放されるが、循環はリークしうる仕様
### **6.2 実行効率**
- 統一されたBox型システムによる最適化
@ -783,7 +795,6 @@ static box Main {
### **7.3 よくある間違いと対策**
```nyash
# ❌ よくある間違い
public { field1 field2 } # 旧構文 → 使用不可
x = 42 # 変数未宣言 → ランタイムエラー
while condition { } # 非対応構文 → パーサーエラー
this.field # thisは使用不可 → me.fieldを使用
@ -794,6 +805,10 @@ field2 # 型なしフィールド
local x = 42 # 事前宣言必須
loop(condition) { } # 統一ループ構文
me.field # self参照はmeのみ
# ✅ Weak field 構文Phase 285A1.4対応)
public weak parent # 糖衣構文Phase 285A1.4
public { weak parent } # ブロック構文Phase 285A1.3- どちらも同義
```
---
@ -831,12 +846,12 @@ let [first, second, ...rest] = array
方針
- try は非推奨。postfix `catch` と `cleanup` を用いる。
- `catch` は直前の式/呼び出しで発生した例外を処理。
- `cleanup` は常に実行finally の後継)。
- `cleanup` は常に実行finally の後継)。`catch` の有無に関係なく付与できる。
例(式レベルの postfix
```
do_work() catch(Error e) { env.console.log(e) }
open(path) cleanup { env.console.log("close") }
do_work() cleanup { env.console.log("done") }
open(path) catch(Error e) { env.console.log(e) } cleanup { env.console.log("close") }
connect(url)
catch(NetworkError e) { env.console.warn(e) }
cleanup { env.console.log("done") }

View File

@ -18,6 +18,7 @@ Imports and namespaces
Variables and scope
- See: reference/language/variables-and-scope.md — Block-scoped locals, assignment resolution, and strong/weak reference guidance.
- See: reference/language/lifecycle.md — Box lifetime, ownership (strong/weak), and finalization (`fini`) SSOT.
Type system (SSOT)
- See: reference/language/types.md — runtime truthiness, `+`/compare/equality semantics, and the role/limits of MIR type facts.

View File

@ -2,6 +2,8 @@
本書は Nyash 言語の「フィールド可視性」と「デリゲーションfrom/override」の設計をまとめた仕様草案です。実装は段階的に進めます。
注: `init { ... }` は legacy のフィールド宣言slotです。新しい宣言モデルstored/computed/once/birth_once`docs/reference/language/EBNF.md` を参照してください。
## 1. フィールド可視性Blocks
- 構文
```nyash
@ -61,4 +63,3 @@
- BoxRef/Handle 仕様: `docs/reference/plugin-system/boxref-behavior.md`
- nyash.toml v2.1v2.2: `docs/reference/plugin-system/nyash-toml-v2_1-spec.md`
- 実装箇所(予定): `src/parser/declarations/box_definition.rs`, `src/core/model.rs`, `src/interpreter/expressions/access.rs`, `src/mir/*`, `src/backend/vm.rs`

View File

@ -238,6 +238,18 @@ box Node {
}
```
**Legacy syntax** (still supported, Phase 285A1.2):
- `init { weak parent }` — old syntax; superseded by direct `weak parent` declaration
- Both syntaxes behave identically and populate the same weak_fields set
- New code should use `weak field_name` directly for clarity
**Visibility blocks** (Phase 285A1.3):
- `weak` is allowed inside visibility blocks: `public { weak parent }`
**Sugar syntax** (Phase 285A1.4):
- `public weak parent` is equivalent to `public { weak parent }`
- `private weak parent` is equivalent to `private { weak parent }`
## 5) Cycles and GC (language-level policy)
### Cycles

View File

@ -42,6 +42,7 @@ Semicolons and ASI (Automatic Semicolon Insertion)
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 仕様)

View File

@ -23,6 +23,19 @@ Terminology (SSOT):
- **Runtime type**: what the VM executes on (`VMValue`).
- **MIR type facts**: builder annotations (`MirType`, `value_types`, `value_origin_newbox`, `TypeCertainty`).
### Null vs Void (SSOT)
Nyash has two surface literals: `null` and `void`.
SSOT policy:
- `null` is the source-level “none” literal used in APIs like `toIntOrNull()` and optional returns.
- `void` is the “no value” literal (and is also the value produced by expressions/statements that do not yield a value).
- At runtime, both are represented as the same “no value” concept (`Void`). Treat `null` as a syntax-level alias of `void` unless a backend explicitly documents a difference (differences are bugs).
Practical consequence:
- `x == null` and `x == void` are equivalent checks.
- `WeakRef.weak_to_strong()` returns `null` on failure (i.e., `void` / none).
---
## 2. Variables and Re-assignment
@ -49,7 +62,7 @@ Runtime rule (SSOT) is implemented by `to_bool_vm` (`src/backend/abi_util.rs`):
- `Integer``0` is false; non-zero is true
- `Float``0.0` is false; non-zero is true
- `String` → empty string is false; otherwise true
- `Void`**TypeError** (fail-fast)
- `Void` (`null` / `void`)**TypeError** (fail-fast)
- `BoxRef`:
- bridge boxes only:
- `BoolBox` / `IntegerBox` / `StringBox` are unboxed and coerced like their primitive equivalents

View File

@ -4,13 +4,15 @@ Status: Stable (Stage3 surface for `local`), default strong references.
This document defines the variable model used by Hakorune/Nyash and clarifies how locals interact with blocks, memory, and references across VMs (Rust VM, Hakorune VM, LLVM harness).
For the lifecycle/finalization SSOT, see: `docs/reference/language/lifecycle.md`.
## Local Variables
- Syntax: `local name = expr`
- Scope: Blockscoped. The variable is visible from its declaration to the end of the lexical block.
- Redeclaration: Writing `local name = ...` inside a nested block creates a new shadowing binding. Writing `name = ...` without `local` updates the nearest existing binding in an enclosing scope.
- Mutability: Locals are mutable unless future keywords specify otherwise (e.g., `const`).
- Lifetime: The variable binding is dropped at block end; any referenced objects live as long as at least one strong reference exists elsewhere.
- Lifetime: The variable binding is dropped at block end (`}`); object lifetime/finalization is defined separately in `docs/reference/language/lifecycle.md`.
Notes:
- Stage3 gate: Parsing `local` requires Stage3 to be enabled (`NYASH_PARSER_STAGE3=1` or equivalent runner profile).
@ -27,8 +29,8 @@ This matches intuitive blockscoped semantics (Lualike), and differs from P
## Reference Semantics (Strong/Weak)
- Default: Locals hold strong references to boxes/collections. Implementation uses reference counting (strong = ownership) with internal synchronization.
- Weak references: Use `WeakBox` to hold a nonowning (weak) reference. Weak refs do not keep the object alive; they can be upgraded to strong at use sites. Intended for backpointers and cachelike links to avoid cycles.
- Default: Locals hold strong references to boxes/collections.
- Weak references: Use `weak(x)` (and fields that store `WeakRef`) to hold a nonowning reference. Weak refs do not keep the object alive; they can be upgraded at use sites (see SSOT: `docs/reference/language/lifecycle.md`).
- Typical guidance:
- Locals and return values: strong references.
- Object fields that create cycles (child→parent): weak references.

View File

@ -343,14 +343,16 @@ i32 filebox_read(u32 instance_id, i32 size, u8** result, size_t* result_len) {
3. **ライフサイクル保証**
- `birth()` → 各メソッド呼び出し → `fini()` の順序を保証
- `fini()`は必ず呼ばれるGC時またはプログラム終了時
- 循環参照による`fini()`遅延に注意
- `fini()` は論理的終了use-after-fini禁止。自動呼び出しは実行経路/所有形態に依存しうるため、必要な資源fd/socket等は明示 `fini()` / `shutdown_plugins_v2()` で確実に解放する
- 循環参照や共有(複数スコープに跨る参照)では `fini()` タイミングが遅延/未観測になりうるため、weak/singleton/明示finiで設計する
- SSOT: `docs/reference/language/lifecycle.md`
### Nyash側の実装
```rust
impl Drop for PluginBox {
fn drop(&mut self) {
// Boxが破棄される時、必ずfiniを呼ぶ
// 破棄時の best-effort cleanup実行経路/所有形態によりタイミングは変わりうる)。
// 言語仕様としては `fini()` は明示的に呼ぶ/`shutdown_plugins_v2()` で閉じるのが推奨。
let result = self.plugin.invoke(
self.handle.type_id,
FINI_METHOD_ID, // 最大値のmethod_id
@ -434,4 +436,4 @@ HTTPServerBox = "http-plugin" # SocketBoxが使えない
- [BID-FFI仕様](./ffi-abi-specification.md)
- [Everything is Box哲学](./everything-is-box.md)
- [実装タスク](../../../予定/native-plan/issues/phase_9_75g_0_chatgpt_enhanced_final.md)
- [実装タスク](../../../予定/native-plan/issues/phase_9_75g_0_chatgpt_enhanced_final.md)

View File

@ -6,13 +6,14 @@
NyashのBoxには「ユーザー定義Box」「ビルトインBox」「プラグインBox」があります。いずれもRAII取得した資源は所有者の寿命で解放に従いますが、プラグインBoxは共有やシングルトン運用があるため、追加ルールがあります。
## 共通ライフサイクル(ユーザー/ビルトイン/プラグイン)
- インスタンスの寿命が尽きると、強参照フィールドpublic/privateに対し順に `fini()` が呼ばれ解放weak はスキップ)
- `local` 変数のスコープを抜けると、そのスコープで生成されたインスタンスは解放対象
- 明示的に `fini()` が呼ばれた場合も同様に後処理を実施
- `fini()` は論理的な終了use-after-fini禁止であり、外部資源fd/socket/native handle など)を決定的に解放するための SSOT です。
- `local` のスコープを抜けると、その binding は drop されます(= その binding が保持していた strong 参照が 1 つ減る)。
- その時点で「最後の strong 参照」になれば物理的な解放が起きますが、タイミングは実装依存です。
- 共有・循環参照がありうるため、スコープ終了“だけ”に `fini()` を期待しないでください。必要な資源は `fini()` / `cleanup` / `shutdown_plugins_v2()` で明示的に閉じます。
補足:
- これらは Nyash のスコープトラッカにより実施されます
- 解放順は生成の逆順LIFOで、カスケード `fini` を保証します
- 言語レベルの SSOT は `docs/reference/language/lifecycle.md` を参照してください(スコープ/所有/weak/`fini`/GC
- `fini()` の中で「strong-owned フィールドを順に `fini()`」するカスケード設計は有用ですが、最終的な順序や禁止事項は SSOT に従います
## プラグインBoxの特則シングルトン
- シングルトン(`nyash.toml`
@ -21,8 +22,8 @@ NyashのBoxには「ユーザー定義Box」「ビルトインBox」「プラグ
- シャットダウン時(`shutdown_plugins_v2()` など)に一括 `fini()` されます
補足:
- Nyashは参照カウントを採用しません。解放は「スコープ終了」または「明示的`fini`」のみで決まります(自己責任モデル)
- プラグインBoxも同じルールです。スコープ終了時に`fini`され、以後の利用はエラーUse after fini
- Nyashの実装は Box 値を参照(共有)として扱います。物理的な生存は strong 参照の有無に依存しうる一方、`fini()` は論理的な終了use-after-fini禁止です
- プラグインBoxも同じルールです。`fini` 後の利用はエラーUse after fini
- 長寿命が必要なケースは「シングルトン」で運用してください個別のBoxに特例は設けない
### 例: `nyash.toml` 抜粋

View File

@ -89,20 +89,21 @@ fn test_weak_reference_mir_stability() {
let source = r#"
box Parent { init { child_weak } }
box Child { init { data } }
static box Main {
main() {
local parent = new Parent()
local child = new Child(42)
parent.child_weak = weak(child)
if parent.child_weak.isAlive() {
print(parent.child_weak.get().data)
local c = parent.child_weak.weak_to_strong()
if c != null {
print(c.data)
}
}
}
"#;
verify_mir_golden("weak_reference", source);
}
```
@ -404,4 +405,4 @@ fi
*最終更新: 2025-08-14 - ChatGPT5推奨3点セット完成*
*Golden Dump Testing = Nyash品質保証の技術的基盤*
*Golden Dump Testing = Nyash品質保証の技術的基盤*