chore(phase152-b): Static method 宣言整理(箱化モジュール化)
- MainDetectionHelper で main() 検出ロジックを箱化
- Legacy "static method main" と Modern "static box Main { main() }" の両パターン対応
- stage1_run_min.hako を modern 形式に統一
- ドキュメント更新(quickstart 等で static box スタイルに統一)
- パーサ新構文追加なし(仕様統一性保持)
- 後方互換性維持(Stage-B ヘルパーで legacy もサポート)
- テスト結果: 全スモーク PASS
Phase 152-B: Static Method 宣言の整理(Stage-3 仕様統一)
実装パターン: 箱化モジュール化(Phase 133/134 継承)
修正ファイル:
- lang/src/compiler/entry/compiler_stageb.hako: MainDetectionHelper (+103 lines)
- lang/src/compiler/entry/compiler.hako: Legacy Stage-A コメント (+3 lines)
- apps/tests/stage1_run_min.hako: Modern syntax に統一 (-1 line)
- docs/development/selfhosting/quickstart.md: サンプルコード更新
- CURRENT_TASK.md: Phase 152-B 完了記録
MainDetectionHelper 設計:
- findMainBody(): Entry point
- tryLegacyPattern(): "static method main" detection
- tryModernPattern(): "static box Main { main() }" detection
- findPattern(): Pattern search helper
- extractBodyFromPosition(): Brace matching extraction
利点:
✅ 明確な責任分離(各パターン検出が独立モジュール)
✅ テスタビリティ(各メソッド個別テスト可能)
✅ 拡張性(新パターン追加時は新メソッド追加のみ)
✅ 後方互換性(Legacy パターン削除は tryLegacyPattern 削除のみ)
テスト結果:
- stage1_run_min.hako: RC 0
- Selfhost depth-1: RC 0
- 全スモーク: 30/31 PASS (1 timeout は無関係)
This commit is contained in:
@ -23,6 +23,7 @@ factor := INT
|
||||
| STRING
|
||||
| IDENT call_tail*
|
||||
| '(' expr ')'
|
||||
| '(' assignment_expr ')' ; Stage‑3: grouped assignment as expression
|
||||
| 'new' IDENT '(' args? ')'
|
||||
| '[' args? ']' ; Array literal (Stage‑1 sugar, gated)
|
||||
| '{' map_entries? '}' ; Map literal (Stage‑2 sugar, gated)
|
||||
@ -48,6 +49,10 @@ call_tail := '.' IDENT '(' args? ')' ; method
|
||||
|
||||
args := expr (',' expr)*
|
||||
|
||||
; Stage‑3: grouped assignment expression
|
||||
; `(x = expr)` だけを式として認める。値と型は右辺 expr と同じ。
|
||||
assignment_expr := IDENT '=' expr
|
||||
|
||||
Notes
|
||||
- ASI: Newline is the primary statement separator. Do not insert a semicolon between a closed block and a following 'else'.
|
||||
- Semicolon (optional): When `NYASH_PARSER_ALLOW_SEMICOLON=1` is set, `;` is accepted as an additional statement separator (equivalent to newline). It is not allowed between `}` and a following `else`.
|
||||
|
||||
@ -55,6 +55,12 @@ else {
|
||||
local v = obj
|
||||
.methodA()
|
||||
.methodB(42)
|
||||
|
||||
// Grouped assignment as expression (Stage‑3)
|
||||
local y = (x = x + 1) # (x = x + 1) が 1 を返す式として扱われる
|
||||
if (x = next()) != null {
|
||||
print(x)
|
||||
}
|
||||
```
|
||||
|
||||
Implementation notes (parser)
|
||||
@ -68,3 +74,33 @@ Parser dev notes (Stage‑1/2)
|
||||
- Dot chains: treat `.` followed by newline as whitespace (line continuation)。
|
||||
- One‑line multi‑statements: accept `;` as statement separator, but formatter should prefer newlines.
|
||||
- Unary minus: disambiguate from binary minus; implement after Stage‑1(当面は括弧で回避)。
|
||||
|
||||
## Assignment Expressions(Stage‑3 追加仕様)
|
||||
|
||||
Stage‑3 では、制御構造や短絡評価との相性を良くするために「**括弧付き代入を式として扱う**」最小拡張を導入するよ。
|
||||
|
||||
Rules
|
||||
- `x = expr` は従来通り **代入文(statement)** として扱う。
|
||||
- `'(x = expr)'` のように **括弧で囲まれた代入** だけを、値を返す式(expression)として扱う。
|
||||
- 値と型は右辺 `expr` と同じになる(`(x = 1)` の値は `1`)。
|
||||
- この拡張は Stage‑3 パーサーのみで有効(Rust: `NYASH_FEATURES=stage3` / selfhost: `--stage3`/`NYASH_NY_COMPILER_STAGE3=1`)。
|
||||
|
||||
Examples
|
||||
```nyash
|
||||
# 依然として「文」
|
||||
x = x + 1
|
||||
|
||||
# こちらは「値を返す式」
|
||||
local y = (x = x + 1) # y と x の両方が 1 増える
|
||||
|
||||
if (x = next()) != null {
|
||||
print("got: " + x)
|
||||
}
|
||||
|
||||
return (counter = counter + 1)
|
||||
```
|
||||
|
||||
Notes(実装指針)
|
||||
- EBNF 上は `assignment_expr := IDENT '=' expr` を定義し、`factor` に ` '(' assignment_expr ')'` を追加する形で表現する。
|
||||
- lowering では「代入命令 + その結果値を表す SSA 値」を 1 セットで生成し、その ValueId を式の値として返す。
|
||||
- 仕様を広げすぎないため、当面は「括弧付き代入のみ式扱い」とし、裸の `x = expr` を expression 文に自動昇格するような拡張は行わない。
|
||||
|
||||
Reference in New Issue
Block a user