runner: split modes (mir/vm/llvm/bench) and extract plugin init; interpreter: split objects into ops/methods/fields; VM logs gated; Phi selection minimal fix; CURRENT_TASK updated; remove legacy backups

This commit is contained in:
Moe Charm
2025-08-26 04:34:14 +09:00
parent 11c149ac2b
commit 1e735d7717
69 changed files with 1023 additions and 992009 deletions

29
.gitignore vendored
View File

@ -48,6 +48,35 @@ nyash-rust/
# Test files # Test files
*.tmp *.tmp
# 🚨 ルートディレクトリ汚染防止(毎回散らかる問題対策)
# デバッグ・テスト関連ファイル
/test_*.txt
/test_*.log
/build_*.txt
/mir_*.txt
/mir_*.log
/vm_*.log
/vm_*.json
/cmp_*.log
/out.txt
/err.txt
/test.txt
/*_output.txt
/*_errors.txt
/*_error.txt
# 一時的なテストファイル(ルートに置かない!)
/test_*.nyash
# HTTP/ネットワークテストログ
/http_test*.log
/http_test*.txt
# 分析・コンサルテーション結果
/*_consultation.txt
/*_analysis.txt
/nekocode_*.txt
*.bak *.bak
*.orig *.orig
test_*.ny test_*.ny

View File

@ -500,10 +500,29 @@ Related-Code: src/backend/vm_instructions.rs::execute_binop()
### 🧪 テスト実行 ### 🧪 テスト実行
#### 📁 **テストファイル配置ルール(重要!)** #### 📁 **テストファイル配置ルール(重要!毎回ルートが散らかる問題**
- **local_testsフォルダを使用**: 一時的なテストファイルは`local_tests/`に配置
- **ルートディレクトリには置かない**: プロジェクトルートが散らからないように ⚠️ **ルートディレクトリの汚染防止ルール** ⚠️
- **実行例**: `./target/debug/nyash local_tests/test_example.nyash` ```bash
# ❌ 絶対ダメ:ルートで実行
./target/release/nyash test.nyash # ログがルートに散乱!
cargo test > test_output.txt # 出力ファイルがルートに!
# ✅ 正しい方法:必ずディレクトリを使う
cd local_tests && ../target/release/nyash test.nyash
./target/release/nyash local_tests/test.nyash
```
**必須ルール:**
- **テストファイル**: 必ず `local_tests/` に配置
- **ログファイル**: 環境変数で `logs/` に出力するか、実行後即削除
- **デバッグ出力**: `local_tests/` または `logs/` に保存
- **一時ファイル**: `/tmp/` を使用
**なぜ毎回ルートが散らかるのか:**
1. テスト実行時にカレントディレクトリにログ出力
2. エラー時のデバッグファイルが自動削除されない
3. VM統計やMIRダンプがデフォルトでカレントに出力
```bash ```bash
# 基本機能テスト # 基本機能テスト
@ -514,8 +533,8 @@ mkdir -p local_tests
echo 'print("Hello Nyash!")' > local_tests/test_hello.nyash echo 'print("Hello Nyash!")' > local_tests/test_hello.nyash
./target/debug/nyash local_tests/test_hello.nyash ./target/debug/nyash local_tests/test_hello.nyash
# 演算子統合テスト # 演算子統合テストlocal_testsから実行
./target/debug/nyash test_comprehensive_operators.nyash ./target/debug/nyash local_tests/test_comprehensive_operators.nyash
# 実用アプリテスト # 実用アプリテスト
./target/debug/nyash app_dice_rpg.nyash ./target/debug/nyash app_dice_rpg.nyash

View File

File diff suppressed because it is too large Load Diff

View File

@ -1,24 +0,0 @@
ChatGPT5<EFBFBD><EFBFBD>k<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɨ<EFBFBD><EFBFBD>:
1. [E0599] no method named `call_fini` found for reference `&enabled::PluginBoxV2`
4@: src/scope_tracker.rs:45:28
<20><><EFBFBD>: plugin.call_fini() - <20><><EFBFBD><EFBFBD>LX(WjD
2. [E0308] mismatched types (2<>@)
4@: src/interpreter/core.rs:579:45, 618:45
<20><><EFBFBD>: &**v - expected `&Box<dyn NyashBox>`, found `&dyn NyashBox`
3. [E0615] attempted to take value of method `instance_id` (3<>@)
4@:
- src/interpreter/expressions/calls.rs:695:98
- src/interpreter/expressions/calls.rs:785:98
- src/backend/vm.rs:567:90
<20><><EFBFBD>: plugin.instance_id - <20><><EFBFBD>ɒգ<C992><D5A3><EFBFBD>hWf(
<20>cH: plugin.instance_id() k <09>
4. [E0609] no field `invoke_fn` on type `&enabled::PluginBoxV2`
4@: src/runtime/plugin_loader_v2.rs:139:19
<20><><EFBFBD>: self.invoke_fn - X(WjDգ<44><D5A3><EFBFBD>
<20>cH: self.inner.invoke_fn
: 7 n<><6E>Ѥ<EFBFBD><D1A4><EFBFBD><EFBFBD>

View File

@ -1,21 +0,0 @@
ChatGPT5実装による更新後のビルドエラー:
改善された点(修正済み):
- ✅ call_fini() メソッドエラー解決
- ✅ instance_id フィールド/メソッドエラー解決
- ✅ invoke_fn フィールドエラー解決
残存エラー2個:
1. [E0308] mismatched types - src/interpreter/core.rs:579:45
エラー: &**v - expected `&Box<dyn NyashBox>`, found `&dyn NyashBox`
2. [E0308] mismatched types - src/interpreter/core.rs:618:45
エラー: &**v - expected `&Box<dyn NyashBox>`, found `&dyn NyashBox`
推奨修正:
- &**v を v に変更Arc<dyn NyashBox>への参照として扱う)
- または型注釈を &dyn NyashBox に変更
影響範囲:
- interpreter/core.rsのみ他のモジュールのエラーは解決済み

View File

@ -1,53 +0,0 @@
src/interpreter/core.rs:33:14: warning: unused macro definition: `debug_trace`
src/mir/loop_builder.rs:9:21: warning: unused imports: `BasicBlockIdGenerator`, `BasicBlock`, `CompareOp`, `EffectMask`, `MirFunction`, and `ValueIdGenerator`
src/mir/loop_builder.rs:13:33: warning: unused import: `HashSet`
src/backend/mod.rs:13:7: warning: unexpected `cfg` condition value: `llvm`
src/backend/mod.rs:23:7: warning: unexpected `cfg` condition value: `llvm`
src/backend/vm_phi.rs:9:41: warning: unused import: `MirInstruction`
src/bid/types.rs:1:5: warning: unused import: `super::Usize`
src/bid/plugin_api.rs:2:5: warning: unused import: `std::os::raw::c_char`
src/bid/plugins/filebox/mod.rs:7:18: warning: unused imports: `NyashHostVtable`, `NyashMethodInfo`, and `NyashPluginInfo`
src/bid/plugins/filebox/mod.rs:10:28: warning: unused imports: `SeekFrom` and `Seek`
src/bid/plugins/filebox/mod.rs:11:20: warning: unused imports: `c_char` and `c_void`
src/bid/plugins/filebox/mod.rs:13:16: warning: unused imports: `CStr` and `CString`
src/bid/loader.rs:4:5: warning: unused import: `std::ffi::c_void`
src/bid/generic_plugin_box.rs:5:23: warning: unused imports: `TlvDecoder` and `TlvEncoder`
src/bid/generic_plugin_box.rs:6:5: warning: unused import: `crate::bid::types::BidTag`
src/runtime/plugin_loader_v2.rs:10:47: warning: unused import: `BoxBase`
src/runtime/plugin_loader_v2.rs:14:9: warning: unused import: `std::ffi::c_void`
src/box_factory/plugin.rs:53:13: warning: unused variable: `registry`: help: if this is intentional, prefix it with an underscore: `_registry`
src/interpreter/expressions/calls.rs:739:13: warning: variable does not need to be mutable
src/interpreter/objects.rs:1106:17: warning: variable does not need to be mutable
src/instance_v2.rs:147:28: warning: unused variable: `args`: help: if this is intentional, prefix it with an underscore: `_args`
src/instance_v2.rs:289:21: warning: unused variable: `nyash_value`: help: if this is intentional, prefix it with an underscore: `_nyash_value`
src/mir/loop_builder.rs:246:39: warning: unused variable: `block_id`: help: if this is intentional, prefix it with an underscore: `_block_id`
src/mir/loop_builder.rs:273:49: warning: unused variable: `block_id`: help: if this is intentional, prefix it with an underscore: `_block_id`
src/backend/vm_phi.rs:48:9: warning: unused variable: `dst`: help: if this is intentional, prefix it with an underscore: `_dst`
src/bid/plugin_api.rs:167:36: warning: unused variable: `f`: help: if this is intentional, prefix it with an underscore: `_f`
src/bid/plugin_api.rs:167:26: warning: variable does not need to be mutable
src/bid/plugin_api.rs:176:35: warning: unused variable: `f`: help: if this is intentional, prefix it with an underscore: `_f`
src/bid/plugin_api.rs:176:25: warning: variable does not need to be mutable
src/bid/plugin_api.rs:183:34: warning: unused variable: `f`: help: if this is intentional, prefix it with an underscore: `_f`
src/bid/plugin_api.rs:183:24: warning: variable does not need to be mutable
src/runtime/plugin_loader_v2.rs:270:46: warning: unused variable: `args`: help: if this is intentional, prefix it with an underscore: `_args`
src/bid/plugins/filebox/mod.rs:44:5: warning: type `FileMode` is more private than the item `FileBoxRegistry::open`: method `FileBoxRegistry::open` is reachable at visibility `pub`
src/mir/loop_builder.rs:35:5: warning: field `block_var_maps` is never read
src/bid/metadata.rs:148:5: warning: fields `type_name_holder` and `method_holders` are never read
src/bid/plugins/filebox/mod.rs:24:5: warning: fields `path` and `mode` are never read
src/runtime/plugin_loader_v2.rs:24:5: warning: fields `box_types` and `init_fn` are never read
src/mir/loop_builder.rs:62:9: warning: unused `Result` that must be used
src/mir/loop_builder.rs:66:9: warning: unused `Result` that must be used
src/mir/loop_builder.rs:78:9: warning: unused `Result` that must be used
src/mir/loop_builder.rs:79:9: warning: unused `Result` that must be used
src/mir/loop_builder.rs:93:9: warning: unused `Result` that must be used
src/bid/plugins/filebox/mod.rs:102:12: warning: creating a shared reference to mutable static: shared reference to mutable static
src/bid/plugins/filebox/mod.rs:105:9: warning: creating a shared reference to mutable static: shared reference to mutable static
warning: `nyash-rust` (lib) generated 44 warnings (run `cargo fix --lib -p nyash-rust` to apply 19 suggestions)
Checking nyash-rust v0.1.0 (/mnt/c/git/nyash-project/nyash)
src/backend/vm.rs:18:12: error[E0432]: unresolved import `crate::scope_tracker`: unresolved import, help: a similar path exists: `nyash_rust::scope_tracker`
src/runner.rs:22:7: warning: unexpected `cfg` condition value: `llvm`
src/runner.rs:503:15: warning: unexpected `cfg` condition value: `llvm`
src/runner.rs:526:19: warning: unexpected `cfg` condition value: `llvm`
src/runner.rs:286:17: warning: variable does not need to be mutable
warning: `nyash-rust` (bin "nyash") generated 36 warnings (32 duplicates)
error: could not compile `nyash-rust` (bin "nyash") due to 1 previous error; 36 warnings emitted

View File

@ -7,9 +7,14 @@
### 直近の実行タスク9.78h ### 直近の実行タスク9.78h
1) 一時デバッグログの抑制(`NYASH_VM_DEBUG_*`のみ) 1) 一時デバッグログの抑制(`NYASH_VM_DEBUG_*`のみ)
- 進捗: Runnerのバナー/プラグイン初期化ログは `NYASH_CLI_VERBOSE`/`NYASH_DEBUG_PLUGIN` のみで出力。
VMの逐次ログは `NYASH_VM_DEBUG[_EXEC|_CMP|_ANDOR|_PHI]` に限定。
2) Phi正規化LoopExecutorの借用衝突解消 → 正しい選択へ復帰) 2) Phi正規化LoopExecutorの借用衝突解消 → 正しい選択へ復帰)
- 進捗: VM側の選択を `previous_block` 基準に復帰fallback: 先頭)。`NYASH_VM_DEBUG_PHI=1` でログ。
- 設計: docs/development/current/PHI_NORMALIZATION_PLAN.md を参照(段階プラン/次アクション)。
3) 基本ボックス統一StringBox/BoolBoxもre-export化 3) 基本ボックス統一StringBox/BoolBoxもre-export化
4) VM分割の導線control_flow/dispatch/frameへ分離設計 4) VM分割の導線control_flow/dispatch/frameへ分離設計
- 進捗: `src/backend/{control_flow.rs,dispatch.rs,frame.rs}` を追加(骨組み)。ビルド通過。
5) 代表スナップショット追加compare/loop/typeop_mixed 5) 代表スナップショット追加compare/loop/typeop_mixed
### すぐ試せるコマンド ### すぐ試せるコマンド
@ -74,7 +79,15 @@ nyash --backend vm local_tests/and_or_truthy_vm.nyash # 期待: false,true,fals
- 対応中: 比較前に i64 へ正規化するフォールバックをVMに実装downcast→toString→parse - 対応中: 比較前に i64 へ正規化するフォールバックをVMに実装downcast→toString→parse
- 80/20ポリシー: 数値にパース可能なら比較継続、失敗時のみTypeError。 - 80/20ポリシー: 数値にパース可能なら比較継続、失敗時のみTypeError。
### 🎯 次の優先タスク ### 🆕 進捗2025-08-26 午前)
- TypeError`And/Or` 経路再発なしを確認3スモーク緑: compare/and_or/and_or_truthy
- ログ抑制の徹底: Runner/VMのデバッグ出力を既定で静音、環境変数でのみ有効化。
- Phi正規化 Step1: `previous_block` によるPhi入力選択をVMに実装`NYASH_VM_DEBUG_PHI=1`)。
- VM分割の骨組み: `control_flow.rs`/`dispatch.rs`/`frame.rs` 追加(今後段階移動)。
- レガシー削除: `src/mir/builder_old.rs`, `src/mir/builder.rs.backup`, `src/parser.rs.backup`, `src/instance.rs.backup`, `src/box_trait.rs.backup` を削除。
- objects.rs 分解 Step1: `execute_new` をヘルパ(三分割)へ抽出しスリム化(等価挙動)。
### 🎯 次の優先タスク(更新)
1. **copilot_issues.txtの確認** 1. **copilot_issues.txtの確認**
- Phase 8.4: AST→MIR Lowering完全実装最優先 - Phase 8.4: AST→MIR Lowering完全実装最優先
@ -87,6 +100,16 @@ nyash --backend vm local_tests/and_or_truthy_vm.nyash # 期待: false,true,fals
- 代替経路の洗い出し: `src/` 全体で `execute_binop`/`And`/`Unsupported binary operation` を再走査し、影響箇所を一掃。 - 代替経路の洗い出し: `src/` 全体で `execute_binop`/`And`/`Unsupported binary operation` を再走査し、影響箇所を一掃。
- 修正後、`local_tests/and_or_vm.nyash``false/true` の出力を確認。 - 修正後、`local_tests/and_or_vm.nyash``false/true` の出力を確認。
- ルート確定: Compare経路はBuilder側のCast導線で安定。VM側は保険フォールバックを維持しつつ一時ログを抑制へ。 - ルート確定: Compare経路はBuilder側のCast導線で安定。VM側は保険フォールバックを維持しつつ一時ログを抑制へ。
1.6 **objects.rs 分解 Step2安全にファイル分割**
- `objects_impl.rs` を導入し、抽出済みヘルパを移動。本体は薄いラッパに。
- 以降: `objects/{fields.rs,methods.rs,ops.rs}` への段階分解。
1.7 **runner.rs 分離**
- `init_bid_plugins``runner/plugin_init.rs` へ抽出。各モードを `runner/modes/*.rs` に。
1.8 **VM分割の段階移動**
- ブロック遷移を `control_flow.rs`、フレーム状態を `frame.rs` に移し、`dispatch.rs` の導線を準備。
2. **MIR26命令対応** 2. **MIR26命令対応**
- TypeOp/WeakRef/Barrierのプリンタ拡張 - TypeOp/WeakRef/Barrierのプリンタ拡張
- スナップショット整備extern_call/loop/boxcall/typeop_mixed 追加済) - スナップショット整備extern_call/loop/boxcall/typeop_mixed 追加済)

View File

@ -0,0 +1,26 @@
# Phi 正規化プラン9.78h スキャフォールド)
目的: ループ/分岐における Phi 選択を正道に戻し、借用衝突を避けつつ段階導入する。
段階プラン80/20
- Step 1: 実行系での選択復帰(完了)
- `previous_block` に基づき `inputs[(bb==prev)]` を選択。見つからない場合は先頭をフォールバック。
- デバッグ: `NYASH_VM_DEBUG_PHI=1` で選択ログ。
- Step 2: LoopExecutor 連携
- `VM::loop_execute_phi``LoopExecutor::execute_phi` に委譲(安全な借用構成に整理)。
- `record_transition(from,to)` をもとにヘッダ検出・イテレーション情報を活用。
- Step 3: 正規 SSA への復帰
- Builder 側で phi 挿入・seal・predecessor 更新を正道で実装。
- Verifier に phi 一貫性(定義支配/マージ使用)チェックを追加・厳格化。
- Step 4: ログ削減とテスト
- 代表ケースloop/if-merge/whileをスナップショット化。
- 既定で静音、`NYASH_VM_DEBUG_PHI` のみで詳細。
実装状況2025-08-26
- Step 1 完了: `VM::loop_execute_phi``previous_block` による選択に対応。
- 既知の課題: LoopExecutor 経由の借用安全な委譲Step 2
次アクション
- VM 内部の phi 実行を LoopExecutor へ委譲できるよう API を見直し(`get_value` クロージャの借用境界を調整)。
- Builder 側の phi 正規化 TODO を CURRENT_TASK に追記。

View File

@ -0,0 +1,92 @@
# VM比較処理のリファクタリング
Status: Pending (80%実装済み)
Created: 2025-08-25
Priority: Medium
Related-Code: src/backend/vm_instructions.rs::execute_compare(), src/backend/vm_values.rs::execute_compare_op()
## 現状80%実装)
- BoxRef比較のTypeErrorは解決済み
- 正規化処理が2箇所に分散execute_compare, execute_compare_op
- デバッグログが複数の環境変数に依存
- 基本動作は完全に正常
## 問題点
1. **重複した正規化ロジック**
- vm_instructions.rs: BoxRef → Integer変換
- vm_values.rs: 同様の変換処理
2. **デバッグの複雑さ**
- NYASH_VM_DEBUG
- NYASH_VM_DEBUG_CMP
- 複数箇所でのログ出力
3. **エラーパスの複雑さ**
- "[BoxRef-BoxRef]", "[BoxRef-Integer]", "[Integer-BoxRef]", "[Default]"
- どこでエラーが出るか予測困難
## 改善案残り20%
### 1. 正規化を単一関数に統一
```rust
fn canonicalize_for_comparison(value: VMValue) -> VMValue {
match value {
VMValue::BoxRef(b) => {
// IntegerBox → Integer
if let Some(ib) = b.as_any().downcast_ref::<IntegerBox>() {
return VMValue::Integer(ib.value);
}
// String parse fallback
if let Ok(n) = b.to_string_box().value.trim().parse::<i64>() {
return VMValue::Integer(n);
}
VMValue::BoxRef(b)
}
other => other,
}
}
```
### 2. 比較処理の階層化
```rust
impl VM {
// エントリーポイント
pub fn execute_compare(...) {
let left = self.canonicalize_value(lhs)?;
let right = self.canonicalize_value(rhs)?;
let result = self.compare_canonical(op, &left, &right)?;
self.set_value(dst, VMValue::Bool(result));
}
// 正規化
fn canonicalize_value(&self, id: ValueId) -> Result<VMValue, VMError> {
let raw = self.get_value(id)?;
Ok(canonicalize_for_comparison(raw))
}
// 比較実行
fn compare_canonical(&self, op: &CompareOp, left: &VMValue, right: &VMValue) -> Result<bool, VMError> {
// シンプルな比較ロジックのみ
}
}
```
### 3. デバッグトレースの統一
```rust
struct ComparisonTrace {
original_left: VMValue,
original_right: VMValue,
canonical_left: VMValue,
canonical_right: VMValue,
result: Result<bool, VMError>,
}
```
## 実装タイミング
- [ ] 次の大きなバグが出たとき
- [ ] Phase 10の最適化フェーズ
- [ ] 新しい比較演算子追加時
## メリット
- デバッグが容易になる
- 新しい型の比較追加が簡単
- テストが書きやすくなる

View File

@ -1,19 +0,0 @@
FileBox Plugin E2E Test Results:
Build Status:
- Main build: ✅ Success
- Plugin build: ✅ Success (with 3 warnings)
Test Results:
- e2e_interpreter_plugin_filebox_close_void: ✅ PASSED
- e2e_vm_plugin_filebox_close_void: ✅ PASSED
- e2e_interpreter_plugin_filebox_delegation: ❌ FAILED
Failure Details:
❌ Interpreter error: Invalid operation: birth() method not yet implemented for builtin box 'FileBox'
The error occurs when trying to create a LoggingFileBox that delegates from FileBox.
The test expects to use birth() constructor but FileBox (as a plugin) doesn't implement it yet.
This suggests the plugin system is working correctly (FileBox is recognized), but the
birth() constructor delegation for plugin boxes needs implementation.

View File

@ -1,31 +0,0 @@
NEW ERROR AFTER FIX:
running 2 tests
test e2e_create_echo_box_and_return_string ... FAILED
test e2e_create_adder_box_and_return_sum ... FAILED
failures:
---- e2e_create_echo_box_and_return_string stdout ----
❌ Interpreter error: Return outside of function
thread 'e2e_create_echo_box_and_return_string' panicked at tests/e2e_plugin_echo.rs:102:33:
exec ok: ReturnOutsideFunction
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
---- e2e_create_adder_box_and_return_sum stdout ----
❌ Interpreter error: Return outside of function
thread 'e2e_create_adder_box_and_return_sum' panicked at tests/e2e_plugin_echo.rs:114:33:
exec ok: ReturnOutsideFunction
failures:
e2e_create_adder_box_and_return_sum
e2e_create_echo_box_and_return_string
test result: FAILED. 0 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.08s
PROGRESS: The Box types (EchoBox, AdderBox) are now recognized!
The error changed from "Unknown Box type" to "Return outside of function".
This suggests the unified registry is working correctly after ChatGPT5's fix.

16
err.txt
View File

@ -1,16 +0,0 @@
🔍 DEBUG: Initializing v2 plugin system
[PluginLoaderV2] nyash_plugin_init rc=0 for libnyash_counter_plugin.so
Net plugin: LOG_ON=false, LOG_PATH=net_plugin.log
[PluginLoaderV2] nyash_plugin_init rc=0 for libnyash_net_plugin.so
[FileBox] Plugin initialized
[PluginLoaderV2] nyash_plugin_init rc=0 for libnyash_filebox_plugin.so
📦 Registering plugin provider for CounterBox
📦 Registering plugin provider for HttpServerBox
📦 Registering plugin provider for HttpClientBox
📦 Registering plugin provider for HttpResponseBox
📦 Registering plugin provider for HttpRequestBox
📦 Registering plugin provider for SocketServerBox
📦 Registering plugin provider for SocketClientBox
📦 Registering plugin provider for SocketConnBox
📦 Registering plugin provider for FileBox
❌ VM execution error: Type error: Unsupported comparison: Lt on BoxRef(IntegerBox { value: 0, base: BoxBase { id: 3, parent_type_id: None } }) and BoxRef(IntegerBox { value: 3, base: BoxBase { id: 7, parent_type_id: None } })

View File

@ -1 +0,0 @@
hello nyash

File diff suppressed because it is too large Load Diff

View File

@ -1,118 +0,0 @@
Gemini先生の部分的な回答レート制限で途中まで
Nyashの統一Box設計について、専門的な観点から分析と提案をさせていただきます。
## 設計の評価
### 美しい点
1. **「Everything is Box」の一貫性**: この哲学は Smalltalk の「Everything is an Object」に通じる美しさがあります。概念的な統一感は言語の学習曲線を緩やかにし、予測可能性を高めます。
2. **透過的な置き換え機構**: プラグインによるビルトインBoxの置き換えは、Rubyの `refinements` や Python の `__import__` フックを彷彿とさせます。テスタビリティと拡張性の観点から優れています。
3. **優先順位システム**: 明確な優先順位(ビルトイン > ユーザー定義 > プラグイン)は、名前解決の曖昧さを排除し、デバッグを容易にします。
### 改善の余地がある点
1. **パフォーマンスのオーバーヘッド**: すべてを `Box<dyn NyashBox>` でラップすることは、小さな値整数、真偽値などにとって大きなオーバーヘッドです。Rust の `enum` を活用した値の内部表現最適化を検討すべきです。
2. **型の曖昧さ**: `Option<Box<dyn NyashBox>>` のような入れ子構造は、実行時の型チェックを複雑にします。静的型付けの利点を活かしきれていません。
## 改善提案
### 1. Enum ベースの値表現
現在の `Box<dyn NyashBox>` 一辺倒から、以下のような enum ベースの表現への移行を提案します:
```rust
pub enum NyashValue {
// 即値(スタック上)
Void,
Bool(bool),
Integer(i64),
Float(f64),
// ヒープ上の不変値
String(Arc<String>),
// 複雑なオブジェクト
Object(Arc<NyashObject>),
}
```
**メリット**:
- 小さな値のヒープアロケーションを回避
- パターンマッチによる高速なディスパッチ
- 型安全性の向上
### 2. トレイトの階層化
基本メソッドの統一案は良いですが、さらに階層化することで柔軟性を高められます:
```rust
// 基本トレイトすべてのBoxが実装
pub trait NyashBox: Send + Sync + Debug {
fn to_string(&self) -> String;
fn type_name(&self) -> &'static str;
fn equals(&self, other: &dyn NyashBox) -> bool;
}
// 拡張トレイト(必要に応じて実装)
pub trait Comparable: NyashBox {
fn compare(&self, other: &dyn NyashBox) -> Option<Ordering>;
}
pub trait Arithmetic: NyashBox {
fn add(&self, other: &dyn NyashBox) -> Result<Box<dyn NyashBox>, String>;
// ...
}
```
### 3. メタプログラミング機能
ユーザー定義Boxの完全統一のために、メタプログラミング機能を提供
```rust
// Box定義時のフック
pub trait BoxMetadata {
fn on_method_missing(&self, name: &str, args: &[NyashValue]) -> Option<NyashValue>;
fn on_field_access(&self, name: &str) -> Option<NyashValue>;
}
```
### 4. パイプライン演算子の実装
パイプライン演算子は、メソッドチェーンの代替として優れています:
```nyash
// 現在
result = str.substring(0, 5).toUpperCase().trim()
// パイプライン版
result = str
|> substring(0, 5)
|> toUpperCase()
|> trim()
```
実装は、単純な構文糖として扱えます。
## 他言語との比較
**Smalltalk**: 最も近い哲学を持ちますが、Nyashの方が実用的ファイルI/O、ネットワーク等を最初から考慮
**Ruby**: オープンクラスの柔軟性はありませんが、その分予測可能性が高い
**Python**: `__getattr__` のような動的フックより、明示的なメソッド定義の方が保守しやすい
## 総合的な推奨事項
1. **段階的な移行**: 現在の設計を一度に変更するのではなく、まず `NyashValue` enum を導入し、徐々に最適化
2. **プロファイリング駆動**: パフォーマンスの問題が実際に発生している箇所から最適化
3. **ドキュメント駆動開発**: 各Boxの振る舞いを明確に文書化し、それに基づいて実装
4. **テストの充実**: 特に異なる種類のBox間の相互作用をテスト
この設計は十分に美しく、実用的です。過度に複雑というより、むしろ適切な抽象化レベルだと評価します。

View File

@ -1,2 +1,5 @@
// Simple return test static box Main {
main() {
return 42 return 42
}
}

View File

@ -1,9 +1,19 @@
# Simple test without external calls // 簡単なNyashテストプログラム
static box Main { print("🎉 Nyash is working!")
init { result } print("Everything is Box!")
main() { // 基本的な演算
me.result = "Simple test" local a = 10
return me.result local b = 20
} local result = a + b
} print("10 + 20 = " + result.toString())
// StringBox
local greeting = "Hello, Nyash!"
print(greeting)
// ArrayBox
local arr = new ArrayBox()
arr.push("First")
arr.push("Second")
print("Array length: " + arr.length().toString())

View File

@ -1,42 +0,0 @@
🔌 v2 plugin system initialized from nyash.toml
✅ v2 plugin system fully configured
🚀 Nyash MIR Compiler - Processing file: local_tests/test_http_error_simple.nyash 🚀
🚀 MIR Output for local_tests/test_http_error_simple.nyash:
; MIR Module: main
define void @main() {
bb0:
0: safepoint
1: %0 = const void
2: %1 = const void
3: %2 = const void
4: %3 = const void
5: %4 = new HttpClientBox()
6: call %4.birth()
7: %5 = const "http://127.0.0.1:8099/nope"
8: %6 = new StringBox(%5)
9: call %6.birth(%5)
10: %7 = const "http://127.0.0.1:8099/nope"
11: %8 = new StringBox(%7)
12: call %8.birth(%7)
13: %9 = call %4.get(%8)
14: %10 = call %9.isOk()
15: br %10, label bb1, label bb2
bb1:
0: %11 = const "unexpected_ok"
1: %12 = new StringBox(%11)
2: call %12.birth(%11)
3: br label bb3
bb2:
0: %13 = call %9.getError()
1: %14 = call %13.toString()
2: br label bb3
bb3:
0: %15 = phi [%12, bb1], [%14, bb2]
1: ret %15
}

View File

@ -1,42 +0,0 @@
🔌 v2 plugin system initialized from nyash.toml
✅ v2 plugin system fully configured
🚀 Nyash MIR Compiler - Processing file: local_tests/test_http_error_simple.nyash 🚀
🚀 MIR Output for local_tests/test_http_error_simple.nyash:
; MIR Module: main
define void @main() {
bb0:
0: safepoint
1: %0 = const void
2: %1 = const void
3: %2 = const void
4: %3 = const void
5: %4 = new HttpClientBox()
6: call %4.birth()
7: %5 = const "http://127.0.0.1:8099/nope"
8: %6 = new StringBox(%5)
9: call %6.birth(%5)
10: %7 = const "http://127.0.0.1:8099/nope"
11: %8 = new StringBox(%7)
12: call %8.birth(%7)
13: %9 = call %4.get(%8)
14: %10 = call %9.isOk()
15: br %10, label bb1, label bb2
bb1:
0: %11 = const "unexpected_ok"
1: %12 = new StringBox(%11)
2: call %12.birth(%11)
3: br label bb3
bb2:
0: %13 = call %9.getError()
1: %14 = call %13.toString()
2: br label bb3
bb3:
0: %15 = phi [%12, bb1], [%14, bb2]
1: ret %14
}

View File

@ -1,42 +0,0 @@
🔌 v2 plugin system initialized from nyash.toml
✅ v2 plugin system fully configured
🚀 Nyash MIR Compiler - Processing file: local_tests/test_http_error_simple.nyash 🚀
🚀 MIR Output for local_tests/test_http_error_simple.nyash:
; MIR Module: main
define void @main() {
bb0:
0: safepoint
1: %0 = const void
2: %1 = const void
3: %2 = const void
4: %3 = const void
5: %4 = new HttpClientBox()
6: call %4.birth()
7: %5 = const "http://127.0.0.1:8099/nope"
8: %6 = new StringBox(%5)
9: call %6.birth(%5)
10: %7 = const "http://127.0.0.1:8099/nope"
11: %8 = new StringBox(%7)
12: call %8.birth(%7)
13: %9 = call %4.get(%8)
14: %10 = call %9.isOk()
15: br %10, label bb1, label bb2
bb1:
0: %11 = const "unexpected_ok"
1: %12 = new StringBox(%11)
2: call %12.birth(%11)
3: br label bb3
bb2:
0: %13 = call %9.getError()
1: %14 = call %13.toString()
2: br label bb3
bb3:
0: %15 = phi [%12, bb1], [%14, bb2]
1: ret %14
}

File diff suppressed because it is too large Load Diff

View File

@ -1,96 +0,0 @@
Nyashプログラミング言語の統一Box設計について相談
【背景】
Nyashは「Everything is Box」哲学を持つプログラミング言語です。現在、以下の3種類のBoxが存在します
1. ビルトインBoxStringBox, IntegerBox等- Rustで実装
2. プラグインBoxFileBox等- 動的ライブラリで提供
3. ユーザー定義Boxbox Person等- Nyashコードで定義
【現在の統一アーキテクチャ】
```
UnifiedBoxRegistry統一レジストリ
├── BuiltinBoxFactory優先度1
├── UserDefinedBoxFactory優先度2
└── PluginBoxFactory優先度3
```
BoxFactoryトレイト
```rust
pub trait BoxFactory: Send + Sync {
fn create_box(&self, name: &str, args: &[Box<dyn NyashBox>]) -> Result<Box<dyn NyashBox>, RuntimeError>;
fn box_types(&self) -> Vec<&str>;
fn supports_birth(&self) -> bool;
}
```
【統一の美しさ】
1. 透過的な置き換え - 同じ名前のBoxをプラグインで上書き可能
2. 統一インターフェース - すべてのBoxが同じAPIを持つ
3. 優先順位システム - ビルトイン > ユーザー定義 > プラグイン
【InstanceBoxによる統一実装】
```rust
pub struct InstanceBox {
pub class_name: String, // "StringBox", "Person"等
pub inner_content: Option<Box<dyn NyashBox>>, // 内包Box統一
pub fields_ng: Arc<Mutex<HashMap<String, NyashValue>>>,
pub methods: Arc<HashMap<String, ASTNode>>,
}
// 3つの形態を統一
InstanceBox::from_any_box("StringBox", Box::new(StringBox::new("hello"))) // ビルトイン
InstanceBox::from_any_box("FileBox", plugin_box) // プラグイン
InstanceBox::from_declaration("Person", fields, methods) // ユーザー定義
```
【検討事項】
1. **基本メソッドの統一**
現在、各Boxで個別実装されている基本メソッドtoString, type, equals等をNyashBoxトレイトのデフォルト実装として統一したい。
```rust
pub trait NyashBox: BoxCore + Debug {
// Nyash標準メソッドデフォルト実装
fn toString(&self) -> Box<dyn NyashBox> {
Box::new(StringBox::new(&self.to_string_box().value))
}
fn type(&self) -> Box<dyn NyashBox> {
Box::new(StringBox::new(self.type_name()))
}
fn equals(&self, other: Box<dyn NyashBox>) -> Box<dyn NyashBox> {
Box::new(BoolBox::new(self.equals_internal(other.as_ref())))
}
}
```
2. **ユーザー定義Boxの完全統一**
ユーザー定義Boxも、ビルトイン/プラグインBoxと同じように扱えるようにしたい。継承も統一的に
```nyash
box MyString from StringBox { } // ビルトイン継承
box MyFile from FileBox { } // プラグイン継承
box Employee from Person { } // ユーザー定義継承
```
3. **動的な切り替え**
実行時にビルトインBoxをプラグインBoxで置き換える機能は既に実装済み。これをさらに洗練させたい。
【質問】
1. この統一設計は美しいと思いますか?それとも過度に複雑でしょうか?
2. 基本メソッドtoString, type, equals, cloneをトレイトのデフォルト実装にすることで、すべてのBoxで統一的に使えるようにする案についてどう思いますか
3. ユーザー定義Boxを、ビルトイン/プラグインBoxと完全に同じレベルで扱うことは、設計として自然でしょうかそれとも強引でしょうか
4. さらに設計を美しくするためのアイデアはありますか?例えば:
- パイプライン演算子(|>)の導入
- エフェクトシステムの整理
- Box階層の整理ValueBox, ContainerBox, IOBox等
5. 他のプログラミング言語Ruby, Python, Smalltalk等の統一オブジェクトシステムと比較して、この設計の良い点・改善点は何でしょうか
6. パフォーマンスと美しさのトレードオフについて、どのようなバランスが良いと思いますか?
プログラミング言語設計の専門的観点から、実装の現実性も考慮しつつ、より美しい設計への道筋をアドバイスしてください。

View File

@ -1,3 +0,0 @@
🔌 v2 plugin system initialized from nyash.toml
✅ v2 plugin system fully configured
🚀 Nyash VM Backend - Executing file: local_tests/simple_loop_test.nyash 🚀

View File

@ -0,0 +1,33 @@
/*!
* VM Control-Flow helpers (scaffolding)
*
* Purpose: Encapsulate block transitions, branching decisions, and phi entry bookkeeping.
* Status: Initial skeleton for future extraction from vm.rs
*/
use crate::mir::BasicBlockId;
use super::vm::{VMError};
/// Result of a block step when evaluating a terminator
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Step {
/// Continue in the same block (advance pc)
Continue,
/// Jump to target block
Jump(BasicBlockId),
/// Function returned (handled by VM)
Return,
}
/// Record a block transition inside VM bookkeeping
pub fn record_transition(
previous_block: &mut Option<BasicBlockId>,
loop_recorder: &mut crate::backend::vm_phi::LoopExecutor,
from: BasicBlockId,
to: BasicBlockId,
) -> Result<(), VMError> {
*previous_block = Some(from);
loop_recorder.record_transition(from, to);
Ok(())
}

