grammar(P0): add peek expression, continue statement, and field type annotations acceptance; add sample apps and interpreter path\n\n- tokenizer: add keywords (peek, continue), tokens (=> as FatArrow, :: as DoubleColon), keep >> as Arrow\n- parser: implement peek as expression (literal patterns only, else required), add continue; accept field 'name: Type' (discard type P0)\n- interpreter: evaluate PeekExpr; add Continue control flow handling\n- apps: add peek-demo, loop-continue-demo, adjust field-decl demo; use ConsoleBox instead of env.console for interpreter backend\n- docs: CURRENT_TASK updated earlier for Phase 12.7 P0\n\nNOTE: peek arms currently single-expression (no block expr yet); VM/MIR path does not lower PeekExpr yet; use --backend interpreter for demos
This commit is contained in:
@ -0,0 +1,297 @@
|
||||
================================================================================
|
||||
Nyash つよつよ糖衣構文提案 - 自己ホスティングに向けて
|
||||
2025-09-03
|
||||
================================================================================
|
||||
|
||||
【背景】
|
||||
自己ホスティング(NyashでNyashコンパイラを書く)を実現するため、
|
||||
コード量を劇的に削減できる強力な糖衣構文を検討する。
|
||||
|
||||
================================================================================
|
||||
1. パイプライン演算子 |> (優先度:最高)
|
||||
================================================================================
|
||||
|
||||
【現在の問題】
|
||||
// ネストが深くて読みにくい
|
||||
local result = trim(uppercase(replace(input, "cat", "nyan")))
|
||||
|
||||
【提案構文】
|
||||
local result = input
|
||||
|> replace($, "cat", "nyan")
|
||||
|> uppercase($)
|
||||
|> trim($)
|
||||
|
||||
// $ は前の結果を表す特殊変数
|
||||
// または第一引数に自動挿入も可
|
||||
local result = input
|
||||
|> replace("cat", "nyan") // 第一引数に自動挿入
|
||||
|> uppercase()
|
||||
|> trim()
|
||||
|
||||
【効果】
|
||||
- AST変換処理が非常に読みやすくなる
|
||||
- 関数合成が直感的
|
||||
- デバッグ時に中間結果を確認しやすい
|
||||
|
||||
================================================================================
|
||||
2. 分割代入(Destructuring)(優先度:高)
|
||||
================================================================================
|
||||
|
||||
【基本形】
|
||||
// タプル分割
|
||||
local (x, y, z) = getCoordinates()
|
||||
|
||||
// Box分割
|
||||
local { name, age, email } = getUserInfo()
|
||||
|
||||
// 配列分割
|
||||
local [first, second, ...rest] = items
|
||||
|
||||
【peek内での構造体パターン】
|
||||
peek ast {
|
||||
BinaryOp(left, op, right) => {
|
||||
// left, op, right が自動的に変数として使える
|
||||
compile(left) + compile(op) + compile(right)
|
||||
}
|
||||
UnaryOp(op, expr) => {
|
||||
compile(op) + compile(expr)
|
||||
}
|
||||
Literal(value) => value.toString()
|
||||
}
|
||||
|
||||
【効果】
|
||||
- パーサー実装で威力発揮
|
||||
- ASTノードの処理が簡潔に
|
||||
- ボイラープレートコード削減
|
||||
|
||||
================================================================================
|
||||
3. null安全演算子 ?. と ?? (優先度:高)
|
||||
================================================================================
|
||||
|
||||
【?.(null安全アクセス)】
|
||||
// 現在
|
||||
local name
|
||||
if user != null {
|
||||
if user.profile != null {
|
||||
if user.profile.name != null {
|
||||
name = user.profile.name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 提案
|
||||
local name = user?.profile?.name
|
||||
|
||||
【??(null合体演算子)】
|
||||
local displayName = user?.name ?? "Anonymous"
|
||||
local port = config?.server?.port ?? 8080
|
||||
|
||||
【組み合わせ】
|
||||
local result = getData()?.process()?.format() ?? "default"
|
||||
|
||||
【効果】
|
||||
- null/undefinedエラーの防止
|
||||
- 防御的プログラミングが簡潔に
|
||||
- 設定値の読み込みで特に有用
|
||||
|
||||
================================================================================
|
||||
4. 文字列テンプレート強化(優先度:高)
|
||||
================================================================================
|
||||
|
||||
【基本テンプレート】
|
||||
// 現在
|
||||
local msg = "Error at line " + line + ", column " + col + ": " + error
|
||||
|
||||
// 提案
|
||||
local msg = `Error at line ${line}, column ${col}: ${error}`
|
||||
|
||||
【複数行テンプレート】
|
||||
local code = ```
|
||||
fn ${name}(${params.join(", ")}) {
|
||||
${body.indent(4)}
|
||||
}
|
||||
```
|
||||
|
||||
【タグ付きテンプレート(将来)】
|
||||
local sql = SQL`SELECT * FROM users WHERE id = ${userId}`
|
||||
local regex = RE`\d{3}-\d{4}` // エスケープ不要
|
||||
|
||||
【効果】
|
||||
- コード生成が劇的に簡単に
|
||||
- SQLやHTML生成で安全性向上
|
||||
- 可読性の大幅改善
|
||||
|
||||
================================================================================
|
||||
5. リスト内包表記(優先度:中)
|
||||
================================================================================
|
||||
|
||||
【基本形】
|
||||
// 現在
|
||||
local result = new ArrayBox()
|
||||
for item in list {
|
||||
if item.isValid() {
|
||||
result.push(item.process())
|
||||
}
|
||||
}
|
||||
|
||||
// 提案
|
||||
local result = [item.process() for item in list if item.isValid()]
|
||||
|
||||
【ネスト】
|
||||
local pairs = [(x, y) for x in xs for y in ys if x != y]
|
||||
|
||||
【辞書内包】
|
||||
local map = {key: value.process() for (key, value) in entries}
|
||||
|
||||
【効果】
|
||||
- 変換処理が1行で書ける
|
||||
- 関数型プログラミングスタイル
|
||||
- メモリ効率的な実装も可能
|
||||
|
||||
================================================================================
|
||||
6. for式(値を返すfor)(優先度:中)
|
||||
================================================================================
|
||||
|
||||
【基本形】
|
||||
local tokens = for token in input yield parseToken(token)
|
||||
|
||||
【フィルタ付き】
|
||||
local validTokens = for token in tokens if token.isValid() yield token
|
||||
|
||||
【変換付き】
|
||||
local ast = for line in lines {
|
||||
local trimmed = line.trim()
|
||||
if trimmed.length() > 0 {
|
||||
yield parseLine(trimmed)
|
||||
}
|
||||
}
|
||||
|
||||
【効果】
|
||||
- リスト内包より複雑な処理に対応
|
||||
- 中間変数を使える
|
||||
- yieldで明示的
|
||||
|
||||
================================================================================
|
||||
7. スプレッド演算子 ... (優先度:中)
|
||||
================================================================================
|
||||
|
||||
【配列展開】
|
||||
local combined = [...array1, ...array2, newItem]
|
||||
local clone = [...original]
|
||||
|
||||
【Box展開】
|
||||
local updated = { ...oldConfig, debug: true, port: 8080 }
|
||||
|
||||
【関数引数展開】
|
||||
processItems(...args)
|
||||
local max = Math.max(...numbers)
|
||||
|
||||
【効果】
|
||||
- 配列・オブジェクト操作が簡潔
|
||||
- イミュータブルな更新が簡単
|
||||
- 可変長引数の処理
|
||||
|
||||
================================================================================
|
||||
8. with文(リソース管理)(優先度:低)
|
||||
================================================================================
|
||||
|
||||
【基本形】
|
||||
with file = openFile("data.txt") {
|
||||
local content = file.read()
|
||||
process(content)
|
||||
} // 自動的にfile.close()
|
||||
|
||||
【複数リソース】
|
||||
with db = connectDB(), file = openLog() {
|
||||
db.query("SELECT...")
|
||||
file.write(result)
|
||||
} // 両方自動クローズ
|
||||
|
||||
【効果】
|
||||
- リソースリークの防止
|
||||
- finally不要
|
||||
- RAII的な管理
|
||||
|
||||
================================================================================
|
||||
9. 関数合成演算子(優先度:低)
|
||||
================================================================================
|
||||
|
||||
【合成 >>】
|
||||
local processLine = trim >> lowercase >> tokenize
|
||||
local result = processLine(input)
|
||||
|
||||
【部分適用】
|
||||
local add5 = add(5, _)
|
||||
local result = add5(10) // 15
|
||||
|
||||
【カリー化】
|
||||
local multiply = fn(a)(b) => a * b
|
||||
local double = multiply(2)
|
||||
|
||||
【効果】
|
||||
- 関数型プログラミング支援
|
||||
- 高階関数の活用
|
||||
- コードの再利用性向上
|
||||
|
||||
================================================================================
|
||||
10. 強力なpeekパターン拡張(優先度:中)
|
||||
================================================================================
|
||||
|
||||
【ガード】
|
||||
peek value {
|
||||
n if n > 0 => "positive"
|
||||
n if n < 0 => "negative"
|
||||
0 => "zero"
|
||||
}
|
||||
|
||||
【範囲】
|
||||
peek score {
|
||||
0..60 => "F"
|
||||
60..70 => "D"
|
||||
70..80 => "C"
|
||||
80..90 => "B"
|
||||
90..100 => "A"
|
||||
}
|
||||
|
||||
【深いパターン】
|
||||
peek ast {
|
||||
If({ condition: BinaryOp(_, "==", _), then, else }) => {
|
||||
optimizeEquality(condition, then, else)
|
||||
}
|
||||
}
|
||||
|
||||
【効果】
|
||||
- より表現力豊かな分岐
|
||||
- コンパイラ実装で必須
|
||||
- コードの意図が明確
|
||||
|
||||
================================================================================
|
||||
実装優先順位まとめ
|
||||
================================================================================
|
||||
|
||||
【Phase 13(次フェーズ)】
|
||||
1. パイプライン演算子 |>
|
||||
2. 分割代入(基本形のみ)
|
||||
3. null安全演算子 ?. と ??
|
||||
4. 文字列テンプレート `${}`
|
||||
|
||||
【Phase 14】
|
||||
5. リスト内包表記
|
||||
6. for式
|
||||
7. peekパターン拡張(ガード)
|
||||
|
||||
【Phase 15以降】
|
||||
8. スプレッド演算子
|
||||
9. with文
|
||||
10. 関数合成演算子
|
||||
|
||||
================================================================================
|
||||
実装時の注意点
|
||||
================================================================================
|
||||
|
||||
1. 各糖衣構文は既存構文へのデシュガーとして実装
|
||||
2. エラーメッセージは元の構文で表示
|
||||
3. デバッガーでのステップ実行に配慮
|
||||
4. 段階的に導入(基本形→拡張形)
|
||||
|
||||
================================================================================
|
||||
Reference in New Issue
Block a user