Files
hakorune/docs/reference/language/statements.md

107 lines
4.0 KiB
Markdown
Raw Permalink Normal View History

# 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)
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:30 +09:00
// 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当面は括弧で回避
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:30 +09:00
## 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 文に自動昇格するような拡張は行わない。