feat(constructor): implement birth() syntax and pack transparency system
## 🌟 birth() Constructor Implementation - Add BIRTH token to tokenizer (src/tokenizer.rs:37,403) - Implement birth() parser support (src/parser/mod.rs) - Add birth() interpreter support with priority system - Priority: birth > pack > init > Box名 ## 🚨 Fix Documentation Inconsistencies - Fix delegation-system.md: pack → birth unified - Fix box-design/README.md: add pack-specific section - Fix LANGUAGE_GUIDE.md: birth unified, pack builtin-only - Fix CLAUDE.md: birth philosophy, pack system separation ## 📋 pack Transparency System Design - Create phase_8_8_pack_transparency_system.md specification - Establish correct pack definition: builtin Box inheritance only - Design user-transparent system: from BuiltinBox() → internal pack - Comprehensive test cases and implementation requirements ## 🧪 Testing - Add test_birth_simple.nyash: birth() functionality verification - Document constructor name decision process - Prepare for Copilot implementation with clear specifications 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
56
CLAUDE.md
56
CLAUDE.md
@ -122,30 +122,56 @@ while condition { } // 使用不可
|
|||||||
loop() { } // 使用不可
|
loop() { } // 使用不可
|
||||||
```
|
```
|
||||||
|
|
||||||
### 🎁 pack構文 - Box哲学の具現化(2025-08-11実装)
|
### 🌟 birth構文 - 生命をBoxに与える(2025-08-15実装)
|
||||||
```nyash
|
```nyash
|
||||||
// 🎁 「箱に詰める」直感的コンストラクタ
|
// 🌟 「Boxに生命を与える」直感的コンストラクタ
|
||||||
box User {
|
box Life {
|
||||||
init { name, email }
|
init { name, energy }
|
||||||
|
|
||||||
pack(userName, userEmail) { // ← Box哲学を体現!
|
birth(lifeName) { // ← Everything is Box哲学を体現!
|
||||||
me.name = userName
|
me.name = lifeName
|
||||||
me.email = userEmail
|
me.energy = 100
|
||||||
|
print("🌟 " + lifeName + " が誕生しました!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🔄 デリゲーションでのpack
|
// 🔄 デリゲーションでのbirth
|
||||||
box AdminUser from User {
|
box Human from Life {
|
||||||
init { permissions }
|
init { intelligence }
|
||||||
|
|
||||||
pack(adminName, adminEmail, perms) {
|
birth(humanName) {
|
||||||
from User.pack(adminName, adminEmail) // 親のpackを呼び出し
|
from Life.birth(humanName) // 親のbirthを呼び出し
|
||||||
me.permissions = perms
|
me.intelligence = 50
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ✅ 優先順位: pack > init > Box名形式
|
// ✅ 優先順位: birth > pack > init > Box名形式
|
||||||
local user = new User("Alice", "alice@example.com") // packが使われる
|
local alice = new Human("Alice") // birthが使われる
|
||||||
|
```
|
||||||
|
|
||||||
|
### 🚨 pack構文 - ビルトインBox継承専用
|
||||||
|
```nyash
|
||||||
|
// ⚠️ pack構文はビルトインBox継承専用!ユーザー定義Boxでは使わない
|
||||||
|
box EnhancedP2P from P2PBox {
|
||||||
|
init { features }
|
||||||
|
|
||||||
|
pack(nodeId, transport) {
|
||||||
|
from P2PBox.pack(nodeId, transport) // ビルトイン初期化
|
||||||
|
me.features = new ArrayBox()
|
||||||
|
}
|
||||||
|
|
||||||
|
override send(intent, data, target) {
|
||||||
|
me.features.push("send:" + intent)
|
||||||
|
return from P2PBox.send(intent, data, target)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ❌ 間違い: ユーザー定義Boxでpack使用
|
||||||
|
box RegularUser {
|
||||||
|
pack(name) { // これは間違い!birth()を使う
|
||||||
|
me.name = name
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 🎯 正統派Nyashスタイル(2025-08-09実装)
|
### 🎯 正統派Nyashスタイル(2025-08-09実装)
|
||||||
|
|||||||
@ -7,6 +7,70 @@
|
|||||||
- **Arc::ptr_eq()検出**: 真のゼロコピー判定実現 ✅
|
- **Arc::ptr_eq()検出**: 真のゼロコピー判定実現 ✅
|
||||||
- **新API978行追加**: すべて正常ビルド・実行成功 ✅
|
- **新API978行追加**: すべて正常ビルド・実行成功 ✅
|
||||||
|
|
||||||
|
## 🚨 **コンストラクタ構文統一の緊急実装 (2025-08-15)**
|
||||||
|
|
||||||
|
### **🌟 birth()実装完了 → pack透明化設計** ✅
|
||||||
|
|
||||||
|
**birth()統一構文実装完了**!次は**pack透明化システム**の実装が必要
|
||||||
|
|
||||||
|
### **🎯 pack透明化設計 - ユーザー完全不可視システム**
|
||||||
|
|
||||||
|
**核心方針**: ユーザーは`pack`を一切書かない・意識しない
|
||||||
|
|
||||||
|
### **📋 ユーザー側の理想的な書き方**
|
||||||
|
```nyash
|
||||||
|
# ✅ ユーザーはこう書く(packを一切意識しない)
|
||||||
|
box EnhancedString from StringBox {
|
||||||
|
init { prefix }
|
||||||
|
|
||||||
|
birth(content, prefixStr) {
|
||||||
|
from StringBox(content) # ← シンプルな呼び出し
|
||||||
|
me.prefix = prefixStr
|
||||||
|
}
|
||||||
|
|
||||||
|
override toString() {
|
||||||
|
return me.prefix + from StringBox.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### **🔧 実装側の内部動作**
|
||||||
|
```rust
|
||||||
|
// from StringBox(content) の解決優先度
|
||||||
|
fn resolve_builtin_delegation(builtin: &str, args: Vec<_>) -> String {
|
||||||
|
if is_builtin_box(builtin) {
|
||||||
|
// 1. ビルトインBoxの場合、内部的にpackを呼ぶ
|
||||||
|
builtin_pack_registry.call_pack(builtin, args)
|
||||||
|
} else {
|
||||||
|
// 2. ユーザー定義Boxの場合、birth優先
|
||||||
|
resolve_user_constructor(builtin, args) // birth > init > Box名
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### **🎯 実装すべきこと**
|
||||||
|
|
||||||
|
**1. ビルトインBox自動判定**
|
||||||
|
- `is_builtin_box()` 関数実装
|
||||||
|
- StringBox, P2PBox, MathBox等をビルトイン登録
|
||||||
|
|
||||||
|
**2. pack透明化システム**
|
||||||
|
- `from BuiltinBox()` → 内部的に `BuiltinBox.pack()` 呼び出し
|
||||||
|
- ユーザーは`pack`という単語を見ない・書かない
|
||||||
|
|
||||||
|
**3. デリゲーション解決統一**
|
||||||
|
- ビルトインBox: 自動pack呼び出し
|
||||||
|
- ユーザー定義Box: birth > init > Box名 優先順位
|
||||||
|
|
||||||
|
**4. エラーメッセージ改善**
|
||||||
|
- ユーザーには「birth()がありません」と表示
|
||||||
|
- packエラーは内部ログのみ
|
||||||
|
|
||||||
|
### **🎉 期待される効果**
|
||||||
|
- **完全透明化**: ユーザーはpackを一切意識しない
|
||||||
|
- **統一体験**: `from Parent()` で全て解決
|
||||||
|
- **設計分離**: ビルトインBox内部実装とユーザーAPI完全分離
|
||||||
|
|
||||||
## 🔄 **次期優先タスク**
|
## 🔄 **次期優先タスク**
|
||||||
**GitHub Issue**: https://github.com/moe-charm/nyash/issues/98
|
**GitHub Issue**: https://github.com/moe-charm/nyash/issues/98
|
||||||
**移植計画**: 3つの実用Cアプリケーション同時移植プロジェクト
|
**移植計画**: 3つの実用Cアプリケーション同時移植プロジェクト
|
||||||
@ -36,6 +100,61 @@
|
|||||||
- **実行性能**: WASM 13.5倍、VM 20.4倍高速化達成
|
- **実行性能**: WASM 13.5倍、VM 20.4倍高速化達成
|
||||||
- **Everything is Box哲学**: 全11個のBox型でRwLock統一完了
|
- **Everything is Box哲学**: 全11個のBox型でRwLock統一完了
|
||||||
|
|
||||||
|
## 🔥 **実装優先度**
|
||||||
|
|
||||||
|
### **🚨 Critical (即時実装)**
|
||||||
|
1. **ビルトインBox判定システム** - is_builtin_box()実装(15分)
|
||||||
|
2. **pack透明化解決** - from BuiltinBox()自動変換(30分)
|
||||||
|
3. **統合テスト作成** - 透明化動作確認(10分)
|
||||||
|
|
||||||
|
### **⚡ High (今週中)**
|
||||||
|
4. **エラーメッセージ改善** - pack隠蔽、birth中心メッセージ
|
||||||
|
5. **ドキュメント更新** - CLAUDE.md透明化設計反映
|
||||||
|
6. **パフォーマンス最適化** - ビルトイン判定高速化
|
||||||
|
|
||||||
|
### **📝 Medium (来週)**
|
||||||
|
7. **既存テスト見直し** - pack直接呼び出し削除
|
||||||
|
8. **delegation-system.md更新** - 透明化設計反映
|
||||||
|
|
||||||
|
### **🔮 Future (今後の予定)**
|
||||||
|
9. **FFI/ABI統合** - ExternBox経由外部API(Phase 11予定)
|
||||||
|
10. **動的ライブラリ読み込み** - 外部ライブラリBox化(Phase 12予定)
|
||||||
|
11. **BID自動生成** - YAML→実装自動化(Phase 13予定)
|
||||||
|
|
||||||
|
## 🚀 **Phase 8.8: pack透明化システム実装準備完了**
|
||||||
|
|
||||||
|
### **✅ 完了事項 (2025-08-15)**
|
||||||
|
1. **birth()実装完了** - コンストラクタ統一構文実装 ✅
|
||||||
|
2. **ドキュメント矛盾修正完了** - pack機能正しい定義確立 ✅
|
||||||
|
3. **pack透明化イシュー作成完了** - Copilot実装仕様書完成 ✅
|
||||||
|
|
||||||
|
### **📋 ドキュメント修正完了リスト**
|
||||||
|
- ✅ `delegation-system.md` - pack→birth統一、pack専用セクション追加
|
||||||
|
- ✅ `box-design/README.md` - pack専用セクション追加
|
||||||
|
- ✅ `LANGUAGE_GUIDE.md` - birth統一、pack専用明記
|
||||||
|
- ✅ `CLAUDE.md` - birth哲学、pack専用システム分離
|
||||||
|
|
||||||
|
### **🎯 次のアクション (Copilot実装待ち)**
|
||||||
|
**イシュー**: `phase_8_8_pack_transparency_system.md`
|
||||||
|
|
||||||
|
#### **実装内容**
|
||||||
|
1. **ビルトインBox判定システム** - `is_builtin_box()` 関数
|
||||||
|
2. **pack透明化解決** - `from BuiltinBox()` 自動変換
|
||||||
|
3. **エラーメッセージ改善** - pack隠蔽、ユーザーフレンドリー化
|
||||||
|
|
||||||
|
#### **必須テストケース (5種類)**
|
||||||
|
- ユーザー定義Box基本動作
|
||||||
|
- ビルトインBox継承
|
||||||
|
- **透明化システム動作** (最重要)
|
||||||
|
- 混在テスト
|
||||||
|
- エラーケーステスト
|
||||||
|
|
||||||
|
#### **完了条件**
|
||||||
|
- 全テストケース PASS
|
||||||
|
- 既存機能継続動作
|
||||||
|
- パフォーマンス維持
|
||||||
|
- ユーザーはpackを一切意識しない
|
||||||
|
|
||||||
---
|
---
|
||||||
**現在状況**: Phase 9.75完了 → Phase 9.5 HTTPサーバー実用テスト準備中
|
**現在状況**: pack透明化システム実装準備完了✅ → Copilot実装開始待ち🤖
|
||||||
**最終更新**: 2025-08-15
|
**最終更新**: 2025-08-15 17:00
|
||||||
115
docs/design-decisions/constructor-name-decision.md
Normal file
115
docs/design-decisions/constructor-name-decision.md
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
# 🌟 Nyash コンストラクタ名決定: birth() 採用
|
||||||
|
|
||||||
|
**決定日**: 2025-08-15
|
||||||
|
**決定者**: Nyashプロジェクトチーム
|
||||||
|
**ステータス**: 正式決定
|
||||||
|
|
||||||
|
## 🎯 **最終決定**
|
||||||
|
|
||||||
|
**`birth()` を唯一のコンストラクタ名として採用**
|
||||||
|
|
||||||
|
## 📋 **検討経過**
|
||||||
|
|
||||||
|
### 候補と評価
|
||||||
|
|
||||||
|
1. **constructor()** - 業界標準だが長い、Box哲学との親和性低い
|
||||||
|
2. **pack()** - Box哲学完璧だが独自性強すぎ、混乱の元
|
||||||
|
3. **init()** - initフィールドとの混乱、廃止済み
|
||||||
|
4. **make()** - Go言語実績あり、短い、実用的
|
||||||
|
5. **birth()** - 🌟 **採用決定** 🌟
|
||||||
|
|
||||||
|
### birth() 選定理由
|
||||||
|
|
||||||
|
**1. 哲学的完璧性**
|
||||||
|
- 「Everything is Box」哲学との完璧な親和性
|
||||||
|
- 「Boxに魂が宿る」生命感のある言語思想を体現
|
||||||
|
- 「生命を誕生させる」直感的イメージ
|
||||||
|
|
||||||
|
**2. 強力なブランディング効果**
|
||||||
|
- 圧倒的独自性で一度見たら忘れない
|
||||||
|
- Nyashらしさを言語の核心で表現
|
||||||
|
- 学習者がコンストラクタを使うたびに世界観を体感
|
||||||
|
|
||||||
|
**3. 実用性**
|
||||||
|
- 短い(5文字)で覚えやすい
|
||||||
|
- 学習コストは低い(初見で一瞬考えるだけ)
|
||||||
|
- 明確で曖昧性がない
|
||||||
|
|
||||||
|
## 💡 **Geminiの専門的評価**
|
||||||
|
|
||||||
|
> 「`birth()` を採用することは、単なる名前選び以上の意味を持つ。それは、**Nyashの哲学を言語の根幹に据えるという宣言**である。学習者はコンストラクタを使うたびに、無意識にその世界観に触れることになる。これは非常に強力なブランディングです。」
|
||||||
|
|
||||||
|
**Gemini最終推奨**: `birth()` 採用
|
||||||
|
|
||||||
|
## 🌟 **構文例**
|
||||||
|
|
||||||
|
```nyash
|
||||||
|
// 基本的な使用法
|
||||||
|
box Life {
|
||||||
|
init { name, energy }
|
||||||
|
|
||||||
|
birth(lifeName) { // 生命を誕生させる
|
||||||
|
me.name = lifeName
|
||||||
|
me.energy = 100
|
||||||
|
print("🌟 " + lifeName + " が誕生しました!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// デリゲーション
|
||||||
|
box Human from Life {
|
||||||
|
init { intelligence }
|
||||||
|
|
||||||
|
birth(humanName) {
|
||||||
|
from Life.birth(humanName) // 親から生命を受け継ぐ
|
||||||
|
me.intelligence = 50
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用例
|
||||||
|
local alice = new Human("Alice") // birth()が自動呼び出し
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 **実装要件**
|
||||||
|
|
||||||
|
### 1. トークナイザー修正
|
||||||
|
```rust
|
||||||
|
BIRTH, // birth (コンストラクタ)
|
||||||
|
|
||||||
|
"birth" => TokenType::BIRTH,
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. パーサー修正
|
||||||
|
- `birth()` 構文パース対応
|
||||||
|
- `init/pack/constructor` と同様の処理システム統合
|
||||||
|
|
||||||
|
### 3. インタープリター修正
|
||||||
|
- `birth/引数数` キーでの検索対応
|
||||||
|
- デリゲーション時の `from Parent.birth()` サポート
|
||||||
|
|
||||||
|
### 4. 優先順位システム
|
||||||
|
```rust
|
||||||
|
// 検索順序
|
||||||
|
1. "birth/引数数" // 最優先
|
||||||
|
2. "init/引数数" // 互換性
|
||||||
|
3. "pack/引数数" // 互換性
|
||||||
|
4. "Box名/引数数" // 互換性
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎉 **期待される効果**
|
||||||
|
|
||||||
|
- **哲学的一貫性**: Everything is Box思想の完璧な体現
|
||||||
|
- **ブランド確立**: Nyash独自の世界観を言語レベルで表現
|
||||||
|
- **学習体験向上**: コンストラクタ使用のたびに世界観を体感
|
||||||
|
- **混乱解消**: initフィールドとの完全な区別
|
||||||
|
- **統一性**: 全てのBoxで同一のbirth()構文
|
||||||
|
|
||||||
|
## 📝 **移行計画**
|
||||||
|
|
||||||
|
1. **Phase 1**: birth()実装(トークナイザー・パーサー・インタープリター)
|
||||||
|
2. **Phase 2**: テスト作成・動作確認
|
||||||
|
3. **Phase 3**: 既存コード段階的移行(互換性維持)
|
||||||
|
4. **Phase 4**: ドキュメント更新(CLAUDE.md等)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**🌟 Nyashは `birth()` でBoxに生命を与える言語として、新たな進化を遂げる 🌟**
|
||||||
226
docs/予定/native-plan/issues/phase_8_8_pack_transparency_system.md
Normal file
226
docs/予定/native-plan/issues/phase_8_8_pack_transparency_system.md
Normal file
@ -0,0 +1,226 @@
|
|||||||
|
# Phase 8.8: pack透明化システム実装
|
||||||
|
|
||||||
|
**Priority**: Critical
|
||||||
|
**Estimated Effort**: 2-3日
|
||||||
|
**Assignee**: Copilot (Claude監修)
|
||||||
|
**Status**: Ready for Implementation
|
||||||
|
|
||||||
|
## 🎯 概要
|
||||||
|
|
||||||
|
**pack構文のユーザー完全透明化システム**を実装する。ユーザーは`pack`を一切意識せず、`from BuiltinBox()`で自動的に内部のpack機能が呼ばれるシステム。
|
||||||
|
|
||||||
|
### 🚨 背景問題
|
||||||
|
- **Copilotがpack機能を誤解**:一般コンストラクタとして実装
|
||||||
|
- **ドキュメント矛盾**:packの定義が混乱していた ✅ 修正済み
|
||||||
|
- **ユーザー体験悪化**:packを意識する必要があった
|
||||||
|
|
||||||
|
## 📋 実装要件
|
||||||
|
|
||||||
|
### 1. **ビルトインBox判定システム**
|
||||||
|
```rust
|
||||||
|
// 実装必要な関数
|
||||||
|
fn is_builtin_box(box_name: &str) -> bool {
|
||||||
|
// StringBox, P2PBox, MathBox, ConsoleBox等を判定
|
||||||
|
}
|
||||||
|
|
||||||
|
// 登録リスト (最低限)
|
||||||
|
const BUILTIN_BOXES: &[&str] = &[
|
||||||
|
"StringBox", "IntegerBox", "BoolBox", "NullBox",
|
||||||
|
"P2PBox", "MathBox", "ConsoleBox", "DebugBox",
|
||||||
|
"TimeBox", "RandomBox", "SoundBox", "MapBox"
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. **pack透明化解決システム**
|
||||||
|
```rust
|
||||||
|
// from BuiltinBox() の自動解決
|
||||||
|
fn resolve_builtin_delegation(builtin: &str, args: Vec<_>) -> Result<(), String> {
|
||||||
|
if is_builtin_box(builtin) {
|
||||||
|
// 内部的に BuiltinBox.pack() を呼ぶ
|
||||||
|
call_builtin_pack(builtin, args)
|
||||||
|
} else {
|
||||||
|
// ユーザー定義Box: birth > init > Box名 の順
|
||||||
|
resolve_user_constructor(builtin, args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. **エラーメッセージ改善**
|
||||||
|
- ユーザーには「birth()がありません」表示
|
||||||
|
- pack関連エラーは内部ログのみ
|
||||||
|
- 混乱を避ける明確なメッセージ
|
||||||
|
|
||||||
|
## 🧪 テスト要件
|
||||||
|
|
||||||
|
### **必須テストケース** (全て PASS 必須)
|
||||||
|
|
||||||
|
#### **A. ユーザー定義Box基本動作**
|
||||||
|
```nyash
|
||||||
|
# test_user_box_basic.nyash
|
||||||
|
box Life {
|
||||||
|
init { name, energy }
|
||||||
|
|
||||||
|
birth(lifeName) {
|
||||||
|
me.name = lifeName
|
||||||
|
me.energy = 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
local alice = new Life("Alice")
|
||||||
|
assert(alice.name == "Alice")
|
||||||
|
assert(alice.energy == 100)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **B. ビルトインBox継承**
|
||||||
|
```nyash
|
||||||
|
# test_builtin_inheritance.nyash
|
||||||
|
box EnhancedP2P from P2PBox {
|
||||||
|
init { features }
|
||||||
|
|
||||||
|
pack(nodeId, transport) {
|
||||||
|
from P2PBox.pack(nodeId, transport) # 明示的pack
|
||||||
|
me.features = new ArrayBox()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
local node = new EnhancedP2P("node1", "tcp")
|
||||||
|
assert(node.features != null)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **C. 透明化システム動作**
|
||||||
|
```nyash
|
||||||
|
# test_transparency.nyash
|
||||||
|
box SimpleString from StringBox {
|
||||||
|
init { prefix }
|
||||||
|
|
||||||
|
birth(content, prefixStr) {
|
||||||
|
from StringBox(content) # ← 透明化!内部的にpack呼び出し
|
||||||
|
me.prefix = prefixStr
|
||||||
|
}
|
||||||
|
|
||||||
|
override toString() {
|
||||||
|
return me.prefix + from StringBox.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
local str = new SimpleString("Hello", ">>> ")
|
||||||
|
assert(str.toString() == ">>> Hello")
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **D. 混在テスト**
|
||||||
|
```nyash
|
||||||
|
# test_mixed_inheritance.nyash
|
||||||
|
box AdvancedCalc from MathBox {
|
||||||
|
init { history }
|
||||||
|
|
||||||
|
birth() {
|
||||||
|
from MathBox() # 透明化
|
||||||
|
me.history = new ArrayBox()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
box Calculator {
|
||||||
|
init { result }
|
||||||
|
|
||||||
|
birth() {
|
||||||
|
me.result = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
local calc1 = new AdvancedCalc() # ビルトイン継承
|
||||||
|
local calc2 = new Calculator() # ユーザー定義
|
||||||
|
assert(calc1.history != null)
|
||||||
|
assert(calc2.result == 0)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **E. エラーケーステスト**
|
||||||
|
```nyash
|
||||||
|
# test_error_cases.nyash
|
||||||
|
|
||||||
|
# 1. 存在しないmethodを呼び出し
|
||||||
|
box BadBox from StringBox {
|
||||||
|
birth(content) {
|
||||||
|
from StringBox.nonexistent() # エラー:適切なメッセージ
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# 2. 引数不一致
|
||||||
|
box ArgMismatch from P2PBox {
|
||||||
|
birth() {
|
||||||
|
from P2PBox("too", "many", "args") # エラー:引数不一致
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### **パフォーマンステスト**
|
||||||
|
```nyash
|
||||||
|
# test_performance.nyash
|
||||||
|
local startTime = getCurrentTime()
|
||||||
|
|
||||||
|
loop(i < 1000) {
|
||||||
|
local str = new SimpleString("test" + i, "prefix")
|
||||||
|
local result = str.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
local endTime = getCurrentTime()
|
||||||
|
local elapsed = endTime - startTime
|
||||||
|
assert(elapsed < 1000) # 1秒以内で完了
|
||||||
|
```
|
||||||
|
|
||||||
|
## ✅ チェックリスト
|
||||||
|
|
||||||
|
### **実装前チェック**
|
||||||
|
- [ ] 既存のbirth()実装が正常動作している
|
||||||
|
- [ ] ドキュメント修正が完了している
|
||||||
|
- [ ] テストファイルが準備されている
|
||||||
|
|
||||||
|
### **実装中チェック**
|
||||||
|
- [ ] `is_builtin_box()` 関数実装完了
|
||||||
|
- [ ] pack透明化解決システム実装完了
|
||||||
|
- [ ] エラーメッセージ改善完了
|
||||||
|
- [ ] 全テストケース PASS
|
||||||
|
|
||||||
|
### **実装後チェック**
|
||||||
|
- [ ] 既存テストファイルが継続動作
|
||||||
|
- [ ] パフォーマンス劣化なし(<5%)
|
||||||
|
- [ ] birth()優先順位システム正常動作
|
||||||
|
- [ ] エラーメッセージがユーザーフレンドリー
|
||||||
|
|
||||||
|
### **統合テスト**
|
||||||
|
- [ ] `test_birth_simple.nyash` 継続動作 ✅
|
||||||
|
- [ ] Chip-8エミュレーター修正版動作
|
||||||
|
- [ ] 全ビルトインBox継承パターン動作
|
||||||
|
- [ ] デリゲーションチェーン正常動作
|
||||||
|
|
||||||
|
## 📂 実装場所
|
||||||
|
|
||||||
|
### **主要ファイル**
|
||||||
|
- `src/interpreter/expressions.rs` - from解決ロジック
|
||||||
|
- `src/interpreter/objects.rs` - コンストラクタ優先順位
|
||||||
|
- `src/interpreter/core.rs` - ビルトインBox判定
|
||||||
|
- `src/box_trait.rs` - BUILTIN_BOXES定数
|
||||||
|
|
||||||
|
### **テストファイル**
|
||||||
|
- `test_pack_transparency.nyash` - 統合テスト
|
||||||
|
- `test_builtin_inheritance.nyash` - ビルトイン継承
|
||||||
|
- `test_user_box_birth.nyash` - ユーザー定義Box
|
||||||
|
- `test_error_cases.nyash` - エラーケース
|
||||||
|
|
||||||
|
## 🎉 完了条件
|
||||||
|
|
||||||
|
1. **全テストケース PASS** ✅
|
||||||
|
2. **既存機能の継続動作** ✅
|
||||||
|
3. **パフォーマンス維持** ✅
|
||||||
|
4. **エラーメッセージ改善** ✅
|
||||||
|
5. **ドキュメント整合性** ✅
|
||||||
|
|
||||||
|
## 🚨 注意事項
|
||||||
|
|
||||||
|
- **既存のbirth()実装は変更しない**
|
||||||
|
- **pack機能自体は残す**(ビルトイン継承で必要)
|
||||||
|
- **ユーザーAPIからpackを完全隠蔽**
|
||||||
|
- **パフォーマンス劣化は避ける**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**実装時は必ずテストファースト開発で進める!** 🧪
|
||||||
@ -65,9 +65,10 @@ not condition, a and b, a or b
|
|||||||
box User {
|
box User {
|
||||||
init { name, email } // フィールド宣言
|
init { name, email } // フィールド宣言
|
||||||
|
|
||||||
pack(userName, userEmail) { // 🎁 Box哲学の具現化!
|
birth(userName, userEmail) { // 🌟 生命をBoxに与える!
|
||||||
me.name = userName
|
me.name = userName
|
||||||
me.email = userEmail
|
me.email = userEmail
|
||||||
|
print("🌟 " + userName + " が誕生しました!")
|
||||||
}
|
}
|
||||||
|
|
||||||
greet() {
|
greet() {
|
||||||
@ -81,8 +82,8 @@ box User {
|
|||||||
box AdminUser from User { // 🔥 from構文でデリゲーション
|
box AdminUser from User { // 🔥 from構文でデリゲーション
|
||||||
init { permissions }
|
init { permissions }
|
||||||
|
|
||||||
pack(adminName, adminEmail, perms) {
|
birth(adminName, adminEmail, perms) {
|
||||||
from User.pack(adminName, adminEmail) // 親のpack呼び出し
|
from User.birth(adminName, adminEmail) // 親のbirth呼び出し
|
||||||
me.permissions = perms
|
me.permissions = perms
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,6 +94,25 @@ box AdminUser from User { // 🔥 from構文でデリゲーション
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### ビルトインBox継承(pack専用)
|
||||||
|
```nyash
|
||||||
|
// ⚠️ pack構文はビルトインBox継承専用
|
||||||
|
box EnhancedP2P from P2PBox {
|
||||||
|
init { features }
|
||||||
|
|
||||||
|
pack(nodeId, transport) {
|
||||||
|
from P2PBox.pack(nodeId, transport) // ビルトイン初期化
|
||||||
|
me.features = new ArrayBox()
|
||||||
|
print("🌐 Enhanced P2P Node created: " + nodeId)
|
||||||
|
}
|
||||||
|
|
||||||
|
override send(intent, data, target) {
|
||||||
|
me.features.push("send:" + intent)
|
||||||
|
return from P2PBox.send(intent, data, target)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
#### Static Box Main パターン
|
#### Static Box Main パターン
|
||||||
```nyash
|
```nyash
|
||||||
static box Main {
|
static box Main {
|
||||||
|
|||||||
@ -63,9 +63,10 @@ local num = new IntegerBox(42)
|
|||||||
box User {
|
box User {
|
||||||
init { name, email }
|
init { name, email }
|
||||||
|
|
||||||
pack(userName, userEmail) {
|
birth(userName, userEmail) {
|
||||||
me.name = userName
|
me.name = userName
|
||||||
me.email = userEmail
|
me.email = userEmail
|
||||||
|
print("🌟 User " + userName + " が誕生しました!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -75,8 +76,8 @@ box User {
|
|||||||
box AdminUser from User {
|
box AdminUser from User {
|
||||||
init { permissions }
|
init { permissions }
|
||||||
|
|
||||||
pack(adminName, adminEmail, perms) {
|
birth(adminName, adminEmail, perms) {
|
||||||
from User.pack(adminName, adminEmail)
|
from User.birth(adminName, adminEmail)
|
||||||
me.permissions = perms
|
me.permissions = perms
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,6 +87,24 @@ box AdminUser from User {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### ビルトインBox継承(pack専用)
|
||||||
|
```nyash
|
||||||
|
// ビルトインBoxを継承する場合のみpackを使用
|
||||||
|
box EnhancedP2P from P2PBox {
|
||||||
|
init { features }
|
||||||
|
|
||||||
|
pack(nodeId, transport) {
|
||||||
|
from P2PBox.pack(nodeId, transport) // ビルトイン初期化
|
||||||
|
me.features = new ArrayBox()
|
||||||
|
}
|
||||||
|
|
||||||
|
override send(intent, data, target) {
|
||||||
|
me.features.push("send:" + intent)
|
||||||
|
return from P2PBox.send(intent, data, target)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### 外部ライブラリ統合(FFI/ABI)
|
### 外部ライブラリ統合(FFI/ABI)
|
||||||
```nyash
|
```nyash
|
||||||
// ExternBoxで外部APIを統一的に利用
|
// ExternBoxで外部APIを統一的に利用
|
||||||
|
|||||||
@ -134,21 +134,22 @@ box MultiChild from ParentA, ParentB {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🎁 pack構文 - Box哲学の具現化
|
## 🌟 birth構文 - Box哲学の具現化
|
||||||
|
|
||||||
### packの優先順位
|
### コンストラクタの優先順位
|
||||||
|
|
||||||
```nyash
|
```nyash
|
||||||
box User {
|
box User {
|
||||||
init { name, email }
|
init { name, email }
|
||||||
|
|
||||||
// 優先度1: pack(推奨)
|
// 優先度1: birth(推奨)
|
||||||
pack(userName, userEmail) {
|
birth(userName, userEmail) {
|
||||||
me.name = userName
|
me.name = userName
|
||||||
me.email = userEmail
|
me.email = userEmail
|
||||||
|
print("🌟 " + userName + " が誕生しました!")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 優先度2: init(packがない場合)
|
// 優先度2: init(birthがない場合)
|
||||||
init(name, email) {
|
init(name, email) {
|
||||||
me.name = name
|
me.name = name
|
||||||
me.email = email
|
me.email = email
|
||||||
@ -161,28 +162,29 @@ box User {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// packが優先的に使用される
|
// birthが優先的に使用される
|
||||||
local user = new User("Alice", "alice@example.com")
|
local user = new User("Alice", "alice@example.com")
|
||||||
```
|
```
|
||||||
|
|
||||||
### packとデリゲーション
|
### birth構文とデリゲーション
|
||||||
|
|
||||||
```nyash
|
```nyash
|
||||||
box Product {
|
box Product {
|
||||||
init { name, price }
|
init { name, price }
|
||||||
|
|
||||||
pack(productName, productPrice) {
|
birth(productName, productPrice) {
|
||||||
me.name = productName
|
me.name = productName
|
||||||
me.price = productPrice
|
me.price = productPrice
|
||||||
|
print("📦 Product created: " + productName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
box DiscountedProduct from Product {
|
box DiscountedProduct from Product {
|
||||||
init { discount }
|
init { discount }
|
||||||
|
|
||||||
pack(name, originalPrice, discountPercent) {
|
birth(name, originalPrice, discountPercent) {
|
||||||
local discountedPrice = originalPrice * (1 - discountPercent / 100)
|
local discountedPrice = originalPrice * (1 - discountPercent / 100)
|
||||||
from Product.pack(name, discountedPrice)
|
from Product.birth(name, discountedPrice) # 親のbirthを呼ぶ
|
||||||
me.discount = discountPercent
|
me.discount = discountPercent
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,6 +194,38 @@ box DiscountedProduct from Product {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 🚨 pack構文 - ビルトインBox継承専用
|
||||||
|
|
||||||
|
**重要**: `pack`構文は**ビルトインBox継承専用**です。ユーザー定義Boxでは使用しません。
|
||||||
|
|
||||||
|
```nyash
|
||||||
|
# ✅ 正しい使い方(ビルトインBox継承のみ)
|
||||||
|
box EnhancedP2P from P2PBox {
|
||||||
|
init { extraFeatures }
|
||||||
|
|
||||||
|
pack(nodeId, transport) {
|
||||||
|
from P2PBox.pack(nodeId, transport) # ビルトインBoxの初期化
|
||||||
|
me.extraFeatures = new ArrayBox()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
box CustomMath from MathBox {
|
||||||
|
init { history }
|
||||||
|
|
||||||
|
pack() {
|
||||||
|
from MathBox.pack() # ビルトインBoxの初期化
|
||||||
|
me.history = new ArrayBox()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# ❌ 間違い(ユーザー定義Boxでpack使用)
|
||||||
|
box RegularUser {
|
||||||
|
pack(name) { # これは間違い!birth()を使う
|
||||||
|
me.name = name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## 🔍 from構文の詳細
|
## 🔍 from構文の詳細
|
||||||
|
|
||||||
### メソッド内でのfrom使用
|
### メソッド内でのfrom使用
|
||||||
|
|||||||
@ -362,7 +362,38 @@ impl NyashInterpreter {
|
|||||||
return Ok(field_value);
|
return Ok(field_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. エラー:見つからない
|
// 4. statics名前空間内のstatic boxをチェック
|
||||||
|
eprintln!("🔍 DEBUG: Checking statics namespace for '{}'...", name);
|
||||||
|
if let Some(statics_namespace) = global_box.get_field("statics") {
|
||||||
|
eprintln!("🔍 DEBUG: statics namespace type: {}", statics_namespace.type_name());
|
||||||
|
|
||||||
|
// MapBoxとして試す
|
||||||
|
if let Some(map_box) = statics_namespace.as_any().downcast_ref::<crate::boxes::map_box::MapBox>() {
|
||||||
|
eprintln!("🔍 DEBUG: statics is a MapBox, looking for '{}'", name);
|
||||||
|
let key_box: Box<dyn NyashBox> = Box::new(StringBox::new(name));
|
||||||
|
let static_box_result = map_box.get(key_box);
|
||||||
|
|
||||||
|
// NullBoxでないかチェック(MapBoxは見つからない場合NullBoxを返す)
|
||||||
|
if static_box_result.type_name() != "NullBox" {
|
||||||
|
eprintln!("🔍 DEBUG: Found '{}' in statics namespace", name);
|
||||||
|
return Ok(Arc::from(static_box_result));
|
||||||
|
} else {
|
||||||
|
eprintln!("🔍 DEBUG: '{}' not found in statics MapBox", name);
|
||||||
|
}
|
||||||
|
} else if let Some(instance) = statics_namespace.as_any().downcast_ref::<crate::instance::InstanceBox>() {
|
||||||
|
eprintln!("🔍 DEBUG: statics is an InstanceBox, looking for '{}'", name);
|
||||||
|
if let Some(static_box) = instance.get_field(name) {
|
||||||
|
eprintln!("🔍 DEBUG: Found '{}' in statics namespace", name);
|
||||||
|
return Ok(static_box);
|
||||||
|
} else {
|
||||||
|
eprintln!("🔍 DEBUG: '{}' not found in statics InstanceBox", name);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
eprintln!("🔍 DEBUG: statics namespace is neither MapBox nor InstanceBox");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. エラー:見つからない
|
||||||
eprintln!("🔍 DEBUG: '{}' not found anywhere!", name);
|
eprintln!("🔍 DEBUG: '{}' not found anywhere!", name);
|
||||||
Err(RuntimeError::UndefinedVariable {
|
Err(RuntimeError::UndefinedVariable {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
|
|||||||
@ -1104,8 +1104,8 @@ impl NyashInterpreter {
|
|||||||
|
|
||||||
drop(box_declarations); // ロック早期解放
|
drop(box_declarations); // ロック早期解放
|
||||||
|
|
||||||
// 4. constructorまたはinitまたはpackの場合の特別処理
|
// 4. constructorまたはinitまたはpackまたはbirthの場合の特別処理
|
||||||
if method == "constructor" || method == "init" || method == "pack" || method == parent {
|
if method == "constructor" || method == "init" || method == "pack" || method == "birth" || method == parent {
|
||||||
return self.execute_from_parent_constructor(parent, &parent_box_decl, current_instance_val.clone_box(), arguments);
|
return self.execute_from_parent_constructor(parent, &parent_box_decl, current_instance_val.clone_box(), arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1177,12 +1177,14 @@ impl NyashInterpreter {
|
|||||||
-> Result<Box<dyn NyashBox>, RuntimeError> {
|
-> Result<Box<dyn NyashBox>, RuntimeError> {
|
||||||
|
|
||||||
// 1. 親クラスのコンストラクタを取得(引数の数でキーを作成)
|
// 1. 親クラスのコンストラクタを取得(引数の数でキーを作成)
|
||||||
// "pack/引数数"、"init/引数数"、"Box名/引数数" の順で試す
|
// "birth/引数数"、"pack/引数数"、"init/引数数"、"Box名/引数数" の順で試す
|
||||||
|
let birth_key = format!("birth/{}", arguments.len());
|
||||||
let pack_key = format!("pack/{}", arguments.len());
|
let pack_key = format!("pack/{}", arguments.len());
|
||||||
let init_key = format!("init/{}", arguments.len());
|
let init_key = format!("init/{}", arguments.len());
|
||||||
let box_name_key = format!("{}/{}", parent, arguments.len());
|
let box_name_key = format!("{}/{}", parent, arguments.len());
|
||||||
|
|
||||||
let parent_constructor = parent_box_decl.constructors.get(&pack_key)
|
let parent_constructor = parent_box_decl.constructors.get(&birth_key)
|
||||||
|
.or_else(|| parent_box_decl.constructors.get(&pack_key))
|
||||||
.or_else(|| parent_box_decl.constructors.get(&init_key))
|
.or_else(|| parent_box_decl.constructors.get(&init_key))
|
||||||
.or_else(|| parent_box_decl.constructors.get(&box_name_key))
|
.or_else(|| parent_box_decl.constructors.get(&box_name_key))
|
||||||
.ok_or(RuntimeError::InvalidOperation {
|
.ok_or(RuntimeError::InvalidOperation {
|
||||||
|
|||||||
@ -713,12 +713,14 @@ impl NyashInterpreter {
|
|||||||
let instance_arc = Arc::from(instance_box);
|
let instance_arc = Arc::from(instance_box);
|
||||||
|
|
||||||
// コンストラクタを呼び出す
|
// コンストラクタを呼び出す
|
||||||
// "pack/引数数"、"init/引数数"、"Box名/引数数" の順で試す
|
// "birth/引数数"、"pack/引数数"、"init/引数数"、"Box名/引数数" の順で試す
|
||||||
|
let birth_key = format!("birth/{}", arguments.len());
|
||||||
let pack_key = format!("pack/{}", arguments.len());
|
let pack_key = format!("pack/{}", arguments.len());
|
||||||
let init_key = format!("init/{}", arguments.len());
|
let init_key = format!("init/{}", arguments.len());
|
||||||
let box_name_key = format!("{}/{}", actual_class_name, arguments.len());
|
let box_name_key = format!("{}/{}", actual_class_name, arguments.len());
|
||||||
|
|
||||||
if let Some(constructor) = final_box_decl.constructors.get(&pack_key)
|
if let Some(constructor) = final_box_decl.constructors.get(&birth_key)
|
||||||
|
.or_else(|| final_box_decl.constructors.get(&pack_key))
|
||||||
.or_else(|| final_box_decl.constructors.get(&init_key))
|
.or_else(|| final_box_decl.constructors.get(&init_key))
|
||||||
.or_else(|| final_box_decl.constructors.get(&box_name_key)) {
|
.or_else(|| final_box_decl.constructors.get(&box_name_key)) {
|
||||||
// コンストラクタを実行
|
// コンストラクタを実行
|
||||||
|
|||||||
@ -451,6 +451,66 @@ impl NyashParser {
|
|||||||
span: Span::unknown(),
|
span: Span::unknown(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// パラメータの数でコンストラクタを区別
|
||||||
|
let constructor_key = format!("{}/{}", field_or_method, params.len());
|
||||||
|
constructors.insert(constructor_key, constructor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// birthトークンをメソッド名として特別処理
|
||||||
|
else if self.match_token(&TokenType::BIRTH) && self.peek_token() == &TokenType::LPAREN {
|
||||||
|
let field_or_method = "birth".to_string();
|
||||||
|
self.advance(); // consume 'birth'
|
||||||
|
|
||||||
|
// コンストラクタとして処理
|
||||||
|
if self.match_token(&TokenType::LPAREN) {
|
||||||
|
// birthは常にコンストラクタ
|
||||||
|
if is_override {
|
||||||
|
return Err(ParseError::UnexpectedToken {
|
||||||
|
expected: "method definition, not constructor after override keyword".to_string(),
|
||||||
|
found: TokenType::BIRTH,
|
||||||
|
line: self.current_token().line,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// コンストラクタの処理
|
||||||
|
self.advance(); // consume '('
|
||||||
|
|
||||||
|
let mut params = Vec::new();
|
||||||
|
while !self.match_token(&TokenType::RPAREN) && !self.is_at_end() {
|
||||||
|
must_advance!(self, _unused, "constructor parameter parsing");
|
||||||
|
|
||||||
|
if let TokenType::IDENTIFIER(param) = &self.current_token().token_type {
|
||||||
|
params.push(param.clone());
|
||||||
|
self.advance();
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.match_token(&TokenType::COMMA) {
|
||||||
|
self.advance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.consume(TokenType::RPAREN)?;
|
||||||
|
self.consume(TokenType::LBRACE)?;
|
||||||
|
|
||||||
|
let mut body = Vec::new();
|
||||||
|
while !self.match_token(&TokenType::RBRACE) && !self.is_at_end() {
|
||||||
|
self.skip_newlines();
|
||||||
|
if !self.match_token(&TokenType::RBRACE) {
|
||||||
|
body.push(self.parse_statement()?);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.consume(TokenType::RBRACE)?;
|
||||||
|
|
||||||
|
let constructor = ASTNode::FunctionDeclaration {
|
||||||
|
name: field_or_method.clone(),
|
||||||
|
params: params.clone(),
|
||||||
|
body,
|
||||||
|
is_static: false,
|
||||||
|
is_override: false,
|
||||||
|
span: Span::unknown(),
|
||||||
|
};
|
||||||
|
|
||||||
// パラメータの数でコンストラクタを区別
|
// パラメータの数でコンストラクタを区別
|
||||||
let constructor_key = format!("{}/{}", field_or_method, params.len());
|
let constructor_key = format!("{}/{}", field_or_method, params.len());
|
||||||
constructors.insert(constructor_key, constructor);
|
constructors.insert(constructor_key, constructor);
|
||||||
@ -461,8 +521,8 @@ impl NyashParser {
|
|||||||
|
|
||||||
// メソッド定義またはコンストラクタか?
|
// メソッド定義またはコンストラクタか?
|
||||||
if self.match_token(&TokenType::LPAREN) {
|
if self.match_token(&TokenType::LPAREN) {
|
||||||
// Box名と同じまたは"init"または"pack"の場合はコンストラクタ
|
// Box名と同じまたは"init"または"pack"または"birth"の場合はコンストラクタ
|
||||||
if field_or_method == name || field_or_method == "init" || field_or_method == "pack" {
|
if field_or_method == name || field_or_method == "init" || field_or_method == "pack" || field_or_method == "birth" {
|
||||||
// コンストラクタはoverrideできない
|
// コンストラクタはoverrideできない
|
||||||
if is_override {
|
if is_override {
|
||||||
return Err(ParseError::UnexpectedToken {
|
return Err(ParseError::UnexpectedToken {
|
||||||
|
|||||||
@ -33,7 +33,8 @@ pub enum TokenType {
|
|||||||
THIS,
|
THIS,
|
||||||
ME,
|
ME,
|
||||||
INIT, // init (初期化ブロック)
|
INIT, // init (初期化ブロック)
|
||||||
PACK, // pack (コンストラクタ)
|
PACK, // pack (コンストラクタ - 互換性)
|
||||||
|
BIRTH, // birth (コンストラクタ)
|
||||||
NOWAIT, // nowait
|
NOWAIT, // nowait
|
||||||
AWAIT, // await
|
AWAIT, // await
|
||||||
INTERFACE, // interface
|
INTERFACE, // interface
|
||||||
@ -399,6 +400,7 @@ impl NyashTokenizer {
|
|||||||
"me" => TokenType::ME,
|
"me" => TokenType::ME,
|
||||||
"init" => TokenType::INIT,
|
"init" => TokenType::INIT,
|
||||||
"pack" => TokenType::PACK,
|
"pack" => TokenType::PACK,
|
||||||
|
"birth" => TokenType::BIRTH,
|
||||||
"nowait" => TokenType::NOWAIT,
|
"nowait" => TokenType::NOWAIT,
|
||||||
"await" => TokenType::AWAIT,
|
"await" => TokenType::AWAIT,
|
||||||
"interface" => TokenType::INTERFACE,
|
"interface" => TokenType::INTERFACE,
|
||||||
|
|||||||
27
test_birth_simple.nyash
Normal file
27
test_birth_simple.nyash
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# 🌟 birth() テスト - 生命をBoxに与える!
|
||||||
|
|
||||||
|
box Life {
|
||||||
|
init { name, energy }
|
||||||
|
|
||||||
|
birth(lifeName) { # 生命を誕生させる
|
||||||
|
me.name = lifeName
|
||||||
|
me.energy = 100
|
||||||
|
print("🌟 " + lifeName + " が誕生しました!")
|
||||||
|
}
|
||||||
|
|
||||||
|
introduce() {
|
||||||
|
print("私の名前は " + me.name + " です。エネルギーは " + me.energy + " です。")
|
||||||
|
return me.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print("=== birth() 構文テスト開始 ===")
|
||||||
|
|
||||||
|
# birth()コンストラクタでLife作成
|
||||||
|
local alice = new Life("Alice")
|
||||||
|
alice.introduce()
|
||||||
|
|
||||||
|
local bob = new Life("Bob")
|
||||||
|
bob.introduce()
|
||||||
|
|
||||||
|
print("=== birth() テスト完了 ===")
|
||||||
Reference in New Issue
Block a user