26
src/backend/dispatch.rs Normal file
View File

@ -0,0 +1,26 @@
/*!
* VM Dispatch table (scaffolding)
*
* Purpose: Centralize mapping from MIR instruction kinds to handler fns.
* Status: Initial skeleton; currently unused. Future: build static table for hot-path dispatch.
*/
use crate::mir::MirInstruction;
use super::vm::{VMError};
/// Placeholder for an instruction dispatch entry
pub struct DispatchEntry;
/// Placeholder dispatch table
pub struct DispatchTable;
impl DispatchTable {
pub fn new() -> Self { Self }
/// Example API for future use: resolve a handler for an instruction
pub fn resolve(&self, _instr: &MirInstruction) -> Option<DispatchEntry> { None }
}
/// Example execution of a dispatch entry
pub fn execute_entry(_entry: &DispatchEntry) -> Result<(), VMError> { Ok(()) }

21
src/backend/frame.rs Normal file
View File

@ -0,0 +1,21 @@
/*!
* VM Frame management (scaffolding)
*
* Purpose: Provide a dedicated struct for per-function execution state (pc, block, locals).
* Status: Initial skeleton; VM still stores fields directly.
*/
use crate::mir::{BasicBlockId, ValueId};
#[derive(Debug, Default, Clone)]
pub struct ExecutionFrame {
pub current_block: Option<BasicBlockId>,
pub pc: usize,
pub last_result: Option<ValueId>,
}
impl ExecutionFrame {
pub fn new() -> Self { Self { current_block: None, pc: 0, last_result: None } }
pub fn reset(&mut self) { self.current_block = None; self.pc = 0; self.last_result = None; }
}

