Files
hakorune/docs/guides/controlflow-builder.md

60 lines
2.6 KiB
Markdown
Raw 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.

# ControlFlowBuilder — If/Match 正規化ビルダー(コンパイル時メタ)
目的
- If/Match の正規化join 変数導入・scrutinee 一回評価・ガード合成・単一 PHI 群)を安全に一貫化するためのビルダー。
- 生成物は AST JSON v0 の文字列(マクロ内で使用)。実行時コストはゼロ。
設計原則
- 合流点は必ず join 変数gensymで収束空 PHI を避け、PHI は合流ブロック先頭へ誘導)。
- 条件/scrutinee は 1 回だけ評価してローカルへ束ねる。
- 構造は If/Match → If 連鎖(パターン条件は PatternBuilder で構築)。
想定 APIMVP
- if_stmt(cond_json, then_stmts_json[], else_stmts_json[]|null) -> If ノード文字列
- if_expr(cond_json, then_expr_json, else_expr_json, res_name) -> statements_json[]
- [ Local(res), If(assign res in both branches) ] を返す
- match_stmt(scrut_json, arms[]) -> statements_json[]
- match_expr(scrut_json, arms[], res_name) -> statements_json[]
- arms: [{ cond_json, guard_json|null, body_expr_json }]
- cond_json は PatternBuilder で組み立てるOR/型チェック等)
使用例(式 If
```
local JB = include "apps/lib/json_builder.hako"
local CF = include "apps/lib/cf_builder.hako" // 実装後に利用
local cond = JB.binary("<", JB.variable("a"), JB.variable("b"))
local then_e = JB.literal_int(10)
local else_e = JB.literal_int(20)
local stmts = CF.if_expr(cond, then_e, else_e, "__res0")
// stmts を元の位置にスプライスProgram 配列へ結合)
```
使用例(式 Match
```
local JB = include "apps/lib/json_builder.hako"
local CF = include "apps/lib/cf_builder.hako"
local PT = include "apps/lib/pattern_builder.hako"
local scrut = JB.variable("x")
local c_small = PT.or_([ PT.eq(JB.literal_int(0)), PT.eq(JB.literal_int(1)) ])
local arms = [
{ cond_json: c_small, guard_json: JB.variable("small"), body_expr_json: JB.literal_string("small") },
{ cond_json: PT.type_is("IntegerBox", scrut), guard_json: null,
body_expr_json: /* toString(as_int(scrut)) を別途構築 */ JB.variable("n_to_string") },
{ cond_json: PT.default(), guard_json: null, body_expr_json: JB.literal_string("other") },
]
local stmts = CF.match_expr(scrut, arms, "__res1")
```
備考
- gensym は MacroCtx から受け取る想定CF 内では与えられた res_name/scrut_name を尊重)。
- 実装は JsonBuilder を用いてノード文字列を生成。
- 将来: cond/guard の短絡は既存の BinaryOp(&&,||) へ委譲し、PyVM/LLVM の規約に従う。
関連
- docs/guides/pattern-builder.md
- docs/guides/if-match-normalize.md
- docs/guides/loopform.md