2025-09-17 22:32:38 +09:00
|
|
|
|
================================================================================
|
|
|
|
|
|
Phase 12.7 文法改革 - 実装前最終チェックリスト
|
|
|
|
|
|
2025-09-03
|
|
|
|
|
|
================================================================================
|
|
|
|
|
|
|
|
|
|
|
|
【ChatGPT5さんからの重要指摘への対応】
|
|
|
|
|
|
|
|
|
|
|
|
================================================================================
|
|
|
|
|
|
1. トークナイザー実装の注意点
|
|
|
|
|
|
================================================================================
|
|
|
|
|
|
|
|
|
|
|
|
【既存の問題】
|
|
|
|
|
|
- 現在のARROWトークンが '>>' になっている → これを修正!
|
|
|
|
|
|
|
|
|
|
|
|
【対応】
|
|
|
|
|
|
```rust
|
|
|
|
|
|
// tokenizer.rs での修正
|
|
|
|
|
|
// 削除または未使用化
|
|
|
|
|
|
// ARROW => ">>" // これは間違い!
|
|
|
|
|
|
|
|
|
|
|
|
// 新規追加
|
|
|
|
|
|
FAT_ARROW => "=>" // peek構文用
|
|
|
|
|
|
DOUBLE_COLON => "::" // Parent::method用(P1だがトークンは今追加)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
【追加する予約語(P0)】
|
|
|
|
|
|
- peek
|
|
|
|
|
|
- continue
|
|
|
|
|
|
- birth
|
|
|
|
|
|
(publicは後述の特殊対応)
|
|
|
|
|
|
|
|
|
|
|
|
================================================================================
|
|
|
|
|
|
2. 値の扱いの明確化
|
|
|
|
|
|
================================================================================
|
|
|
|
|
|
|
|
|
|
|
|
【空ブロックの値】
|
|
|
|
|
|
- 空ブロック {} の値は **VoidBox** とする
|
|
|
|
|
|
- 最後の式がない場合もVoidBox
|
|
|
|
|
|
|
|
|
|
|
|
【peek式の値規約】
|
|
|
|
|
|
```nyash
|
|
|
|
|
|
// 単一式の値
|
|
|
|
|
|
peek x {
|
|
|
|
|
|
1 => "one" // StringBoxを返す
|
|
|
|
|
|
else => "other"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ブロックの値(最後の式)
|
|
|
|
|
|
peek x {
|
|
|
|
|
|
1 => {
|
|
|
|
|
|
print("got one")
|
|
|
|
|
|
"one" // これが値
|
|
|
|
|
|
}
|
|
|
|
|
|
else => {
|
|
|
|
|
|
// 空ブロックはVoidBox
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 関数Boxの値(P0では単純に関数オブジェクト)
|
|
|
|
|
|
peek op {
|
|
|
|
|
|
"add" => fn(a, b) { return a + b } // 関数Boxを返す
|
|
|
|
|
|
else => fn() { return 0 }
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
================================================================================
|
|
|
|
|
|
3. 等値比較の詳細規約
|
|
|
|
|
|
================================================================================
|
|
|
|
|
|
|
|
|
|
|
|
【peek内のパターンマッチング(P0)】
|
|
|
|
|
|
- StringBox: 完全一致、大文字小文字を区別
|
|
|
|
|
|
- IntegerBox: == による数値比較
|
|
|
|
|
|
- BoolBox: true/false の完全一致
|
|
|
|
|
|
- VoidBox/null: null との一致
|
|
|
|
|
|
|
|
|
|
|
|
【typeof との組み合わせ】
|
|
|
|
|
|
```nyash
|
|
|
|
|
|
peek typeof(value) {
|
|
|
|
|
|
"StringBox" => processString(value)
|
|
|
|
|
|
"IntegerBox" => processInt(value)
|
|
|
|
|
|
else => processOther(value)
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
※ typeof は既存実装の型名文字列をそのまま返す
|
|
|
|
|
|
|
|
|
|
|
|
================================================================================
|
|
|
|
|
|
4. publicキーワードの扱い
|
|
|
|
|
|
================================================================================
|
|
|
|
|
|
|
|
|
|
|
|
【現状との調整】
|
|
|
|
|
|
- 既存: public { field1, field2 } ブロック形式
|
|
|
|
|
|
- 新規: public field: Type 個別指定形式
|
|
|
|
|
|
|
|
|
|
|
|
【P0での対応】
|
|
|
|
|
|
```rust
|
|
|
|
|
|
// 両方をサポート(移行期間)
|
|
|
|
|
|
box Example {
|
|
|
|
|
|
// 新形式
|
|
|
|
|
|
public name: StringBox
|
|
|
|
|
|
count: IntegerBox
|
|
|
|
|
|
|
|
|
|
|
|
// 旧形式(レガシー、警告付きでサポート)
|
|
|
|
|
|
public { oldField1, oldField2 }
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
【実装方針】
|
|
|
|
|
|
- publicを「文脈依存キーワード」として扱う
|
|
|
|
|
|
- Box内でのみ特別な意味を持つ
|
|
|
|
|
|
- それ以外では識別子として使える(後方互換性)
|
|
|
|
|
|
|
|
|
|
|
|
================================================================================
|
|
|
|
|
|
5. フィールド宣言の段階実装
|
|
|
|
|
|
================================================================================
|
|
|
|
|
|
|
|
|
|
|
|
【P0(今回)】
|
|
|
|
|
|
- パースのみ: name: Type
|
|
|
|
|
|
- publicプレフィックス対応
|
|
|
|
|
|
- デフォルト値なし(= expr はP1へ)
|
|
|
|
|
|
|
|
|
|
|
|
【P1(次回)】
|
|
|
|
|
|
- デフォルト値: name: Type = expr
|
|
|
|
|
|
- birth内での自動初期化
|
|
|
|
|
|
|
|
|
|
|
|
【現在の回避策】
|
|
|
|
|
|
```nyash
|
|
|
|
|
|
box Counter {
|
|
|
|
|
|
count: IntegerBox
|
|
|
|
|
|
cache: MapBox // デフォルト値はP1まで待つ
|
|
|
|
|
|
|
|
|
|
|
|
birth() {
|
|
|
|
|
|
me.count = 0
|
|
|
|
|
|
me.cache = new MapBox() // birth内で明示的に初期化
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
================================================================================
|
|
|
|
|
|
6. デシュガー戦略(P0)
|
|
|
|
|
|
================================================================================
|
|
|
|
|
|
|
|
|
|
|
|
【peek → if-else連鎖】
|
|
|
|
|
|
```nyash
|
|
|
|
|
|
// Nyashコード
|
|
|
|
|
|
peek animal {
|
|
|
|
|
|
"dog" => bark()
|
|
|
|
|
|
"cat" => meow()
|
|
|
|
|
|
else => silent()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// デシュガー後(概念的)
|
|
|
|
|
|
if animal == "dog" {
|
|
|
|
|
|
bark()
|
|
|
|
|
|
} else if animal == "cat" {
|
|
|
|
|
|
meow()
|
|
|
|
|
|
} else {
|
|
|
|
|
|
silent()
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
【実装の簡単さ優先】
|
|
|
|
|
|
- VM/MIRは既存のif-else処理をそのまま利用
|
|
|
|
|
|
- 最適化(ジャンプテーブル等)はP1以降
|
|
|
|
|
|
|
|
|
|
|
|
================================================================================
|
|
|
|
|
|
7. 最小限のテストケース(P0)
|
|
|
|
|
|
================================================================================
|
|
|
|
|
|
|
|
|
|
|
|
```nyash
|
2025-11-06 15:41:52 +09:00
|
|
|
|
// test_peek_basic.hako
|
2025-09-17 22:32:38 +09:00
|
|
|
|
local animal = "cat"
|
|
|
|
|
|
local sound = peek animal {
|
|
|
|
|
|
"dog" => "woof"
|
|
|
|
|
|
"cat" => "meow"
|
|
|
|
|
|
else => "..."
|
|
|
|
|
|
}
|
|
|
|
|
|
print(sound) // "meow"
|
|
|
|
|
|
|
2025-11-06 15:41:52 +09:00
|
|
|
|
// test_peek_block.hako
|
2025-09-17 22:32:38 +09:00
|
|
|
|
local result = peek x {
|
|
|
|
|
|
1 => {
|
|
|
|
|
|
local temp = "one"
|
|
|
|
|
|
temp // 値
|
|
|
|
|
|
}
|
|
|
|
|
|
else => "other"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-06 15:41:52 +09:00
|
|
|
|
// test_continue.hako
|
2025-09-17 22:32:38 +09:00
|
|
|
|
local i = 0
|
|
|
|
|
|
local sum = 0
|
|
|
|
|
|
loop(i < 5) {
|
|
|
|
|
|
i = i + 1
|
|
|
|
|
|
if i == 3 {
|
|
|
|
|
|
continue
|
|
|
|
|
|
}
|
|
|
|
|
|
sum = sum + i
|
|
|
|
|
|
}
|
|
|
|
|
|
print(sum) // 12 (1+2+4+5, 3はスキップ)
|
|
|
|
|
|
|
2025-11-06 15:41:52 +09:00
|
|
|
|
// test_field_declaration.hako
|
2025-09-17 22:32:38 +09:00
|
|
|
|
box Point {
|
|
|
|
|
|
public x: IntegerBox
|
|
|
|
|
|
public y: IntegerBox
|
|
|
|
|
|
private z: IntegerBox
|
|
|
|
|
|
|
|
|
|
|
|
birth(x, y) {
|
|
|
|
|
|
me.x = x
|
|
|
|
|
|
me.y = y
|
|
|
|
|
|
me.z = 0
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
================================================================================
|
|
|
|
|
|
8. 実装順序(推奨)
|
|
|
|
|
|
================================================================================
|
|
|
|
|
|
|
|
|
|
|
|
1. tokenizer.rs
|
|
|
|
|
|
- FAT_ARROW, DOUBLE_COLON追加
|
|
|
|
|
|
- peek, continue, birth を予約語追加
|
|
|
|
|
|
|
|
|
|
|
|
2. parser/expressions.rs
|
|
|
|
|
|
- parse_peek_expr() 実装
|
|
|
|
|
|
- else必須チェック
|
|
|
|
|
|
|
|
|
|
|
|
3. parser/statements.rs
|
|
|
|
|
|
- Continue文追加
|
|
|
|
|
|
- フィールド宣言パース追加
|
|
|
|
|
|
|
|
|
|
|
|
4. ast.rs
|
|
|
|
|
|
- PeekExpr, ContinueStmt追加
|
|
|
|
|
|
- Field構造体に型情報追加
|
|
|
|
|
|
|
|
|
|
|
|
5. interpreter/evaluator.rs
|
|
|
|
|
|
- peek式の評価(if-elseとして)
|
|
|
|
|
|
- continue処理(既存のControlFlow利用)
|
|
|
|
|
|
|
|
|
|
|
|
================================================================================
|
|
|
|
|
|
9. P1に回すもの(今回は実装しない)
|
|
|
|
|
|
================================================================================
|
|
|
|
|
|
|
|
|
|
|
|
- import文の完全実装
|
|
|
|
|
|
- Parent::method() 記法(トークンのみ追加)
|
|
|
|
|
|
- fn{} クロージャの完全実装(環境キャプチャ等)
|
|
|
|
|
|
- フィールドのデフォルト値
|
|
|
|
|
|
- @override等の属性
|
|
|
|
|
|
|
|
|
|
|
|
================================================================================
|
|
|
|
|
|
10. 合意事項の最終確認
|
|
|
|
|
|
================================================================================
|
|
|
|
|
|
|
|
|
|
|
|
✓ peekは「式」として値を返す
|
|
|
|
|
|
✓ else節は必須(コンパイルエラー)
|
|
|
|
|
|
✓ 空ブロックの値はVoidBox
|
|
|
|
|
|
✓ publicは文脈依存キーワード(互換性維持)
|
|
|
|
|
|
✓ フィールドのデフォルト値はP1送り
|
|
|
|
|
|
✓ デシュガーでシンプル実装(最適化は後回し)
|
|
|
|
|
|
|
|
|
|
|
|
================================================================================
|