Files
hakorune/docs/reference/language/statements.md
nyash-codex 4b6b75932c 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 は無関係)
2025-12-04 13:54:45 +09:00

107 lines
4.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Statement Separation and Semicolons
Status: Adopted for Phase 15.3+; parser implementation is staged.
Policy
- Newline as primary statement separator.
- Semicolons are optional and only needed when multiple statements appear on one physical line.
- Minimal ASI (auto semicolon insertion) rules to avoid surprises.
Rules (minimal and predictable)
- Newline ends a statement when:
- Parenthesis/brace/bracket depth is 0, and
- The line does not end with a continuation token (`+ - * / . ,` etc.).
- Newline does NOT end a statement when:
- Inside any open grouping `(...)`, `[...]`, `{...}`; or
- The previous token is a continuation token.
- `return/break/continue` end the statement at newline unless the value is on the same line or grouped via parentheses.
- `if/else` (and similar paired constructs): do not insert a semicolon between a block and a following `else`.
- Oneline multistatements are allowed with semicolons: `x = 1; y = 2; print(y)`.
- Method chains can break across lines after a dot: `obj\n .method()` (newline treated as whitespace).
Style guidance
- Prefer newline separation (no semicolons) for readability.
- Use semicolons only when placing multiple statements on a single line.
Examples
```nyash
// Preferred (no semicolons)
local x = 5
x = x + 1
print(x)
// One line with multiple statements (use semicolons)
local x = 5; x = x + 1; print(x)
// Line continuation by operator
local n = 1 +
2 +
3
// Grouping across lines
return (
1 + 2 + 3
)
// if / else on separate lines without inserting a semicolon
if cond {
x = x - 1
}
else {
print(x)
}
// Dot chain across lines
local v = obj
.methodA()
.methodB(42)
// Grouped assignment as expression (Stage3)
local y = (x = x + 1) # (x = x + 1) が 1 を返す式として扱われる
if (x = next()) != null {
print(x)
}
```
Implementation notes (parser)
- Tokenizer keeps track of grouping depth.
- At newline, attempt ASI only when depth==0 and previous token is not a continuation.
- Error messages should suggest adding a continuation token or grouping when a newline unexpectedly ends a statement.
Parser dev notes (Stage1/2)
- return + newline: treat bare `return` as statement end. To return an expression on the next line, require grouping with parentheses.
- if/else: never insert a semicolon between a closed block and `else` (ASI禁止箇所)。
- Dot chains: treat `.` followed by newline as whitespace (line continuation)。
- Oneline multistatements: accept `;` as statement separator, but formatter should prefer newlines.
- Unary minus: disambiguate from binary minus; implement after Stage1当面は括弧で回避
## Assignment ExpressionsStage3 追加仕様)
Stage3 では、制御構造や短絡評価との相性を良くするために「**括弧付き代入を式として扱う**」最小拡張を導入するよ。
Rules
- `x = expr` は従来通り **代入文statement** として扱う。
- `'(x = expr)'` のように **括弧で囲まれた代入** だけを、値を返す式expressionとして扱う。
- 値と型は右辺 `expr` と同じになる(`(x = 1)` の値は `1`)。
- この拡張は Stage3 パーサーのみで有効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 文に自動昇格するような拡張は行わない。