View File

@ -8,6 +8,10 @@ pub mod vm_instructions;
pub mod vm_values; pub mod vm_values;
pub mod vm_boxcall; pub mod vm_boxcall;
pub mod vm_stats; pub mod vm_stats;
// Phase 9.78h: VM split scaffolding (control_flow/dispatch/frame)
pub mod control_flow;
pub mod dispatch;
pub mod frame;
#[cfg(feature = "wasm-backend")] #[cfg(feature = "wasm-backend")]
pub mod wasm; pub mod wasm;

View File

@ -225,14 +225,25 @@ pub struct VM {
} }
impl VM { impl VM {
/// Helper: execute phi via loop executor (exposes private field safely) /// Helper: execute phi selection based on previous_block (borrow-safe minimal)
pub(super) fn loop_execute_phi(&mut self, _dst: ValueId, inputs: &[(BasicBlockId, ValueId)]) -> Result<VMValue, VMError> { pub(super) fn loop_execute_phi(&mut self, _dst: ValueId, inputs: &[(BasicBlockId, ValueId)]) -> Result<VMValue, VMError> {
// 80/20 minimal: select first input when we can't safely borrow executor + self simultaneously if inputs.is_empty() {
if let Some((_, val_id)) = inputs.first() { return Err(VMError::InvalidInstruction("Phi node has no inputs".to_string()));
self.get_value(*val_id)
} else {
Err(VMError::InvalidInstruction("Phi node has no inputs".to_string()))
} }
let debug_phi = std::env::var("NYASH_VM_DEBUG").ok().as_deref() == Some("1")
|| std::env::var("NYASH_VM_DEBUG_PHI").ok().as_deref() == Some("1");
let prev = self.previous_block;
if debug_phi { eprintln!("[VM] phi-select prev={:?} inputs={:?}", prev, inputs); }
if let Some(prev_bb) = prev {
if let Some((_, val_id)) = inputs.iter().find(|(bb, _)| *bb == prev_bb) {
if debug_phi { eprintln!("[VM] phi-select hit prev={:?} -> {:?}", prev_bb, val_id); }
return self.get_value(*val_id);
}
}
// Fallback: first input
let (_, val_id) = inputs[0];
if debug_phi { eprintln!("[VM] phi-select fallback first -> {:?}", val_id); }
self.get_value(val_id)
} }
/// Create a new VM instance /// Create a new VM instance
pub fn new() -> Self { pub fn new() -> Self {
@ -438,7 +449,9 @@ impl VM {
/// Execute a single instruction /// Execute a single instruction
fn execute_instruction(&mut self, instruction: &MirInstruction) -> Result<ControlFlow, VMError> { fn execute_instruction(&mut self, instruction: &MirInstruction) -> Result<ControlFlow, VMError> {
// Record instruction for stats // Record instruction for stats
eprintln!("[VM] execute_instruction: {:?}", instruction); let debug_global = std::env::var("NYASH_VM_DEBUG").ok().as_deref() == Some("1");
let debug_exec = debug_global || std::env::var("NYASH_VM_DEBUG_EXEC").ok().as_deref() == Some("1");
if debug_exec { eprintln!("[VM] execute_instruction: {:?}", instruction); }
self.record_instruction(instruction); self.record_instruction(instruction);
match instruction { match instruction {
@ -447,7 +460,7 @@ impl VM {
self.execute_const(*dst, value), self.execute_const(*dst, value),
MirInstruction::BinOp { dst, op, lhs, rhs } => { MirInstruction::BinOp { dst, op, lhs, rhs } => {
if std::env::var("NYASH_VM_DEBUG_ANDOR").ok().as_deref() == Some("1") { if debug_global || std::env::var("NYASH_VM_DEBUG_ANDOR").ok().as_deref() == Some("1") {
eprintln!("[VM] execute_instruction -> BinOp({:?})", op); eprintln!("[VM] execute_instruction -> BinOp({:?})", op);
} }
self.execute_binop(*dst, op, *lhs, *rhs) self.execute_binop(*dst, op, *lhs, *rhs)
@ -457,12 +470,13 @@ impl VM {
self.execute_unaryop(*dst, op, *operand), self.execute_unaryop(*dst, op, *operand),
MirInstruction::Compare { dst, op, lhs, rhs } => { MirInstruction::Compare { dst, op, lhs, rhs } => {
eprintln!("[VM] dispatch Compare op={:?} lhs={:?} rhs={:?}", op, lhs, rhs); let debug_cmp = debug_global || std::env::var("NYASH_VM_DEBUG_CMP").ok().as_deref() == Some("1");
if debug_cmp { eprintln!("[VM] dispatch Compare op={:?} lhs={:?} rhs={:?}", op, lhs, rhs); }
// Fast path: if both BoxRef, try numeric parse and compare // Fast path: if both BoxRef, try numeric parse and compare
if let (Ok(lv), Ok(rv)) = (self.get_value(*lhs), self.get_value(*rhs)) { if let (Ok(lv), Ok(rv)) = (self.get_value(*lhs), self.get_value(*rhs)) {
eprintln!("[VM] values before fastpath: left={:?} right={:?}", lv, rv); if debug_cmp { eprintln!("[VM] values before fastpath: left={:?} right={:?}", lv, rv); }
if let (VMValue::BoxRef(lb), VMValue::BoxRef(rb)) = (&lv, &rv) { if let (VMValue::BoxRef(lb), VMValue::BoxRef(rb)) = (&lv, &rv) {
eprintln!("[VM] BoxRef types: lty={} rty={} lstr={} rstr={}", lb.type_name(), rb.type_name(), lb.to_string_box().value, rb.to_string_box().value); if debug_cmp { eprintln!("[VM] BoxRef types: lty={} rty={} lstr={} rstr={}", lb.type_name(), rb.type_name(), lb.to_string_box().value, rb.to_string_box().value); }
let li = lb.as_any().downcast_ref::<crate::box_trait::IntegerBox>().map(|x| x.value) let li = lb.as_any().downcast_ref::<crate::box_trait::IntegerBox>().map(|x| x.value)
.or_else(|| lb.to_string_box().value.trim().parse::<i64>().ok()); .or_else(|| lb.to_string_box().value.trim().parse::<i64>().ok());
let ri = rb.as_any().downcast_ref::<crate::box_trait::IntegerBox>().map(|x| x.value) let ri = rb.as_any().downcast_ref::<crate::box_trait::IntegerBox>().map(|x| x.value)

View File

@ -58,10 +58,12 @@ impl VM {
/// Execute a comparison instruction /// Execute a comparison instruction
pub(super) fn execute_compare(&mut self, dst: ValueId, op: &CompareOp, lhs: ValueId, rhs: ValueId) -> Result<ControlFlow, VMError> { pub(super) fn execute_compare(&mut self, dst: ValueId, op: &CompareOp, lhs: ValueId, rhs: ValueId) -> Result<ControlFlow, VMError> {
eprintln!("[VM] execute_compare enter op={:?} lhs={:?} rhs={:?}", op, lhs, rhs); let debug_cmp = std::env::var("NYASH_VM_DEBUG").ok().as_deref() == Some("1") ||
std::env::var("NYASH_VM_DEBUG_CMP").ok().as_deref() == Some("1");
if debug_cmp { eprintln!("[VM] execute_compare enter op={:?} lhs={:?} rhs={:?}", op, lhs, rhs); }
let mut left = self.get_value(lhs)?; let mut left = self.get_value(lhs)?;
let mut right = self.get_value(rhs)?; let mut right = self.get_value(rhs)?;
eprintln!("[VM] execute_compare values: left={:?} right={:?}", left, right); if debug_cmp { eprintln!("[VM] execute_compare values: left={:?} right={:?}", left, right); }
// Canonicalize BoxRef(any) → try Integer via downcast/parse (no type_name reliance) // Canonicalize BoxRef(any) → try Integer via downcast/parse (no type_name reliance)
left = match left { left = match left {

View File

@ -136,7 +136,9 @@ impl VM {
/// Execute comparison operation /// Execute comparison operation
pub(super) fn execute_compare_op(&self, op: &CompareOp, left: &VMValue, right: &VMValue) -> Result<bool, VMError> { pub(super) fn execute_compare_op(&self, op: &CompareOp, left: &VMValue, right: &VMValue) -> Result<bool, VMError> {
eprintln!("[VM] execute_compare_op enter: op={:?}, left={:?}, right={:?}", op, left, right); let debug_cmp = std::env::var("NYASH_VM_DEBUG").ok().as_deref() == Some("1") ||
std::env::var("NYASH_VM_DEBUG_CMP").ok().as_deref() == Some("1");
if debug_cmp { eprintln!("[VM] execute_compare_op enter: op={:?}, left={:?}, right={:?}", op, left, right); }
match (left, right) { match (left, right) {
// Mixed numeric // Mixed numeric
(VMValue::Integer(l), VMValue::Float(r)) => { (VMValue::Integer(l), VMValue::Float(r)) => {

File diff suppressed because it is too large Load Diff

View File

@ -1,538 +0,0 @@
/*!
* Nyash Instance System - Box Instance Implementation
*
* BoxインスタンスとClassBoxの実装
* Everything is Box哲学に基づくオブジェクト指向システム
*/
use crate::box_trait::{NyashBox, StringBox, BoolBox, VoidBox, BoxCore, BoxBase, SharedNyashBox};
use crate::ast::ASTNode;
use crate::value::NyashValue;
use crate::interpreter::NyashInterpreter;
use std::collections::HashMap;
use std::fmt::{Debug, Display};
use std::any::Any;
use std::sync::{Arc, Mutex};
/// Boxインスタンス - フィールドとメソッドを持つオブジェクト
#[derive(Debug, Clone)]
pub struct InstanceBox {
/// クラス名
pub class_name: String,
/// フィールド値 (Updated to use Arc for reference sharing)
pub fields: Arc<Mutex<HashMap<String, SharedNyashBox>>>,
/// 🔗 Next-generation fields (weak reference capable)
pub fields_ng: Arc<Mutex<HashMap<String, NyashValue>>>,
/// メソッド定義ClassBoxから共有
pub methods: Arc<HashMap<String, ASTNode>>,
/// Box基底
base: BoxBase,
/// 解放済みフラグ
finalized: Arc<Mutex<bool>>,
/// 🔥 Phase 2: finiシステム完全実装 - ChatGPT5設計
/// init宣言順序決定的カスケード用
init_field_order: Vec<String>,
/// weak フィールド高速判定用
weak_fields_union: std::collections::HashSet<String>,
/// 解放中フラグ(再入防止)
in_finalization: Arc<Mutex<bool>>,
}
impl InstanceBox {
pub fn new(class_name: String, fields: Vec<String>, methods: HashMap<String, ASTNode>) -> Self {
// フィールドをVoidBoxで初期化
let mut field_map: HashMap<String, SharedNyashBox> = HashMap::new();
for field in &fields {
field_map.insert(field.clone(), Arc::new(VoidBox::new()));
}
Self {
class_name,
fields: Arc::new(Mutex::new(field_map)),
fields_ng: Arc::new(Mutex::new(HashMap::new())), // 🔗 Initialize next-gen fields
methods: Arc::new(methods),
base: BoxBase::new(),
finalized: Arc::new(Mutex::new(false)),
init_field_order: fields.clone(), // 🔥 Basic field order for backwards compatibility
weak_fields_union: std::collections::HashSet::new(), // 🔥 Empty for backwards compatibility
in_finalization: Arc::new(Mutex::new(false)), // 🔥 Initialize finalization guard
}
}
/// 🔥 Enhanced constructor with complete fini system support
pub fn new_with_box_info(
class_name: String,
fields: Vec<String>,
methods: HashMap<String, ASTNode>,
init_field_order: Vec<String>,
weak_fields: Vec<String>
) -> Self {
// フィールドをVoidBoxで初期化
let mut field_map = HashMap::new();
for field in &fields {
field_map.insert(field.clone(), Arc::new(VoidBox::new()) as Arc<dyn NyashBox>);
}
// Weak fields をHashSetに変換高速判定用
let weak_fields_union: std::collections::HashSet<String> = weak_fields.into_iter().collect();
Self {
class_name,
fields: Arc::new(Mutex::new(field_map)),
fields_ng: Arc::new(Mutex::new(HashMap::new())),
methods: Arc::new(methods),
base: BoxBase::new(),
finalized: Arc::new(Mutex::new(false)),
init_field_order, // 🔥 決定的カスケード順序
weak_fields_union, // 🔥 高速weak判定
in_finalization: Arc::new(Mutex::new(false)), // 🔥 再入防止
}
}
/// 🔗 Unified field access - prioritizes fields_ng, fallback to legacy fields with conversion
pub fn get_field_unified(&self, field_name: &str) -> Option<NyashValue> {
// Check fields_ng first
if let Some(value) = self.fields_ng.lock().unwrap().get(field_name) {
return Some(value.clone());
}
// Fallback to legacy fields with conversion
if let Some(legacy_box) = self.fields.lock().unwrap().get(field_name) {
// For backward compatibility, we need to work around the type mismatch
// Since we can't easily convert Box<dyn NyashBox> to Arc<Mutex<dyn NyashBox>>
// We'll use the from_box method which handles this conversion
// We need to create a temporary Arc to satisfy the method signature
let _temp_arc = Arc::new(Mutex::new(VoidBox::new()));
// Unfortunately, there's a type system limitation here
// For now, let's return a simple converted value
let string_rep = legacy_box.to_string_box().value;
return Some(NyashValue::String(string_rep));
}
None
}
/// 🔗 Unified field setting - always stores in fields_ng
pub fn set_field_unified(&self, field_name: String, value: NyashValue) -> Result<(), String> {
// Always store in fields_ng for future compatibility
self.fields_ng.lock().unwrap().insert(field_name.clone(), value.clone());
// For backward compatibility, also update legacy fields if they exist
// Convert NyashValue back to Box<dyn NyashBox> for legacy storage
if self.fields.lock().unwrap().contains_key(&field_name) {
if let Ok(legacy_box) = value.to_box() {
// Convert Arc<Mutex<dyn NyashBox>> to Box<dyn NyashBox>
if let Ok(_inner_box) = legacy_box.try_lock() {
self.fields.lock().unwrap().insert(field_name, Arc::from(_inner_box.clone_box()));
}
}
}
Ok(())
}
/// 🔗 Set weak field - converts strong reference to weak and stores in fields_ng
pub fn set_weak_field(&self, field_name: String, value: NyashValue) -> Result<(), String> {
match value {
NyashValue::Box(arc_box) => {
let weak_ref = Arc::downgrade(&arc_box);
let field_name_clone = field_name.clone(); // Clone for eprintln
self.fields_ng.lock().unwrap().insert(field_name, NyashValue::WeakBox(weak_ref));
eprintln!("🔗 DEBUG: Successfully converted strong reference to weak for field '{}'", field_name_clone);
Ok(())
}
_ => {
// For non-Box values, store as-is (they don't need weak conversion)
self.fields_ng.lock().unwrap().insert(field_name, value);
Ok(())
}
}
}
/// 🔗 Set weak field from legacy Box<dyn NyashBox> - helper method for interpreter
pub fn set_weak_field_from_legacy(&self, field_name: String, legacy_box: Box<dyn NyashBox>) -> Result<(), String> {
// Convert Box<dyn NyashBox> to Arc<Mutex<dyn NyashBox>> via temporary wrapper
// We create a temporary holder struct that implements NyashBox
// Store the object info in a way we can track
let object_info = legacy_box.to_string_box().value;
let field_name_clone = field_name.clone();
// Create a special weak reference marker with object details
let weak_marker = format!("WEAK_REF_TO:{}", object_info);
self.fields_ng.lock().unwrap().insert(field_name, NyashValue::String(weak_marker));
eprintln!("🔗 DEBUG: Stored weak field '{}' with reference tracking", field_name_clone);
Ok(())
}
/// 🔗 Get weak field with auto-upgrade and nil fallback
pub fn get_weak_field(&self, field_name: &str, interpreter: &NyashInterpreter) -> Option<NyashValue> {
if let Some(value) = self.fields_ng.lock().unwrap().get(field_name) {
match value {
NyashValue::WeakBox(weak_ref) => {
if let Some(strong_ref) = weak_ref.upgrade() {
eprintln!("🔗 DEBUG: Weak field '{}' upgraded successfully", field_name);
Some(NyashValue::Box(strong_ref))
} else {
eprintln!("🔗 DEBUG: Weak field '{}' target was dropped - returning null", field_name);
Some(NyashValue::Null) // 🎯 Auto-nil behavior!
}
}
NyashValue::String(s) => {
// For string-based weak fields, check if they're marked as "dropped"
if s.starts_with("WEAK_REF_TO:") {
// Extract the object ID from the weak reference string
// Format: "WEAK_REF_TO:<ClassName instance #ID>"
let mut is_dropped = false;
if let Some(hash_pos) = s.find('#') {
let id_str = &s[hash_pos + 1..];
let id_end = id_str.find('>').unwrap_or(id_str.len());
let clean_id_str = &id_str[..id_end];
if let Ok(id) = clean_id_str.parse::<u64>() {
is_dropped = interpreter.invalidated_ids.lock().unwrap().contains(&id);
eprintln!("🔗 DEBUG: Checking weak field '{}' with ID {} - dropped: {}", field_name, id, is_dropped);
} else {
eprintln!("🔗 DEBUG: Failed to parse ID from weak reference: {}", clean_id_str);
}
} else {
// Fallback to old behavior for backwards compatibility
is_dropped = s.contains("Parent") && interpreter.invalidated_ids.lock().unwrap().contains(&999);
eprintln!("🔗 DEBUG: Using fallback check for weak field '{}' - dropped: {}", field_name, is_dropped);
}
if is_dropped {
eprintln!("🔗 DEBUG: Weak field '{}' target was dropped - returning null", field_name);
return Some(NyashValue::Null); // 🎉 Auto-nil!
}
// Still valid
eprintln!("🔗 DEBUG: Weak field '{}' still has valid reference", field_name);
Some(value.clone())
} else if s == "WEAK_REFERENCE_DROPPED" {
eprintln!("🔗 DEBUG: Weak field '{}' target was dropped - returning null", field_name);
Some(NyashValue::Null)
} else {
eprintln!("🔗 DEBUG: Weak field '{}' still has valid reference", field_name);
Some(value.clone())
}
}
_ => {
// Non-weak value, return as-is
Some(value.clone())
}
}
} else {
None
}
}
/// 🔗 Mark weak references to this instance as dropped
pub fn invalidate_weak_references_to(&self, target_info: &str) {
let mut fields = self.fields_ng.lock().unwrap();
for (field_name, value) in fields.iter_mut() {
match value {
NyashValue::String(s) => {
// Check if this is a weak reference to the target
if s.starts_with("WEAK_REF_TO:") && s.contains(target_info) {
*s = "WEAK_REFERENCE_DROPPED".to_string();
eprintln!("🔗 DEBUG: Marked weak field '{}' as dropped", field_name);
}
}
NyashValue::WeakBox(weak_ref) => {
// Check if the weak reference is dead
if weak_ref.upgrade().is_none() {
eprintln!("🔗 DEBUG: Weak field '{}' reference is already dead", field_name);
}
}
_ => {}
}
}
}
/// 🔗 Global invalidation - call this when any object is dropped
pub fn global_invalidate_weak_references(target_info: &str) {
// In a real implementation, we'd maintain a global registry of all instances
// and iterate through them to invalidate weak references.
// For this demo, we'll add the capability to the instance itself.
eprintln!("🔗 DEBUG: Global weak reference invalidation for: {}", target_info);
}
/// フィールドの値を取得
pub fn get_field(&self, field_name: &str) -> Option<SharedNyashBox> {
eprintln!("✅ FIX: get_field('{}') returning shared Arc reference", field_name);
// 🔧 修正v.clone_box() → Arc::clone(v) で参照共有
self.fields.lock().unwrap().get(field_name).map(Arc::clone)
}
/// フィールドに値を設定
pub fn set_field(&self, field_name: &str, value: SharedNyashBox) -> Result<(), String> {
eprintln!("🔧 INSTANCE: set_field('{}') with shared Arc reference id={}",
field_name, value.box_id());
let mut fields = self.fields.lock().unwrap();
if fields.contains_key(field_name) {
if let Some(old_value) = fields.get(field_name) {
eprintln!("🔧 INSTANCE: Replacing field '{}': old_id={} -> new_id={}",
field_name, old_value.box_id(), value.box_id());
}
fields.insert(field_name.to_string(), value);
Ok(())
} else {
Err(format!("Field '{}' does not exist in {}", field_name, self.class_name))
}
}
/// 🌍 GlobalBox用フィールドを動的に追加・設定
pub fn set_field_dynamic(&mut self, field_name: String, value: SharedNyashBox) {
let mut fields = self.fields.lock().unwrap();
fields.insert(field_name, value);
}
/// メソッド定義を取得
pub fn get_method(&self, method_name: &str) -> Option<&ASTNode> {
self.methods.get(method_name)
}
/// メソッドが存在するかチェック
pub fn has_method(&self, method_name: &str) -> bool {
self.methods.contains_key(method_name)
}
/// 🌍 GlobalBox用メソッドを動的に追加 - 🔥 暗黙オーバーライド禁止による安全実装
pub fn add_method(&mut self, method_name: String, method_ast: ASTNode) -> Result<(), String> {
// Arc<T>は不変なので、新しいHashMapを作成してArcで包む
let mut new_methods = (*self.methods).clone();
// 🚨 暗黙オーバーライド禁止:既存メソッドの検査
if let Some(_existing_method) = new_methods.get(&method_name) {
// 新しいメソッドのoverride状態を確認
let is_override = match &method_ast {
crate::ast::ASTNode::FunctionDeclaration { is_override, .. } => *is_override,
_ => false, // FunctionDeclaration以外はオーバーライドなし
};
if !is_override {
// 🔥 明示的オーバーライド革命overrideキーワードなしの重複を禁止
return Err(format!(
"🚨 EXPLICIT OVERRIDE REQUIRED: Method '{}' already exists.\n\
💡 To replace the existing method, use 'override {}(...) {{ ... }}'.\n\
🌟 This is Nyash's explicit delegation philosophy - no hidden overrides!",
method_name, method_name
));
}
// override宣言があれば、明示的な置換として許可
eprintln!("🔥 EXPLICIT OVERRIDE: Method '{}' replaced with override declaration", method_name);
}
new_methods.insert(method_name, method_ast);
self.methods = Arc::new(new_methods);
Ok(())
}
/// 🔥 Enhanced fini()メソッド - ChatGPT5設計による完全実装
pub fn fini(&self) -> Result<(), String> {
// 1) finalized チェックidempotent
let mut finalized = self.finalized.lock().unwrap();
if *finalized {
// 既に解放済みなら何もしない
return Ok(());
}
// 2) in_finalization = true再入防止
let mut in_finalization = self.in_finalization.lock().unwrap();
if *in_finalization {
return Err("Circular finalization detected - fini() called recursively".to_string());
}
*in_finalization = true;
// 3) TODO: ユーザー定義fini()実行(インタープリター側で実装予定)
// このメソッドは低レベルなfini処理なので、高レベルなユーザー定義fini()は
// インタープリター側で先に呼び出される想定
// 4) 自動カスケード: init_field_order の強参照フィールドに child.fini()
self.cascade_finalize_fields()?;
// 5) 全フィールドクリア + finalized = true
let mut fields = self.fields.lock().unwrap();
fields.clear();
let mut fields_ng = self.fields_ng.lock().unwrap();
fields_ng.clear();
*finalized = true;
*in_finalization = false; // 再入フラグをクリア
eprintln!("🔥 fini(): Instance {} (ID: {}) finalized", self.class_name, self.base.id);
Ok(())
}
/// 🔥 自動カスケード解放 - init宣言順でフィールドをfini
fn cascade_finalize_fields(&self) -> Result<(), String> {
let fields_ng = self.fields_ng.lock().unwrap();
// init_field_order の逆順でfiniを実行LIFO - Last In First Out
for field_name in self.init_field_order.iter().rev() {
// weak フィールドはスキップ
if self.weak_fields_union.contains(field_name) {
eprintln!("🔥 fini(): Skipping weak field '{}' (non-owning reference)", field_name);
continue;
}
// フィールドの値を取得してfini呼び出し
if let Some(field_value) = fields_ng.get(field_name) {
match field_value {
crate::value::NyashValue::Box(arc_box) => {
if let Ok(inner_box) = arc_box.try_lock() {
// InstanceBoxならfini()を呼び出し
if let Some(instance) = inner_box.as_any().downcast_ref::<InstanceBox>() {
eprintln!("🔥 fini(): Cascading finalization to field '{}'", field_name);
if let Err(e) = instance.fini() {
eprintln!("🔥 fini(): Warning - failed to finalize field '{}': {}", field_name, e);
// エラーは警告として記録するが、続行する
}
}
}
}
_ => {
// non-Box値はfini不要
}
}
}
}
Ok(())
}
/// 解放済みかチェック
pub fn is_finalized(&self) -> bool {
*self.finalized.lock().unwrap()
}
/// 🔥 解放中かチェック
pub fn is_in_finalization(&self) -> bool {
*self.in_finalization.lock().unwrap()
}
/// 🔥 指定フィールドがweakかチェック
pub fn is_weak_field(&self, field_name: &str) -> bool {
self.weak_fields_union.contains(field_name)
}
}
impl NyashBox for InstanceBox {
fn to_string_box(&self) -> StringBox {
StringBox::new(format!("<{} instance #{}>", self.class_name, self.base.id))
}
fn equals(&self, other: &dyn NyashBox) -> BoolBox {
if let Some(other_instance) = other.as_any().downcast_ref::<InstanceBox>() {
// 同じインスタンスIDなら等しい
BoolBox::new(self.base.id == other_instance.base.id)
} else {
BoolBox::new(false)
}
}
fn type_name(&self) -> &'static str {
"InstanceBox"
}
fn clone_box(&self) -> Box<dyn NyashBox> {
// インスタンスは同じフィールドを共有
Box::new(self.clone())
}
/// 仮実装: clone_boxと同じ後で修正
fn share_box(&self) -> Box<dyn NyashBox> {
self.clone_box()
}
}
impl BoxCore for InstanceBox {
fn box_id(&self) -> u64 {
self.base.id
}
fn parent_type_id(&self) -> Option<std::any::TypeId> {
self.base.parent_type_id
}
fn fmt_box(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "<{} instance #{}>", self.class_name, self.base.id)
}
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}
impl Display for InstanceBox {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.fmt_box(f)
}
}
// ===== Tests =====
#[cfg(test)]
mod tests {
use super::*;
use crate::box_trait::IntegerBox;
#[test]
fn test_instance_creation() {
let fields = vec!["x".to_string(), "y".to_string()];
let methods = HashMap::new();
let instance = InstanceBox::new("Point".to_string(), fields, methods);
assert_eq!(instance.class_name, "Point");
assert!(instance.get_field("x").is_some());
assert!(instance.get_field("y").is_some());
assert!(instance.get_field("z").is_none());
}
#[test]
fn test_field_access() {
let fields = vec!["value".to_string()];
let methods = HashMap::new();
let instance = InstanceBox::new("TestBox".to_string(), fields, methods);
// フィールドに値を設定
let int_value = Box::new(IntegerBox::new(42)) as Box<dyn NyashBox>;
instance.set_field("value", int_value).unwrap();
// フィールドの値を取得
let retrieved = instance.get_field("value").unwrap();
let int_box = retrieved.as_any().downcast_ref::<IntegerBox>().unwrap();
assert_eq!(int_box.value, 42);
}
#[test]
fn test_instance_equality() {
let instance1 = InstanceBox::new("Test".to_string(), vec![], HashMap::new());
let instance2 = InstanceBox::new("Test".to_string(), vec![], HashMap::new());
// 異なるインスタンスは等しくない
assert!(!instance1.equals(&instance2).value);
// 同じインスタンスは等しい
assert!(instance1.equals(&instance1).value);
}
}

View File

@ -33,7 +33,7 @@ mod core;
mod expressions; mod expressions;
mod statements; mod statements;
mod functions; mod functions;
mod objects; pub mod objects;
mod objects_basic_constructors; mod objects_basic_constructors;
mod io; mod io;
mod methods; mod methods;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,193 @@
use super::*;
impl NyashInterpreter {
/// Box宣言を登録 - 🔥 コンストラクタオーバーロード禁止対応
pub(crate) fn register_box_declaration(
&mut self,
name: String,
fields: Vec<String>,
public_fields: Vec<String>,
private_fields: Vec<String>,
methods: HashMap<String, ASTNode>,
constructors: HashMap<String, ASTNode>,
init_fields: Vec<String>,
weak_fields: Vec<String>,
is_interface: bool,
extends: Vec<String>,
implements: Vec<String>,
type_parameters: Vec<String>
) -> Result<(), RuntimeError> {
if !constructors.is_empty() {
eprintln!("🐛 DEBUG: Registering Box '{}' with constructors: {:?}", name, constructors.keys().collect::<Vec<_>>());
}
if constructors.len() > 1 {
let constructor_names: Vec<String> = constructors.keys().cloned().collect();
return Err(RuntimeError::InvalidOperation {
message: format!(
"🚨 CONSTRUCTOR OVERLOAD FORBIDDEN: Box '{}' has {} constructors: [{}].\n\
🌟 Nyash's explicit philosophy: One Box, One Constructor!\n\
💡 Use different Box classes for different initialization patterns.\n\
📖 Example: UserBox, AdminUserBox, GuestUserBox instead of User(type)",
name,
constructors.len(),
constructor_names.join(", ")
)
});
}
let box_decl = super::BoxDeclaration {
name: name.clone(),
fields,
public_fields,
private_fields,
methods,
constructors,
init_fields,
weak_fields,
is_interface,
extends,
implements,
type_parameters,
};
{
let mut box_decls = self.shared.box_declarations.write().unwrap();
box_decls.insert(name, box_decl);
}
Ok(())
}
/// 🔥 ジェネリクス型引数の検証
pub(super) fn validate_generic_arguments(&self, box_decl: &BoxDeclaration, type_arguments: &[String])
-> Result<(), RuntimeError> {
if box_decl.type_parameters.len() != type_arguments.len() {
return Err(RuntimeError::TypeError {
message: format!(
"Generic class '{}' expects {} type parameters, got {}. Expected: <{}>, Got: <{}>",
box_decl.name,
box_decl.type_parameters.len(),
type_arguments.len(),
box_decl.type_parameters.join(", "),
type_arguments.join(", ")
),
});
}
if box_decl.type_parameters.is_empty() && !type_arguments.is_empty() {
return Err(RuntimeError::TypeError {
message: format!(
"Class '{}' is not generic, but got type arguments <{}>",
box_decl.name,
type_arguments.join(", ")
),
});
}
for type_arg in type_arguments {
if !self.is_valid_type(type_arg) {
return Err(RuntimeError::TypeError { message: format!("Unknown type '{}'", type_arg) });
}
}
Ok(())
}
/// 型が有効かどうかをチェック
fn is_valid_type(&self, type_name: &str) -> bool {
if let Ok(reg) = self.runtime.box_registry.lock() {
if reg.has_type(type_name) { return true; }
}
self.shared.box_declarations.read().unwrap().contains_key(type_name)
}
/// 継承チェーンを解決してフィールドとメソッドを収集 - Inheritance resolution
pub(crate) fn resolve_inheritance(&self, box_decl: &BoxDeclaration)
-> Result<(Vec<String>, HashMap<String, ASTNode>), RuntimeError> {
let mut all_fields = Vec::new();
let mut all_methods = HashMap::new();
for parent_name in &box_decl.extends {
use crate::box_trait::is_builtin_box;
let mut is_builtin = is_builtin_box(parent_name);
#[cfg(all(feature = "gui", not(target_arch = "wasm32")))]
{
if parent_name == "EguiBox" { is_builtin = true; }
}
if is_builtin {
// skip builtin inheritance
} else {
let parent_decl = {
let box_decls = self.shared.box_declarations.read().unwrap();
box_decls.get(parent_name)
.ok_or(RuntimeError::UndefinedClass { name: parent_name.to_string() })?
.clone()
};
if parent_decl.is_interface {
return Err(RuntimeError::InvalidOperation {
message: format!("Cannot extend interface '{}'. Use 'implements' instead.", parent_name),
});
}
let (parent_fields, parent_methods) = self.resolve_inheritance(&parent_decl)?;
all_fields.extend(parent_fields);
all_methods.extend(parent_methods);
}
}
all_fields.extend(box_decl.fields.clone());
for init_field in &box_decl.init_fields {
if !all_fields.contains(init_field) { all_fields.push(init_field.clone()); }
}
for (method_name, method_ast) in &box_decl.methods {
all_methods.insert(method_name.clone(), method_ast.clone());
}
for interface_name in &box_decl.implements {
let interface_decl = {
let box_decls = self.shared.box_declarations.read().unwrap();
box_decls.get(interface_name)
.ok_or(RuntimeError::UndefinedClass { name: interface_name.clone() })?
.clone()
};
if !interface_decl.is_interface {
return Err(RuntimeError::InvalidOperation { message: format!("'{}' is not an interface", interface_name) });
}
for (required_method, _) in &interface_decl.methods {
if !all_methods.contains_key(required_method) {
return Err(RuntimeError::InvalidOperation {
message: format!("Class '{}' must implement method '{}' from interface '{}'",
box_decl.name, required_method, interface_name),
});
}
}
}
Ok((all_fields, all_methods))
}
/// 🚀 ジェネリクス型を特殊化してBoxDeclarationを生成
pub(super) fn specialize_generic_class(
&self,
generic_decl: &BoxDeclaration,
type_arguments: &[String]
) -> Result<BoxDeclaration, RuntimeError> {
use std::collections::HashMap;
let specialized_name = format!("{}_{}", generic_decl.name, type_arguments.join("_"));
let mut type_mapping = HashMap::new();
for (i, param) in generic_decl.type_parameters.iter().enumerate() {
type_mapping.insert(param.clone(), type_arguments[i].clone());
}
let mut specialized = generic_decl.clone();
specialized.name = specialized_name.clone();
specialized.type_parameters.clear();
specialized.init_fields = self.substitute_types_in_fields(&specialized.init_fields, &type_mapping);
let mut updated_constructors = HashMap::new();
for (old_key, constructor_node) in &generic_decl.constructors {
if let Some(args_count) = old_key.split('/').nth(1) {
let new_key = format!("{}/{}", specialized_name, args_count);
updated_constructors.insert(new_key, constructor_node.clone());
}
}
specialized.constructors = updated_constructors;
Ok(specialized)
}
/// フィールドの型置換(現状はそのまま)
pub(super) fn substitute_types_in_fields(
&self,
fields: &[String],
_type_mapping: &HashMap<String, String>
) -> Vec<String> {
fields.to_vec()
}
}

View File

@ -0,0 +1,66 @@
use super::*;
use crate::box_trait::SharedNyashBox;
impl NyashInterpreter {
/// コンストラクタを実行 - Constructor execution
pub(super) fn execute_constructor(
&mut self,
instance: &SharedNyashBox,
constructor: &ASTNode,
arguments: &[ASTNode],
box_decl: &BoxDeclaration
) -> Result<(), RuntimeError> {
if let ASTNode::FunctionDeclaration { name: _, params, body, .. } = constructor {
let mut arg_values = Vec::new();
for arg in arguments { arg_values.push(self.execute_expression(arg)?); }
if params.len() != arg_values.len() {
return Err(RuntimeError::InvalidOperation {
message: format!("Constructor expects {} arguments, got {}", params.len(), arg_values.len()),
});
}
let saved_locals = self.save_local_vars();
self.local_vars.clear();
for (param, value) in params.iter().zip(arg_values.iter()) {
self.declare_local_variable(param, value.clone_or_share());
}
self.declare_local_variable("me", instance.clone_or_share());
let old_context = self.current_constructor_context.clone();
self.current_constructor_context = Some(ConstructorContext {
class_name: box_decl.name.clone(),
parent_class: box_decl.extends.first().cloned(),
});
let mut result = Ok(());
for statement in body.iter() {
if let Err(e) = self.execute_statement(statement) { result = Err(e); break; }
}
self.restore_local_vars(saved_locals);
self.current_constructor_context = old_context;
result
} else {
Err(RuntimeError::InvalidOperation { message: "Invalid constructor node".to_string() })
}
}
/// 親コンストラクタを実行 - Parent constructor execution
pub(crate) fn execute_parent_constructor(&mut self, parent_class: &str, arguments: &[ASTNode])
-> Result<Box<dyn NyashBox>, RuntimeError> {
let parent_decl = {
let box_decls = self.shared.box_declarations.read().unwrap();
box_decls.get(parent_class)
.ok_or(RuntimeError::UndefinedClass { name: parent_class.to_string() })?
.clone()
};
let birth_key = format!("birth/{}", arguments.len());
if let Some(parent_constructor) = parent_decl.constructors.get(&birth_key) {
let this_instance = self.resolve_variable("me").map_err(|_| RuntimeError::InvalidOperation {
message: "'this' not available in parent constructor call".to_string(),
})?;
self.execute_constructor(&this_instance, parent_constructor, arguments, &parent_decl)?;
Ok(Box::new(VoidBox::new()))
} else {
Err(RuntimeError::InvalidOperation {
message: format!("No constructor found for parent class {} with {} arguments", parent_class, arguments.len()),
})
}
}
}

View File

@ -0,0 +1,15 @@
/*!
* Interpreter Objects Module (mod)
*
* Split into submodules:
* - ops.rs: instantiation (execute_new) and helpers
* - methods.rs: constructor-related methods
* - fields.rs: declarations, inheritance, generics utilities
*/
use super::*;
mod ops;
mod methods;
mod fields;

View File

@ -0,0 +1,91 @@
use super::*;
use crate::box_trait::SharedNyashBox;
use std::sync::Arc;
impl NyashInterpreter {
/// Evaluate `new` expression arguments to NyashBox values
pub(super) fn new_eval_args(&mut self, arguments: &[ASTNode]) -> Result<Vec<Box<dyn NyashBox>>, RuntimeError> {
arguments.iter().map(|arg| self.execute_expression(arg)).collect()
}
/// If user-defined and type args provided, validate/specialize and register declaration
pub(super) fn new_specialize_if_needed(&self, class: &str, type_arguments: &[String]) -> Result<String, RuntimeError> {
let mut target_class = class.to_string();
let user_defined_exists = {
let box_decls = self.shared.box_declarations.read().unwrap();
box_decls.contains_key(class)
};
if user_defined_exists && !type_arguments.is_empty() {
let generic_decl = {
let box_decls = self.shared.box_declarations.read().unwrap();
box_decls.get(class).cloned()
};
if let Some(generic_decl) = generic_decl {
self.validate_generic_arguments(&generic_decl, type_arguments)?;
let specialized = self.specialize_generic_class(&generic_decl, type_arguments)?;
target_class = specialized.name.clone();
// Insert specialized declaration so registry can create it
let mut box_decls = self.shared.box_declarations.write().unwrap();
box_decls.insert(target_class.clone(), specialized);
}
}
Ok(target_class)
}
/// Create box via registry and optionally run user-defined constructor (birth/arity)
pub(super) fn new_create_via_registry_and_maybe_ctor(
&mut self,
target_class: &str,
args: Vec<Box<dyn NyashBox>>,
arguments: &[ASTNode],
) -> Result<Box<dyn NyashBox>, RuntimeError> {
// Try unified registry (use interpreter's runtime registry to include user-defined boxes)
let registry = self.runtime.box_registry.clone();
let registry_lock = registry.lock().unwrap();
match registry_lock.create_box(target_class, &args) {
Ok(box_instance) => {
// Check if this is a user-defined box that needs constructor execution
if let Some(_instance_box) = box_instance.as_any().downcast_ref::<crate::instance_v2::InstanceBox>() {
// Check if we have a box declaration for this class
let (box_decl_opt, constructor_opt) = {
let box_decls = self.shared.box_declarations.read().unwrap();
if let Some(box_decl) = box_decls.get(target_class) {
// Find the birth constructor (unified constructor system)
let birth_key = format!("birth/{}", arguments.len());
let constructor = box_decl.constructors.get(&birth_key).cloned();
(Some(box_decl.clone()), constructor)
} else { (None, None) }
};
if let Some(box_decl) = box_decl_opt {
if let Some(constructor) = constructor_opt {
// Execute the constructor
let instance_arc: SharedNyashBox = Arc::from(box_instance);
drop(registry_lock); // Release lock before executing constructor
self.execute_constructor(&instance_arc, &constructor, arguments, &box_decl)?;
return Ok((*instance_arc).clone_box());
} else if arguments.is_empty() {
// No constructor needed for zero arguments
return Ok(box_instance);
} else {
return Err(RuntimeError::InvalidOperation {
message: format!("No constructor found for {} with {} arguments", target_class, arguments.len()),
});
}
}
}
// Not a user-defined box or no constructor needed
Ok(box_instance)
},
Err(e) => Err(e),
}
}
/// new式を実行 - Object creation engine
pub(crate) fn execute_new(&mut self, class: &str, arguments: &[ASTNode], type_arguments: &[String])
-> Result<Box<dyn NyashBox>, RuntimeError> {
// 80/20 path: unified registry + constructor
let args = self.new_eval_args(arguments)?;
let target_class = self.new_specialize_if_needed(class, type_arguments)?;
self.new_create_via_registry_and_maybe_ctor(&target_class, args, arguments)
}
}

View File

@ -58,6 +58,7 @@ pub mod cli;
// Runtime system (plugins, registry, etc.) // Runtime system (plugins, registry, etc.)
pub mod runtime; pub mod runtime;
pub mod runner_plugin_init;
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
pub mod wasm_test; pub mod wasm_test;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -28,10 +28,11 @@ use nyash_rust::backend::{wasm::WasmBackend, aot::AotBackend};
#[cfg(feature = "llvm")] #[cfg(feature = "llvm")]
use nyash_rust::backend::{llvm_compile_and_execute}; use nyash_rust::backend::{llvm_compile_and_execute};
use std::{fs, process}; use std::{fs, process};
mod modes;
// v2 plugin system imports // v2 plugin system imports
use nyash_rust::runtime::{init_global_loader_v2, get_global_registry, get_global_loader_v2, PluginConfig}; use nyash_rust::runtime;
use crate::runtime; use nyash_rust::runner_plugin_init;
/// Main execution coordinator /// Main execution coordinator
pub struct NyashRunner { pub struct NyashRunner {
@ -50,7 +51,7 @@ impl NyashRunner {
runtime::init_global_unified_registry(); runtime::init_global_unified_registry();
// Try to initialize BID plugins from nyash.toml (best-effort) // Try to initialize BID plugins from nyash.toml (best-effort)
self.init_bid_plugins(); runner_plugin_init::init_bid_plugins();
// Optional: enable VM stats via CLI flags // Optional: enable VM stats via CLI flags
if self.config.vm_stats { if self.config.vm_stats {
@ -78,38 +79,7 @@ impl NyashRunner {
} }
} }
fn init_bid_plugins(&self) { // init_bid_plugins moved to runner_plugin_init.rs
// v2プラグインシステムを初期化
eprintln!("🔍 DEBUG: Initializing v2 plugin system");
// Try to load nyash.toml configuration
if let Ok(()) = init_global_loader_v2("nyash.toml") {
println!("🔌 v2 plugin system initialized from nyash.toml");
// Apply plugin configuration to the box registry
let loader = get_global_loader_v2();
let loader = loader.read().unwrap();
if let Some(config) = &loader.config {
// Register plugin providers in the box registry
let registry = get_global_registry();
for (lib_name, lib_def) in &config.libraries {
for box_name in &lib_def.boxes {
eprintln!(" 📦 Registering plugin provider for {}", box_name);
// Note: plugin_name is lib_name in v2 system
registry.apply_plugin_config(&PluginConfig {
plugins: [(box_name.clone(), lib_name.clone())].into(),
});
}
}
println!("✅ v2 plugin system fully configured");
}
} else {
eprintln!("⚠️ Failed to load nyash.toml - plugins disabled");
}
}
/// Execute file-based mode with backend selection /// Execute file-based mode with backend selection
fn execute_file_mode(&self, filename: &str) { fn execute_file_mode(&self, filename: &str) {
@ -158,19 +128,31 @@ impl NyashRunner {
process::exit(1); process::exit(1);
} }
} else if self.config.backend == "vm" { } else if self.config.backend == "vm" {
if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") {
println!("🚀 Nyash VM Backend - Executing file: {} 🚀", filename); println!("🚀 Nyash VM Backend - Executing file: {} 🚀", filename);
}
self.execute_vm_mode(filename); self.execute_vm_mode(filename);
} else if self.config.backend == "llvm" { } else if self.config.backend == "llvm" {
if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") {
println!("⚡ Nyash LLVM Backend - Executing file: {}", filename); println!("⚡ Nyash LLVM Backend - Executing file: {}", filename);
}
self.execute_llvm_mode(filename); self.execute_llvm_mode(filename);
} else { } else {
if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") {
println!("🦀 Nyash Rust Implementation - Executing file: {} 🦀", filename); println!("🦀 Nyash Rust Implementation - Executing file: {} 🦀", filename);
}
if let Some(fuel) = self.config.debug_fuel { if let Some(fuel) = self.config.debug_fuel {
if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") {
println!("🔥 Debug fuel limit: {} iterations", fuel); println!("🔥 Debug fuel limit: {} iterations", fuel);
}
} else { } else {
if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") {
println!("🔥 Debug fuel limit: unlimited"); println!("🔥 Debug fuel limit: unlimited");
} }
}
if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") {
println!("===================================================="); println!("====================================================");
}
self.execute_nyash_file(filename); self.execute_nyash_file(filename);
} }

50
src/runner/modes/bench.rs Normal file
View File

@ -0,0 +1,50 @@
use super::super::NyashRunner;
use nyash_rust::{parser::NyashParser, interpreter::NyashInterpreter, box_factory::builtin::BuiltinGroups, mir::MirCompiler, backend::VM};
impl NyashRunner {
/// Execute benchmark mode (split)
pub(crate) fn execute_benchmark_mode(&self) {
println!("🏁 Running benchmark mode with {} iterations", self.config.iterations);
let test_code = r#"
local x
x = 42
local y
y = x + 58
return y
"#;
println!("\n🧪 Test code:\n{}", test_code);
// Interpreter
println!("\n⚡ Interpreter Backend:");
let start = std::time::Instant::now();
for _ in 0..self.config.iterations {
if let Ok(ast) = NyashParser::parse_from_string(test_code) {
let mut interp = NyashInterpreter::new_with_groups(BuiltinGroups::native_full());
let _ = interp.execute(ast);
}
}
let interpreter_time = start.elapsed();
println!(" {} iterations in {:?} ({:.2} ops/sec)", self.config.iterations, interpreter_time, self.config.iterations as f64 / interpreter_time.as_secs_f64());
// VM
println!("\n🚀 VM Backend:");
let start = std::time::Instant::now();
for _ in 0..self.config.iterations {
if let Ok(ast) = NyashParser::parse_from_string(test_code) {
let mut mc = MirCompiler::new();
if let Ok(cr) = mc.compile(ast) {
let mut vm = VM::new();
let _ = vm.execute_module(&cr.module);
}
}
}
let vm_time = start.elapsed();
println!(" {} iterations in {:?} ({:.2} ops/sec)", self.config.iterations, vm_time, self.config.iterations as f64 / vm_time.as_secs_f64());
// Summary
let speedup = interpreter_time.as_secs_f64() / vm_time.as_secs_f64();
println!("\n📊 Performance Summary:\n VM is {:.2}x {} than Interpreter", if speedup > 1.0 { speedup } else { 1.0 / speedup }, if speedup > 1.0 { "faster" } else { "slower" });
}
}

70
src/runner/modes/llvm.rs Normal file
View File

@ -0,0 +1,70 @@
use super::super::NyashRunner;
use nyash_rust::{parser::NyashParser, mir::{MirCompiler, MirInstruction}, box_trait::IntegerBox};
use std::{fs, process};
impl NyashRunner {
/// Execute LLVM mode (split)
pub(crate) fn execute_llvm_mode(&self, filename: &str) {
// Read the file
let code = match fs::read_to_string(filename) {
Ok(content) => content,
Err(e) => { eprintln!("❌ Error reading file {}: {}", filename, e); process::exit(1); }
};
// Parse to AST
let ast = match NyashParser::parse_from_string(&code) {
Ok(ast) => ast,
Err(e) => { eprintln!("❌ Parse error: {}", e); process::exit(1); }
};
// Compile to MIR
let mut mir_compiler = MirCompiler::new();
let compile_result = match mir_compiler.compile(ast) {
Ok(result) => result,
Err(e) => { eprintln!("❌ MIR compilation error: {}", e); process::exit(1); }
};
println!("📊 MIR Module compiled successfully!");
println!("📊 Functions: {}", compile_result.module.functions.len());
// Execute via LLVM backend (mock or real)
#[cfg(feature = "llvm")]
{
use nyash_rust::backend::llvm_compile_and_execute;
let temp_path = "nyash_llvm_temp";
match llvm_compile_and_execute(&compile_result.module, temp_path) {
Ok(result) => {
if let Some(int_result) = result.as_any().downcast_ref::<IntegerBox>() {
let exit_code = int_result.value;
println!("✅ LLVM execution completed!");
println!("📊 Exit code: {}", exit_code);
process::exit(exit_code as i32);
} else {
println!("✅ LLVM execution completed (non-integer result)!");
println!("📊 Result: {}", result.to_string_box().value);
}
},
Err(e) => { eprintln!("❌ LLVM execution error: {}", e); process::exit(1); }
}
}
#[cfg(not(feature = "llvm"))]
{
println!("🔧 Mock LLVM Backend Execution:");
println!(" Build with --features llvm for real compilation.");
if let Some(main_func) = compile_result.module.functions.get("Main.main") {
for (_bid, block) in &main_func.blocks {
for inst in &block.instructions {
match inst {
MirInstruction::Return { value: Some(_) } => { println!("✅ Mock exit code: 42"); process::exit(42); }
MirInstruction::Return { value: None } => { println!("✅ Mock exit code: 0"); process::exit(0); }
_ => {}
}
}
}
}
println!("✅ Mock exit code: 0");
process::exit(0);
}
}
}

49
src/runner/modes/mir.rs Normal file
View File

@ -0,0 +1,49 @@
use super::super::NyashRunner;
use nyash_rust::{parser::NyashParser, mir::{MirCompiler, MirPrinter}};
use std::{fs, process};
impl NyashRunner {
/// Execute MIR compilation and processing mode (split)
pub(crate) fn execute_mir_mode(&self, filename: &str) {
// Read the file
let code = match fs::read_to_string(filename) {
Ok(content) => content,
Err(e) => { eprintln!("❌ Error reading file {}: {}", filename, e); process::exit(1); }
};
// Parse to AST
let ast = match NyashParser::parse_from_string(&code) {
Ok(ast) => ast,
Err(e) => { eprintln!("❌ Parse error: {}", e); process::exit(1); }
};
// Compile to MIR (opt passes configurable)
let mut mir_compiler = MirCompiler::with_options(!self.config.no_optimize);
let compile_result = match mir_compiler.compile(ast) {
Ok(result) => result,
Err(e) => { eprintln!("❌ MIR compilation error: {}", e); process::exit(1); }
};
// Verify MIR if requested
if self.config.verify_mir {
println!("🔍 Verifying MIR...");
match &compile_result.verification_result {
Ok(()) => println!("✅ MIR verification passed!"),
Err(errors) => {
eprintln!("❌ MIR verification failed:");
for error in errors { eprintln!("{}", error); }
process::exit(1);
}
}
}
// Dump MIR if requested
if self.config.dump_mir {
let mut printer = if self.config.mir_verbose { MirPrinter::verbose() } else { MirPrinter::new() };
if self.config.mir_verbose_effects { printer.set_show_effects_inline(true); }
println!("🚀 MIR Output for {}:", filename);
println!("{}", printer.print_module(&compile_result.module));
}
}
}

6
src/runner/modes/mod.rs Normal file
View File

@ -0,0 +1,6 @@
pub mod mir;
pub mod vm;
pub mod llvm;
pub mod bench;
// WASM/AOT modes remain in runner.rs for now (feature-gated)

84
src/runner/modes/vm.rs Normal file
View File

@ -0,0 +1,84 @@
use super::super::NyashRunner;
use nyash_rust::{parser::NyashParser, mir::MirCompiler, backend::VM, runtime::{NyashRuntime, NyashRuntimeBuilder}, ast::ASTNode, core::model::BoxDeclaration as CoreBoxDecl, interpreter::SharedState, box_factory::{builtin::BuiltinGroups, user_defined::UserDefinedBoxFactory}};
use std::{fs, process};
use std::sync::Arc;
impl NyashRunner {
/// Execute VM mode (split)
pub(crate) fn execute_vm_mode(&self, filename: &str) {
// Read the file
let code = match fs::read_to_string(filename) {
Ok(content) => content,
Err(e) => { eprintln!("❌ Error reading file {}: {}", filename, e); process::exit(1); }
};
// Parse to AST
let ast = match NyashParser::parse_from_string(&code) {
Ok(ast) => ast,
Err(e) => { eprintln!("❌ Parse error: {}", e); process::exit(1); }
};
// Prepare runtime and collect Box declarations for VM user-defined types
let runtime = {
let rt = NyashRuntimeBuilder::new()
.with_builtin_groups(BuiltinGroups::native_full())
.build();
self.collect_box_declarations(&ast, &rt);
// Register UserDefinedBoxFactory backed by the same declarations
let mut shared = SharedState::new();
shared.box_declarations = rt.box_declarations.clone();
let udf = Arc::new(UserDefinedBoxFactory::new(shared));
if let Ok(mut reg) = rt.box_registry.lock() { reg.register(udf); }
rt
};
// Compile to MIR (opt passes configurable)
let mut mir_compiler = MirCompiler::with_options(!self.config.no_optimize);
let compile_result = match mir_compiler.compile(ast) {
Ok(result) => result,
Err(e) => { eprintln!("❌ MIR compilation error: {}", e); process::exit(1); }
};
// Execute with VM using prepared runtime
let mut vm = VM::with_runtime(runtime);
match vm.execute_module(&compile_result.module) {
Ok(result) => {
println!("✅ VM execution completed successfully!");
println!("Result: {:?}", result);
},
Err(e) => { eprintln!("❌ VM execution error: {}", e); process::exit(1); }
}
}
/// Collect Box declarations from AST and register into runtime
pub(crate) fn collect_box_declarations(&self, ast: &ASTNode, runtime: &NyashRuntime) {
fn walk(node: &ASTNode, runtime: &NyashRuntime) {
match node {
ASTNode::Program { statements, .. } => { for st in statements { walk(st, runtime); } }
ASTNode::FunctionDeclaration { body, .. } => { for st in body { walk(st, runtime); } }
ASTNode::BoxDeclaration { name, fields, public_fields, private_fields, methods, constructors, init_fields, weak_fields, is_interface, extends, implements, type_parameters, .. } => {
for (_mname, mnode) in methods { walk(mnode, runtime); }
for (_ckey, cnode) in constructors { walk(cnode, runtime); }
let decl = CoreBoxDecl {
name: name.clone(),
fields: fields.clone(),
public_fields: public_fields.clone(),
private_fields: private_fields.clone(),
methods: methods.clone(),
constructors: constructors.clone(),
init_fields: init_fields.clone(),
weak_fields: weak_fields.clone(),
is_interface: *is_interface,
extends: extends.clone(),
implements: implements.clone(),
type_parameters: type_parameters.clone(),
};
if let Ok(mut map) = runtime.box_declarations.write() { map.insert(name.clone(), decl); }
}
_ => {}
}
}
walk(ast, runtime);
}
}

36
src/runner_plugin_init.rs Normal file
View File

@ -0,0 +1,36 @@
/*!
* Runner plugin initialization (extracted from runner.rs)
*
* Purpose: Initialize v2 plugin system from nyash.toml and apply config
* Behavior: Quiet by default; use NYASH_CLI_VERBOSE=1 or NYASH_DEBUG_PLUGIN=1 for logs
*/
use crate::runtime::{init_global_loader_v2, get_global_registry, get_global_loader_v2, PluginConfig};
pub fn init_bid_plugins() {
let cli_verbose = std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1");
let plugin_debug = std::env::var("NYASH_DEBUG_PLUGIN").ok().as_deref() == Some("1");
if plugin_debug { eprintln!("🔍 DEBUG: Initializing v2 plugin system"); }
if let Ok(()) = init_global_loader_v2("nyash.toml") {
if plugin_debug || cli_verbose {
println!("🔌 v2 plugin system initialized from nyash.toml");
}
let loader = get_global_loader_v2();
let loader = loader.read().unwrap();
if let Some(config) = &loader.config {
let registry = get_global_registry();
for (lib_name, lib_def) in &config.libraries {
for box_name in &lib_def.boxes {
if plugin_debug { eprintln!(" 📦 Registering plugin provider for {}", box_name); }
registry.apply_plugin_config(&PluginConfig { plugins: [(box_name.clone(), lib_name.clone())].into(), });
}
}
if plugin_debug || cli_verbose {
println!("✅ v2 plugin system fully configured");
}
}
} else if plugin_debug || cli_verbose {
eprintln!("⚠️ Failed to load nyash.toml - plugins disabled");
}
}

434
ta.txt
View File

@ -1,434 +0,0 @@
warning: unused imports: `BoolBox`, `IntegerBox`, and `StringBox`
--> src/ast.rs:885:28
|
885 | use crate::box_trait::{StringBox, IntegerBox, BoolBox};
| ^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
warning: unused import: `Mutex`
--> src/instance_v2.rs:387:26
|
387 | use std::sync::{Arc, Mutex};
| ^^^^^
warning: unused imports: `BasicBlockIdGenerator`, `BasicBlock`, `CompareOp`, `EffectMask`, `MirFunction`, and `ValueIdGenerator`
--> src/mir/loop_builder.rs:9:21
|
9 | MirInstruction, BasicBlock, BasicBlockId, MirFunction, ValueId,
| ^^^^^^^^^^ ^^^^^^^^^^^
10 | ConstValue, CompareOp, BasicBlockIdGenerator, ValueIdGenerator, EffectMask
| ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ ^^^^^^^^^^
warning: unused import: `HashSet`
--> src/mir/loop_builder.rs:13:33
|
13 | use std::collections::{HashMap, HashSet};
| ^^^^^^^
warning: unused import: `BasicBlock`
--> src/mir/verification.rs:311:75
|
311 | use crate::mir::{MirFunction, FunctionSignature, MirType, EffectMask, BasicBlock};
| ^^^^^^^^^^
warning: unexpected `cfg` condition value: `llvm`
--> src/backend/mod.rs:13:7
|
13 | #[cfg(feature = "llvm")]
| ^^^^^^^^^^^^^^^^
|
= note: expected values for `feature` are: `all-examples`, `cli`, `default`, `dynamic-file`, `gui`, `gui-examples`, and `wasm-backend`
= help: consider adding `llvm` as a feature in `Cargo.toml`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
= note: `#[warn(unexpected_cfgs)]` on by default
warning: unexpected `cfg` condition value: `llvm`
--> src/backend/mod.rs:23:7
|
23 | #[cfg(feature = "llvm")]
| ^^^^^^^^^^^^^^^^
|
= note: expected values for `feature` are: `all-examples`, `cli`, `default`, `dynamic-file`, `gui`, `gui-examples`, and `wasm-backend`
= help: consider adding `llvm` as a feature in `Cargo.toml`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
warning: unused imports: `BasicBlock`, `EffectMask`, `FunctionSignature`, `MirFunction`, `MirModule`, and `MirType`
--> src/backend/vm.rs:860:22
|
860 | use crate::mir::{MirModule, MirFunction, FunctionSignature, MirType, EffectMask, BasicBlock};
| ^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ ^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^
warning: unused import: `MirInstruction`
--> src/backend/vm_phi.rs:9:41
|
9 | use crate::mir::{BasicBlockId, ValueId, MirInstruction};
| ^^^^^^^^^^^^^^
warning: unused import: `super::Usize`
--> src/bid/types.rs:1:5
|
1 | use super::Usize;
| ^^^^^^^^^^^^
warning: unused import: `std::os::raw::c_char`
--> src/bid/plugin_api.rs:2:5
|
2 | use std::os::raw::c_char;
| ^^^^^^^^^^^^^^^^^^^^
warning: unused imports: `NyashHostVtable`, `NyashMethodInfo`, and `NyashPluginInfo`
--> src/bid/plugins/filebox/mod.rs:7:18
|
7 | use crate::bid::{NyashPluginInfo, NyashMethodInfo, NyashHostVtable};
| ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
warning: unused imports: `SeekFrom` and `Seek`
--> src/bid/plugins/filebox/mod.rs:10:28
|
10 | use std::io::{Read, Write, Seek, SeekFrom};
| ^^^^ ^^^^^^^^
warning: unused imports: `c_char` and `c_void`
--> src/bid/plugins/filebox/mod.rs:11:20
|
11 | use std::os::raw::{c_char, c_void};
| ^^^^^^ ^^^^^^
warning: unused imports: `CStr` and `CString`
--> src/bid/plugins/filebox/mod.rs:13:16
|
13 | use std::ffi::{CStr, CString};
| ^^^^ ^^^^^^^
warning: unused import: `std::ffi::c_void`
--> src/bid/loader.rs:3:5
|
3 | use std::ffi::c_void;
| ^^^^^^^^^^^^^^^^
warning: unused imports: `TlvDecoder` and `TlvEncoder`
--> src/bid/generic_plugin_box.rs:2:23
|
2 | use crate::bid::tlv::{TlvEncoder, TlvDecoder};
| ^^^^^^^^^^ ^^^^^^^^^^
warning: unused import: `crate::bid::types::BidTag`
--> src/bid/generic_plugin_box.rs:3:5
|
3 | use crate::bid::types::BidTag;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused import: `BoxBase`
--> src/runtime/plugin_loader_v2.rs:7:43
|
7 | use crate::box_trait::{NyashBox, BoxCore, BoxBase, StringBox};
| ^^^^^^^
warning: unused import: `std::ffi::c_void`
--> src/runtime/plugin_loader_v2.rs:11:5
|
11 | use std::ffi::c_void;
| ^^^^^^^^^^^^^^^^
warning: unused imports: `BidHandle` and `BoxTypeId`
--> src/runtime/tests.rs:10:22
|
10 | use crate::bid::{BidHandle, BoxTypeId};
| ^^^^^^^^^ ^^^^^^^^^
warning: unused variable: `registry`
--> src/box_factory/plugin.rs:53:13
|
53 | let registry = get_global_registry();
| ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_registry`
|
= note: `#[warn(unused_variables)]` on by default
warning: unused variable: `args`
--> src/instance_v2.rs:147:28
|
147 | pub fn init(&mut self, args: &[Box<dyn NyashBox>]) -> Result<(), String> {
| ^^^^ help: if this is intentional, prefix it with an underscore: `_args`
warning: unused variable: `nyash_value`
--> src/instance_v2.rs:289:21
|
289 | if let Some(nyash_value) = self.fields_ng.lock().unwrap().get(field_name) {
| ^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_nyash_value`
warning: variable does not need to be mutable
--> src/mir/basic_block.rs:314:13
|
314 | let mut bb = BasicBlock::new(bb_id);
| ----^^
| |
| help: remove this `mut`
|
= note: `#[warn(unused_mut)]` on by default
warning: unused variable: `block_id`
--> src/mir/loop_builder.rs:246:39
|
246 | fn mark_block_unsealed(&mut self, block_id: BasicBlockId) -> Result<(), String> {
| ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_block_id`
warning: unused variable: `block_id`
--> src/mir/loop_builder.rs:273:49
|
273 | fn get_variable_at_block(&self, name: &str, block_id: BasicBlockId) -> Option<ValueId> {
| ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_block_id`
warning: unused variable: `child`
--> src/mir/ownership_verifier_simple.rs:313:13
|
313 | let child = value_gen.next();
| ^^^^^ help: if this is intentional, prefix it with an underscore: `_child`
warning: unused variable: `dst`
--> src/backend/vm_phi.rs:48:9
|
48 | dst: ValueId,
| ^^^ help: if this is intentional, prefix it with an underscore: `_dst`
warning: unused variable: `f`
--> src/bid/plugin_api.rs:167:36
|
167 | pub fn with_alloc<F>(mut self, f: F) -> Self
| ^ help: if this is intentional, prefix it with an underscore: `_f`
warning: variable does not need to be mutable
--> src/bid/plugin_api.rs:167:26
|
167 | pub fn with_alloc<F>(mut self, f: F) -> Self
| ----^^^^
| |
| help: remove this `mut`
warning: unused variable: `f`
--> src/bid/plugin_api.rs:176:35
|
176 | pub fn with_free<F>(mut self, f: F) -> Self
| ^ help: if this is intentional, prefix it with an underscore: `_f`
warning: variable does not need to be mutable
--> src/bid/plugin_api.rs:176:25
|
176 | pub fn with_free<F>(mut self, f: F) -> Self
| ----^^^^
| |
| help: remove this `mut`
warning: unused variable: `f`
--> src/bid/plugin_api.rs:183:34
|
183 | pub fn with_log<F>(mut self, f: F) -> Self
| ^ help: if this is intentional, prefix it with an underscore: `_f`
warning: variable does not need to be mutable
--> src/bid/plugin_api.rs:183:24
|
183 | pub fn with_log<F>(mut self, f: F) -> Self
| ----^^^^
| |
| help: remove this `mut`
warning: unused variable: `args`
--> src/runtime/plugin_loader_v2.rs:236:46
|
236 | pub fn create_box(&self, box_type: &str, args: &[Box<dyn NyashBox>]) -> BidResult<Box<dyn NyashBox>> {
| ^^^^ help: if this is intentional, prefix it with an underscore: `_args`
warning: variable does not need to be mutable
--> src/tests/box_tests.rs:11:13
|
11 | let mut array = ArrayBox::new();
| ----^^^^^
| |
| help: remove this `mut`
warning: variable does not need to be mutable
--> src/tests/box_tests.rs:90:13
|
90 | let mut stream = NyashStreamBox::from_data(vec![72, 101, 108, 108, 111]); // "Hello"
| ----^^^^^^
| |
| help: remove this `mut`
warning: type `FileMode` is more private than the item `FileBoxRegistry::open`
--> src/bid/plugins/filebox/mod.rs:44:5
|
44 | pub fn open(&mut self, path: &str, mode: FileMode) -> Result<BidHandle, std::io::Error> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ method `FileBoxRegistry::open` is reachable at visibility `pub`
|
note: but type `FileMode` is only usable at visibility `pub(self)`
--> src/bid/plugins/filebox/mod.rs:29:1
|
29 | enum FileMode {
| ^^^^^^^^^^^^^
= note: `#[warn(private_interfaces)]` on by default
warning: field `block_var_maps` is never read
--> src/mir/loop_builder.rs:35:5
|
27 | pub struct LoopBuilder<'a> {
| ----------- field in this struct
...
35 | block_var_maps: HashMap<BasicBlockId, HashMap<String, ValueId>>,
| ^^^^^^^^^^^^^^
|
= note: `#[warn(dead_code)]` on by default
warning: fields `type_name_holder` and `method_holders` are never read
--> src/bid/metadata.rs:148:5
|
143 | pub struct PluginMetadata {
| -------------- fields in this struct
...
148 | type_name_holder: Option<CString>,
| ^^^^^^^^^^^^^^^^
149 | method_holders: Vec<(NyashMethodInfo, CString)>,
| ^^^^^^^^^^^^^^
warning: fields `path` and `mode` are never read
--> src/bid/plugins/filebox/mod.rs:24:5
|
22 | struct FileBoxState {
| ------------ fields in this struct
23 | file: File,
24 | path: String,
| ^^^^
25 | mode: FileMode,
| ^^^^
warning: fields `box_types` and `init_fn` are never read
--> src/runtime/plugin_loader_v2.rs:20:5
|
15 | pub struct LoadedPluginV2 {
| -------------- fields in this struct
...
20 | box_types: Vec<String>,
| ^^^^^^^^^
...
23 | init_fn: Option<unsafe extern "C" fn() -> i32>,
| ^^^^^^^
warning: unused `Result` that must be used
--> src/mir/loop_builder.rs:62:9
|
62 | self.add_predecessor(header_id, preheader_id);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
= note: `#[warn(unused_must_use)]` on by default
help: use `let _ = ...` to ignore the resulting value
|
62 | let _ = self.add_predecessor(header_id, preheader_id);
| +++++++
warning: unused `Result` that must be used
--> src/mir/loop_builder.rs:66:9
|
66 | self.mark_block_unsealed(header_id);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
help: use `let _ = ...` to ignore the resulting value
|
66 | let _ = self.mark_block_unsealed(header_id);
| +++++++
warning: unused `Result` that must be used
--> src/mir/loop_builder.rs:78:9
|
78 | self.add_predecessor(body_id, header_id);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
help: use `let _ = ...` to ignore the resulting value
|
78 | let _ = self.add_predecessor(body_id, header_id);
| +++++++
warning: unused `Result` that must be used
--> src/mir/loop_builder.rs:79:9
|
79 | self.add_predecessor(after_loop_id, header_id);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
help: use `let _ = ...` to ignore the resulting value
|
79 | let _ = self.add_predecessor(after_loop_id, header_id);
| +++++++
warning: unused `Result` that must be used
--> src/mir/loop_builder.rs:93:9
|
93 | self.add_predecessor(header_id, latch_id);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
help: use `let _ = ...` to ignore the resulting value
|
93 | let _ = self.add_predecessor(header_id, latch_id);
| +++++++
warning: creating a shared reference to mutable static
--> src/bid/plugins/filebox/mod.rs:102:12
|
102 | if FILEBOX_REGISTRY.is_none() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
= note: `#[warn(static_mut_refs)]` on by default
warning: creating a shared reference to mutable static
--> src/bid/plugins/filebox/mod.rs:105:9
|
105 | FILEBOX_REGISTRY.as_ref().unwrap().clone()
| ^^^^^^^^^^^^^^^^^^^^^^^^^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
warning: `nyash-rust` (lib test) generated 50 warnings (run `cargo fix --lib -p nyash-rust --tests` to apply 25 suggestions)
Finished `test` profile [unoptimized + debuginfo] target(s) in 1.81s
Running unittests src/lib.rs (target/debug/deps/nyash_rust-027bd4c76143e77b)
running 1 test
🔍 DEBUG: Starting interpreter execution...
🔍 DEBUG: execute_node called with node type: Program
🔍 DEBUG: Executing program with 1 statements
🔍 DEBUG: Executing statement 1 of 1: Assignment
🔍 execute_statement called with node type: "Assignment"
🔍 About to call execute_assignment...
🔍 execute_assignment called, evaluating value expression...
🔍 execute_new called for class: IntegerBox, with 1 arguments
🔍 Trying unified registry for class: IntegerBox
🏭 Unified registry created: IntegerBox
🔍 execute_new called for class: IntegerBox, with 1 arguments
🔍 Trying unified registry for class: IntegerBox
🏭 Unified registry created: IntegerBox
🔧 execute_binary_op: op=Add, left=IntegerBox, right=IntegerBox
🔍 try_add_operation: left=IntegerBox, right=IntegerBox
🔍 After unwrap: left=IntegerBox, right=IntegerBox
🔍 Checking StringBox downcast...
🔍 StringBox downcast FAILED!
❌ Interpreter error: Invalid operation: Addition not supported between IntegerBox and IntegerBox
🔍 DEBUG: Interpreter execution completed
thread 'interpreter::core::tests::test_arithmetic' panicked at src/interpreter/core.rs:590:34:
called `Result::unwrap()` on an `Err` value: InvalidOperation { message: "Addition not supported between IntegerBox and IntegerBox" }
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
test interpreter::core::tests::test_arithmetic ... FAILED
failures:
failures:
interpreter::core::tests::test_arithmetic
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 155 filtered out; finished in 0.19s
error: test failed, to rerun pass `--lib`

View File

@ -1 +0,0 @@
Hello from Nyash!

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,405 +0,0 @@
Compiling nyash-rust v0.1.0 (/mnt/c/git/nyash-project/nyash)
warning: unused imports: `BoolBox`, `IntegerBox`, and `StringBox`
--> src/ast.rs:885:28
|
885 | use crate::box_trait::{StringBox, IntegerBox, BoolBox};
| ^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
warning: unused import: `Mutex`
--> src/instance_v2.rs:387:26
|
387 | use std::sync::{Arc, Mutex};
| ^^^^^
warning: unused imports: `BasicBlockIdGenerator`, `BasicBlock`, `CompareOp`, `EffectMask`, `MirFunction`, and `ValueIdGenerator`
--> src/mir/loop_builder.rs:9:21
|
9 | MirInstruction, BasicBlock, BasicBlockId, MirFunction, ValueId,
| ^^^^^^^^^^ ^^^^^^^^^^^
10 | ConstValue, CompareOp, BasicBlockIdGenerator, ValueIdGenerator, EffectMask
| ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ ^^^^^^^^^^
warning: unused import: `HashSet`
--> src/mir/loop_builder.rs:13:33
|
13 | use std::collections::{HashMap, HashSet};
| ^^^^^^^
warning: unused import: `BasicBlock`
--> src/mir/verification.rs:311:75
|
311 | use crate::mir::{MirFunction, FunctionSignature, MirType, EffectMask, BasicBlock};
| ^^^^^^^^^^
warning: unexpected `cfg` condition value: `llvm`
--> src/backend/mod.rs:13:7
|
13 | #[cfg(feature = "llvm")]
| ^^^^^^^^^^^^^^^^
|
= note: expected values for `feature` are: `all-examples`, `cli`, `default`, `dynamic-file`, `gui`, `gui-examples`, and `wasm-backend`
= help: consider adding `llvm` as a feature in `Cargo.toml`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
= note: `#[warn(unexpected_cfgs)]` on by default
warning: unexpected `cfg` condition value: `llvm`
--> src/backend/mod.rs:23:7
|
23 | #[cfg(feature = "llvm")]
| ^^^^^^^^^^^^^^^^
|
= note: expected values for `feature` are: `all-examples`, `cli`, `default`, `dynamic-file`, `gui`, `gui-examples`, and `wasm-backend`
= help: consider adding `llvm` as a feature in `Cargo.toml`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
warning: unused imports: `BasicBlock`, `EffectMask`, `FunctionSignature`, `MirFunction`, `MirModule`, and `MirType`
--> src/backend/vm.rs:860:22
|
860 | use crate::mir::{MirModule, MirFunction, FunctionSignature, MirType, EffectMask, BasicBlock};
| ^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ ^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^
warning: unused import: `MirInstruction`
--> src/backend/vm_phi.rs:9:41
|
9 | use crate::mir::{BasicBlockId, ValueId, MirInstruction};
| ^^^^^^^^^^^^^^
warning: unused import: `super::Usize`
--> src/bid/types.rs:1:5
|
1 | use super::Usize;
| ^^^^^^^^^^^^
warning: unused import: `std::os::raw::c_char`
--> src/bid/plugin_api.rs:2:5
|
2 | use std::os::raw::c_char;
| ^^^^^^^^^^^^^^^^^^^^
warning: unused imports: `NyashHostVtable`, `NyashMethodInfo`, and `NyashPluginInfo`
--> src/bid/plugins/filebox/mod.rs:7:18
|
7 | use crate::bid::{NyashPluginInfo, NyashMethodInfo, NyashHostVtable};
| ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
warning: unused imports: `SeekFrom` and `Seek`
--> src/bid/plugins/filebox/mod.rs:10:28
|
10 | use std::io::{Read, Write, Seek, SeekFrom};
| ^^^^ ^^^^^^^^
warning: unused imports: `c_char` and `c_void`
--> src/bid/plugins/filebox/mod.rs:11:20
|
11 | use std::os::raw::{c_char, c_void};
| ^^^^^^ ^^^^^^
warning: unused imports: `CStr` and `CString`
--> src/bid/plugins/filebox/mod.rs:13:16
|
13 | use std::ffi::{CStr, CString};
| ^^^^ ^^^^^^^
warning: unused import: `std::ffi::c_void`
--> src/bid/loader.rs:3:5
|
3 | use std::ffi::c_void;
| ^^^^^^^^^^^^^^^^
warning: unused imports: `TlvDecoder` and `TlvEncoder`
--> src/bid/generic_plugin_box.rs:2:23
|
2 | use crate::bid::tlv::{TlvEncoder, TlvDecoder};
| ^^^^^^^^^^ ^^^^^^^^^^
warning: unused import: `crate::bid::types::BidTag`
--> src/bid/generic_plugin_box.rs:3:5
|
3 | use crate::bid::types::BidTag;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: unused import: `BoxBase`
--> src/runtime/plugin_loader_v2.rs:7:43
|
7 | use crate::box_trait::{NyashBox, BoxCore, BoxBase, StringBox};
| ^^^^^^^
warning: unused import: `std::ffi::c_void`
--> src/runtime/plugin_loader_v2.rs:11:5
|
11 | use std::ffi::c_void;
| ^^^^^^^^^^^^^^^^
warning: unused imports: `BidHandle` and `BoxTypeId`
--> src/runtime/tests.rs:10:22
|
10 | use crate::bid::{BidHandle, BoxTypeId};
| ^^^^^^^^^ ^^^^^^^^^
warning: unused variable: `registry`
--> src/box_factory/plugin.rs:53:13
|
53 | let registry = get_global_registry();
| ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_registry`
|
= note: `#[warn(unused_variables)]` on by default
warning: unused variable: `args`
--> src/instance_v2.rs:147:28
|
147 | pub fn init(&mut self, args: &[Box<dyn NyashBox>]) -> Result<(), String> {
| ^^^^ help: if this is intentional, prefix it with an underscore: `_args`
warning: unused variable: `nyash_value`
--> src/instance_v2.rs:289:21
|
289 | if let Some(nyash_value) = self.fields_ng.lock().unwrap().get(field_name) {
| ^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_nyash_value`
warning: variable does not need to be mutable
--> src/mir/basic_block.rs:314:13
|
314 | let mut bb = BasicBlock::new(bb_id);
| ----^^
| |
| help: remove this `mut`
|
= note: `#[warn(unused_mut)]` on by default
warning: unused variable: `block_id`
--> src/mir/loop_builder.rs:246:39
|
246 | fn mark_block_unsealed(&mut self, block_id: BasicBlockId) -> Result<(), String> {
| ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_block_id`
warning: unused variable: `block_id`
--> src/mir/loop_builder.rs:273:49
|
273 | fn get_variable_at_block(&self, name: &str, block_id: BasicBlockId) -> Option<ValueId> {
| ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_block_id`
warning: unused variable: `child`
--> src/mir/ownership_verifier_simple.rs:313:13
|
313 | let child = value_gen.next();
| ^^^^^ help: if this is intentional, prefix it with an underscore: `_child`
warning: unused variable: `dst`
--> src/backend/vm_phi.rs:48:9
|
48 | dst: ValueId,
| ^^^ help: if this is intentional, prefix it with an underscore: `_dst`
warning: unused variable: `f`
--> src/bid/plugin_api.rs:167:36
|
167 | pub fn with_alloc<F>(mut self, f: F) -> Self
| ^ help: if this is intentional, prefix it with an underscore: `_f`
warning: variable does not need to be mutable
--> src/bid/plugin_api.rs:167:26
|
167 | pub fn with_alloc<F>(mut self, f: F) -> Self
| ----^^^^
| |
| help: remove this `mut`
warning: unused variable: `f`
--> src/bid/plugin_api.rs:176:35
|
176 | pub fn with_free<F>(mut self, f: F) -> Self
| ^ help: if this is intentional, prefix it with an underscore: `_f`
warning: variable does not need to be mutable
--> src/bid/plugin_api.rs:176:25
|
176 | pub fn with_free<F>(mut self, f: F) -> Self
| ----^^^^
| |
| help: remove this `mut`
warning: unused variable: `f`
--> src/bid/plugin_api.rs:183:34
|
183 | pub fn with_log<F>(mut self, f: F) -> Self
| ^ help: if this is intentional, prefix it with an underscore: `_f`
warning: variable does not need to be mutable
--> src/bid/plugin_api.rs:183:24
|
183 | pub fn with_log<F>(mut self, f: F) -> Self
| ----^^^^
| |
| help: remove this `mut`
warning: unused variable: `args`
--> src/runtime/plugin_loader_v2.rs:236:46
|
236 | pub fn create_box(&self, box_type: &str, args: &[Box<dyn NyashBox>]) -> BidResult<Box<dyn NyashBox>> {
| ^^^^ help: if this is intentional, prefix it with an underscore: `_args`
warning: variable does not need to be mutable
--> src/tests/box_tests.rs:11:13
|
11 | let mut array = ArrayBox::new();
| ----^^^^^
| |
| help: remove this `mut`
warning: variable does not need to be mutable
--> src/tests/box_tests.rs:90:13
|
90 | let mut stream = NyashStreamBox::from_data(vec![72, 101, 108, 108, 111]); // "Hello"
| ----^^^^^^
| |
| help: remove this `mut`
warning: type `FileMode` is more private than the item `FileBoxRegistry::open`
--> src/bid/plugins/filebox/mod.rs:44:5
|
44 | pub fn open(&mut self, path: &str, mode: FileMode) -> Result<BidHandle, std::io::Error> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ method `FileBoxRegistry::open` is reachable at visibility `pub`
|
note: but type `FileMode` is only usable at visibility `pub(self)`
--> src/bid/plugins/filebox/mod.rs:29:1
|
29 | enum FileMode {
| ^^^^^^^^^^^^^
= note: `#[warn(private_interfaces)]` on by default
warning: field `block_var_maps` is never read
--> src/mir/loop_builder.rs:35:5
|
27 | pub struct LoopBuilder<'a> {
| ----------- field in this struct
...
35 | block_var_maps: HashMap<BasicBlockId, HashMap<String, ValueId>>,
| ^^^^^^^^^^^^^^
|
= note: `#[warn(dead_code)]` on by default
warning: fields `type_name_holder` and `method_holders` are never read
--> src/bid/metadata.rs:148:5
|
143 | pub struct PluginMetadata {
| -------------- fields in this struct
...
148 | type_name_holder: Option<CString>,
| ^^^^^^^^^^^^^^^^
149 | method_holders: Vec<(NyashMethodInfo, CString)>,
| ^^^^^^^^^^^^^^
warning: fields `path` and `mode` are never read
--> src/bid/plugins/filebox/mod.rs:24:5
|
22 | struct FileBoxState {
| ------------ fields in this struct
23 | file: File,
24 | path: String,
| ^^^^
25 | mode: FileMode,
| ^^^^
warning: fields `box_types` and `init_fn` are never read
--> src/runtime/plugin_loader_v2.rs:20:5
|
15 | pub struct LoadedPluginV2 {
| -------------- fields in this struct
...
20 | box_types: Vec<String>,
| ^^^^^^^^^
...
23 | init_fn: Option<unsafe extern "C" fn() -> i32>,
| ^^^^^^^
warning: unused `Result` that must be used
--> src/mir/loop_builder.rs:62:9
|
62 | self.add_predecessor(header_id, preheader_id);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
= note: `#[warn(unused_must_use)]` on by default
help: use `let _ = ...` to ignore the resulting value
|
62 | let _ = self.add_predecessor(header_id, preheader_id);
| +++++++
warning: unused `Result` that must be used
--> src/mir/loop_builder.rs:66:9
|
66 | self.mark_block_unsealed(header_id);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
help: use `let _ = ...` to ignore the resulting value
|
66 | let _ = self.mark_block_unsealed(header_id);
| +++++++
warning: unused `Result` that must be used
--> src/mir/loop_builder.rs:78:9
|
78 | self.add_predecessor(body_id, header_id);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
help: use `let _ = ...` to ignore the resulting value
|
78 | let _ = self.add_predecessor(body_id, header_id);
| +++++++
warning: unused `Result` that must be used
--> src/mir/loop_builder.rs:79:9
|
79 | self.add_predecessor(after_loop_id, header_id);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
help: use `let _ = ...` to ignore the resulting value
|
79 | let _ = self.add_predecessor(after_loop_id, header_id);
| +++++++
warning: unused `Result` that must be used
--> src/mir/loop_builder.rs:93:9
|
93 | self.add_predecessor(header_id, latch_id);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this `Result` may be an `Err` variant, which should be handled
help: use `let _ = ...` to ignore the resulting value
|
93 | let _ = self.add_predecessor(header_id, latch_id);
| +++++++
warning: creating a shared reference to mutable static
--> src/bid/plugins/filebox/mod.rs:102:12
|
102 | if FILEBOX_REGISTRY.is_none() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
= note: `#[warn(static_mut_refs)]` on by default
warning: creating a shared reference to mutable static
--> src/bid/plugins/filebox/mod.rs:105:9
|
105 | FILEBOX_REGISTRY.as_ref().unwrap().clone()
| ^^^^^^^^^^^^^^^^^^^^^^^^^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
error: could not compile `nyash-rust` (lib)
Caused by:
could not execute process `/home/tomoaki/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/rustc --crate-name nyash_rust --edition=2021 src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --crate-type cdylib --crate-type rlib --emit=dep-info,link -C embed-bitcode=no -C debuginfo=2 --cfg 'feature="cli"' --cfg 'feature="default"' --check-cfg 'cfg(docsrs,test)' --check-cfg 'cfg(feature, values("all-examples", "cli", "default", "dynamic-file", "gui", "gui-examples", "wasm-backend"))' -C metadata=024e0bfefa24aea7 --out-dir /mnt/c/git/nyash-project/nyash/target/debug/deps -C incremental=/mnt/c/git/nyash-project/nyash/target/debug/incremental -L dependency=/mnt/c/git/nyash-project/nyash/target/debug/deps --extern anyhow=/mnt/c/git/nyash-project/nyash/target/debug/deps/libanyhow-cb0106135621df54.rlib --extern chrono=/mnt/c/git/nyash-project/nyash/target/debug/deps/libchrono-0d332b6d25ba4f26.rlib --extern clap=/mnt/c/git/nyash-project/nyash/target/debug/deps/libclap-402745ede5642e57.rlib --extern console_error_panic_hook=/mnt/c/git/nyash-project/nyash/target/debug/deps/libconsole_error_panic_hook-8d542a370ca115ea.rlib --extern env_logger=/mnt/c/git/nyash-project/nyash/target/debug/deps/libenv_logger-b5822987cce07060.rlib --extern js_sys=/mnt/c/git/nyash-project/nyash/target/debug/deps/libjs_sys-9f8e174f128030e3.rlib --extern lazy_static=/mnt/c/git/nyash-project/nyash/target/debug/deps/liblazy_static-a60c6f0d6f5b0a48.rlib --extern libloading=/mnt/c/git/nyash-project/nyash/target/debug/deps/liblibloading-212293e6e9433adc.rlib --extern log=/mnt/c/git/nyash-project/nyash/target/debug/deps/liblog-97254b5c9fae48ec.rlib --extern once_cell=/mnt/c/git/nyash-project/nyash/target/debug/deps/libonce_cell-140027e2059e248c.rlib --extern regex=/mnt/c/git/nyash-project/nyash/target/debug/deps/libregex-593e58218ee7d01e.rlib --extern serde=/mnt/c/git/nyash-project/nyash/target/debug/deps/libserde-fe05dc3dd0f4c02d.rlib --extern serde_json=/mnt/c/git/nyash-project/nyash/target/debug/deps/libserde_json-4c960d663cd516d2.rlib --extern thiserror=/mnt/c/git/nyash-project/nyash/target/debug/deps/libthiserror-4e3b67f662716893.rlib --extern toml=/mnt/c/git/nyash-project/nyash/target/debug/deps/libtoml-5883ff1c2c8abaf1.rlib --extern wasm_bindgen=/mnt/c/git/nyash-project/nyash/target/debug/deps/libwasm_bindgen-79650e8bccd47590.rlib --extern web_sys=/mnt/c/git/nyash-project/nyash/target/debug/deps/libweb_sys-a459292f085ab080.rlib` (never executed)
Caused by:
Operation not permitted (os error 1)
warning: build failed, waiting for other jobs to finish...
warning: `nyash-rust` (lib test) generated 50 warnings (run `cargo fix --lib -p nyash-rust --tests` to apply 25 suggestions)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,197 +0,0 @@
🔍 DEBUG: Initializing v2 plugin system
[net] Net plugin initialized, LOG_ON=true, LOG_PATH=net_plugin.log
Net plugin: LOG_ON=true, LOG_PATH=net_plugin.log
[PluginLoaderV2] nyash_plugin_init rc=0 for libnyash_net_plugin.so
[PluginLoaderV2] nyash_plugin_init rc=0 for libnyash_counter_plugin.so
[FileBox] Plugin initialized
[PluginLoaderV2] nyash_plugin_init rc=0 for libnyash_filebox_plugin.so
🔌 v2 plugin system initialized from nyash.toml
📦 Registering plugin provider for HttpServerBox
📦 Registering plugin provider for HttpClientBox
📦 Registering plugin provider for HttpResponseBox
📦 Registering plugin provider for HttpRequestBox
📦 Registering plugin provider for SocketServerBox
📦 Registering plugin provider for SocketClientBox
📦 Registering plugin provider for SocketConnBox
📦 Registering plugin provider for CounterBox
📦 Registering plugin provider for FileBox
✅ v2 plugin system fully configured
🦀 Nyash Rust Implementation - Executing file: local_tests/test_http_simple_e2e.nyash 🦀
🔥 Debug fuel limit: 100000 iterations
====================================================
📝 File contents:
// Very simple HTTP test
local srv, cli, r, resp
srv = new HttpServerBox()
print("HttpServerBox created")
// Start server
local startResult = srv.start(8090)
print("Server start result:")
print(startResult)
// Create client
cli = new HttpClientBox()
print("HttpClientBox created")
// Make request
r = cli.get("http://localhost:8090/test")
print("Request made")
// Accept connection
local acceptResult = srv.accept()
print("Accept result:")
print(acceptResult)
// Get value from accept result
local req = acceptResult.get_value()
print("Got request value")
// Create response
resp = new HttpResponseBox()
resp.write("Hello!")
print("Response created and written")
// Send response
req.respond(resp)
print("Response sent")
// Get response on client side
local clientResp = r.get_value()
print("Got client response")
// Read body
local body = clientResp.readBody()
print("Body: " + body)
🚀 Parsing and executing...
🔍 DEBUG: Starting parse with fuel: Some(100000)...
🔍 DEBUG: Parse completed, AST created
🔍 DEBUG: About to print parse success message...
✅ Parse successful!
🔍 DEBUG: Parse success message printed
🔍 DEBUG: Creating interpreter...
🔍 DEBUG: Starting execution...
🔍 create_box called for: HttpServerBox
🔍 Config loaded successfully
🔍 Found library: libnyash_net_plugin.so for box type: HttpServerBox
🔍 Plugin loaded successfully
🔍 Reading nyash.toml for type configuration...
🔍 nyash.toml read successfully
🔍 nyash.toml parsed successfully
🔍 Found box config for HttpServerBox with type_id: 20
🔍 Preparing to call birth() with type_id: 20
🔍 Output buffer allocated, about to call plugin invoke_fn...
🔍 Calling invoke_fn(type_id=20, method_id=0, instance_id=0, tlv_args=[1, 0, 0, 0], output_buf, output_size=1024)
🔍 invoke_fn returned with result: 0
🎉 birth() success: HttpServerBox instance_id=1
🔍 DEBUG: PluginBoxV2::share_box called for HttpServerBox (id=1)
HttpServerBox created
🔍 stdlib not initialized for method call
🔍 DEBUG: PluginBoxV2::share_box called for HttpServerBox (id=1)
🔍 DEBUG: execute_method_call - object type: PluginBoxV2, method: start
🔍 DEBUG: Checking StringBox downcast for type: PluginBoxV2
🔍 DEBUG: StringBox downcast failed
🔍 execute_plugin_box_v2_method called: HttpServerBox.start
[PluginLoaderV2] Invoke HttpServerBox.start: resolving and encoding args (argc=1)
[PluginLoaderV2] arg[0]: Integer(8090) -> I32(tag=2)
[net] http:listener bound 127.0.0.1:8090
Server start result:
Ok(void)
🔍 create_box called for: HttpClientBox
🔍 Config loaded successfully
🔍 Found library: libnyash_net_plugin.so for box type: HttpClientBox
🔍 Plugin loaded successfully
🔍 Reading nyash.toml for type configuration...
🔍 nyash.toml read successfully
🔍 nyash.toml parsed successfully
🔍 Found box config for HttpClientBox with type_id: 23
🔍 Preparing to call birth() with type_id: 23
🔍 Output buffer allocated, about to call plugin invoke_fn...
🔍 Calling invoke_fn(type_id=23, method_id=0, instance_id=0, tlv_args=[1, 0, 0, 0], output_buf, output_size=1024)
🔍 invoke_fn returned with result: 0
🎉 birth() success: HttpClientBox instance_id=1
🔍 DEBUG: PluginBoxV2::share_box called for HttpClientBox (id=1)
HttpClientBox created
🔍 stdlib not initialized for method call
🔍 DEBUG: PluginBoxV2::share_box called for HttpClientBox (id=1)
🔍 DEBUG: execute_method_call - object type: PluginBoxV2, method: get
🔍 DEBUG: Checking StringBox downcast for type: PluginBoxV2
🔍 DEBUG: StringBox downcast failed
🔍 execute_plugin_box_v2_method called: HttpClientBox.get
[PluginLoaderV2] Invoke HttpClientBox.get: resolving and encoding args (argc=1)
[PluginLoaderV2] arg[0]: String(len=26) -> String(tag=6)
[net] client.get: url=http://localhost:8090/test resp_id=1 tcp_ok=true conn_id=1
[net] http:accept linked resp_id hint=1 for req_id=1 conn_id=2
🔍 DEBUG: PluginBoxV2::share_box called for HttpResponseBox (id=1)
Request made
🔍 stdlib not initialized for method call
🔍 DEBUG: PluginBoxV2::share_box called for HttpServerBox (id=1)
🔍 DEBUG: execute_method_call - object type: PluginBoxV2, method: accept
🔍 DEBUG: Checking StringBox downcast for type: PluginBoxV2
🔍 DEBUG: StringBox downcast failed
🔍 execute_plugin_box_v2_method called: HttpServerBox.accept
[PluginLoaderV2] Invoke HttpServerBox.accept: resolving and encoding args (argc=0)
[net] server.accept: return req_id=1 srv_id=1
Accept result:
🔍 DEBUG: PluginBoxV2::share_box called for HttpRequestBox (id=1)
Ok(HttpRequestBox(1))
🔍 stdlib not initialized for method call
🔍 DEBUG: PluginBoxV2::share_box called for HttpRequestBox (id=1)
🔍 DEBUG: execute_method_call - object type: NyashResultBox, method: get_value
🔍 DEBUG: Checking StringBox downcast for type: NyashResultBox
🔍 DEBUG: StringBox downcast failed
🔍 DEBUG: PluginBoxV2::share_box called for HttpRequestBox (id=1)
🔍 DEBUG: PluginBoxV2::share_box called for HttpRequestBox (id=1)
Got request value
🔍 create_box called for: HttpResponseBox
🔍 Config loaded successfully
🔍 Found library: libnyash_net_plugin.so for box type: HttpResponseBox
🔍 Plugin loaded successfully
🔍 Reading nyash.toml for type configuration...
🔍 nyash.toml read successfully
🔍 nyash.toml parsed successfully
🔍 Found box config for HttpResponseBox with type_id: 22
🔍 Preparing to call birth() with type_id: 22
🔍 Output buffer allocated, about to call plugin invoke_fn...
🔍 Calling invoke_fn(type_id=22, method_id=0, instance_id=0, tlv_args=[1, 0, 0, 0], output_buf, output_size=1024)
🔍 invoke_fn returned with result: 0
🎉 birth() success: HttpResponseBox instance_id=2
🔍 DEBUG: PluginBoxV2::share_box called for HttpResponseBox (id=2)
🔍 stdlib not initialized for method call
🔍 DEBUG: PluginBoxV2::share_box called for HttpResponseBox (id=2)
🔍 DEBUG: execute_method_call - object type: PluginBoxV2, method: write
🔍 DEBUG: Checking StringBox downcast for type: PluginBoxV2
🔍 DEBUG: StringBox downcast failed
🔍 execute_plugin_box_v2_method called: HttpResponseBox.write
[PluginLoaderV2] Invoke HttpResponseBox.write: resolving and encoding args (argc=1)
[PluginLoaderV2] arg[0]: String(len=6) -> String(tag=6)
[net] HttpResponse.write: id=2 bytes_len=6
[net] HttpResponse.write: body now has 6 bytes
Response created and written
🔍 stdlib not initialized for method call
🔍 DEBUG: PluginBoxV2::share_box called for HttpRequestBox (id=1)
🔍 DEBUG: execute_method_call - object type: PluginBoxV2, method: respond
🔍 DEBUG: Checking StringBox downcast for type: PluginBoxV2
🔍 DEBUG: StringBox downcast failed
🔍 execute_plugin_box_v2_method called: HttpRequestBox.respond
🔍 DEBUG: PluginBoxV2::share_box called for HttpResponseBox (id=2)
[PluginLoaderV2] Invoke HttpRequestBox.respond: resolving and encoding args (argc=1)
[PluginLoaderV2] arg[0]: PluginBoxV2(HttpResponseBox, id=2) -> Handle(tag=8)
Response sent
🔍 stdlib not initialized for method call
🔍 DEBUG: PluginBoxV2::share_box called for HttpResponseBox (id=1)
🔍 DEBUG: execute_method_call - object type: NyashResultBox, method: get_value
🔍 DEBUG: Checking StringBox downcast for type: NyashResultBox
🔍 DEBUG: StringBox downcast failed
🔍 DEBUG: PluginBoxV2::share_box called for HttpResponseBox (id=1)
🔍 DEBUG: PluginBoxV2::share_box called for HttpResponseBox (id=1)
Got client response
🔍 stdlib not initialized for method call
🔍 DEBUG: PluginBoxV2::share_box called for HttpResponseBox (id=1)
🔍 DEBUG: execute_method_call - object type: PluginBoxV2, method: readBody
🔍 DEBUG: Checking StringBox downcast for type: PluginBoxV2
🔍 DEBUG: StringBox downcast failed
🔍 execute_plugin_box_v2_method called: HttpResponseBox.readBody
[PluginLoaderV2] Invoke HttpResponseBox.readBody: resolving and encoding args (argc=0)

View File

@ -1,71 +0,0 @@
running 8 tests
test mir::instruction_v2::tests::test_instruction_count ... ok
test mir::instruction_v2::tests::test_ownership_operations ... ok
test mir::instruction_v2::tests::test_effect_categories ... ok
test instance_v2::tests::test_from_declaration_creation ... ok
test instance_v2::tests::test_from_any_box_creation ... ok
test instance_v2::tests::test_unified_approach ... ok
test instance_v2::tests::test_field_operations ... ok
test config::nyash_toml_v2::tests::test_parse_v2_config ... ok
test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 148 filtered out; finished in 0.04s
running 8 tests
test mir::instruction_v2::tests::test_ownership_operations ... ok
test mir::instruction_v2::tests::test_instruction_count ... ok
test mir::instruction_v2::tests::test_effect_categories ... ok
test instance_v2::tests::test_field_operations ... ok
test instance_v2::tests::test_from_declaration_creation ... ok
test instance_v2::tests::test_from_any_box_creation ... ok
test instance_v2::tests::test_unified_approach ... ok
test config::nyash_toml_v2::tests::test_parse_v2_config ... ok
test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 137 filtered out; finished in 0.04s
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 3 filtered out; finished in 0.00s
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 16 filtered out; finished in 0.00s
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out; finished in 0.00s
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 3 filtered out; finished in 0.00s
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 3 filtered out; finished in 0.00s
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

View File

@ -1,5 +0,0 @@
static box Main {
main() {
return 42
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,19 +0,0 @@
// 簡単なNyashテストプログラム
print("🎉 Nyash is working!")
print("Everything is Box!")
// 基本的な演算
local a = 10
local b = 20
local result = a + b
print("10 + 20 = " + result.toString())
// StringBox
local greeting = "Hello, Nyash!"
print(greeting)
// ArrayBox
local arr = new ArrayBox()
arr.push("First")
arr.push("Second")
print("Array length: " + arr.length().toString())

View File

@ -1,86 +0,0 @@
🔍 DEBUG: Initializing v2 plugin system
[PluginLoaderV2] nyash_plugin_init rc=0 for libnyash_counter_plugin.so
[FileBox] Plugin initialized
[PluginLoaderV2] nyash_plugin_init rc=0 for libnyash_filebox_plugin.so
Net plugin: LOG_ON=false, LOG_PATH=net_plugin.log
[PluginLoaderV2] nyash_plugin_init rc=0 for libnyash_net_plugin.so
🔌 v2 plugin system initialized from nyash.toml
📦 Registering plugin provider for CounterBox
📦 Registering plugin provider for FileBox
📦 Registering plugin provider for HttpServerBox
📦 Registering plugin provider for HttpClientBox
📦 Registering plugin provider for HttpResponseBox
📦 Registering plugin provider for HttpRequestBox
📦 Registering plugin provider for SocketServerBox
📦 Registering plugin provider for SocketClientBox
📦 Registering plugin provider for SocketConnBox
v2 plugin system fully configured
🚀 Nyash VM Backend - Executing file: local_tests/vm_stats_http_404.nyash 🚀
🔍 create_box called for: HttpServerBox
🔍 Config loaded successfully
🔍 Found library: libnyash_net_plugin.so for box type: HttpServerBox
🔍 Plugin loaded successfully
🔍 Reading nyash.toml for type configuration...
🔍 nyash.toml read successfully
🔍 nyash.toml parsed successfully
🔍 Found box config for HttpServerBox with type_id: 20
🔍 Preparing to call birth() with type_id: 20
🔍 Output buffer allocated, about to call plugin invoke_fn...
🔍 Calling invoke_fn(type_id=20, method_id=0, instance_id=0, tlv_args=[1, 0, 0, 0], output_buf, output_size=1024)
🔍 invoke_fn returned with result: 0
🎉 birth() success: HttpServerBox instance_id=1
[PluginLoaderV2] Invoke HttpServerBox.birth: resolving and encoding args (argc=0)
[VMPlugin] call HttpServerBox.birth recv_id=1 returns_result=false
[PluginLoaderV2] Invoke HttpServerBox.start: resolving and encoding args (argc=1)
[PluginLoaderV2] arg[0]: Integer(8404) -> I32(tag=2)
[VMPlugin] call HttpServerBox.start recv_id=1 returns_result=true
🔍 create_box called for: HttpClientBox
🔍 Config loaded successfully
🔍 Found library: libnyash_net_plugin.so for box type: HttpClientBox
🔍 Plugin loaded successfully
🔍 Reading nyash.toml for type configuration...
🔍 nyash.toml read successfully
🔍 nyash.toml parsed successfully
🔍 Found box config for HttpClientBox with type_id: 23
🔍 Preparing to call birth() with type_id: 23
🔍 Output buffer allocated, about to call plugin invoke_fn...
🔍 Calling invoke_fn(type_id=23, method_id=0, instance_id=0, tlv_args=[1, 0, 0, 0], output_buf, output_size=1024)
🔍 invoke_fn returned with result: 0
🎉 birth() success: HttpClientBox instance_id=1
[PluginLoaderV2] Invoke HttpClientBox.birth: resolving and encoding args (argc=0)
[VMPlugin] call HttpClientBox.birth recv_id=1 returns_result=false
[PluginLoaderV2] Invoke HttpClientBox.get: resolving and encoding args (argc=1)
[PluginLoaderV2] arg[0]: String(len=31) -> String(tag=6)
[VMPlugin] call HttpClientBox.get recv_id=1 returns_result=true
[PluginLoaderV2] Invoke HttpServerBox.accept: resolving and encoding args (argc=0)
[VMPlugin] call HttpServerBox.accept recv_id=1 returns_result=true
🔍 create_box called for: HttpResponseBox
🔍 Config loaded successfully
🔍 Found library: libnyash_net_plugin.so for box type: HttpResponseBox
🔍 Plugin loaded successfully
🔍 Reading nyash.toml for type configuration...
🔍 nyash.toml read successfully
🔍 nyash.toml parsed successfully
🔍 Found box config for HttpResponseBox with type_id: 22
🔍 Preparing to call birth() with type_id: 22
🔍 Output buffer allocated, about to call plugin invoke_fn...
🔍 Calling invoke_fn(type_id=22, method_id=0, instance_id=0, tlv_args=[1, 0, 0, 0], output_buf, output_size=1024)
🔍 invoke_fn returned with result: 0
🎉 birth() success: HttpResponseBox instance_id=2
[PluginLoaderV2] Invoke HttpResponseBox.birth: resolving and encoding args (argc=0)
[VMPlugin] call HttpResponseBox.birth recv_id=2 returns_result=false
[PluginLoaderV2] Invoke HttpResponseBox.setStatus: resolving and encoding args (argc=1)
[PluginLoaderV2] arg[0]: Integer(404) -> I32(tag=2)
[VMPlugin] call HttpResponseBox.setStatus recv_id=2 returns_result=false
[PluginLoaderV2] Invoke HttpResponseBox.write: resolving and encoding args (argc=1)
[PluginLoaderV2] arg[0]: String(len=9) -> String(tag=6)
[VMPlugin] call HttpResponseBox.write recv_id=2 returns_result=false
[PluginLoaderV2] Invoke HttpRequestBox.respond: resolving and encoding args (argc=1)
[PluginLoaderV2] arg[0]: PluginBoxV2(HttpResponseBox, id=2) -> Handle(tag=8)
[VMPlugin] call HttpRequestBox.respond recv_id=1 returns_result=false
[PluginLoaderV2] Invoke HttpResponseBox.getStatus: resolving and encoding args (argc=0)
[VMPlugin] call HttpResponseBox.getStatus recv_id=1 returns_result=false
[PluginLoaderV2] Invoke HttpResponseBox.readBody: resolving and encoding args (argc=0)
[VMPlugin] call HttpResponseBox.readBody recv_id=1 returns_result=false
VM execution completed successfully!
Result: StringBox { value: "404:Not Found", base: BoxBase { id: 57, parent_type_id: None } }

View File

@ -1,3 +0,0 @@
🔌 v2 plugin system initialized from nyash.toml
v2 plugin system fully configured
🚀 Nyash VM Backend - Executing file: local_tests/vm_stats_http_err.nyash 🚀

View File

@ -1,39 +0,0 @@
🔌 v2 plugin system initialized from nyash.toml
v2 plugin system fully configured
🚀 Nyash VM Backend - Executing file: local_tests/vm_stats_filebox.nyash 🚀
{
"counts": {
"BoxCall": 17,
"Const": 13,
"NewBox": 12,
"Return": 1,
"Safepoint": 1
},
"elapsed_ms": 26.658774,
"timestamp_ms": 1755900319445,
"top20": [
{
"count": 17,
"op": "BoxCall"
},
{
"count": 13,
"op": "Const"
},
{
"count": 12,
"op": "NewBox"
},
{
"count": 1,
"op": "Return"
},
{
"count": 1,
"op": "Safepoint"
}
],
"total": 44
}
VM execution completed successfully!
Result: StringBox { value: "HELLO", base: BoxBase { id: 59, parent_type_id: None } }

View File

@ -1,3 +0,0 @@
🔌 v2 plugin system initialized from nyash.toml
v2 plugin system fully configured
🚀 Nyash VM Backend - Executing file: local_tests/vm_stats_http_ok.nyash 🚀

View File

@ -1,50 +0,0 @@
🔌 v2 plugin system initialized from nyash.toml
v2 plugin system fully configured
🚀 Nyash VM Backend - Executing file: local_tests/test_vm_simple.nyash 🚀
15
{
"counts": {
"BinOp": 1,
"BoxCall": 2,
"Const": 5,
"NewBox": 2,
"Print": 1,
"Return": 1,
"Safepoint": 1
},
"elapsed_ms": 0.154706,
"timestamp_ms": 1755939354732,
"top20": [
{
"count": 5,
"op": "Const"
},
{
"count": 2,
"op": "BoxCall"
},
{
"count": 2,
"op": "NewBox"
},
{
"count": 1,
"op": "BinOp"
},
{
"count": 1,
"op": "Print"
},
{
"count": 1,
"op": "Return"
},
{
"count": 1,
"op": "Safepoint"
}
],
"total": 13
}
VM execution completed successfully!
Result: IntegerBox { value: 15, base: BoxBase { id: 12, parent_type_id: None } }

View File

@ -1,75 +0,0 @@
🔌 v2 plugin system initialized from nyash.toml
v2 plugin system fully configured
🚀 Nyash VM Backend - Executing file: local_tests/weak_field_poc.nyash 🚀
0
{
"counts": {
"BarrierRead": 1,
"BarrierWrite": 1,
"BoxCall": 2,
"Const": 9,
"NewBox": 2,
"Print": 1,
"RefGet": 4,
"RefSet": 3,
"Return": 3,
"Safepoint": 1,
"WeakLoad": 1,
"WeakNew": 1
},
"elapsed_ms": 0.194731,
"timestamp_ms": 1755956955634,
"top20": [
{
"count": 9,
"op": "Const"
},
{
"count": 4,
"op": "RefGet"
},
{
"count": 3,
"op": "RefSet"
},
{
"count": 3,
"op": "Return"
},
{
"count": 2,
"op": "BoxCall"
},
{
"count": 2,
"op": "NewBox"
},
{
"count": 1,
"op": "BarrierRead"
},
{
"count": 1,
"op": "BarrierWrite"
},
{
"count": 1,
"op": "Print"
},
{
"count": 1,
"op": "Safepoint"
},
{
"count": 1,
"op": "WeakLoad"
},
{
"count": 1,
"op": "WeakNew"
}
],
"total": 29
}
VM execution completed successfully!
Result: IntegerBox { value: 0, base: BoxBase { id: 4, parent_type_id: None } }

View File

@ -1,65 +0,0 @@
🔌 v2 plugin system initialized from nyash.toml
v2 plugin system fully configured
🚀 Nyash VM Backend - Executing file: local_tests/weak_field_poc.nyash 🚀
0
{
"counts": {
"Barrier": 2,
"BoxCall": 2,
"Const": 9,
"NewBox": 2,
"Print": 1,
"RefGet": 4,
"RefSet": 3,
"Return": 3,
"Safepoint": 1,
"WeakRef": 2
},
"elapsed_ms": 0.16804799999999998,
"timestamp_ms": 1755957108401,
"top20": [
{
"count": 9,
"op": "Const"
},
{
"count": 4,
"op": "RefGet"
},
{
"count": 3,
"op": "RefSet"
},
{
"count": 3,
"op": "Return"
},
{
"count": 2,
"op": "Barrier"
},
{
"count": 2,
"op": "BoxCall"
},
{
"count": 2,
"op": "NewBox"
},
{
"count": 2,
"op": "WeakRef"
},
{
"count": 1,
"op": "Print"
},
{
"count": 1,
"op": "Safepoint"
}
],
"total": 29
}
VM execution completed successfully!
Result: IntegerBox { value: 0, base: BoxBase { id: 4, parent_type_id: None } }