feat(plugin): Fix plugin BoxRef return and Box argument support
- Fixed deadlock in FileBox plugin copyFrom implementation (single lock) - Added TLV Handle (tag=8) parsing in calls.rs for returned BoxRefs - Improved plugin loader with config path consistency and detailed logging - Fixed loader routing for proper Handle type_id/fini_method_id resolution - Added detailed logging for TLV encoding/decoding in plugin_loader_v2 Test docs/examples/plugin_boxref_return.nyash now works correctly: - cloneSelf() returns FileBox Handle properly - copyFrom(Box) accepts plugin Box arguments - Both FileBox instances close and fini correctly 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
30
docs/guides/README.md
Normal file
30
docs/guides/README.md
Normal file
@ -0,0 +1,30 @@
|
||||
# Nyash User Guides 📚
|
||||
|
||||
Nyashプログラミング言語の利用者向けガイドとチュートリアルです。
|
||||
|
||||
## 🚀 はじめに
|
||||
- `getting-started.md` - Nyashを始めるためのクイックガイド
|
||||
|
||||
## 📖 サブディレクトリ
|
||||
|
||||
### tutorials/
|
||||
- `hello-world.md` - 最初のNyashプログラム
|
||||
- `basic-boxes.md` - Box(クラス)の基礎
|
||||
- `delegation.md` - デリゲーションの使い方
|
||||
- `p2p-apps.md` - P2Pアプリケーション開発
|
||||
|
||||
### examples/
|
||||
- 実践的なサンプルコード集
|
||||
- よくあるパターンの実装例
|
||||
- ベストプラクティス
|
||||
|
||||
### wasm-guide/
|
||||
- WebAssemblyビルドガイド
|
||||
- ブラウザープレイグラウンドの使い方
|
||||
- Webアプリケーション開発
|
||||
|
||||
## 🎯 学習順序
|
||||
1. `getting-started.md` から始める
|
||||
2. `tutorials/` のチュートリアルを順番に
|
||||
3. `examples/` で実践的なコードを学ぶ
|
||||
4. 特定用途(WASM等)は各ガイドへ
|
||||
547
docs/guides/getting-started.md
Normal file
547
docs/guides/getting-started.md
Normal file
@ -0,0 +1,547 @@
|
||||
# 🚀 Getting Started with Nyash - Practical Guide
|
||||
|
||||
**最終更新: 2025年8月8日**
|
||||
|
||||
## 🎯 5分でNyashを理解する
|
||||
|
||||
Nyashは「Everything is Box」哲学に基づく、シンプルで強力なプログラミング言語です。
|
||||
このガイドでは、実際にコードを書きながらNyashの機能を学んでいきます。
|
||||
|
||||
## ⚡ クイックスタート
|
||||
|
||||
### **1. 環境構築**
|
||||
```bash
|
||||
# リポジトリのクローン
|
||||
git clone [repository-url]
|
||||
cd nyash/nyash-rust
|
||||
|
||||
# ビルド
|
||||
cargo build
|
||||
|
||||
# 実行
|
||||
./target/debug/nyash your_program.nyash
|
||||
```
|
||||
|
||||
### **2. はじめてのNyashプログラム**
|
||||
`hello.nyash`を作成:
|
||||
```nyash
|
||||
print("Hello, Nyash World!")
|
||||
print("Everything is Box! 🎉")
|
||||
```
|
||||
|
||||
実行:
|
||||
```bash
|
||||
./target/debug/nyash hello.nyash
|
||||
```
|
||||
|
||||
出力:
|
||||
```
|
||||
Hello, Nyash World!
|
||||
Everything is Box! 🎉
|
||||
```
|
||||
|
||||
## 📚 基本構文チュートリアル
|
||||
|
||||
### **Step 1: 変数と初期化**
|
||||
```nyash
|
||||
# 🎯 新機能:初期化付き変数宣言
|
||||
local name = "Alice"
|
||||
local age = 25
|
||||
local height = 165.5
|
||||
local isStudent = true
|
||||
|
||||
print("Name: " + name)
|
||||
print("Age: " + age)
|
||||
print("Height: " + height)
|
||||
print("Student: " + isStudent)
|
||||
|
||||
# 複数変数の同時宣言・初期化
|
||||
local x = 10, y = 20, z = 30
|
||||
print("Sum: " + (x + y + z)) # 60
|
||||
|
||||
# 混合宣言(初期化あり・なし)
|
||||
local initialized = 42, uninitialized, another = "test"
|
||||
uninitialized = "assigned later"
|
||||
print("Values: " + initialized + ", " + uninitialized + ", " + another)
|
||||
```
|
||||
|
||||
### **Step 2: 演算子の使用**
|
||||
```nyash
|
||||
local a = 10
|
||||
local b = 3
|
||||
|
||||
# 算術演算子
|
||||
print("Addition: " + (a + b)) # 13
|
||||
print("Subtraction: " + (a - b)) # 7
|
||||
print("Multiplication: " + (a * b)) # 30
|
||||
print("Division: " + (a / b)) # 3.3333333333333335
|
||||
|
||||
# 論理演算子(自然言語ライク)
|
||||
local hasPermission = true
|
||||
local isLoggedIn = true
|
||||
local canAccess = hasPermission and isLoggedIn
|
||||
print("Can access: " + canAccess) # true
|
||||
|
||||
local isDenied = not canAccess
|
||||
print("Is denied: " + isDenied) # false
|
||||
|
||||
# 比較演算子
|
||||
print("a > b: " + (a > b)) # true
|
||||
print("a == b: " + (a == b)) # false
|
||||
```
|
||||
|
||||
### **Step 3: 制御構造**
|
||||
```nyash
|
||||
function testControlFlow() {
|
||||
local score = 85
|
||||
|
||||
# if文
|
||||
if score >= 90 {
|
||||
print("Grade: A")
|
||||
} else if score >= 80 {
|
||||
print("Grade: B") # これが実行される
|
||||
} else {
|
||||
print("Grade: C or below")
|
||||
}
|
||||
|
||||
# ループ(統一構文)
|
||||
local count = 0
|
||||
loop(count < 3) {
|
||||
print("Count: " + count)
|
||||
count = count + 1
|
||||
if count == 2 {
|
||||
print("Breaking at 2")
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
testControlFlow()
|
||||
```
|
||||
|
||||
### **Step 4: Box(クラス)の定義**
|
||||
```nyash
|
||||
box Person {
|
||||
init { name, age, email } # フィールド定義(カンマ必須!)
|
||||
|
||||
# コンストラクタ(引数サポート)
|
||||
Person(n, a, e) {
|
||||
me.name = n
|
||||
me.age = a
|
||||
me.email = e
|
||||
print("Person created: " + me.name)
|
||||
}
|
||||
|
||||
# メソッド
|
||||
introduce() {
|
||||
print("Hi, I'm " + me.name + ", age " + me.age)
|
||||
}
|
||||
|
||||
getInfo() {
|
||||
return me.name + " (" + me.age + ") - " + me.email
|
||||
}
|
||||
|
||||
# デストラクタ
|
||||
fini() {
|
||||
print("Person destroyed: " + me.name)
|
||||
}
|
||||
}
|
||||
|
||||
# 使用例
|
||||
person = new Person("Bob", 30, "bob@example.com")
|
||||
person.introduce()
|
||||
print("Info: " + person.getInfo())
|
||||
```
|
||||
|
||||
## 🏭 実践例:Calculator アプリ
|
||||
|
||||
完全なCalculatorアプリを実装:
|
||||
|
||||
```nyash
|
||||
# 📱 Calculator App - Nyash版
|
||||
|
||||
box Calculator {
|
||||
init { history }
|
||||
|
||||
Calculator() {
|
||||
me.history = new ArrayBox()
|
||||
print("🧮 Calculator initialized!")
|
||||
}
|
||||
|
||||
add(a, b) {
|
||||
local result = a + b
|
||||
me.addToHistory("ADD", a, b, result)
|
||||
return result
|
||||
}
|
||||
|
||||
subtract(a, b) {
|
||||
local result = a - b
|
||||
me.addToHistory("SUB", a, b, result)
|
||||
return result
|
||||
}
|
||||
|
||||
multiply(a, b) {
|
||||
local result = a * b
|
||||
me.addToHistory("MUL", a, b, result)
|
||||
return result
|
||||
}
|
||||
|
||||
divide(a, b) {
|
||||
if b == 0 {
|
||||
print("❌ Error: Division by zero!")
|
||||
return 0
|
||||
}
|
||||
local result = a / b
|
||||
me.addToHistory("DIV", a, b, result)
|
||||
return result
|
||||
}
|
||||
|
||||
addToHistory(op, a, b, result) {
|
||||
local record = op + ": " + a + " " + op + " " + b + " = " + result
|
||||
me.history.push(record)
|
||||
}
|
||||
|
||||
showHistory() {
|
||||
print("📊 Calculation History:")
|
||||
local size = me.history.size()
|
||||
local i = 0
|
||||
loop(i < size) {
|
||||
print(" " + (i + 1) + ". " + me.history.get(i))
|
||||
i = i + 1
|
||||
}
|
||||
}
|
||||
|
||||
clear() {
|
||||
me.history = new ArrayBox()
|
||||
print("🧹 History cleared!")
|
||||
}
|
||||
}
|
||||
|
||||
# ✨ Calculator使用例
|
||||
calc = new Calculator()
|
||||
|
||||
print("=== Basic Operations ===")
|
||||
print("10 + 5 = " + calc.add(10, 5))
|
||||
print("10 - 3 = " + calc.subtract(10, 3))
|
||||
print("4 * 7 = " + calc.multiply(4, 7))
|
||||
print("15 / 3 = " + calc.divide(15, 3))
|
||||
print("10 / 0 = " + calc.divide(10, 0)) # ゼロ除算エラーテスト
|
||||
|
||||
print("")
|
||||
calc.showHistory()
|
||||
|
||||
print("")
|
||||
print("=== Complex Calculations ===")
|
||||
local complex1 = calc.add(calc.multiply(3, 4), calc.divide(20, 4))
|
||||
print("(3 * 4) + (20 / 4) = " + complex1)
|
||||
|
||||
calc.showHistory()
|
||||
```
|
||||
|
||||
## ⚡ 並行処理の実践
|
||||
|
||||
```nyash
|
||||
# 🚀 Parallel Processing Example
|
||||
|
||||
function heavyComputation(iterations) {
|
||||
print("⚙️ Starting computation with " + iterations + " iterations...")
|
||||
|
||||
local sum = 0
|
||||
local i = 0
|
||||
loop(i < iterations) {
|
||||
sum = sum + (i * i)
|
||||
i = i + 1
|
||||
|
||||
# 進捗表示(1000回毎)
|
||||
if (i % 1000) == 0 {
|
||||
print(" Progress: " + i + "/" + iterations)
|
||||
}
|
||||
}
|
||||
|
||||
print("✅ Computation completed: " + sum)
|
||||
return sum
|
||||
}
|
||||
|
||||
function parallelDemo() {
|
||||
print("🚀 Starting parallel computations...")
|
||||
|
||||
# 3つのタスクを並行実行
|
||||
future1 = nowait heavyComputation(5000)
|
||||
future2 = nowait heavyComputation(3000)
|
||||
future3 = nowait heavyComputation(4000)
|
||||
|
||||
print("⏳ All tasks started. Waiting for results...")
|
||||
|
||||
# 結果を待機して取得
|
||||
result1 = await future1
|
||||
result2 = await future2
|
||||
result3 = await future3
|
||||
|
||||
local total = result1 + result2 + result3
|
||||
print("🎉 All tasks completed!")
|
||||
print("Total sum: " + total)
|
||||
|
||||
return total
|
||||
}
|
||||
|
||||
# 実行
|
||||
parallelDemo()
|
||||
```
|
||||
|
||||
## 🏗️ Static Box(名前空間)の活用
|
||||
|
||||
```nyash
|
||||
# 🏗️ Utility Classes with Static Boxes
|
||||
|
||||
static box MathUtils {
|
||||
init { PI, E }
|
||||
|
||||
static {
|
||||
me.PI = 3.14159265359
|
||||
me.E = 2.71828182846
|
||||
}
|
||||
|
||||
square(x) {
|
||||
return x * x
|
||||
}
|
||||
|
||||
circleArea(radius) {
|
||||
return me.PI * me.square(radius)
|
||||
}
|
||||
|
||||
power(base, exp) {
|
||||
local result = 1
|
||||
local i = 0
|
||||
loop(i < exp) {
|
||||
result = result * base
|
||||
i = i + 1
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
static box StringUtils {
|
||||
init { EMPTY }
|
||||
|
||||
static {
|
||||
me.EMPTY = ""
|
||||
}
|
||||
|
||||
reverse(str) {
|
||||
# 簡易的な実装例
|
||||
return "REVERSED:" + str
|
||||
}
|
||||
|
||||
isEmpty(str) {
|
||||
return str == me.EMPTY
|
||||
}
|
||||
}
|
||||
|
||||
# 使用例
|
||||
print("π = " + MathUtils.PI)
|
||||
print("Circle area (r=5): " + MathUtils.circleArea(5))
|
||||
print("2^8 = " + MathUtils.power(2, 8))
|
||||
|
||||
print("Empty check: " + StringUtils.isEmpty(""))
|
||||
print("Reverse: " + StringUtils.reverse("Hello"))
|
||||
```
|
||||
|
||||
## 🐛 デバッグ機能の活用
|
||||
|
||||
```nyash
|
||||
# 🐛 Debug Features Showcase
|
||||
|
||||
box DebugExample {
|
||||
init { data, counter }
|
||||
|
||||
DebugExample() {
|
||||
me.data = "example"
|
||||
me.counter = 0
|
||||
}
|
||||
|
||||
process() {
|
||||
me.counter = me.counter + 1
|
||||
return "Processed #" + me.counter
|
||||
}
|
||||
}
|
||||
|
||||
function debuggingDemo() {
|
||||
# DebugBoxでトラッキング開始
|
||||
DEBUG = new DebugBox()
|
||||
DEBUG.startTracking()
|
||||
|
||||
print("🔍 Creating objects for debugging...")
|
||||
|
||||
# オブジェクトを作成してトラッキング
|
||||
obj1 = new DebugExample()
|
||||
obj2 = new DebugExample()
|
||||
|
||||
DEBUG.trackBox(obj1, "Primary Object")
|
||||
DEBUG.trackBox(obj2, "Secondary Object")
|
||||
|
||||
# 処理実行
|
||||
result1 = obj1.process()
|
||||
result2 = obj2.process()
|
||||
result3 = obj1.process()
|
||||
|
||||
print("Results: " + result1 + ", " + result2 + ", " + result3)
|
||||
|
||||
# デバッグレポート表示
|
||||
print("")
|
||||
print("=== Memory Report ===")
|
||||
print(DEBUG.memoryReport())
|
||||
|
||||
print("")
|
||||
print("=== Full Debug Dump ===")
|
||||
print(DEBUG.dumpAll())
|
||||
|
||||
# デバッグ情報をファイルに保存
|
||||
DEBUG.saveToFile("debug_output.txt")
|
||||
print("🎉 Debug information saved to debug_output.txt")
|
||||
}
|
||||
|
||||
debuggingDemo()
|
||||
```
|
||||
|
||||
## 📦 ファイル組織とモジュール
|
||||
|
||||
### **プロジェクト構造**
|
||||
```
|
||||
my_nyash_project/
|
||||
├── main.nyash # メインプログラム
|
||||
├── utils/
|
||||
│ ├── math.nyash # 数学ユーティリティ
|
||||
│ ├── string.nyash # 文字列ユーティリティ
|
||||
│ └── debug.nyash # デバッグ関数
|
||||
└── models/
|
||||
├── person.nyash # Personクラス
|
||||
└── calculator.nyash # Calculatorクラス
|
||||
```
|
||||
|
||||
### **main.nyash**
|
||||
```nyash
|
||||
# 📦 Module System Example
|
||||
|
||||
include "utils/math.nyash"
|
||||
include "utils/string.nyash"
|
||||
include "models/person.nyash"
|
||||
include "models/calculator.nyash"
|
||||
|
||||
function main() {
|
||||
print("🚀 Multi-module Nyash Application")
|
||||
|
||||
# 各モジュールの機能を使用
|
||||
person = new Person("Alice", 25, "alice@example.com")
|
||||
person.introduce()
|
||||
|
||||
calc = new Calculator()
|
||||
result = calc.add(10, 20)
|
||||
print("Calculation result: " + result)
|
||||
}
|
||||
|
||||
main()
|
||||
```
|
||||
|
||||
## 🎯 ベストプラクティス
|
||||
|
||||
### **1. 変数命名**
|
||||
```nyash
|
||||
# ✅ Good
|
||||
local userName = "alice"
|
||||
local totalAmount = 1000
|
||||
local isComplete = true
|
||||
|
||||
# ❌ Avoid
|
||||
local x = "alice"
|
||||
local amt = 1000
|
||||
local flag = true
|
||||
```
|
||||
|
||||
### **2. Box設計**
|
||||
```nyash
|
||||
# ✅ Good: 明確な責任分離
|
||||
box UserAccount {
|
||||
init { username, email, balance }
|
||||
|
||||
UserAccount(u, e) {
|
||||
me.username = u
|
||||
me.email = e
|
||||
me.balance = 0
|
||||
}
|
||||
|
||||
deposit(amount) {
|
||||
me.balance = me.balance + amount
|
||||
}
|
||||
}
|
||||
|
||||
# ❌ Avoid: 責任の混在
|
||||
box EverythingBox {
|
||||
# 多すぎる責任を持たせない
|
||||
}
|
||||
```
|
||||
|
||||
### **3. エラーハンドリング**
|
||||
```nyash
|
||||
function safeOperation(a, b) {
|
||||
if b == 0 {
|
||||
print("❌ Error: Division by zero")
|
||||
return 0
|
||||
}
|
||||
return a / b
|
||||
}
|
||||
```
|
||||
|
||||
### **4. パフォーマンス考慮**
|
||||
```nyash
|
||||
# ✅ 効率的:static box使用
|
||||
result = MathUtils.calculate(data)
|
||||
|
||||
# ✅ 効率的:初期化付き宣言
|
||||
local result = heavyCalculation(), cache = new MapBox()
|
||||
|
||||
# ⚠️ 注意:不要なオブジェクト生成を避ける
|
||||
loop(i < 1000) {
|
||||
# 毎回new しない設計を心がける
|
||||
}
|
||||
```
|
||||
|
||||
## 🚀 次のステップ
|
||||
|
||||
### **学習順序**
|
||||
1. ✅ **基本構文** - このガイドで完了
|
||||
2. **並行処理** - `test_async_*.nyash`を参考に
|
||||
3. **Static Box応用** - ユーティリティクラス作成
|
||||
4. **デバッグ技法** - DebugBox完全活用
|
||||
5. **アプリケーション開発** - 実践的なプロジェクト
|
||||
|
||||
### **サンプルプログラム**
|
||||
```bash
|
||||
# 実装済みサンプル
|
||||
./target/debug/nyash test_local_init.nyash # 初期化付き変数
|
||||
./target/debug/nyash app_dice_rpg.nyash # RPGバトルゲーム
|
||||
./target/debug/nyash app_statistics.nyash # 統計計算
|
||||
./target/debug/nyash test_async_parallel.nyash # 並行処理
|
||||
```
|
||||
|
||||
### **リファレンス**
|
||||
- `docs/LANGUAGE_OVERVIEW_2025.md` - 言語全体概要
|
||||
- `docs/TECHNICAL_ARCHITECTURE_2025.md` - 技術仕様
|
||||
- `CLAUDE.md` - 開発者向け詳細情報
|
||||
|
||||
## 🎉 おめでとうございます!
|
||||
|
||||
このガイドでNyashの主要機能を学習しました!
|
||||
|
||||
**習得内容:**
|
||||
- ✅ 基本構文(変数・演算子・制御構造)
|
||||
- ✅ Box(クラス)定義とオブジェクト指向
|
||||
- ✅ 並行処理・非同期プログラミング
|
||||
- ✅ Static Box・名前空間システム
|
||||
- ✅ デバッグ機能・開発支援ツール
|
||||
- ✅ 実践的なアプリケーション開発
|
||||
|
||||
**Nyashでプログラミングの新しい可能性を探究してください!** 🚀
|
||||
|
||||
---
|
||||
*Getting Started Guide v1.0*
|
||||
*Everything is Box - Start Simple, Think Big*
|
||||
274
docs/guides/language-guide.md
Normal file
274
docs/guides/language-guide.md
Normal file
@ -0,0 +1,274 @@
|
||||
# 📚 Nyash Programming Language - 完全ガイド
|
||||
|
||||
**最終更新: 2025年8月12日 - Phase 1完了, P2P実装準備完了**
|
||||
|
||||
## 📖 概要
|
||||
|
||||
Nyashは「Everything is Box」哲学に基づく革新的なプログラミング言語です。
|
||||
Rust製インタープリターによる高性能実行と、直感的な構文により、学習しやすく実用的な言語として完成しました。
|
||||
|
||||
## 🎯 核心哲学: "Everything is Box"
|
||||
|
||||
```nyash
|
||||
# すべてのデータがBoxとして統一的に表現される
|
||||
number = 42 # IntegerBox
|
||||
text = "hello" # StringBox
|
||||
flag = true # BoolBox
|
||||
array = new ArrayBox() # ArrayBox
|
||||
debug = new DebugBox() # DebugBox
|
||||
```
|
||||
|
||||
**重要な利点:**
|
||||
- **統一性**: すべてのデータが共通インターフェース
|
||||
- **メモリ安全性**: Arc<Mutex>パターンで完全スレッドセーフ
|
||||
- **拡張性**: 新しいBox型を容易に追加可能
|
||||
|
||||
---
|
||||
|
||||
## 🔤 言語構文リファレンス
|
||||
|
||||
### 🏷️ **変数宣言・スコープ**
|
||||
|
||||
```nyash
|
||||
// ローカル変数宣言
|
||||
local x, y
|
||||
local name = "Alice"
|
||||
|
||||
// 所有権移転変数(関数戻り値用)
|
||||
outbox result = compute()
|
||||
|
||||
// グローバル変数
|
||||
global CONFIG = "dev"
|
||||
```
|
||||
|
||||
### 🧮 **演算子**
|
||||
|
||||
```nyash
|
||||
// 算術演算子
|
||||
a + b, a - b, a * b, a / b
|
||||
|
||||
// 比較演算子
|
||||
a == b, a != b, a < b, a > b, a <= b, a >= b
|
||||
|
||||
// 論理演算子
|
||||
not condition, a and b, a or b
|
||||
|
||||
// Cross-type演算 (Phase 1で完全実装)
|
||||
10 + 3.14 // → 13.14 (型変換)
|
||||
"Value: " + 42 // → "Value: 42" (文字列連結)
|
||||
```
|
||||
|
||||
### 🏗️ **Box定義・デリゲーション**
|
||||
|
||||
#### 基本Box定義
|
||||
```nyash
|
||||
box User {
|
||||
init { name, email } // フィールド宣言
|
||||
|
||||
birth(userName, userEmail) { // 🌟 生命をBoxに与える!
|
||||
me.name = userName
|
||||
me.email = userEmail
|
||||
print("🌟 " + userName + " が誕生しました!")
|
||||
}
|
||||
|
||||
greet() {
|
||||
print("Hello, " + me.name)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### デリゲーション (2025-08 革命)
|
||||
```nyash
|
||||
box AdminUser from User { // 🔥 from構文でデリゲーション
|
||||
init { permissions }
|
||||
|
||||
birth(adminName, adminEmail, perms) {
|
||||
from User.birth(adminName, adminEmail) // 親のbirth呼び出し
|
||||
me.permissions = perms
|
||||
}
|
||||
|
||||
override greet() { // 明示的オーバーライド
|
||||
from User.greet() // 親メソッド呼び出し
|
||||
print("Admin privileges: " + me.permissions)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### ビルトイン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 パターン
|
||||
```nyash
|
||||
static box Main {
|
||||
init { console, result }
|
||||
|
||||
main() {
|
||||
me.console = new ConsoleBox()
|
||||
me.console.log("🎉 Everything is Box!")
|
||||
return "Success!"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 🔄 **制御構造**
|
||||
|
||||
```nyash
|
||||
// 条件分岐
|
||||
if condition {
|
||||
// 処理
|
||||
} else {
|
||||
// 別処理
|
||||
}
|
||||
|
||||
// ループ(唯一の正しい形式)
|
||||
loop(condition) {
|
||||
// 処理
|
||||
if breakCondition {
|
||||
break
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📦 ビルトインBox型
|
||||
|
||||
### 基本型
|
||||
- **StringBox**: 文字列 (`"hello"`)
|
||||
- **IntegerBox**: 整数 (`42`)
|
||||
- **FloatBox**: 浮動小数点数 (`new FloatBox(3.14)`) ✅ Phase 1完了
|
||||
- **BoolBox**: 真偽値 (`true`, `false`)
|
||||
- **NullBox**: NULL値 (`null`)
|
||||
|
||||
### データ構造
|
||||
- **ArrayBox**: 配列 (`new ArrayBox()`) ✅ Phase 1で sort/reverse/indexOf/slice 実装
|
||||
- **MapBox**: 連想配列 (`new MapBox()`)
|
||||
|
||||
### ユーティリティ
|
||||
- **ConsoleBox**: コンソール出力 (`new ConsoleBox()`)
|
||||
- **DebugBox**: デバッグ機能 (`new DebugBox()`)
|
||||
- **MathBox**: 数学関数 (`new MathBox()`)
|
||||
- **TimeBox**: 時刻処理 (`new TimeBox()`)
|
||||
- **DateTimeBox**: 日時処理 (`new DateTimeBox()`) ✅ Phase 1で完全動作
|
||||
|
||||
### 高度機能
|
||||
- **RandomBox**: 乱数生成
|
||||
- **BufferBox**: バッファ操作
|
||||
- **RegexBox**: 正規表現
|
||||
- **JSONBox**: JSON処理
|
||||
- **StreamBox**: ストリーム処理
|
||||
|
||||
### P2P通信 (Phase 2実装中)
|
||||
- **IntentBox**: 構造化メッセージ (実装予定)
|
||||
- **P2PBox**: P2P通信ノード (実装予定)
|
||||
|
||||
---
|
||||
|
||||
## 🚀 実用例
|
||||
|
||||
### データ処理例
|
||||
```nyash
|
||||
// 配列操作
|
||||
local numbers = new ArrayBox()
|
||||
numbers.push(3)
|
||||
numbers.push(1)
|
||||
numbers.push(2)
|
||||
numbers.sort() // [1, 2, 3]
|
||||
|
||||
// 型変換・演算
|
||||
local result = 10 + new FloatBox(3.14) // 13.14
|
||||
print("Result: " + result.toString())
|
||||
```
|
||||
|
||||
### P2P通信例 (将来実装)
|
||||
```nyash
|
||||
// P2Pノード作成
|
||||
local node_a = new P2PBox("alice", transport: "inprocess")
|
||||
local node_b = new P2PBox("bob", transport: "inprocess")
|
||||
|
||||
// メッセージ受信ハンドラ
|
||||
node_b.on("chat.message", function(intent, from) {
|
||||
print("From " + from + ": " + intent.payload.text)
|
||||
})
|
||||
|
||||
// 構造化メッセージ送信
|
||||
local msg = new IntentBox("chat.message", { text: "Hello P2P!" })
|
||||
node_a.send("bob", msg) // → "From alice: Hello P2P!"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 重要な注意点
|
||||
|
||||
### 必須のコンマ
|
||||
```nyash
|
||||
// ✅ 正しい
|
||||
init { field1, field2 }
|
||||
|
||||
// ❌ 間違い(CPU暴走の原因)
|
||||
init { field1 field2 }
|
||||
```
|
||||
|
||||
### 変数宣言厳密化
|
||||
```nyash
|
||||
// ✅ 明示宣言必須
|
||||
local x
|
||||
x = 42
|
||||
|
||||
// ❌ 未宣言変数への代入はエラー
|
||||
y = 42 // Runtime Error + 修正提案
|
||||
```
|
||||
|
||||
### ループ構文統一
|
||||
```nyash
|
||||
// ✅ 唯一の正しい形式
|
||||
loop(condition) { }
|
||||
|
||||
// ❌ 削除済み構文
|
||||
while condition { } // 使用不可
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📈 実装状況 (2025-08-12)
|
||||
|
||||
### ✅ Phase 1完了
|
||||
- FloatBox toString() メソッド
|
||||
- ArrayBox 改良 (sort/reverse/indexOf/slice)
|
||||
- Cross-type演算子システム
|
||||
- 包括的テストスイート (188行)
|
||||
|
||||
### 🚧 Phase 2実装中
|
||||
- IntentBox (構造化メッセージ)
|
||||
- MessageBus (プロセス内シングルトン)
|
||||
- P2PBox (P2P通信ノード)
|
||||
|
||||
### 📋 将来予定
|
||||
- WebSocket/WebRTC通信
|
||||
- 非同期処理 (async/await)
|
||||
- 追加のBox型拡張
|
||||
|
||||
---
|
||||
|
||||
**🎉 Nyashで「Everything is Box」の世界を体験しよう!**
|
||||
|
||||
📚 **関連ドキュメント:**
|
||||
- [Getting Started](GETTING_STARTED.md) - 環境構築・最初の一歩
|
||||
- [P2P Guide](P2P_GUIDE.md) - P2P通信システム完全ガイド
|
||||
- [Built-in Boxes](reference/builtin-boxes.md) - ビルトインBox詳細リファレンス
|
||||
234
docs/guides/p2p-guide.md
Normal file
234
docs/guides/p2p-guide.md
Normal file
@ -0,0 +1,234 @@
|
||||
# 📡 Nyash P2P通信システム - 完全ガイド
|
||||
|
||||
**目標**: NyaMeshP2Pライブラリ実現のための本格的P2P通信システム
|
||||
|
||||
## 🏗️ システム全体像
|
||||
|
||||
```
|
||||
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
|
||||
│ P2PBox │◄──►│ MessageBus │◄──►│ Transport │
|
||||
│ (ユーザーAPI) │ │ (ローカル配送) │ │ (送受信層) │
|
||||
└─────────────┘ └──────────────┘ └─────────────┘
|
||||
▲ ▲ ▲
|
||||
│ │ │
|
||||
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
|
||||
│ IntentBox │ │ ハンドラ管理 │ │ InProcess │
|
||||
│ (構造化MSG) │ │ ノード登録 │ │ WebSocket │
|
||||
└─────────────┘ └──────────────┘ │ WebRTC │
|
||||
└─────────────┘
|
||||
```
|
||||
|
||||
**核心思想**: 「P2PBox一つにTransport一つ + 共有MessageBus」
|
||||
|
||||
## 🧩 4つの主要Box
|
||||
|
||||
### 1. **IntentBox** - 構造化メッセージ 📨
|
||||
```rust
|
||||
pub struct IntentBoxData {
|
||||
pub name: String, // "chat.message", "file.share"等
|
||||
pub payload: serde_json::Value, // 任意のJSON data
|
||||
}
|
||||
pub type IntentBox = Arc<Mutex<IntentBoxData>>;
|
||||
```
|
||||
|
||||
```nyash
|
||||
// 使用例
|
||||
msg = new IntentBox("chat.message", { text: "Hello P2P!", timestamp: 12345 })
|
||||
print(msg.name) // "chat.message"
|
||||
print(msg.payload) // {"text":"Hello P2P!","timestamp":12345}
|
||||
```
|
||||
|
||||
### 2. **MessageBus** - プロセス内シングルトン 🚌
|
||||
```rust
|
||||
pub struct MessageBusData {
|
||||
nodes: HashMap<String, BusEndpoint>, // ノード登録
|
||||
subscribers: HashMap<String, Vec<IntentHandler>>, // "node_id:intent_name" → ハンドラー
|
||||
stats: BusStatistics,
|
||||
}
|
||||
pub type MessageBus = Arc<Mutex<MessageBusData>>;
|
||||
|
||||
// シングルトンアクセス
|
||||
MessageBusData::global() -> MessageBus
|
||||
```
|
||||
|
||||
**役割**: 同プロセス内での超高速メッセージルーティング・ハンドラ管理
|
||||
|
||||
### 3. **Transport** - 送受信抽象化 🔌
|
||||
```rust
|
||||
pub trait Transport: Send + Sync {
|
||||
fn node_id(&self) -> &str;
|
||||
fn send(&self, to: &str, intent: IntentBox, opts: SendOpts) -> Result<(), SendError>;
|
||||
fn on_receive(&mut self, callback: Box<dyn Fn(IntentEnvelope) + Send + Sync>);
|
||||
}
|
||||
|
||||
// 3種類の実装
|
||||
pub struct InProcessTransport { ... } // 同プロセス内
|
||||
pub struct WebSocketTransport { ... } // WebSocket通信
|
||||
pub struct WebRTCTransport { ... } // WebRTC P2P
|
||||
```
|
||||
|
||||
### 4. **P2PBox** - 統合ユーザーAPI 🎉
|
||||
```rust
|
||||
pub struct P2PBoxData {
|
||||
node_id: String,
|
||||
transport: Arc<dyn Transport>,
|
||||
bus: MessageBus, // 全P2PBoxで共有
|
||||
}
|
||||
pub type P2PBox = Arc<Mutex<P2PBoxData>>;
|
||||
|
||||
impl P2PBoxData {
|
||||
pub fn new(node_id: String, kind: TransportKind) -> P2PBox
|
||||
pub fn on(&self, intent_name: &str, handler: IntentHandler) -> Result<(), P2PError>
|
||||
pub fn send(&self, to: &str, intent: IntentBox) -> Result<(), SendError>
|
||||
}
|
||||
```
|
||||
|
||||
## 🚀 実用的使用例
|
||||
|
||||
### Level 1: 基本的なP2P通信
|
||||
```nyash
|
||||
// 2つのノード作成
|
||||
node_a = new P2PBox("alice", transport: "inprocess")
|
||||
node_b = new P2PBox("bob", transport: "inprocess")
|
||||
|
||||
// 受信ハンドラ設定
|
||||
node_b.on("chat.message", function(intent, from) {
|
||||
console = new ConsoleBox()
|
||||
console.log("From " + from + ": " + intent.payload.text)
|
||||
})
|
||||
|
||||
// メッセージ送信
|
||||
msg = new IntentBox("chat.message", { text: "Hello P2P!" })
|
||||
node_a.send("bob", msg) // → "From alice: Hello P2P!"
|
||||
```
|
||||
|
||||
### Level 2: 糖衣構文(将来実装)
|
||||
```nyash
|
||||
// 文字列直送(内部でIntentBox化) - 個別送信のみ
|
||||
node_a.send("bob", "hello") // → IntentBox("message", "hello")
|
||||
node_a.send("bob", "chat:hello") // → IntentBox("chat", "hello")
|
||||
// 注意: ブロードキャスト機能は安全性のため除外(無限ループリスク回避)
|
||||
```
|
||||
|
||||
### Level 3: 異なるTransport
|
||||
```nyash
|
||||
// 将来:異なるTransportでも同じAPI
|
||||
local_node = new P2PBox("local", transport: "inprocess")
|
||||
web_node = new P2PBox("web", transport: "websocket", { url: "ws://localhost:8080" })
|
||||
p2p_node = new P2PBox("p2p", transport: "webrtc", { ice_servers: [...] })
|
||||
|
||||
// Transportに関係なく同じsend/onメソッド
|
||||
msg = new IntentBox("file.share", { filename: "data.json" })
|
||||
local_node.send("web", msg) // WebSocket経由
|
||||
web_node.send("p2p", msg) // WebRTC経由
|
||||
```
|
||||
|
||||
## 🔄 送受信フロー詳細
|
||||
|
||||
### 📤 送信フロー(node_a.send("node_b", intent))
|
||||
```
|
||||
1. bus.has_node("node_b") == true?
|
||||
YES → bus.route("node_b", intent) ← 同プロセス内の最速配送
|
||||
NO → transport.send("node_b", intent, opts) ← WebSocket/WebRTC経由
|
||||
```
|
||||
|
||||
### 📥 受信フロー(ネットワークからの到着)
|
||||
```
|
||||
transport.on_receive コールバックで受信
|
||||
↓
|
||||
1. envelope.to == self.node_id?
|
||||
YES → bus.dispatch_to_local(self.node_id, intent) ← 自分宛
|
||||
NO → 2へ
|
||||
↓
|
||||
2. bus.has_node(envelope.to)?
|
||||
YES → bus.route(envelope.to, intent) ← 同プロセス内転送
|
||||
NO → bus.trace_drop(envelope) ← ルート不明
|
||||
```
|
||||
|
||||
## 📋 段階的実装計画
|
||||
|
||||
### **Phase 1: 基盤実装** (最優先)
|
||||
1. **IntentBox** - メッセージBox(`src/boxes/intent_box.rs`)
|
||||
2. **MessageBus** - プロセス内シングルトン(`src/messaging/message_bus.rs`)
|
||||
3. **Transport trait** - 送受信抽象化(`src/transport/mod.rs`)
|
||||
|
||||
### **Phase 2: InProcess実装**
|
||||
4. **InProcessTransport** - Bus経由の同プロセス通信(`src/transport/inprocess.rs`)
|
||||
5. **P2PBox基本実装** - new, on, send メソッド(`src/boxes/p2p_box.rs`)
|
||||
6. **インタープリター統合** - Nyash言語でのnew構文対応
|
||||
|
||||
### **Phase 3: ネットワーク拡張** (将来)
|
||||
7. **WebSocketTransport** - WebSocket経由通信
|
||||
8. **WebRTCTransport** - 直接P2P通信
|
||||
9. **高度機能** - timeout, ACK, reconnect等
|
||||
|
||||
## 🧪 テスト戦略
|
||||
|
||||
### **基本動作確認テスト**
|
||||
```nyash
|
||||
// tests/phase2/p2p_basic_test.nyash
|
||||
node_a = new P2PBox("alice", transport: "inprocess")
|
||||
node_b = new P2PBox("bob", transport: "inprocess")
|
||||
|
||||
node_b.on("test.ping", function(intent, from) {
|
||||
console = new ConsoleBox()
|
||||
console.log("PING from " + from)
|
||||
})
|
||||
|
||||
msg = new IntentBox("test.ping", { timestamp: 12345 })
|
||||
result = node_a.send("bob", msg)
|
||||
|
||||
// 期待出力: "PING from alice"
|
||||
```
|
||||
|
||||
## 🎯 重要な設計原則
|
||||
|
||||
### **なぜ「非InProcessでもBusを持つ」のか?**
|
||||
1. **ローカル最速配送**: Busが知ってればゼロコピー級の高速配送
|
||||
2. **統一API**: ローカルもネットも外側APIは同じsend/onメソッド
|
||||
3. **集約ログ**: 全P2P通信の統一ログ・メトリクス・デバッグ
|
||||
4. **ハンドラ集約**: on()/subscribe登録・解除・トレースが一箇所
|
||||
|
||||
### **同期→非同期の段階的対応**
|
||||
- **Phase 1**: `send()` は同期版 `fn` で実装開始
|
||||
- **Phase 2**: 基本機能確立後に `async fn` 化
|
||||
- **Phase 3**: Nyashインタープリターでのasync/await対応
|
||||
|
||||
### **Arc<Mutex>統一アーキテクチャ準拠**
|
||||
- すべてのBoxは既存の `Arc<Mutex<_>>` パターンに準拠
|
||||
- `MessageBus` も `Arc<Mutex<MessageBusData>>`
|
||||
- `IntentBox` も `Arc<Mutex<IntentBoxData>>`
|
||||
|
||||
## 🚨 エラーハンドリング
|
||||
|
||||
```rust
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum SendError {
|
||||
NodeNotFound(String), // 宛先ノードが見つからない
|
||||
NetworkError(String), // ネットワークエラー
|
||||
Timeout, // 送信タイムアウト
|
||||
SerializationError(String), // JSON変換エラー
|
||||
BusError(String), // MessageBusエラー
|
||||
}
|
||||
```
|
||||
|
||||
## 🌟 最終目標
|
||||
|
||||
```nyash
|
||||
// NyaMeshP2Pライブラリの実現
|
||||
mesh = new NyaMesh("my_node")
|
||||
mesh.join("chat_room")
|
||||
mesh.send("Hello everyone!")
|
||||
mesh.on("message", function(msg, from) {
|
||||
print(from + ": " + msg)
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**📚 関連ドキュメント**
|
||||
- **[DetailedP2PBoxSpec.md](DetailedP2PBoxSpec.md)** - ChatGPT大会議完全仕様(詳細版)
|
||||
- **[MessageBusDesign.md](MessageBusDesign.md)** - MessageBus詳細設計
|
||||
- **[CURRENT_TASK.md](../CURRENT_TASK.md)** - 現在の実装状況・優先順位
|
||||
|
||||
📝 最終更新: 2025-08-12 | 🎓 設計協力: Gemini先生・ChatGPT先生 | 🎯 目標: **Everything is Box**哲学によるP2P通信革命
|
||||
547
docs/guides/tutorials/1_getting_started.md
Normal file
547
docs/guides/tutorials/1_getting_started.md
Normal file
@ -0,0 +1,547 @@
|
||||
# 🚀 Getting Started with Nyash - Practical Guide
|
||||
|
||||
**最終更新: 2025年8月8日**
|
||||
|
||||
## 🎯 5分でNyashを理解する
|
||||
|
||||
Nyashは「Everything is Box」哲学に基づく、シンプルで強力なプログラミング言語です。
|
||||
このガイドでは、実際にコードを書きながらNyashの機能を学んでいきます。
|
||||
|
||||
## ⚡ クイックスタート
|
||||
|
||||
### **1. 環境構築**
|
||||
```bash
|
||||
# リポジトリのクローン
|
||||
git clone [repository-url]
|
||||
cd nyash/nyash-rust
|
||||
|
||||
# ビルド
|
||||
cargo build
|
||||
|
||||
# 実行
|
||||
./target/debug/nyash your_program.nyash
|
||||
```
|
||||
|
||||
### **2. はじめてのNyashプログラム**
|
||||
`hello.nyash`を作成:
|
||||
```nyash
|
||||
print("Hello, Nyash World!")
|
||||
print("Everything is Box! 🎉")
|
||||
```
|
||||
|
||||
実行:
|
||||
```bash
|
||||
./target/debug/nyash hello.nyash
|
||||
```
|
||||
|
||||
出力:
|
||||
```
|
||||
Hello, Nyash World!
|
||||
Everything is Box! 🎉
|
||||
```
|
||||
|
||||
## 📚 基本構文チュートリアル
|
||||
|
||||
### **Step 1: 変数と初期化**
|
||||
```nyash
|
||||
# 🎯 新機能:初期化付き変数宣言
|
||||
local name = "Alice"
|
||||
local age = 25
|
||||
local height = 165.5
|
||||
local isStudent = true
|
||||
|
||||
print("Name: " + name)
|
||||
print("Age: " + age)
|
||||
print("Height: " + height)
|
||||
print("Student: " + isStudent)
|
||||
|
||||
# 複数変数の同時宣言・初期化
|
||||
local x = 10, y = 20, z = 30
|
||||
print("Sum: " + (x + y + z)) # 60
|
||||
|
||||
# 混合宣言(初期化あり・なし)
|
||||
local initialized = 42, uninitialized, another = "test"
|
||||
uninitialized = "assigned later"
|
||||
print("Values: " + initialized + ", " + uninitialized + ", " + another)
|
||||
```
|
||||
|
||||
### **Step 2: 演算子の使用**
|
||||
```nyash
|
||||
local a = 10
|
||||
local b = 3
|
||||
|
||||
# 算術演算子
|
||||
print("Addition: " + (a + b)) # 13
|
||||
print("Subtraction: " + (a - b)) # 7
|
||||
print("Multiplication: " + (a * b)) # 30
|
||||
print("Division: " + (a / b)) # 3.3333333333333335
|
||||
|
||||
# 論理演算子(自然言語ライク)
|
||||
local hasPermission = true
|
||||
local isLoggedIn = true
|
||||
local canAccess = hasPermission and isLoggedIn
|
||||
print("Can access: " + canAccess) # true
|
||||
|
||||
local isDenied = not canAccess
|
||||
print("Is denied: " + isDenied) # false
|
||||
|
||||
# 比較演算子
|
||||
print("a > b: " + (a > b)) # true
|
||||
print("a == b: " + (a == b)) # false
|
||||
```
|
||||
|
||||
### **Step 3: 制御構造**
|
||||
```nyash
|
||||
function testControlFlow() {
|
||||
local score = 85
|
||||
|
||||
# if文
|
||||
if score >= 90 {
|
||||
print("Grade: A")
|
||||
} else if score >= 80 {
|
||||
print("Grade: B") # これが実行される
|
||||
} else {
|
||||
print("Grade: C or below")
|
||||
}
|
||||
|
||||
# ループ(統一構文)
|
||||
local count = 0
|
||||
loop(count < 3) {
|
||||
print("Count: " + count)
|
||||
count = count + 1
|
||||
if count == 2 {
|
||||
print("Breaking at 2")
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
testControlFlow()
|
||||
```
|
||||
|
||||
### **Step 4: Box(クラス)の定義**
|
||||
```nyash
|
||||
box Person {
|
||||
init { name, age, email } # フィールド定義(カンマ必須!)
|
||||
|
||||
# コンストラクタ(引数サポート)
|
||||
Person(n, a, e) {
|
||||
me.name = n
|
||||
me.age = a
|
||||
me.email = e
|
||||
print("Person created: " + me.name)
|
||||
}
|
||||
|
||||
# メソッド
|
||||
introduce() {
|
||||
print("Hi, I'm " + me.name + ", age " + me.age)
|
||||
}
|
||||
|
||||
getInfo() {
|
||||
return me.name + " (" + me.age + ") - " + me.email
|
||||
}
|
||||
|
||||
# デストラクタ
|
||||
fini() {
|
||||
print("Person destroyed: " + me.name)
|
||||
}
|
||||
}
|
||||
|
||||
# 使用例
|
||||
person = new Person("Bob", 30, "bob@example.com")
|
||||
person.introduce()
|
||||
print("Info: " + person.getInfo())
|
||||
```
|
||||
|
||||
## 🏭 実践例:Calculator アプリ
|
||||
|
||||
完全なCalculatorアプリを実装:
|
||||
|
||||
```nyash
|
||||
# 📱 Calculator App - Nyash版
|
||||
|
||||
box Calculator {
|
||||
init { history }
|
||||
|
||||
Calculator() {
|
||||
me.history = new ArrayBox()
|
||||
print("🧮 Calculator initialized!")
|
||||
}
|
||||
|
||||
add(a, b) {
|
||||
local result = a + b
|
||||
me.addToHistory("ADD", a, b, result)
|
||||
return result
|
||||
}
|
||||
|
||||
subtract(a, b) {
|
||||
local result = a - b
|
||||
me.addToHistory("SUB", a, b, result)
|
||||
return result
|
||||
}
|
||||
|
||||
multiply(a, b) {
|
||||
local result = a * b
|
||||
me.addToHistory("MUL", a, b, result)
|
||||
return result
|
||||
}
|
||||
|
||||
divide(a, b) {
|
||||
if b == 0 {
|
||||
print("❌ Error: Division by zero!")
|
||||
return 0
|
||||
}
|
||||
local result = a / b
|
||||
me.addToHistory("DIV", a, b, result)
|
||||
return result
|
||||
}
|
||||
|
||||
addToHistory(op, a, b, result) {
|
||||
local record = op + ": " + a + " " + op + " " + b + " = " + result
|
||||
me.history.push(record)
|
||||
}
|
||||
|
||||
showHistory() {
|
||||
print("📊 Calculation History:")
|
||||
local size = me.history.size()
|
||||
local i = 0
|
||||
loop(i < size) {
|
||||
print(" " + (i + 1) + ". " + me.history.get(i))
|
||||
i = i + 1
|
||||
}
|
||||
}
|
||||
|
||||
clear() {
|
||||
me.history = new ArrayBox()
|
||||
print("🧹 History cleared!")
|
||||
}
|
||||
}
|
||||
|
||||
# ✨ Calculator使用例
|
||||
calc = new Calculator()
|
||||
|
||||
print("=== Basic Operations ===")
|
||||
print("10 + 5 = " + calc.add(10, 5))
|
||||
print("10 - 3 = " + calc.subtract(10, 3))
|
||||
print("4 * 7 = " + calc.multiply(4, 7))
|
||||
print("15 / 3 = " + calc.divide(15, 3))
|
||||
print("10 / 0 = " + calc.divide(10, 0)) # ゼロ除算エラーテスト
|
||||
|
||||
print("")
|
||||
calc.showHistory()
|
||||
|
||||
print("")
|
||||
print("=== Complex Calculations ===")
|
||||
local complex1 = calc.add(calc.multiply(3, 4), calc.divide(20, 4))
|
||||
print("(3 * 4) + (20 / 4) = " + complex1)
|
||||
|
||||
calc.showHistory()
|
||||
```
|
||||
|
||||
## ⚡ 並行処理の実践
|
||||
|
||||
```nyash
|
||||
# 🚀 Parallel Processing Example
|
||||
|
||||
function heavyComputation(iterations) {
|
||||
print("⚙️ Starting computation with " + iterations + " iterations...")
|
||||
|
||||
local sum = 0
|
||||
local i = 0
|
||||
loop(i < iterations) {
|
||||
sum = sum + (i * i)
|
||||
i = i + 1
|
||||
|
||||
# 進捗表示(1000回毎)
|
||||
if (i % 1000) == 0 {
|
||||
print(" Progress: " + i + "/" + iterations)
|
||||
}
|
||||
}
|
||||
|
||||
print("✅ Computation completed: " + sum)
|
||||
return sum
|
||||
}
|
||||
|
||||
function parallelDemo() {
|
||||
print("🚀 Starting parallel computations...")
|
||||
|
||||
# 3つのタスクを並行実行
|
||||
future1 = nowait heavyComputation(5000)
|
||||
future2 = nowait heavyComputation(3000)
|
||||
future3 = nowait heavyComputation(4000)
|
||||
|
||||
print("⏳ All tasks started. Waiting for results...")
|
||||
|
||||
# 結果を待機して取得
|
||||
result1 = await future1
|
||||
result2 = await future2
|
||||
result3 = await future3
|
||||
|
||||
local total = result1 + result2 + result3
|
||||
print("🎉 All tasks completed!")
|
||||
print("Total sum: " + total)
|
||||
|
||||
return total
|
||||
}
|
||||
|
||||
# 実行
|
||||
parallelDemo()
|
||||
```
|
||||
|
||||
## 🏗️ Static Box(名前空間)の活用
|
||||
|
||||
```nyash
|
||||
# 🏗️ Utility Classes with Static Boxes
|
||||
|
||||
static box MathUtils {
|
||||
init { PI, E }
|
||||
|
||||
static {
|
||||
me.PI = 3.14159265359
|
||||
me.E = 2.71828182846
|
||||
}
|
||||
|
||||
square(x) {
|
||||
return x * x
|
||||
}
|
||||
|
||||
circleArea(radius) {
|
||||
return me.PI * me.square(radius)
|
||||
}
|
||||
|
||||
power(base, exp) {
|
||||
local result = 1
|
||||
local i = 0
|
||||
loop(i < exp) {
|
||||
result = result * base
|
||||
i = i + 1
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
static box StringUtils {
|
||||
init { EMPTY }
|
||||
|
||||
static {
|
||||
me.EMPTY = ""
|
||||
}
|
||||
|
||||
reverse(str) {
|
||||
# 簡易的な実装例
|
||||
return "REVERSED:" + str
|
||||
}
|
||||
|
||||
isEmpty(str) {
|
||||
return str == me.EMPTY
|
||||
}
|
||||
}
|
||||
|
||||
# 使用例
|
||||
print("π = " + MathUtils.PI)
|
||||
print("Circle area (r=5): " + MathUtils.circleArea(5))
|
||||
print("2^8 = " + MathUtils.power(2, 8))
|
||||
|
||||
print("Empty check: " + StringUtils.isEmpty(""))
|
||||
print("Reverse: " + StringUtils.reverse("Hello"))
|
||||
```
|
||||
|
||||
## 🐛 デバッグ機能の活用
|
||||
|
||||
```nyash
|
||||
# 🐛 Debug Features Showcase
|
||||
|
||||
box DebugExample {
|
||||
init { data, counter }
|
||||
|
||||
DebugExample() {
|
||||
me.data = "example"
|
||||
me.counter = 0
|
||||
}
|
||||
|
||||
process() {
|
||||
me.counter = me.counter + 1
|
||||
return "Processed #" + me.counter
|
||||
}
|
||||
}
|
||||
|
||||
function debuggingDemo() {
|
||||
# DebugBoxでトラッキング開始
|
||||
DEBUG = new DebugBox()
|
||||
DEBUG.startTracking()
|
||||
|
||||
print("🔍 Creating objects for debugging...")
|
||||
|
||||
# オブジェクトを作成してトラッキング
|
||||
obj1 = new DebugExample()
|
||||
obj2 = new DebugExample()
|
||||
|
||||
DEBUG.trackBox(obj1, "Primary Object")
|
||||
DEBUG.trackBox(obj2, "Secondary Object")
|
||||
|
||||
# 処理実行
|
||||
result1 = obj1.process()
|
||||
result2 = obj2.process()
|
||||
result3 = obj1.process()
|
||||
|
||||
print("Results: " + result1 + ", " + result2 + ", " + result3)
|
||||
|
||||
# デバッグレポート表示
|
||||
print("")
|
||||
print("=== Memory Report ===")
|
||||
print(DEBUG.memoryReport())
|
||||
|
||||
print("")
|
||||
print("=== Full Debug Dump ===")
|
||||
print(DEBUG.dumpAll())
|
||||
|
||||
# デバッグ情報をファイルに保存
|
||||
DEBUG.saveToFile("debug_output.txt")
|
||||
print("🎉 Debug information saved to debug_output.txt")
|
||||
}
|
||||
|
||||
debuggingDemo()
|
||||
```
|
||||
|
||||
## 📦 ファイル組織とモジュール
|
||||
|
||||
### **プロジェクト構造**
|
||||
```
|
||||
my_nyash_project/
|
||||
├── main.nyash # メインプログラム
|
||||
├── utils/
|
||||
│ ├── math.nyash # 数学ユーティリティ
|
||||
│ ├── string.nyash # 文字列ユーティリティ
|
||||
│ └── debug.nyash # デバッグ関数
|
||||
└── models/
|
||||
├── person.nyash # Personクラス
|
||||
└── calculator.nyash # Calculatorクラス
|
||||
```
|
||||
|
||||
### **main.nyash**
|
||||
```nyash
|
||||
# 📦 Module System Example
|
||||
|
||||
include "utils/math.nyash"
|
||||
include "utils/string.nyash"
|
||||
include "models/person.nyash"
|
||||
include "models/calculator.nyash"
|
||||
|
||||
function main() {
|
||||
print("🚀 Multi-module Nyash Application")
|
||||
|
||||
# 各モジュールの機能を使用
|
||||
person = new Person("Alice", 25, "alice@example.com")
|
||||
person.introduce()
|
||||
|
||||
calc = new Calculator()
|
||||
result = calc.add(10, 20)
|
||||
print("Calculation result: " + result)
|
||||
}
|
||||
|
||||
main()
|
||||
```
|
||||
|
||||
## 🎯 ベストプラクティス
|
||||
|
||||
### **1. 変数命名**
|
||||
```nyash
|
||||
# ✅ Good
|
||||
local userName = "alice"
|
||||
local totalAmount = 1000
|
||||
local isComplete = true
|
||||
|
||||
# ❌ Avoid
|
||||
local x = "alice"
|
||||
local amt = 1000
|
||||
local flag = true
|
||||
```
|
||||
|
||||
### **2. Box設計**
|
||||
```nyash
|
||||
# ✅ Good: 明確な責任分離
|
||||
box UserAccount {
|
||||
init { username, email, balance }
|
||||
|
||||
UserAccount(u, e) {
|
||||
me.username = u
|
||||
me.email = e
|
||||
me.balance = 0
|
||||
}
|
||||
|
||||
deposit(amount) {
|
||||
me.balance = me.balance + amount
|
||||
}
|
||||
}
|
||||
|
||||
# ❌ Avoid: 責任の混在
|
||||
box EverythingBox {
|
||||
# 多すぎる責任を持たせない
|
||||
}
|
||||
```
|
||||
|
||||
### **3. エラーハンドリング**
|
||||
```nyash
|
||||
function safeOperation(a, b) {
|
||||
if b == 0 {
|
||||
print("❌ Error: Division by zero")
|
||||
return 0
|
||||
}
|
||||
return a / b
|
||||
}
|
||||
```
|
||||
|
||||
### **4. パフォーマンス考慮**
|
||||
```nyash
|
||||
# ✅ 効率的:static box使用
|
||||
result = MathUtils.calculate(data)
|
||||
|
||||
# ✅ 効率的:初期化付き宣言
|
||||
local result = heavyCalculation(), cache = new MapBox()
|
||||
|
||||
# ⚠️ 注意:不要なオブジェクト生成を避ける
|
||||
loop(i < 1000) {
|
||||
# 毎回new しない設計を心がける
|
||||
}
|
||||
```
|
||||
|
||||
## 🚀 次のステップ
|
||||
|
||||
### **学習順序**
|
||||
1. ✅ **基本構文** - このガイドで完了
|
||||
2. **並行処理** - `test_async_*.nyash`を参考に
|
||||
3. **Static Box応用** - ユーティリティクラス作成
|
||||
4. **デバッグ技法** - DebugBox完全活用
|
||||
5. **アプリケーション開発** - 実践的なプロジェクト
|
||||
|
||||
### **サンプルプログラム**
|
||||
```bash
|
||||
# 実装済みサンプル
|
||||
./target/debug/nyash test_local_init.nyash # 初期化付き変数
|
||||
./target/debug/nyash app_dice_rpg.nyash # RPGバトルゲーム
|
||||
./target/debug/nyash app_statistics.nyash # 統計計算
|
||||
./target/debug/nyash test_async_parallel.nyash # 並行処理
|
||||
```
|
||||
|
||||
### **リファレンス**
|
||||
- `docs/LANGUAGE_OVERVIEW_2025.md` - 言語全体概要
|
||||
- `docs/TECHNICAL_ARCHITECTURE_2025.md` - 技術仕様
|
||||
- `CLAUDE.md` - 開発者向け詳細情報
|
||||
|
||||
## 🎉 おめでとうございます!
|
||||
|
||||
このガイドでNyashの主要機能を学習しました!
|
||||
|
||||
**習得内容:**
|
||||
- ✅ 基本構文(変数・演算子・制御構造)
|
||||
- ✅ Box(クラス)定義とオブジェクト指向
|
||||
- ✅ 並行処理・非同期プログラミング
|
||||
- ✅ Static Box・名前空間システム
|
||||
- ✅ デバッグ機能・開発支援ツール
|
||||
- ✅ 実践的なアプリケーション開発
|
||||
|
||||
**Nyashでプログラミングの新しい可能性を探究してください!** 🚀
|
||||
|
||||
---
|
||||
*Getting Started Guide v1.0*
|
||||
*Everything is Box - Start Simple, Think Big*
|
||||
254
docs/guides/tutorials/2_language_guide.md
Normal file
254
docs/guides/tutorials/2_language_guide.md
Normal file
@ -0,0 +1,254 @@
|
||||
# 📚 Nyash Programming Language - 完全ガイド
|
||||
|
||||
**最終更新: 2025年8月12日 - Phase 1完了, P2P実装準備完了**
|
||||
|
||||
## 📖 概要
|
||||
|
||||
Nyashは「Everything is Box」哲学に基づく革新的なプログラミング言語です。
|
||||
Rust製インタープリターによる高性能実行と、直感的な構文により、学習しやすく実用的な言語として完成しました。
|
||||
|
||||
## 🎯 核心哲学: "Everything is Box"
|
||||
|
||||
```nyash
|
||||
# すべてのデータがBoxとして統一的に表現される
|
||||
number = 42 # IntegerBox
|
||||
text = "hello" # StringBox
|
||||
flag = true # BoolBox
|
||||
array = new ArrayBox() # ArrayBox
|
||||
debug = new DebugBox() # DebugBox
|
||||
```
|
||||
|
||||
**重要な利点:**
|
||||
- **統一性**: すべてのデータが共通インターフェース
|
||||
- **メモリ安全性**: Arc<Mutex>パターンで完全スレッドセーフ
|
||||
- **拡張性**: 新しいBox型を容易に追加可能
|
||||
|
||||
---
|
||||
|
||||
## 🔤 言語構文リファレンス
|
||||
|
||||
### 🏷️ **変数宣言・スコープ**
|
||||
|
||||
```nyash
|
||||
// ローカル変数宣言
|
||||
local x, y
|
||||
local name = "Alice"
|
||||
|
||||
// 所有権移転変数(関数戻り値用)
|
||||
outbox result = compute()
|
||||
|
||||
// グローバル変数
|
||||
global CONFIG = "dev"
|
||||
```
|
||||
|
||||
### 🧮 **演算子**
|
||||
|
||||
```nyash
|
||||
// 算術演算子
|
||||
a + b, a - b, a * b, a / b
|
||||
|
||||
// 比較演算子
|
||||
a == b, a != b, a < b, a > b, a <= b, a >= b
|
||||
|
||||
// 論理演算子
|
||||
not condition, a and b, a or b
|
||||
|
||||
// Cross-type演算 (Phase 1で完全実装)
|
||||
10 + 3.14 // → 13.14 (型変換)
|
||||
"Value: " + 42 // → "Value: 42" (文字列連結)
|
||||
```
|
||||
|
||||
### 🏗️ **Box定義・デリゲーション**
|
||||
|
||||
#### 基本Box定義
|
||||
```nyash
|
||||
box User {
|
||||
init { name, email } // フィールド宣言
|
||||
|
||||
pack(userName, userEmail) { // 🎁 Box哲学の具現化!
|
||||
me.name = userName
|
||||
me.email = userEmail
|
||||
}
|
||||
|
||||
greet() {
|
||||
print("Hello, " + me.name)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### デリゲーション (2025-08 革命)
|
||||
```nyash
|
||||
box AdminUser from User { // 🔥 from構文でデリゲーション
|
||||
init { permissions }
|
||||
|
||||
pack(adminName, adminEmail, perms) {
|
||||
from User.pack(adminName, adminEmail) // 親のpack呼び出し
|
||||
me.permissions = perms
|
||||
}
|
||||
|
||||
override greet() { // 明示的オーバーライド
|
||||
from User.greet() // 親メソッド呼び出し
|
||||
print("Admin privileges: " + me.permissions)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Static Box Main パターン
|
||||
```nyash
|
||||
static box Main {
|
||||
init { console, result }
|
||||
|
||||
main() {
|
||||
me.console = new ConsoleBox()
|
||||
me.console.log("🎉 Everything is Box!")
|
||||
return "Success!"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 🔄 **制御構造**
|
||||
|
||||
```nyash
|
||||
// 条件分岐
|
||||
if condition {
|
||||
// 処理
|
||||
} else {
|
||||
// 別処理
|
||||
}
|
||||
|
||||
// ループ(唯一の正しい形式)
|
||||
loop(condition) {
|
||||
// 処理
|
||||
if breakCondition {
|
||||
break
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📦 ビルトインBox型
|
||||
|
||||
### 基本型
|
||||
- **StringBox**: 文字列 (`"hello"`)
|
||||
- **IntegerBox**: 整数 (`42`)
|
||||
- **FloatBox**: 浮動小数点数 (`new FloatBox(3.14)`) ✅ Phase 1完了
|
||||
- **BoolBox**: 真偽値 (`true`, `false`)
|
||||
- **NullBox**: NULL値 (`null`)
|
||||
|
||||
### データ構造
|
||||
- **ArrayBox**: 配列 (`new ArrayBox()`) ✅ Phase 1で sort/reverse/indexOf/slice 実装
|
||||
- **MapBox**: 連想配列 (`new MapBox()`)
|
||||
|
||||
### ユーティリティ
|
||||
- **ConsoleBox**: コンソール出力 (`new ConsoleBox()`)
|
||||
- **DebugBox**: デバッグ機能 (`new DebugBox()`)
|
||||
- **MathBox**: 数学関数 (`new MathBox()`)
|
||||
- **TimeBox**: 時刻処理 (`new TimeBox()`)
|
||||
- **DateTimeBox**: 日時処理 (`new DateTimeBox()`) ✅ Phase 1で完全動作
|
||||
|
||||
### 高度機能
|
||||
- **RandomBox**: 乱数生成
|
||||
- **BufferBox**: バッファ操作
|
||||
- **RegexBox**: 正規表現
|
||||
- **JSONBox**: JSON処理
|
||||
- **StreamBox**: ストリーム処理
|
||||
|
||||
### P2P通信 (Phase 2実装中)
|
||||
- **IntentBox**: 構造化メッセージ (実装予定)
|
||||
- **P2PBox**: P2P通信ノード (実装予定)
|
||||
|
||||
---
|
||||
|
||||
## 🚀 実用例
|
||||
|
||||
### データ処理例
|
||||
```nyash
|
||||
// 配列操作
|
||||
local numbers = new ArrayBox()
|
||||
numbers.push(3)
|
||||
numbers.push(1)
|
||||
numbers.push(2)
|
||||
numbers.sort() // [1, 2, 3]
|
||||
|
||||
// 型変換・演算
|
||||
local result = 10 + new FloatBox(3.14) // 13.14
|
||||
print("Result: " + result.toString())
|
||||
```
|
||||
|
||||
### P2P通信例 (将来実装)
|
||||
```nyash
|
||||
// P2Pノード作成
|
||||
local node_a = new P2PBox("alice", transport: "inprocess")
|
||||
local node_b = new P2PBox("bob", transport: "inprocess")
|
||||
|
||||
// メッセージ受信ハンドラ
|
||||
node_b.on("chat.message", function(intent, from) {
|
||||
print("From " + from + ": " + intent.payload.text)
|
||||
})
|
||||
|
||||
// 構造化メッセージ送信
|
||||
local msg = new IntentBox("chat.message", { text: "Hello P2P!" })
|
||||
node_a.send("bob", msg) // → "From alice: Hello P2P!"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 重要な注意点
|
||||
|
||||
### 必須のコンマ
|
||||
```nyash
|
||||
// ✅ 正しい
|
||||
init { field1, field2 }
|
||||
|
||||
// ❌ 間違い(CPU暴走の原因)
|
||||
init { field1 field2 }
|
||||
```
|
||||
|
||||
### 変数宣言厳密化
|
||||
```nyash
|
||||
// ✅ 明示宣言必須
|
||||
local x
|
||||
x = 42
|
||||
|
||||
// ❌ 未宣言変数への代入はエラー
|
||||
y = 42 // Runtime Error + 修正提案
|
||||
```
|
||||
|
||||
### ループ構文統一
|
||||
```nyash
|
||||
// ✅ 唯一の正しい形式
|
||||
loop(condition) { }
|
||||
|
||||
// ❌ 削除済み構文
|
||||
while condition { } // 使用不可
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📈 実装状況 (2025-08-12)
|
||||
|
||||
### ✅ Phase 1完了
|
||||
- FloatBox toString() メソッド
|
||||
- ArrayBox 改良 (sort/reverse/indexOf/slice)
|
||||
- Cross-type演算子システム
|
||||
- 包括的テストスイート (188行)
|
||||
|
||||
### 🚧 Phase 2実装中
|
||||
- IntentBox (構造化メッセージ)
|
||||
- MessageBus (プロセス内シングルトン)
|
||||
- P2PBox (P2P通信ノード)
|
||||
|
||||
### 📋 将来予定
|
||||
- WebSocket/WebRTC通信
|
||||
- 非同期処理 (async/await)
|
||||
- 追加のBox型拡張
|
||||
|
||||
---
|
||||
|
||||
**🎉 Nyashで「Everything is Box」の世界を体験しよう!**
|
||||
|
||||
📚 **関連ドキュメント:**
|
||||
- [Getting Started](GETTING_STARTED.md) - 環境構築・最初の一歩
|
||||
- [P2P Guide](P2P_GUIDE.md) - P2P通信システム完全ガイド
|
||||
- [Built-in Boxes](reference/builtin-boxes.md) - ビルトインBox詳細リファレンス
|
||||
102
docs/guides/tutorials/playground_guide.md
Normal file
102
docs/guides/tutorials/playground_guide.md
Normal file
@ -0,0 +1,102 @@
|
||||
# Nyash Playground Guide(ブラウザデモ活用ガイド)
|
||||
|
||||
最終更新: 2025-08-13
|
||||
|
||||
## リンク
|
||||
- Playground: https://moe-charm.github.io/nyash/projects/nyash-wasm/nyash_playground.html
|
||||
|
||||
## ねらい
|
||||
- 言語の要点(init/fini/weak/スコープ解放)を“動く例”で体感
|
||||
- レビュワーやチームへの共有・再現を容易化(ゼロインストール)
|
||||
|
||||
## 使い方(最短)
|
||||
1) 上記リンクを開く
|
||||
2) 下のサンプルコードをコピー&ペースト
|
||||
3) Run/実行ボタンで結果確認(ログ・出力・エラー挙動)
|
||||
|
||||
---
|
||||
|
||||
## シナリオ1: 循環参照 vs weak(自動nil化)
|
||||
|
||||
```nyash
|
||||
# Parent↔Child の双方向参照。
|
||||
# 子→親は weak 参照にして、リークとダングリングを防ぐ。
|
||||
|
||||
box Parent {
|
||||
init { child }
|
||||
pack() {
|
||||
me.child = new Child()
|
||||
me.child.setParent(me)
|
||||
}
|
||||
getName() { return "P" }
|
||||
fini() { print("Parent.fini") }
|
||||
}
|
||||
|
||||
box Child {
|
||||
init { weak parent }
|
||||
setParent(p) { me.parent = p }
|
||||
show() {
|
||||
if (me.parent != null) { print("parent=" + me.parent.getName()) }
|
||||
else { print("parent is gone") }
|
||||
}
|
||||
fini() { print("Child.fini") }
|
||||
}
|
||||
|
||||
p = new Parent()
|
||||
p.child.show() # => parent=P
|
||||
|
||||
# 親を明示的に破棄(fini 呼出しが発火する環境であればここで解放)
|
||||
p.fini()
|
||||
|
||||
# 親が破棄済みなので、weak 参照は自動的に nil 化される
|
||||
p.child.show() # => parent is gone(想定)
|
||||
```
|
||||
|
||||
ポイント:
|
||||
- `init { weak parent }`で弱参照を宣言
|
||||
- 参照先が破棄されるとアクセス時に自動で`null`扱い
|
||||
|
||||
---
|
||||
|
||||
## シナリオ2: 再代入時の fini 発火(予備解放)
|
||||
|
||||
```nyash
|
||||
box Holder { init { obj } }
|
||||
box Thing { fini() { print("Thing.fini") } }
|
||||
|
||||
h = new Holder()
|
||||
h.obj = new Thing()
|
||||
h.obj = new Thing() # 旧 obj に対して fini() が呼ばれる(ログで確認)
|
||||
```
|
||||
|
||||
ポイント:
|
||||
- フィールド再代入の節目で `fini()` が自動呼出し
|
||||
- 二重解放は内部で抑止(安全側)
|
||||
|
||||
---
|
||||
|
||||
## シナリオ3: スコープ抜けでローカル解放
|
||||
|
||||
```nyash
|
||||
function make() {
|
||||
local t
|
||||
t = new Thing()
|
||||
# 関数を抜けるとスコープ追跡により t が解放される
|
||||
}
|
||||
|
||||
box Thing { fini() { print("Thing.fini (scope)") } }
|
||||
|
||||
make() # => Thing.fini (scope)
|
||||
```
|
||||
|
||||
ポイント:
|
||||
- `local`で宣言された変数はスコープ終了時に一括解放
|
||||
- 暗黙ではなく構文規約で明示(未宣言代入はエラー)
|
||||
|
||||
---
|
||||
|
||||
## Tips(レビュー/論文向け)
|
||||
- 論文やREADMEから本ガイドへリンクし、コピー&ペーストで再現
|
||||
- 期待ログ(例: `Thing.fini`)を明記して、挙動の確認を容易に
|
||||
- 比較のため「weakなし版」と「weakあり版」を並記
|
||||
|
||||
64
docs/guides/wasm-guide/README.md
Normal file
64
docs/guides/wasm-guide/README.md
Normal file
@ -0,0 +1,64 @@
|
||||
# 🌐 Nyash WASM ガイド
|
||||
|
||||
Nyash WebAssembly(WASM)実行に関する包括的ガイド
|
||||
|
||||
## 📖 ドキュメント一覧
|
||||
|
||||
### 基本ガイド
|
||||
- **[Rust依存性分析](rust-dependency-analysis.md)** - 実行時Rust依存性の詳細分析
|
||||
- **[Phase比較](phase-comparison.md)** - 9.77手動実装 vs 9.8+FFI基盤の比較
|
||||
- **[配布ガイド](deployment-guide.md)** - WASM配布・実行方法
|
||||
|
||||
### 技術仕様
|
||||
- **[FFI/BIDチュートリアル](ffi-bid-tutorial.md)** - 外部API統合方法
|
||||
- **[メモリ管理](memory-management.md)** - WASM メモリレイアウト・最適化
|
||||
|
||||
## 🚀 クイックスタート
|
||||
|
||||
### WASM コンパイル
|
||||
```bash
|
||||
# 基本コンパイル
|
||||
./target/release/nyash --compile-wasm program.nyash
|
||||
|
||||
# AOT コンパイル(配布用)
|
||||
./target/release/nyash --aot program.nyash
|
||||
```
|
||||
|
||||
### ブラウザー実行
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<script>
|
||||
WebAssembly.instantiateStreaming(fetch('program.wasm'), importObject)
|
||||
.then(instance => instance.exports.main());
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
## 🎯 実行方式選択
|
||||
|
||||
| 用途 | 方式 | コマンド |
|
||||
|------|------|----------|
|
||||
| **開発・テスト** | インタープリター | `nyash program.nyash` |
|
||||
| **高速実行** | VM | `nyash --backend vm program.nyash` |
|
||||
| **Web配布** | WASM | `nyash --compile-wasm program.nyash` |
|
||||
| **ネイティブ配布** | AOT | `nyash --aot program.nyash` |
|
||||
|
||||
## 📊 性能比較
|
||||
|
||||
| バックエンド | 実行速度 | 配布サイズ | 依存関係 |
|
||||
|-------------|----------|------------|----------|
|
||||
| インタープリター | 1x | - | Rust |
|
||||
| VM | 20.4x | - | Rust |
|
||||
| **WASM** | **13.5x** | **小** | **なし** |
|
||||
| AOT | 目標1000x+ | 小 | なし |
|
||||
|
||||
## 🔗 関連ドキュメント
|
||||
- [言語ガイド](../LANGUAGE_GUIDE.md)
|
||||
- [実行バックエンド](../execution-backends.md)
|
||||
- [ビルドガイド](../build/README.md)
|
||||
|
||||
---
|
||||
**最終更新**: 2025-08-15
|
||||
23
docs/guides/wasm-guide/planning/README.md
Normal file
23
docs/guides/wasm-guide/planning/README.md
Normal file
@ -0,0 +1,23 @@
|
||||
# 🌐 WASM/AOT WASM 問題・課題管理
|
||||
|
||||
## 📁 フォルダ概要
|
||||
NyashのWebAssembly(WASM)およびAOT WASM機能の問題点、制限事項、今後の改善計画を管理します。
|
||||
|
||||
## 📋 ドキュメント一覧
|
||||
|
||||
### 現在の問題・制限
|
||||
- **[current_issues.md](current_issues.md)**: 現在発生中の技術的問題
|
||||
- **[compatibility_matrix.md](compatibility_matrix.md)**: wasmtimeバージョン互換性マトリクス
|
||||
- **[unsupported_features.md](unsupported_features.md)**: 未実装MIR命令・機能一覧
|
||||
|
||||
### 改善計画
|
||||
- **[improvement_roadmap.md](improvement_roadmap.md)**: WASM/AOT機能改善計画
|
||||
- **[optimization_targets.md](optimization_targets.md)**: 性能最適化目標
|
||||
|
||||
### 技術仕様
|
||||
- **[wasm_backend_spec.md](wasm_backend_spec.md)**: WASM Backend詳細仕様
|
||||
- **[aot_pipeline_spec.md](aot_pipeline_spec.md)**: AOT変換パイプライン仕様
|
||||
|
||||
---
|
||||
|
||||
**目標**: NyashのWASM/AOT機能を Production Ready レベルまで向上させる
|
||||
185
docs/guides/wasm-guide/planning/compatibility_matrix.md
Normal file
185
docs/guides/wasm-guide/planning/compatibility_matrix.md
Normal file
@ -0,0 +1,185 @@
|
||||
# 🔄 wasmtime互換性マトリクス
|
||||
|
||||
## 📅 最終更新: 2025-08-15
|
||||
|
||||
## 🎯 **現在の状況**
|
||||
|
||||
### 開発環境
|
||||
```toml
|
||||
# Cargo.toml
|
||||
wasmtime = "18.0"
|
||||
wabt = "0.10"
|
||||
```
|
||||
|
||||
### 実行環境
|
||||
```bash
|
||||
# システムインストール
|
||||
wasmtime 35.0.0 (509af9e5f 2025-07-22)
|
||||
```
|
||||
|
||||
### 互換性状況
|
||||
❌ **非互換**: 18.0.4 vs 35.0.0 - 実行不可
|
||||
|
||||
---
|
||||
|
||||
## 📊 **バージョン互換性マトリクス**
|
||||
|
||||
| Nyash wasmtime | System wasmtime | 互換性 | 状況 | 対応 |
|
||||
|----------------|-----------------|--------|------|------|
|
||||
| **18.0.4** | **35.0.0** | ❌ | 現在 | 要修正 |
|
||||
| 35.0.x | 35.0.x | ✅ | 目標 | 推奨 |
|
||||
| 34.0.x | 35.0.x | ⚠️ | 検証必要 | テスト |
|
||||
| 33.0.x | 35.0.x | ❌ | 古すぎ | 非推奨 |
|
||||
|
||||
---
|
||||
|
||||
## 🔧 **修正オプション**
|
||||
|
||||
### Option A: Nyash側更新 (推奨)
|
||||
```toml
|
||||
# Cargo.toml - 更新案
|
||||
wasmtime = "35.0"
|
||||
wabt = "0.10" # 互換性確認必要
|
||||
```
|
||||
|
||||
**メリット**:
|
||||
- ✅ 最新機能・性能向上
|
||||
- ✅ セキュリティ修正取り込み
|
||||
- ✅ 将来性
|
||||
|
||||
**リスク**:
|
||||
- ⚠️ API変更による修正必要
|
||||
- ⚠️ 既存.cwasmファイル互換性喪失
|
||||
|
||||
### Option B: システム側ダウングレード
|
||||
```bash
|
||||
# wasmtime 18.0.4 をインストール
|
||||
curl -sSf https://wasmtime.dev/install.sh | bash -s -- --version 18.0.4
|
||||
```
|
||||
|
||||
**メリット**:
|
||||
- ✅ Nyashコード修正不要
|
||||
- ✅ 即座対応可能
|
||||
|
||||
**デメリット**:
|
||||
- ❌ 古いバージョン使用
|
||||
- ❌ セキュリティリスク
|
||||
- ❌ 他プロジェクトへの影響
|
||||
|
||||
---
|
||||
|
||||
## 🎯 **推奨対応手順**
|
||||
|
||||
### Step 1: 依存関係調査 (30分)
|
||||
```bash
|
||||
# 現在の依存関係確認
|
||||
cargo tree | grep wasmtime
|
||||
cargo tree | grep wabt
|
||||
|
||||
# API変更点調査
|
||||
# https://github.com/bytecodealliance/wasmtime/releases
|
||||
```
|
||||
|
||||
### Step 2: テスト環境構築 (30分)
|
||||
```bash
|
||||
# ブランチ作成
|
||||
git checkout -b feature/wasmtime-35-upgrade
|
||||
|
||||
# Cargo.toml更新
|
||||
# wasmtime = "35.0"
|
||||
|
||||
# 依存関係更新
|
||||
cargo update
|
||||
```
|
||||
|
||||
### Step 3: ビルド修正 (2-4時間)
|
||||
予想される修正箇所:
|
||||
- `src/backend/aot/compiler.rs`: Engine設定API
|
||||
- `src/backend/wasm/mod.rs`: Module生成API
|
||||
- `src/backend/aot/config.rs`: Config構造変更
|
||||
|
||||
### Step 4: 動作確認 (1時間)
|
||||
```bash
|
||||
# 基本コンパイル
|
||||
cargo build --release
|
||||
|
||||
# WASM/AOT テスト
|
||||
./target/release/nyash --aot test_simple.nyash
|
||||
wasmtime --allow-precompiled test_simple.cwasm
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📋 **wasmtime API変更予想箇所**
|
||||
|
||||
### 18.x → 35.x 主要変更点
|
||||
|
||||
#### Engine/Store API
|
||||
```rust
|
||||
// 18.x (予想)
|
||||
let engine = Engine::default();
|
||||
let store = Store::new(&engine, ());
|
||||
|
||||
// 35.x (要確認)
|
||||
let engine = Engine::new(&Config::default())?;
|
||||
let mut store = Store::new(&engine, ());
|
||||
```
|
||||
|
||||
#### Module serialize/deserialize
|
||||
```rust
|
||||
// 18.x
|
||||
module.serialize()?;
|
||||
Module::deserialize(&engine, bytes)?;
|
||||
|
||||
// 35.x (API変更可能性)
|
||||
module.serialize()?; // 戻り値型変更?
|
||||
unsafe { Module::deserialize(&engine, bytes)? } // unsafe要求?
|
||||
```
|
||||
|
||||
#### Config API
|
||||
```rust
|
||||
// 18.x
|
||||
let config = Config::new();
|
||||
|
||||
// 35.x
|
||||
let mut config = Config::new();
|
||||
config.cranelift_opt_level(OptLevel::Speed)?;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ **アクションアイテム**
|
||||
|
||||
### 緊急 (今日)
|
||||
- [ ] wasmtime 35.0 API ドキュメント確認
|
||||
- [ ] 修正工数見積もり (2-8時間予想)
|
||||
|
||||
### 短期 (今週)
|
||||
- [ ] **wasmtime 35.0 への更新実装**
|
||||
- [ ] 全WASM/AOT機能のテスト実行
|
||||
- [ ] 互換性問題解決
|
||||
|
||||
### 中期 (来週)
|
||||
- [ ] wasmtime自動バージョン検知機能
|
||||
- [ ] CI/CDでの互換性テスト自動化
|
||||
|
||||
---
|
||||
|
||||
## 🎯 **成功指標**
|
||||
|
||||
### 技術指標
|
||||
```bash
|
||||
# ✅ 成功条件
|
||||
./target/release/nyash --aot test.nyash # コンパイル成功
|
||||
wasmtime --allow-precompiled test.cwasm # 実行成功
|
||||
echo $? # 0 (正常終了)
|
||||
```
|
||||
|
||||
### 性能指標
|
||||
- コンパイル時間: 18.x と同等以上
|
||||
- 実行速度: 18.x と同等以上
|
||||
- メモリ使用量: 18.x と同等以下
|
||||
|
||||
---
|
||||
|
||||
**🚀 Next Action**: wasmtime 35.0 へのアップグレード実装を最優先で開始
|
||||
176
docs/guides/wasm-guide/planning/current_issues.md
Normal file
176
docs/guides/wasm-guide/planning/current_issues.md
Normal file
@ -0,0 +1,176 @@
|
||||
# 🚨 WASM/AOT WASM 現在の問題・制限事項
|
||||
|
||||
## 📅 最終更新: 2025-08-15
|
||||
|
||||
## 🔴 **緊急度: 高**
|
||||
|
||||
### 1. **BoxCall命令未実装**
|
||||
**問題**: `toString()`, `print()` 等のBox メソッド呼び出しがWASMで未対応
|
||||
|
||||
**エラー例**:
|
||||
```bash
|
||||
❌ WASM compilation error: Unsupported instruction: BoxCall {
|
||||
dst: Some(ValueId(6)),
|
||||
box_val: ValueId(4),
|
||||
method: "toString",
|
||||
args: [],
|
||||
effects: EffectMask(16)
|
||||
}
|
||||
```
|
||||
|
||||
**影響範囲**:
|
||||
- 基本的なBox操作(toString, print等)が全て使用不可
|
||||
- 実用的なNyashプログラムがWASMでコンパイル不可
|
||||
|
||||
**修正必要ファイル**:
|
||||
- `src/backend/wasm/codegen.rs`: BoxCall命令の実装
|
||||
|
||||
---
|
||||
|
||||
### 2. **wasmtimeバージョン互換性問題**
|
||||
**問題**: コンパイル時wasmtimeとシステムwasmtimeのバージョン不一致
|
||||
|
||||
**エラー例**:
|
||||
```bash
|
||||
Error: Module was compiled with incompatible Wasmtime version '18.0.4'
|
||||
System wasmtime: 35.0.0
|
||||
```
|
||||
|
||||
**原因**:
|
||||
```toml
|
||||
# Cargo.toml
|
||||
wasmtime = "18.0" # コンパイル時
|
||||
|
||||
# システム
|
||||
wasmtime 35.0.0 # 実行時
|
||||
```
|
||||
|
||||
**影響**:
|
||||
- AOT (.cwasm) ファイルが実行不可
|
||||
- 配布用実行ファイル生成失敗
|
||||
|
||||
**修正策**:
|
||||
1. **短期**: Cargo.tomlのwasmtimeバージョン更新
|
||||
2. **長期**: 互換性保証メカニズム実装
|
||||
|
||||
---
|
||||
|
||||
### 3. **WASM出力バイナリエラー**
|
||||
**問題**: WAT → WASM変換でUTF-8エラー発生
|
||||
|
||||
**エラー例**:
|
||||
```bash
|
||||
❌ Generated WASM is not valid UTF-8
|
||||
```
|
||||
|
||||
**推測原因**:
|
||||
- WAT形式の生成に問題
|
||||
- wabt crateとの連携ミス
|
||||
|
||||
**修正必要箇所**:
|
||||
- `src/backend/wasm/codegen.rs`: WAT生成ロジック
|
||||
- WASM バイナリ出力パイプライン
|
||||
|
||||
---
|
||||
|
||||
## 🟠 **緊急度: 中**
|
||||
|
||||
### 4. **RuntimeImports未実装機能**
|
||||
**問題**: WASMで必要なランタイム関数が部分実装
|
||||
|
||||
**未実装機能**:
|
||||
- Box メモリ管理 (malloc, free)
|
||||
- 型キャスト・変換
|
||||
- 配列・Map操作
|
||||
- 例外ハンドリング
|
||||
|
||||
**ファイル**: `src/backend/wasm/runtime.rs`
|
||||
|
||||
---
|
||||
|
||||
### 5. **メモリ管理最適化不足**
|
||||
**問題**: WASMメモリレイアウトが非効率
|
||||
|
||||
**課題**:
|
||||
- Box ヘッダーサイズ固定 (12 bytes)
|
||||
- ガベージコレクション未実装
|
||||
- メモリ断片化対策なし
|
||||
|
||||
**ファイル**: `src/backend/wasm/memory.rs`
|
||||
|
||||
---
|
||||
|
||||
## 🟡 **緊急度: 低**
|
||||
|
||||
### 6. **デバッグ情報不足**
|
||||
**問題**: WASM実行時のエラー情報が不十分
|
||||
|
||||
**改善点**:
|
||||
- ソースマップ生成
|
||||
- スタックトレース詳細化
|
||||
- ブレークポイント対応
|
||||
|
||||
---
|
||||
|
||||
### 7. **最適化機能未実装**
|
||||
**問題**: WASM出力が最適化されていない
|
||||
|
||||
**未実装最適化**:
|
||||
- デッドコード除去
|
||||
- インライン展開
|
||||
- 定数畳み込み
|
||||
|
||||
---
|
||||
|
||||
## 📊 **問題優先度マトリクス**
|
||||
|
||||
| 問題 | 緊急度 | 重要度 | 修正工数 | 優先順位 |
|
||||
|------|--------|--------|----------|----------|
|
||||
| BoxCall未実装 | 高 | 高 | 中 | **1** |
|
||||
| wasmtimeバージョン | 高 | 高 | 低 | **2** |
|
||||
| WASM出力エラー | 高 | 中 | 中 | **3** |
|
||||
| RuntimeImports | 中 | 高 | 高 | **4** |
|
||||
| メモリ管理 | 中 | 中 | 高 | **5** |
|
||||
| デバッグ情報 | 低 | 中 | 中 | **6** |
|
||||
| 最適化 | 低 | 低 | 高 | **7** |
|
||||
|
||||
## 🎯 **修正ロードマップ**
|
||||
|
||||
### Phase 1: 基本機能復旧 (1週間)
|
||||
1. **BoxCall命令実装**
|
||||
2. **wasmtimeバージョン統一**
|
||||
3. **WASM出力エラー修正**
|
||||
|
||||
### Phase 2: 機能拡充 (2週間)
|
||||
4. **RuntimeImports完全実装**
|
||||
5. **メモリ管理改善**
|
||||
|
||||
### Phase 3: 品質向上 (1週間)
|
||||
6. **デバッグ情報強化**
|
||||
7. **基本最適化実装**
|
||||
|
||||
## 📝 **テスト必要項目**
|
||||
|
||||
### 基本動作テスト
|
||||
```bash
|
||||
# BoxCall テスト
|
||||
./target/release/nyash --compile-wasm test_boxcall.nyash
|
||||
|
||||
# AOT テスト
|
||||
./target/release/nyash --aot test_simple.nyash
|
||||
wasmtime --allow-precompiled test_simple.cwasm
|
||||
```
|
||||
|
||||
### 互換性テスト
|
||||
```bash
|
||||
# バージョン確認
|
||||
cargo tree | grep wasmtime
|
||||
wasmtime --version
|
||||
|
||||
# 実行テスト
|
||||
wasmtime test_output.wasm
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**🎯 目標**: Phase 1完了でWASM基本機能復旧、Nyash WASMが実用レベルに到達
|
||||
228
docs/guides/wasm-guide/planning/unsupported_features.md
Normal file
228
docs/guides/wasm-guide/planning/unsupported_features.md
Normal file
@ -0,0 +1,228 @@
|
||||
# 🚫 WASM Backend 未実装機能一覧
|
||||
|
||||
## 📅 最終更新: 2025-08-15
|
||||
|
||||
## 🎯 **概要**
|
||||
NyashのWASM Backend で現在未実装のMIR命令・機能・Nyash言語機能を体系的にまとめました。
|
||||
|
||||
---
|
||||
|
||||
## 🔴 **緊急度: 高 - 基本機能**
|
||||
|
||||
### 1. **BoxCall命令**
|
||||
**MIR命令**: `BoxCall { dst, box_val, method, args, effects }`
|
||||
|
||||
**未実装メソッド**:
|
||||
```rust
|
||||
// 基本Box操作
|
||||
toString() // ❌ 文字列変換
|
||||
equals(other) // ❌ 等価比較
|
||||
clone() // ❌ オブジェクト複製
|
||||
|
||||
// StringBox
|
||||
length() // ❌ 文字列長
|
||||
substring(start, end) // ❌ 部分文字列
|
||||
indexOf(str) // ❌ 文字列検索
|
||||
|
||||
// IntegerBox/Math
|
||||
add(other) // ❌ 加算
|
||||
subtract(other) // ❌ 減算
|
||||
multiply(other) // ❌ 乗算
|
||||
divide(other) // ❌ 除算
|
||||
|
||||
// ArrayBox
|
||||
push(item) // ❌ 要素追加
|
||||
pop() // ❌ 要素削除
|
||||
get(index) // ❌ 要素取得
|
||||
length() // ❌ 配列長
|
||||
|
||||
// ConsoleBox
|
||||
log(message) // ❌ コンソール出力
|
||||
warn(message) // ❌ 警告出力
|
||||
error(message) // ❌ エラー出力
|
||||
```
|
||||
|
||||
**修正ファイル**: `src/backend/wasm/codegen.rs`
|
||||
|
||||
---
|
||||
|
||||
### 2. **ExternCall命令**
|
||||
**MIR命令**: `ExternCall { dst, extern_name, method, args, effects }`
|
||||
|
||||
**未実装機能**:
|
||||
```rust
|
||||
// ブラウザーAPI
|
||||
console_log(msg) // ❌ JavaScript console.log
|
||||
canvas_fillRect() // ❌ Canvas描画
|
||||
fetch(url) // ❌ HTTP通信
|
||||
|
||||
// システムAPI
|
||||
file_read(path) // ❌ ファイル読み取り
|
||||
file_write(path, data) // ❌ ファイル書き込み
|
||||
```
|
||||
|
||||
**修正ファイル**: `src/backend/wasm/runtime.rs`
|
||||
|
||||
---
|
||||
|
||||
## 🟠 **緊急度: 中 - 制御フロー**
|
||||
|
||||
### 3. **条件分岐最適化**
|
||||
**MIR命令**: `Branch`, `Jump`, `Compare`
|
||||
|
||||
**問題**:
|
||||
- ネストした条件分岐のブロック管理
|
||||
- Switch文相当の最適化
|
||||
- 短絡評価 (and, or) の効率化
|
||||
|
||||
### 4. **ループ最適化**
|
||||
**MIR命令**: `Loop`, `Phi`
|
||||
|
||||
**未実装**:
|
||||
- ループ内変数の最適化
|
||||
- 無限ループ検出・対策
|
||||
- ループアンローリング
|
||||
|
||||
---
|
||||
|
||||
## 🟡 **緊急度: 低 - 高級機能**
|
||||
|
||||
### 5. **メモリ管理高級機能**
|
||||
**未実装機能**:
|
||||
```rust
|
||||
// 弱参照
|
||||
WeakNew, WeakLoad, WeakCheck // ❌ 弱参照システム
|
||||
|
||||
// メモリ同期
|
||||
MemCopy, AtomicFence // ❌ メモリ操作・同期
|
||||
|
||||
// ガベージコレクション
|
||||
// 自動メモリ解放、循環参照検出
|
||||
```
|
||||
|
||||
### 6. **並行処理**
|
||||
**未実装機能**:
|
||||
```rust
|
||||
// 非同期・並行
|
||||
Send, Recv // ❌ メッセージパッシング
|
||||
Safepoint // ❌ GC安全点
|
||||
|
||||
// スレッド・タスク
|
||||
spawn_task() // ❌ タスク生成
|
||||
await_result() // ❌ 非同期待機
|
||||
```
|
||||
|
||||
### 7. **例外処理**
|
||||
**未実装機能**:
|
||||
```rust
|
||||
// 例外・エラーハンドリング
|
||||
try_catch() // ❌ 例外キャッチ
|
||||
throw_error() // ❌ 例外スロー
|
||||
finally_block() // ❌ finally実行
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 **実装優先度マトリクス**
|
||||
|
||||
| 機能カテゴリ | 緊急度 | 実装工数 | ユーザー影響 | 優先順位 |
|
||||
|--------------|--------|----------|--------------|----------|
|
||||
| **BoxCall基本** | 高 | 中 | 致命的 | **1** |
|
||||
| **ExternCall** | 高 | 高 | 高 | **2** |
|
||||
| **条件分岐** | 中 | 低 | 中 | **3** |
|
||||
| **ループ最適化** | 中 | 中 | 中 | **4** |
|
||||
| **メモリ管理** | 低 | 高 | 低 | **5** |
|
||||
| **並行処理** | 低 | 高 | 低 | **6** |
|
||||
| **例外処理** | 低 | 中 | 低 | **7** |
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ **実装戦略**
|
||||
|
||||
### Phase 1: BoxCall基本実装 (1週間)
|
||||
```rust
|
||||
// 目標: 基本的なNyashプログラムがWASMで動作
|
||||
impl WasmCodegen {
|
||||
fn generate_box_call(&mut self, dst: Option<ValueId>, box_val: ValueId,
|
||||
method: &str, args: Vec<ValueId>) -> Result<(), WasmError> {
|
||||
match method {
|
||||
"toString" => self.generate_to_string_call(dst, box_val),
|
||||
"equals" => self.generate_equals_call(dst, box_val, args),
|
||||
"length" => self.generate_length_call(dst, box_val),
|
||||
// ... 基本メソッド追加
|
||||
_ => Err(WasmError::UnsupportedInstruction(format!("Unknown method: {}", method)))
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Phase 2: ExternCall統合 (2週間)
|
||||
```rust
|
||||
// 目標: ブラウザーとの連携動作
|
||||
impl RuntimeImports {
|
||||
fn register_browser_apis(&mut self) {
|
||||
self.register("console_log", console_log_impl);
|
||||
self.register("canvas_fillRect", canvas_fill_rect_impl);
|
||||
// ... ブラウザーAPI追加
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Phase 3: 最適化・高級機能 (1ヶ月)
|
||||
- 制御フロー最適化
|
||||
- メモリ管理改善
|
||||
- パフォーマンス向上
|
||||
|
||||
---
|
||||
|
||||
## 📋 **テストケース**
|
||||
|
||||
### Level 1: 基本BoxCall
|
||||
```nyash
|
||||
# test_basic_boxcall.nyash
|
||||
local str = "Hello"
|
||||
local len = str.length() # BoxCall実装必要
|
||||
print("Length: " + len.toString()) # BoxCall + ExternCall
|
||||
```
|
||||
|
||||
### Level 2: Box操作
|
||||
```nyash
|
||||
# test_box_operations.nyash
|
||||
local arr = new ArrayBox()
|
||||
arr.push("item1") # BoxCall実装必要
|
||||
local item = arr.get(0) # BoxCall実装必要
|
||||
print(item.toString()) # BoxCall実装必要
|
||||
```
|
||||
|
||||
### Level 3: 外部連携
|
||||
```nyash
|
||||
# test_extern_integration.nyash
|
||||
local console = new ExternBox("console")
|
||||
console.call("log", "Hello Browser!") # ExternCall実装必要
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ **実装完了判定基準**
|
||||
|
||||
### 基本機能復旧
|
||||
```bash
|
||||
# 以下が全て成功すること
|
||||
./target/release/nyash --compile-wasm test_basic_boxcall.nyash
|
||||
./target/release/nyash --compile-wasm test_box_operations.nyash
|
||||
./target/release/nyash --compile-wasm test_extern_integration.nyash
|
||||
|
||||
# WASM実行成功
|
||||
wasmtime test_basic_boxcall.wasm
|
||||
wasmtime test_box_operations.wasm
|
||||
wasmtime test_extern_integration.wasm
|
||||
```
|
||||
|
||||
### パフォーマンス基準
|
||||
- コンパイル時間: インタープリター比 2倍以内
|
||||
- 実行速度: インタープリター比 5倍以上高速
|
||||
- メモリ使用量: 合理的範囲内
|
||||
|
||||
---
|
||||
|
||||
**🎯 目標**: Phase 1完了でNyash WASM基本機能が実用レベルに到達し、Phase 2でブラウザー連携が完全動作する状態を実現
|
||||
194
docs/guides/wasm-guide/rust-dependency-analysis.md
Normal file
194
docs/guides/wasm-guide/rust-dependency-analysis.md
Normal file
@ -0,0 +1,194 @@
|
||||
# 🔍 Nyash WASM実行におけるRust依存性分析
|
||||
|
||||
## 📅 最終更新: 2025-08-15
|
||||
|
||||
## 🎯 概要
|
||||
Nyash WASMの実行時Rust依存性について、Phase 9.77(手動実装)とPhase 9.8+(FFI基盤)を比較分析し、真のRust依存脱却の実現方法を解説。
|
||||
|
||||
## 🔍 重要な発見: 実行時Rust依存性は**ゼロ**
|
||||
|
||||
### **結論**
|
||||
**どちらの方式でも実行時Rust依存はなし!**
|
||||
|
||||
| 方式 | コンパイル時 | 実行時 | 配布ファイル |
|
||||
|------|-------------|--------|-------------|
|
||||
| **Phase 9.77 (手動)** | ❌ Rust必要 | ✅ **Rust不要** | .wasm + .js のみ |
|
||||
| **Phase 9.8+ (FFI)** | ❌ Rust必要 | ✅ **Rust不要** | .wasm + .js のみ |
|
||||
|
||||
## 🛠️ Phase 9.77: 手動実装アプローチ
|
||||
|
||||
### **特徴**
|
||||
- 基本的なCanvas/Console操作を手動でWASM import実装
|
||||
- 緊急復旧に最適(1-2週間で完了)
|
||||
- 実行時はWASM + JavaScriptのみ
|
||||
|
||||
### **実行時依存関係**
|
||||
```mermaid
|
||||
graph LR
|
||||
A[ブラウザー] --> B[app.wasm]
|
||||
A --> C[importObject.js]
|
||||
B --> C
|
||||
style A fill:#4ecdc4
|
||||
style B fill:#f9ca24
|
||||
style C fill:#f0932b
|
||||
```
|
||||
|
||||
### **生成例**
|
||||
```bash
|
||||
# コンパイル時 - Rust必要
|
||||
cargo build --target wasm32-unknown-unknown
|
||||
# → app.wasm 生成
|
||||
|
||||
# 実行時 - Rust完全不要!
|
||||
# ブラウザーでWASM + JavaScriptのみ
|
||||
```
|
||||
|
||||
## 🚀 Phase 9.8+: FFI基盤アプローチ
|
||||
|
||||
### **特徴**
|
||||
- BID(Box Interface Definition)からの自動生成
|
||||
- 新API追加が数分で完了
|
||||
- 長期開発効率の飛躍的向上
|
||||
|
||||
### **自動生成フロー**
|
||||
```mermaid
|
||||
graph TD
|
||||
A[BID YAML定義] --> B[nyash bid gen]
|
||||
B --> C[WASM import宣言]
|
||||
B --> D[JavaScript実装]
|
||||
B --> E[Rust生成コード]
|
||||
C --> F[配布: WASM + JS]
|
||||
D --> F
|
||||
style F fill:#2ed573
|
||||
```
|
||||
|
||||
### **生成コマンド**
|
||||
```bash
|
||||
# BID定義から自動生成
|
||||
nyash bid gen --target wasm bid/canvas.yaml
|
||||
|
||||
# コンパイル
|
||||
cargo build --target wasm32-unknown-unknown
|
||||
|
||||
# 実行時 - Rust完全不要!
|
||||
# 同じくWASM + JavaScriptのみ
|
||||
```
|
||||
|
||||
## 📦 配布ファイル構成(共通)
|
||||
|
||||
どちらの方式でも、配布時は以下のファイルのみ:
|
||||
|
||||
```
|
||||
my_nyash_app/
|
||||
├── app.wasm # コンパイル済みWASM(Rust不要)
|
||||
├── runtime.js # importObject実装(JavaScript)
|
||||
├── index.html # HTMLページ
|
||||
└── README.md # 使用説明
|
||||
```
|
||||
|
||||
## 🌐 実際の実行例
|
||||
|
||||
### **HTMLファイル**(Rust一切不要)
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head><title>Nyash App</title></head>
|
||||
<body>
|
||||
<canvas id="gameCanvas" width="400" height="300"></canvas>
|
||||
<script src="runtime.js"></script>
|
||||
<script>
|
||||
// WASMロード・実行(Rust依存なし)
|
||||
WebAssembly.instantiateStreaming(
|
||||
fetch('app.wasm'),
|
||||
importObject
|
||||
).then(instance => {
|
||||
instance.exports.main();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
### **実行環境要件**
|
||||
- ✅ モダンブラウザー(Chrome, Firefox, Safari, Edge)
|
||||
- ✅ WebAssembly対応
|
||||
- ❌ Rust不要
|
||||
- ❌ Node.js不要
|
||||
- ❌ 特別なランタイム不要
|
||||
|
||||
## 📊 方式比較詳細
|
||||
|
||||
| 評価軸 | Phase 9.77 手動 | Phase 9.8+ FFI |
|
||||
|--------|-----------------|----------------|
|
||||
| **実行時Rust依存** | ❌ なし | ❌ なし |
|
||||
| **配布ファイル** | WASM + JS | WASM + JS |
|
||||
| **開発時間** | 1-2週間 | 3-4週間 |
|
||||
| **API追加工数** | 数時間(手動) | 数分(自動) |
|
||||
| **保守性** | 低 | 高 |
|
||||
| **拡張性** | 限定的 | 無制限 |
|
||||
| **学習コスト** | 中 | 高 |
|
||||
|
||||
## 🎯 実用的選択指針
|
||||
|
||||
### **Phase 9.77を選ぶべき場合**
|
||||
- ✅ **即座にRust依存脱却したい**
|
||||
- ✅ **基本的なCanvas/Console操作で十分**
|
||||
- ✅ **短期プロジェクト**
|
||||
- ✅ **学習コスト最小化**
|
||||
|
||||
### **Phase 9.8+を選ぶべき場合**
|
||||
- ✅ **長期開発プロジェクト**
|
||||
- ✅ **多様な外部API統合が必要**
|
||||
- ✅ **チーム開発**
|
||||
- ✅ **API拡張の自動化が重要**
|
||||
|
||||
## 💡 戦略的アプローチ
|
||||
|
||||
### **段階的進化パス**
|
||||
```mermaid
|
||||
graph LR
|
||||
A[現在: Rust依存] --> B[Phase 9.77: 手動WASM]
|
||||
B --> C[Phase 9.8+: FFI基盤]
|
||||
C --> D[完全自動化]
|
||||
|
||||
style A fill:#ff6b6b
|
||||
style B fill:#f9ca24
|
||||
style C fill:#4ecdc4
|
||||
style D fill:#2ed573
|
||||
```
|
||||
|
||||
### **推奨戦略**
|
||||
1. **Phase 9.77**: 手動実装で即座にRust依存脱却
|
||||
2. **検証**: 実用性・性能確認
|
||||
3. **Phase 9.8+**: 必要に応じてFFI基盤へ移行
|
||||
|
||||
## 🎉 期待される効果
|
||||
|
||||
### **即時効果(Phase 9.77)**
|
||||
- **Rust依存完全排除**(実行時)
|
||||
- **配布の簡素化**
|
||||
- **ブラウザー単体実行**
|
||||
- **学習コスト削減**
|
||||
|
||||
### **長期効果(Phase 9.8+)**
|
||||
- **開発効率の飛躍的向上**
|
||||
- **API拡張の自動化**
|
||||
- **チーム開発の標準化**
|
||||
- **エコシステム拡充**
|
||||
|
||||
## 🔗 関連ドキュメント
|
||||
|
||||
### **技術仕様**
|
||||
- [FFI/ABI仕様](../reference/box-design/ffi-abi-specification.md)
|
||||
- [実行バックエンド](../execution-backends.md)
|
||||
|
||||
### **実装計画**
|
||||
- [Phase 9.77詳細](../../予定/native-plan/issues/phase_9_77_wasm_emergency.md)
|
||||
- [Copilot Issues](../../予定/native-plan/copilot_issues.txt)
|
||||
|
||||
### **問題分析**
|
||||
- [WASM現在の問題](../../予定/wasm/current_issues.md)
|
||||
|
||||
---
|
||||
|
||||
**この分析により、NyashはWASMを通じて真のRust依存脱却を実現し、ブラウザー環境での自由な実行が可能になります。** 🚀
|
||||
114
docs/guides/wasm-guide/wasm_browser_plan.md
Normal file
114
docs/guides/wasm-guide/wasm_browser_plan.md
Normal file
@ -0,0 +1,114 @@
|
||||
# 🌐 Nyash WebAssembly ブラウザデビュー計画
|
||||
|
||||
## 🎯 なぜこれが天才的か
|
||||
|
||||
1. **extern box不要** - Rust側でWASM対応Boxを実装すればOK
|
||||
2. **GUI即実現** - Canvas/DOM使って即座にビジュアルアプリ
|
||||
3. **配布超簡単** - URLアクセスだけで動く
|
||||
4. **既存資産活用** - 現在のNyashインタープリターをそのままWASM化
|
||||
|
||||
## 🏗️ アーキテクチャ
|
||||
|
||||
```
|
||||
ブラウザ
|
||||
↓
|
||||
Nyashコード(テキストエリア)
|
||||
↓
|
||||
NyashインタープリターWASM
|
||||
↓
|
||||
WasmBox / DOMBox / CanvasBox
|
||||
↓
|
||||
ブラウザAPI(DOM/Canvas/Event)
|
||||
```
|
||||
|
||||
## 📦 新しいBox実装案
|
||||
|
||||
### 1. WasmBox - WebAssembly制御
|
||||
```nyash
|
||||
wasm = new WasmBox()
|
||||
console = wasm.getConsole()
|
||||
console.log("Hello from Nyash in Browser!")
|
||||
```
|
||||
|
||||
### 2. DOMBox - DOM操作
|
||||
```nyash
|
||||
dom = new DOMBox()
|
||||
button = dom.createElement("button")
|
||||
button.setText("Click me!")
|
||||
button.onClick(new MethodBox(me, "handleClick"))
|
||||
dom.body.appendChild(button)
|
||||
```
|
||||
|
||||
### 3. CanvasBox - 描画
|
||||
```nyash
|
||||
canvas = new CanvasBox(800, 600)
|
||||
ctx = canvas.getContext2D()
|
||||
ctx.fillStyle = "red"
|
||||
ctx.fillRect(100, 100, 50, 50)
|
||||
```
|
||||
|
||||
### 4. EventBox - イベント処理
|
||||
```nyash
|
||||
events = new EventBox()
|
||||
events.onKeyDown(new MethodBox(me, "handleKey"))
|
||||
events.onMouseMove(new MethodBox(me, "handleMouse"))
|
||||
```
|
||||
|
||||
## 🚀 実装手順
|
||||
|
||||
### Phase 1: 基本WASM化
|
||||
1. Cargo.tomlにwasm-bindgen追加
|
||||
2. lib.rsでWASM用エクスポート作成
|
||||
3. 簡単なeval関数を公開
|
||||
4. HTMLページで動作確認
|
||||
|
||||
### Phase 2: ブラウザBox実装
|
||||
1. ConsoleBox - console.log対応
|
||||
2. DOMBox - 基本的なDOM操作
|
||||
3. AlertBox - alert/confirm/prompt
|
||||
|
||||
### Phase 3: ビジュアルアプリ
|
||||
1. CanvasBox実装
|
||||
2. Snakeゲーム移植
|
||||
3. お絵かきアプリ
|
||||
4. 簡単なIDE
|
||||
|
||||
## 💡 サンプルアプリ
|
||||
|
||||
### 1. インタラクティブREPL
|
||||
```nyash
|
||||
// ブラウザ上でNyashコード実行
|
||||
input = dom.getElementById("code-input")
|
||||
output = dom.getElementById("output")
|
||||
button = dom.getElementById("run-button")
|
||||
|
||||
button.onClick(new MethodBox(me, "runCode"))
|
||||
|
||||
runCode() {
|
||||
code = input.getValue()
|
||||
result = eval(code)
|
||||
output.setText(result.toString())
|
||||
}
|
||||
```
|
||||
|
||||
### 2. ビジュアルSnakeゲーム
|
||||
```nyash
|
||||
canvas = new CanvasBox(400, 400)
|
||||
game = new SnakeGame(canvas)
|
||||
game.start()
|
||||
```
|
||||
|
||||
### 3. Nyashプレイグラウンド
|
||||
- コードエディタ
|
||||
- 実行結果表示
|
||||
- サンプルコード集
|
||||
- 共有機能
|
||||
|
||||
## 🎉 メリット
|
||||
|
||||
1. **即座にデモ可能** - URL共有だけ
|
||||
2. **ビジュアルフィードバック** - GUIアプリが作れる
|
||||
3. **学習曲線なし** - ブラウザだけあればOK
|
||||
4. **実用アプリ** - 本格的なWebアプリも可能
|
||||
|
||||
これ、本当にすぐできるにゃ!
|
||||
141
docs/guides/wasm-guide/wasm_quick_start.md
Normal file
141
docs/guides/wasm-guide/wasm_quick_start.md
Normal file
@ -0,0 +1,141 @@
|
||||
# 🚀 Nyash WASM クイックスタート実装
|
||||
|
||||
## Step 1: Cargo.toml修正
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
wasm-bindgen = "0.2"
|
||||
web-sys = "0.3"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[dependencies.web-sys]
|
||||
version = "0.3"
|
||||
features = [
|
||||
"console",
|
||||
"Document",
|
||||
"Element",
|
||||
"HtmlElement",
|
||||
"HtmlCanvasElement",
|
||||
"CanvasRenderingContext2d",
|
||||
"Window",
|
||||
]
|
||||
```
|
||||
|
||||
## Step 2: lib.rsにWASMエクスポート追加
|
||||
|
||||
```rust
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct NyashWasm {
|
||||
interpreter: NyashInterpreter,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl NyashWasm {
|
||||
#[wasm_bindgen(constructor)]
|
||||
pub fn new() -> Self {
|
||||
// panicをconsole.errorに
|
||||
console_error_panic_hook::set_once();
|
||||
|
||||
let mut interpreter = NyashInterpreter::new();
|
||||
// WASMBox等を登録
|
||||
Self { interpreter }
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn eval(&mut self, code: &str) -> String {
|
||||
match self.interpreter.eval(code) {
|
||||
Ok(result) => format!("{:?}", result),
|
||||
Err(e) => format!("Error: {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Step 3: ConsoleBox実装
|
||||
|
||||
```rust
|
||||
// src/boxes/console_box.rs
|
||||
pub struct ConsoleBox;
|
||||
|
||||
impl NyashBox for ConsoleBox {
|
||||
fn box_type(&self) -> &'static str { "ConsoleBox" }
|
||||
|
||||
fn call_method(&self, name: &str, args: Vec<Arc<dyn NyashBox>>) -> Result<Arc<dyn NyashBox>, String> {
|
||||
match name {
|
||||
"log" => {
|
||||
let msg = args[0].to_string();
|
||||
web_sys::console::log_1(&msg.into());
|
||||
Ok(Arc::new(VoidBox))
|
||||
}
|
||||
_ => Err(format!("Unknown method: {}", name))
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Step 4: 簡単なHTML
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Nyash in Browser!</title>
|
||||
<style>
|
||||
#editor { width: 100%; height: 200px; }
|
||||
#output { border: 1px solid #ccc; padding: 10px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>🐱 Nyash Browser Playground</h1>
|
||||
<textarea id="editor">
|
||||
// Nyashコードをここに書くにゃ!
|
||||
console = new ConsoleBox()
|
||||
console.log("Hello from Nyash in Browser!")
|
||||
|
||||
x = 10
|
||||
y = 20
|
||||
console.log("x + y = " + (x + y))
|
||||
</textarea>
|
||||
<br>
|
||||
<button onclick="runNyash()">実行!</button>
|
||||
<div id="output"></div>
|
||||
|
||||
<script type="module">
|
||||
import init, { NyashWasm } from './nyash_wasm.js';
|
||||
|
||||
let nyash;
|
||||
|
||||
async function main() {
|
||||
await init();
|
||||
nyash = new NyashWasm();
|
||||
window.runNyash = () => {
|
||||
const code = document.getElementById('editor').value;
|
||||
const output = nyash.eval(code);
|
||||
document.getElementById('output').textContent = output;
|
||||
};
|
||||
}
|
||||
|
||||
main();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
## ビルドコマンド
|
||||
|
||||
```bash
|
||||
# wasm-packインストール
|
||||
cargo install wasm-pack
|
||||
|
||||
# ビルド
|
||||
wasm-pack build --target web --out-dir www
|
||||
|
||||
# ローカルサーバー起動
|
||||
cd www && python3 -m http.server 8000
|
||||
```
|
||||
|
||||
これで http://localhost:8000 でNyashがブラウザで動く!🎉
|
||||
Reference in New Issue
Block a user