behavior-contracts 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/dist/behavior.d.ts +47 -0
  2. package/dist/behavior.d.ts.map +1 -1
  3. package/dist/behavior.js.map +1 -1
  4. package/dist/generator/core.d.ts +1 -1
  5. package/dist/generator/core.d.ts.map +1 -1
  6. package/dist/generator/core.js.map +1 -1
  7. package/dist/generator/emit-straightline-go.d.ts +77 -0
  8. package/dist/generator/emit-straightline-go.d.ts.map +1 -0
  9. package/dist/generator/emit-straightline-go.js +592 -0
  10. package/dist/generator/emit-straightline-go.js.map +1 -0
  11. package/dist/generator/emit-straightline-php.d.ts +46 -0
  12. package/dist/generator/emit-straightline-php.d.ts.map +1 -0
  13. package/dist/generator/emit-straightline-php.js +501 -0
  14. package/dist/generator/emit-straightline-php.js.map +1 -0
  15. package/dist/generator/emit-straightline-python.d.ts +36 -0
  16. package/dist/generator/emit-straightline-python.d.ts.map +1 -0
  17. package/dist/generator/emit-straightline-python.js +441 -0
  18. package/dist/generator/emit-straightline-python.js.map +1 -0
  19. package/dist/generator/emit-straightline-rust.d.ts +78 -0
  20. package/dist/generator/emit-straightline-rust.d.ts.map +1 -0
  21. package/dist/generator/emit-straightline-rust.js +615 -0
  22. package/dist/generator/emit-straightline-rust.js.map +1 -0
  23. package/dist/generator/emit-straightline-typed-go.d.ts +39 -0
  24. package/dist/generator/emit-straightline-typed-go.d.ts.map +1 -0
  25. package/dist/generator/emit-straightline-typed-go.js +828 -0
  26. package/dist/generator/emit-straightline-typed-go.js.map +1 -0
  27. package/dist/generator/emit-straightline-typed-rust.d.ts +48 -0
  28. package/dist/generator/emit-straightline-typed-rust.d.ts.map +1 -0
  29. package/dist/generator/emit-straightline-typed-rust.js +823 -0
  30. package/dist/generator/emit-straightline-typed-rust.js.map +1 -0
  31. package/dist/generator/emit-straightline-typed-typescript.d.ts +49 -0
  32. package/dist/generator/emit-straightline-typed-typescript.d.ts.map +1 -0
  33. package/dist/generator/emit-straightline-typed-typescript.js +314 -0
  34. package/dist/generator/emit-straightline-typed-typescript.js.map +1 -0
  35. package/dist/generator/emit-straightline-typescript.d.ts +36 -0
  36. package/dist/generator/emit-straightline-typescript.d.ts.map +1 -0
  37. package/dist/generator/emit-straightline-typescript.js +397 -0
  38. package/dist/generator/emit-straightline-typescript.js.map +1 -0
  39. package/dist/generator/index.d.ts +13 -0
  40. package/dist/generator/index.d.ts.map +1 -1
  41. package/dist/generator/index.js +39 -0
  42. package/dist/generator/index.js.map +1 -1
  43. package/dist/generator/literal.d.ts +7 -0
  44. package/dist/generator/literal.d.ts.map +1 -1
  45. package/dist/generator/literal.js +41 -0
  46. package/dist/generator/literal.js.map +1 -1
  47. package/dist/generator/straightline.d.ts +147 -0
  48. package/dist/generator/straightline.d.ts.map +1 -0
  49. package/dist/generator/straightline.js +122 -0
  50. package/dist/generator/straightline.js.map +1 -0
  51. package/dist/generator/typed.d.ts +156 -0
  52. package/dist/generator/typed.d.ts.map +1 -0
  53. package/dist/generator/typed.js +108 -0
  54. package/dist/generator/typed.js.map +1 -0
  55. package/dist/guard.d.ts +18 -0
  56. package/dist/guard.d.ts.map +1 -1
  57. package/dist/guard.js +56 -0
  58. package/dist/guard.js.map +1 -1
  59. package/dist/index.d.ts +7 -4
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +10 -2
  62. package/dist/index.js.map +1 -1
  63. package/dist/primitives.d.ts +112 -0
  64. package/dist/primitives.d.ts.map +1 -0
  65. package/dist/primitives.js +206 -0
  66. package/dist/primitives.js.map +1 -0
  67. package/package.json +1 -1
@@ -0,0 +1,441 @@
1
+ import { emitDocLiteral, emitDocLiteralCompact } from "./literal.js";
2
+ import { emitStraightlineModule, } from "./straightline.js";
3
+ /** primitive namespace alias(生成コード内 — `behavior_contracts.primitives` を `cgp` で import)。 */
4
+ const CGP = "cgp";
5
+ /**
6
+ * scope 式(生成コード内)。scope は「input + それまでの ok 結果」のその時点のスナップで
7
+ * あり、run_behavior の base_scope() と同じく exec ごとに新規に組む。native/primitive 双方へ
8
+ * `_scope()`(関数呼び)を渡す(呼び時点の results を読む — 決定的)。
9
+ */
10
+ const SCOPE = "_scope()";
11
+ /**
12
+ * map 本体(over/guard/ports)の要素 scope 式(生成コード内)。run_behavior の map と同じく
13
+ * `{**base_scope(), as: el}` を per-element で組む(生成コードは map arm 内で `_mscope()` を
14
+ * ローカル定義する)。
15
+ */
16
+ const MAP_SCOPE = "_mscope()";
17
+ /** IR リテラルを python 式として emit(primitive 被演算子用の単一行リテラル)。 */
18
+ function lit(node) {
19
+ return emitDocLiteralCompact(node, "py");
20
+ }
21
+ /** args 配列(比較・算術の二項/単項)を要素ごとに IR リテラルへ落として `, ` 連結。 */
22
+ function argList(arg) {
23
+ return arg.map((a) => lit(a)).join(", ");
24
+ }
25
+ // A0 primitives.py の引数形に合わせた op → 呼び式の綴じ方(TS oracle と違い python の primitive は
26
+ // 被演算子を **位置引数**で取る: add(a, b, scope) / cond(c, then, els, scope) / obj(fields, scope) …)。
27
+ // 命名は docs/codegen-primitives.md(python 列)に一致。ref/refOpt/concat と単純リテラルはここに無い
28
+ // (native 化するため emitExpr が直接 native コードを出す — 本 issue の脱解釈)。
29
+ const OP_EMITTERS = {
30
+ // リテラルラッパ(int は i64 checked / float は NaN/Inf checked — native 化しない)
31
+ int: (arg, s) => `${CGP}.int_lit(${lit(arg)}, ${s})`,
32
+ float: (arg, s) => `${CGP}.float_lit(${lit(arg)}, ${s})`,
33
+ // 構築(fields/elements は未評価 IR)
34
+ obj: (arg, s) => `${CGP}.obj(${lit(arg)}, ${s})`,
35
+ arr: (arg, s) => `${CGP}.arr(${lit(arg)}, ${s})`,
36
+ // 数値(checked。二項は a,b / 単項は a)
37
+ add: (arg, s) => `${CGP}.add(${argList(arg)}, ${s})`,
38
+ sub: (arg, s) => `${CGP}.sub(${argList(arg)}, ${s})`,
39
+ mul: (arg, s) => `${CGP}.mul(${argList(arg)}, ${s})`,
40
+ neg: (arg, s) => `${CGP}.neg(${argList(arg)}, ${s})`,
41
+ div: (arg, s) => `${CGP}.div(${argList(arg)}, ${s})`,
42
+ mod: (arg, s) => `${CGP}.mod(${argList(arg)}, ${s})`,
43
+ // 比較(二項)
44
+ eq: (arg, s) => `${CGP}.eq(${argList(arg)}, ${s})`,
45
+ ne: (arg, s) => `${CGP}.ne(${argList(arg)}, ${s})`,
46
+ lt: (arg, s) => `${CGP}.lt(${argList(arg)}, ${s})`,
47
+ le: (arg, s) => `${CGP}.le(${argList(arg)}, ${s})`,
48
+ gt: (arg, s) => `${CGP}.gt(${argList(arg)}, ${s})`,
49
+ ge: (arg, s) => `${CGP}.ge(${argList(arg)}, ${s})`,
50
+ // bool/null(短絡: 被演算子は未評価 IR で渡す — primitive 内 evaluate が短絡)
51
+ and: (arg, s) => `${CGP}.and_(${argList(arg)}, ${s})`,
52
+ or: (arg, s) => `${CGP}.or_(${argList(arg)}, ${s})`,
53
+ not: (arg, s) => `${CGP}.not_(${argList(arg)}, ${s})`,
54
+ coalesce: (arg, s) => `${CGP}.coalesce(${argList(arg)}, ${s})`,
55
+ cond: (arg, s) => `${CGP}.cond(${argList(arg)}, ${s})`,
56
+ len: (arg, s) => `${CGP}.len_(${argList(arg)}, ${s})`,
57
+ };
58
+ /** ref/refOpt の path(string 配列)を python list リテラルへ。 */
59
+ function pathLit(arg) {
60
+ return lit(arg);
61
+ }
62
+ /**
63
+ * emitExpr — Expression IR ノードを python 式へ落とす(脱解釈: 単純式は native、意味論式は primitive)。
64
+ *
65
+ * - `concat` → native `_sl_concat([...])`(str-only / arity>=2 を native チェック)。
66
+ * - `ref` / `refOpt` → native `_sl_ref(...)` / `_sl_ref_opt(...)`(path を native 走査)。
67
+ * - str/bool/None/int/float → native python リテラル(portability guard 済み → 安全域内で evaluate と同値)。
68
+ * - それ以外の演算子ノード → A0 primitive(`cgp.*`。被演算子は未評価 IR リテラル=短絡保存)。
69
+ * - 未知の形 → 到達しない(Portability Guard 通過済み)。防御的に primitive `eval_expr` へ。
70
+ *
71
+ * native 経路は `evaluate()` も `cgp.*` も呼ばない(AC#2/#7 の grep 証明の対象)。
72
+ */
73
+ function emitExpr(node, scopeVar) {
74
+ // スカラリテラル(native)。
75
+ if (node === null)
76
+ return "None";
77
+ if (typeof node === "boolean")
78
+ return node ? "True" : "False";
79
+ if (typeof node === "string")
80
+ return lit(node);
81
+ if (typeof node === "number")
82
+ return lit(node); // literal.ts が安全域を fail-closed 済み
83
+ if (typeof node === "object" && !Array.isArray(node)) {
84
+ const keys = Object.keys(node);
85
+ if (keys.length === 1) {
86
+ const op = keys[0];
87
+ const arg = node[op];
88
+ // ── 単純式の native 化(脱解釈)──────────────────────────────────────
89
+ if (op === "ref")
90
+ return `_sl_ref(${pathLit(arg)}, ${scopeVar})`;
91
+ if (op === "refOpt")
92
+ return `_sl_ref_opt(${pathLit(arg)}, ${scopeVar})`;
93
+ if (op === "concat") {
94
+ const parts = arg.map((p) => emitExpr(p, scopeVar));
95
+ return `_sl_concat([${parts.join(", ")}])`;
96
+ }
97
+ // ── 意味論式(overflow/短絡/fail-closed)は A0 primitive SSoT へ ─────────
98
+ const em = OP_EMITTERS[op];
99
+ if (em)
100
+ return em(arg, scopeVar);
101
+ }
102
+ }
103
+ // 配列裸出し等の不正形は Portability Guard で弾かれ到達しないが、防御的に SSoT へ委譲。
104
+ return `${CGP}.eval_expr(${lit(node)}, ${scopeVar})`;
105
+ }
106
+ // ── per-node exec 分岐 / component 関数 / module の綴じ方 ──────────────────────
107
+ /** ops リテラル(run_plan に渡す OpSpec[] の python list リテラル)を綴じる。 */
108
+ function emitOpsLiteral(plan) {
109
+ const rows = plan.opsLiteral.map((o) => {
110
+ const parts = [`"id": ${JSON.stringify(o.id)}`, `"parent": ${o.parent === null ? "None" : String(o.parent)}`];
111
+ if (o.bindField !== undefined)
112
+ parts.push(`"bindField": ${JSON.stringify(o.bindField)}`);
113
+ if (o.relationKind !== undefined)
114
+ parts.push(`"relationKind": ${JSON.stringify(o.relationKind)}`);
115
+ if (o.policy !== undefined)
116
+ parts.push(`"policy": ${JSON.stringify(o.policy)}`);
117
+ return ` {${parts.join(", ")}},`;
118
+ });
119
+ return `[\n${rows.join("\n")}\n ]`;
120
+ }
121
+ /** map arm の要素 ports リテラル(要素 scope `_mscope()` で評価)。 */
122
+ function emitMapPorts(op) {
123
+ if (op.ports.length === 0)
124
+ return "{}";
125
+ return `{\n${op.ports
126
+ .map((p) => ` ${JSON.stringify(p.name)}: ${p.expr},`)
127
+ .join("\n")}\n }`;
128
+ }
129
+ /**
130
+ * emitMapArm — map ノードの直線展開(要素反復・guard skip・per-element/batched handler・into
131
+ * zip-attach)。run_behavior の map 分岐を生成 python へ直線展開する。op-log 等価のため handler は
132
+ * run_behavior と同じ ctx(非 batched は bound 付き、batched は無し)・同じ ports 形で呼ぶ。guard は
133
+ * cond primitive(strict-bool SSoT)で、into は A0 `cgp.hydrate_into`(zip-attach SSoT)で解決する。
134
+ */
135
+ function emitMapArm(op) {
136
+ const comp = JSON.stringify(op.component);
137
+ const nodeId = JSON.stringify(op.id);
138
+ const asKey = JSON.stringify(op.as);
139
+ const guardCheck = op.guard === undefined ? "" : `\n if ${op.guard} is not True:\n continue`;
140
+ const intoTail = op.into === undefined
141
+ ? " return {\"ok\": _collected}"
142
+ : ` # map.into zip-attach(behavior.py applyInto): over と同じ長さ・順序で guard 通過要素へ
143
+ # 書き戻す(skip 要素は無変更、親不変)。Failure code は run_behavior と一致。
144
+ _augmented = []
145
+ _k = 0
146
+ for _mj, _oel in enumerate(_over):
147
+ if _k < len(_kept_idx) and _kept_idx[_k] == _mj:
148
+ if not isinstance(_oel, dict):
149
+ raise BehaviorFailure("MAP_INTO_ELEMENT_NOT_OBJECT", "map '${op.id}': 'into' requires object elements (element %d is not an object)" % _mj)
150
+ _augmented.append({**_oel, ${JSON.stringify(op.into)}: _collected[_k]})
151
+ _k += 1
152
+ else:
153
+ _augmented.append(_oel)
154
+ return {"ok": _augmented}`;
155
+ const body = op.batched
156
+ ? ` _items = []
157
+ for _mi, _el in enumerate(_over):
158
+ def _mscope(_el=_el):
159
+ return {**_scope(), ${asKey}: _el}${guardCheck}
160
+ _items.append(${emitMapPorts(op)})
161
+ _kept_idx.append(_mi)
162
+ if not _items:
163
+ _collected = []
164
+ else:
165
+ h = handlers.get(${comp})
166
+ if h is None:
167
+ raise BehaviorFailure("UNKNOWN_COMPONENT", "component '${op.component}' has no handler (fail-closed)")
168
+ outcome = h({"items": _items}, {"nodeId": ${nodeId}, "component": ${comp}})
169
+ if "error" in outcome:
170
+ return outcome
171
+ _r = outcome["ok"]
172
+ if not isinstance(_r, list) or len(_r) != len(_items):
173
+ raise BehaviorFailure("MAP_BATCH_RESULT_MISMATCH", "map '${op.id}': batched handler must return a list aligned to items (want %d)" % len(_items))
174
+ _collected = _r
175
+ ${intoTail}`
176
+ : ` _collected = []
177
+ h = handlers.get(${comp})
178
+ if h is None:
179
+ raise BehaviorFailure("UNKNOWN_COMPONENT", "component '${op.component}' has no handler (fail-closed)")
180
+ for _mi, _el in enumerate(_over):
181
+ def _mscope(_el=_el):
182
+ return {**_scope(), ${asKey}: _el}${guardCheck}
183
+ ports = ${emitMapPorts(op)}
184
+ outcome = h(ports, {"nodeId": ${nodeId}, "component": ${comp}, "bound": _el})
185
+ if "error" in outcome:
186
+ return outcome
187
+ _collected.append(outcome["ok"])
188
+ _kept_idx.append(_mi)
189
+ ${intoTail}`;
190
+ return ` if i == ${op.index}:
191
+ _over = ${op.over}
192
+ if not isinstance(_over, list):
193
+ raise BehaviorFailure("MAP_OVER_NOT_ARRAY", "map '${op.id}': 'over' did not evaluate to an array")
194
+ _kept_idx = []
195
+ ${body}`;
196
+ }
197
+ /** 1ノードの exec 分岐本体(index で分岐 — nodeKind ディスパッチではない)。 */
198
+ function emitExecArm(op) {
199
+ if (op.kind === "cond") {
200
+ // cond は純 Expression。scope を渡して1式評価(handler は呼ばない)。
201
+ return ` if i == ${op.index}:\n return {"ok": ${op.expr}}`;
202
+ }
203
+ if (op.kind === "map")
204
+ return emitMapArm(op);
205
+ // componentRef: 各 port を名前付き native/primitive 呼びで評価 → handler 注入呼び。
206
+ const portLines = op.ports.length === 0
207
+ ? " ports = {}"
208
+ : ` ports = {\n${op.ports
209
+ .map((p) => ` ${JSON.stringify(p.name)}: ${p.expr},`)
210
+ .join("\n")}\n }`;
211
+ return ` if i == ${op.index}:
212
+ ${portLines}
213
+ h = handlers.get(${JSON.stringify(op.component)})
214
+ if h is None:
215
+ raise BehaviorFailure("UNKNOWN_COMPONENT", "component '${op.component}' has no handler (fail-closed)")
216
+ return h(ports, {"nodeId": ${JSON.stringify(op.id)}, "component": ${JSON.stringify(op.component)}})`;
217
+ }
218
+ /**
219
+ * emitComponentFn — 1 component の直線 python 関数を綴じる。run_behavior の実行フロー
220
+ * (results 蓄積 + base_scope + run_plan + 未生成書き戻し + output 評価)を **生成コードに
221
+ * 直線展開**する(汎用 exec/nodeKind/eval_ports は無い。各 exec 分岐は index で確定・ハードコード)。
222
+ */
223
+ function emitComponentFn(plan) {
224
+ const arms = plan.ops.map(emitExecArm).join("\n");
225
+ const planLiteral = plan.component.plan ? emitDocLiteral(plan.component.plan, "py", 1) : "None";
226
+ const output = emitExpr(plan.component.output, SCOPE);
227
+ const relationKinds = plan.opsLiteral.map((o) => (o.relationKind === "connection" ? "connection" : "single"));
228
+ const relLit = "[" + relationKinds.map((r) => JSON.stringify(r)).join(", ") + "]";
229
+ return `def run_${sanitize(plan.name)}(handlers, input):
230
+ ops = ${emitOpsLiteral(plan)}
231
+ results = {}
232
+
233
+ def _scope():
234
+ return {**input, **results}
235
+
236
+ relation_kinds = ${relLit}
237
+
238
+ def _exec(op, _bound):
239
+ i = _op_index(ops, op["id"])
240
+ ${arms}
241
+ raise BehaviorFailure("UNKNOWN_NODE_KIND", "op '%s' has no generated exec arm (fail-closed)" % op["id"])
242
+
243
+ def _wrapped_exec(op, bound):
244
+ outcome = _exec(op, bound)
245
+ if "ok" in outcome:
246
+ results[op["id"]] = outcome["ok"]
247
+ return outcome
248
+
249
+ run = ${CGP}.run_plan(${planLiteral}, ops, _wrapped_exec)
250
+ for _i, _st in enumerate(run["states"]):
251
+ if _st is not None and _st.get("status") == "skipped":
252
+ results[ops[_i]["id"]] = ${CGP}.unproduced_value(relation_kinds[_i])
253
+ return ${output}`;
254
+ }
255
+ /** component 名を関数名に使える形へ(決定的。名前一意は DUPLICATE_COMPONENT で保証)。 */
256
+ function sanitize(name) {
257
+ return name.replace(/[^A-Za-z0-9_]/g, "_");
258
+ }
259
+ function emitComponent(plan, _ctx) {
260
+ return emitComponentFn(plan);
261
+ }
262
+ function emitModule(plans, ctx) {
263
+ const { fingerprint, specVersions, componentNames, runtimeImport } = ctx;
264
+ const names = componentNames.map((n) => JSON.stringify(n)).join(", ");
265
+ const namesTuple = componentNames.length === 1 ? `(${names},)` : `(${names})`;
266
+ const irLiteral = emitDocLiteral(ctx.ir, "py");
267
+ const fns = plans.map((p) => emitComponent(p, ctx)).join("\n\n\n");
268
+ const dispatchArms = plans
269
+ .map((p) => ` if name == ${JSON.stringify(p.name)}:\n return run_${sanitize(p.name)}(handlers, dict(input))`)
270
+ .join("\n");
271
+ return `# GENERATED by behavior-contracts common generator (bc#40, straight-line) — DO NOT EDIT.
272
+ # Input: portable component-graph IR only (scp-ir-architecture.md §5/§7.4).
273
+ # This is the STRAIGHT-LINE codegen endpoint (typed-codegen.md §4.1 / bc#40 A2): each
274
+ # component is emitted as a native python function that drives the plan via the run_plan
275
+ # primitive and evaluates every port + output either NATIVELY (concat -> python string
276
+ # concat; ref/refOpt -> native scope/field access) or through the A0 expression-operator
277
+ # primitives (#36) for overflow / short-circuit / fail-closed operators + injected handlers.
278
+ # It does NOT go through run_behavior's tree-walk (no nodeKind dispatch / no eval_ports loop
279
+ # / no generic exec). Scope: componentRef + cond + map (over/when/into/batched — bc#42 A3);
280
+ # into is zip-attached inline (native, MAP_INTO_ELEMENT_NOT_OBJECT fail-closed). plan.concurrency is preserved: the
281
+ # run_plan primitive dispatches same-stage independent ops up to plan.concurrency in flight
282
+ # (ThreadPoolExecutor), matching run_behavior's parallel behavior (bc#42 AC#2). Handlers are
283
+ # ALWAYS injected at the boundary.
284
+ # irFingerprint: ${fingerprint}
285
+ from ${runtimeImport} import SPEC_VERSIONS, fingerprint_component_graph, BehaviorFailure, ExprFailure, primitives as ${CGP}
286
+
287
+ # Spec versions baked at generation time (fail-closed constant comparison at load).
288
+ EXPECTED_SPEC_VERSIONS = {"behavior": ${specVersions.behavior}, "expression": ${specVersions.expression}, "plan": ${specVersions.plan}}
289
+
290
+ # FNV-1a 64 fingerprint of the source portable IR (canonical_json discipline, #208).
291
+ IR_FINGERPRINT = ${JSON.stringify(fingerprint)}
292
+
293
+ # Component names exposed by bind(), in IR declaration order.
294
+ COMPONENT_NAMES = ${namesTuple}
295
+
296
+ # The portable component-graph IR, embedded for the load-time fingerprint self-check only.
297
+ IR = ${irLiteral}
298
+
299
+
300
+ def _check_generated_module():
301
+ # load-time fail-closed checks (#208 prepared-artifact discipline, checked ONCE).
302
+ for _k, _want in EXPECTED_SPEC_VERSIONS.items():
303
+ _got = SPEC_VERSIONS.get(_k)
304
+ if _got != _want:
305
+ raise RuntimeError(
306
+ "behavior-contracts generated module: spec-version skew for '%s' "
307
+ "(generated=%s, runtime=%s) — regenerate against this runtime (fail-closed)"
308
+ % (_k, _want, _got)
309
+ )
310
+ _got_fp = fingerprint_component_graph(IR)
311
+ if _got_fp != IR_FINGERPRINT:
312
+ raise RuntimeError(
313
+ "behavior-contracts generated module: IR fingerprint mismatch "
314
+ "(baked=%s, embedded literal=%s) — the generated code was modified or corrupted (fail-closed)"
315
+ % (IR_FINGERPRINT, _got_fp)
316
+ )
317
+
318
+
319
+ _check_generated_module()
320
+
321
+ _MISSING = object()
322
+
323
+
324
+ # ── native-ized simple-expression helpers (de-interpretation — NO evaluate tree-walk) ──
325
+ # These statically unroll ref/refOpt/concat into native python, reproducing expr_eval.py's
326
+ # fail-closed semantics EXACTLY (same Failure codes via ExprFailure — the semantics SSoT is
327
+ # still one class). This is the Phase-B de-interpretation win: no recursive evaluate dispatch
328
+ # and no per-node operator lookup for pure ref/concat ports.
329
+ def _sl_ref(path, scope):
330
+ head = path[0]
331
+ if head not in scope:
332
+ raise ExprFailure("UNKNOWN_BINDING", "unknown binding: %s" % head)
333
+ cur = scope[head]
334
+ for seg in path[1:]:
335
+ if cur is None:
336
+ raise ExprFailure("NULL_REF", "null intermediate at .%s(?. を使う)" % seg)
337
+ if not isinstance(cur, dict):
338
+ raise ExprFailure("TYPE_MISMATCH", "cannot access .%s on %s" % (seg, _type_name(cur)))
339
+ got = cur.get(seg, _MISSING)
340
+ if got is _MISSING:
341
+ raise ExprFailure("MISSING_PROP", "missing property .%s" % seg)
342
+ cur = got
343
+ return cur
344
+
345
+
346
+ def _sl_ref_opt(path, scope):
347
+ head = path[0]
348
+ if head not in scope:
349
+ raise ExprFailure("UNKNOWN_BINDING", "unknown binding: %s" % head)
350
+ cur = scope[head]
351
+ for seg in path[1:]:
352
+ if cur is None:
353
+ return None # ?. null propagation
354
+ if not isinstance(cur, dict):
355
+ raise ExprFailure("TYPE_MISMATCH", "cannot access .%s on %s" % (seg, _type_name(cur)))
356
+ got = cur.get(seg, _MISSING)
357
+ if got is _MISSING:
358
+ raise ExprFailure("MISSING_PROP", "missing property .%s" % seg)
359
+ cur = got
360
+ return cur
361
+
362
+
363
+ def _sl_concat(parts):
364
+ # n-ary (min 2). string-only (TYPE_MISMATCH otherwise) — matches expr_eval.py concat.
365
+ if len(parts) < 2:
366
+ raise ExprFailure("INVALID_NODE", "concat expects >= 2 args, got %d" % len(parts))
367
+ for p in parts:
368
+ if not isinstance(p, str):
369
+ raise ExprFailure("TYPE_MISMATCH", "concat: string のみ(got %s)" % _type_name(p))
370
+ return "".join(parts)
371
+
372
+
373
+ def _type_name(v):
374
+ # expr_eval.py _type_name: JS-flavored type names for parity of messages.
375
+ if v is None:
376
+ return "null"
377
+ if isinstance(v, bool):
378
+ return "boolean"
379
+ if isinstance(v, str):
380
+ return "string"
381
+ if isinstance(v, (int, float)):
382
+ return "number"
383
+ if isinstance(v, list):
384
+ return "array"
385
+ return "object"
386
+
387
+
388
+ def _op_index(ops, op_id):
389
+ for i, o in enumerate(ops):
390
+ if o["id"] == op_id:
391
+ return i
392
+ return -1
393
+
394
+
395
+ # ── straight-line component functions (no run_behavior tree-walk) ───────────────────
396
+ ${fns}
397
+
398
+
399
+ def bind(handlers):
400
+ """Inject handlers (boundary injection; catalog name -> implementation) and get one
401
+ callable per component. Each callable runs the straight-line function for that component
402
+ (plan via run_plan primitive + per-node native/primitive port eval + injected handler) —
403
+ NOT the run_behavior tree-walk. Observationally equivalent to the run_behavior path:
404
+ same values, same emitted op sequence, same Failure code/message."""
405
+
406
+ def _make(name):
407
+ def _call(input=None):
408
+ return _dispatch(name, handlers, dict(input or {}))
409
+
410
+ return _call
411
+
412
+ return {name: _make(name) for name in COMPONENT_NAMES}
413
+
414
+
415
+ def _dispatch(name, handlers, input):
416
+ ${dispatchArms}
417
+ raise BehaviorFailure("UNKNOWN_ENTRY", "component '%s' not found in this module (fail-closed)" % name)
418
+ `;
419
+ }
420
+ const dialect = {
421
+ emitExpr,
422
+ mapScopeVar: MAP_SCOPE,
423
+ emitComponent,
424
+ emitModule,
425
+ };
426
+ function emit(ctx) {
427
+ return emitStraightlineModule(ctx, dialect, SCOPE);
428
+ }
429
+ /**
430
+ * pythonStraightlineEmitter — 言語識別子 `"python-straightline"` の emitter plugin。
431
+ * 既存の `python`(リテラル焼き込み・endpoint 3-literal → run_behavior)と併存する additive な
432
+ * 第2モード(単純式を native 化し `evaluate` 解釈を消す脱解釈経路 — typed-codegen.md §4.1)。
433
+ */
434
+ export const pythonStraightlineEmitter = {
435
+ language: "python-straightline",
436
+ fileExtension: ".py",
437
+ defaultRuntimeImport: "behavior_contracts",
438
+ filenameHint: "behaviors.straightline.generated.py",
439
+ emit,
440
+ };
441
+ //# sourceMappingURL=emit-straightline-python.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit-straightline-python.js","sourceRoot":"","sources":["../../src/generator/emit-straightline-python.ts"],"names":[],"mappings":"AA6BA,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrE,OAAO,EACL,sBAAsB,GAIvB,MAAM,mBAAmB,CAAC;AAE3B,4FAA4F;AAC5F,MAAM,GAAG,GAAG,KAAK,CAAC;AAClB;;;;GAIG;AACH,MAAM,KAAK,GAAG,UAAU,CAAC;AACzB;;;;GAIG;AACH,MAAM,SAAS,GAAG,WAAW,CAAC;AAE9B,0DAA0D;AAC1D,SAAS,GAAG,CAAC,IAAa;IACxB,OAAO,qBAAqB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AAC3C,CAAC;AAKD,uDAAuD;AACvD,SAAS,OAAO,CAAC,GAAY;IAC3B,OAAQ,GAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1D,CAAC;AAED,6EAA6E;AAC7E,2FAA2F;AAC3F,8EAA8E;AAC9E,4DAA4D;AAC5D,MAAM,WAAW,GAA8B;IAC7C,qEAAqE;IACrE,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,YAAY,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG;IACpD,KAAK,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,cAAc,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG;IACxD,8BAA8B;IAC9B,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,QAAQ,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG;IAChD,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,QAAQ,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG;IAChD,8BAA8B;IAC9B,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,QAAQ,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG;IACpD,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,QAAQ,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG;IACpD,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,QAAQ,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG;IACpD,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,QAAQ,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG;IACpD,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,QAAQ,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG;IACpD,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,QAAQ,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG;IACpD,SAAS;IACT,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG;IAClD,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG;IAClD,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG;IAClD,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG;IAClD,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG;IAClD,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG;IAClD,4DAA4D;IAC5D,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,SAAS,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG;IACrD,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,QAAQ,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG;IACnD,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,SAAS,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG;IACrD,QAAQ,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,aAAa,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG;IAC9D,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,SAAS,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG;IACtD,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,SAAS,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG;CACtD,CAAC;AAEF,uDAAuD;AACvD,SAAS,OAAO,CAAC,GAAY;IAC3B,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC;AAClB,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAS,QAAQ,CAAC,IAAa,EAAE,QAAgB;IAC/C,mBAAmB;IACnB,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,MAAM,CAAC;IACjC,IAAI,OAAO,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;IAC9D,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/C,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,kCAAkC;IAClF,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACrD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAA+B,CAAC,CAAC;QAC1D,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;YACnB,MAAM,GAAG,GAAI,IAAgC,CAAC,EAAE,CAAC,CAAC;YAClD,8DAA8D;YAC9D,IAAI,EAAE,KAAK,KAAK;gBAAE,OAAO,WAAW,OAAO,CAAC,GAAG,CAAC,KAAK,QAAQ,GAAG,CAAC;YACjE,IAAI,EAAE,KAAK,QAAQ;gBAAE,OAAO,eAAe,OAAO,CAAC,GAAG,CAAC,KAAK,QAAQ,GAAG,CAAC;YACxE,IAAI,EAAE,KAAK,QAAQ,EAAE,CAAC;gBACpB,MAAM,KAAK,GAAI,GAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;gBACnE,OAAO,eAAe,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;YAC7C,CAAC;YACD,kEAAkE;YAClE,MAAM,EAAE,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;YAC3B,IAAI,EAAE;gBAAE,OAAO,EAAE,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IACD,0DAA0D;IAC1D,OAAO,GAAG,GAAG,cAAc,GAAG,CAAC,IAAI,CAAC,KAAK,QAAQ,GAAG,CAAC;AACvD,CAAC;AAED,0EAA0E;AAE1E,8DAA8D;AAC9D,SAAS,cAAc,CAAC,IAAmB;IACzC,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACrC,MAAM,KAAK,GAAG,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC9G,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,gBAAgB,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QACzF,IAAI,CAAC,CAAC,YAAY,KAAK,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,mBAAmB,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;QAClG,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAChF,OAAO,YAAY,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IAC1C,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;AACxC,CAAC;AAED,wDAAwD;AACxD,SAAS,YAAY,CAAC,EAA4C;IAChE,IAAI,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACvC,OAAO,MAAM,EAAE,CAAC,KAAK;SAClB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,mBAAmB,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC;SACnE,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC;AACjC,CAAC;AAED;;;;;GAKG;AACH,SAAS,UAAU,CAAC,EAA4C;IAC9D,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACrC,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACpC,MAAM,UAAU,GACd,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,wBAAwB,EAAE,CAAC,KAAK,6CAA6C,CAAC;IAC9G,MAAM,QAAQ,GACZ,EAAE,CAAC,IAAI,KAAK,SAAS;QACnB,CAAC,CAAC,yCAAyC;QAC3C,CAAC,CAAC;;;;;;;qFAO6E,EAAE,CAAC,EAAE;iDACzC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC;;;;sCAIlC,CAAC;IACrC,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO;QACrB,CAAC,CAAC;;;0CAGoC,KAAK,SAAS,UAAU;gCAClC,YAAY,CAAC,EAAE,CAAC;;;;;mCAKb,IAAI;;6EAEsC,EAAE,CAAC,SAAS;4DAC7B,MAAM,kBAAkB,IAAI;;;;;+EAKT,EAAE,CAAC,EAAE;;EAElF,QAAQ,EAAE;QACR,CAAC,CAAC;+BACyB,IAAI;;yEAEsC,EAAE,CAAC,SAAS;;;0CAG3C,KAAK,SAAS,UAAU;0BACxC,YAAY,CAAC,EAAE,CAAC;gDACM,MAAM,kBAAkB,IAAI;;;;;EAK1E,QAAQ,EAAE,CAAC;IACX,OAAO,mBAAmB,EAAE,CAAC,KAAK;sBACd,EAAE,CAAC,IAAI;;oEAEuC,EAAE,CAAC,EAAE;;EAEvE,IAAI,EAAE,CAAC;AACT,CAAC;AAED,wDAAwD;AACxD,SAAS,WAAW,CAAC,EAAkB;IACrC,IAAI,EAAE,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACvB,oDAAoD;QACpD,OAAO,mBAAmB,EAAE,CAAC,KAAK,gCAAgC,EAAE,CAAC,IAAI,GAAG,CAAC;IAC/E,CAAC;IACD,IAAI,EAAE,CAAC,IAAI,KAAK,KAAK;QAAE,OAAO,UAAU,CAAC,EAAE,CAAC,CAAC;IAC7C,oEAAoE;IACpE,MAAM,SAAS,GACb,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;QACnB,CAAC,CAAC,wBAAwB;QAC1B,CAAC,CAAC,0BAA0B,EAAE,CAAC,KAAK;aAC/B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,mBAAmB,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC;aACnE,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC;IACrC,OAAO,mBAAmB,EAAE,CAAC,KAAK;EAClC,SAAS;+BACoB,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC;;yEAEc,EAAE,CAAC,SAAS;yCAC5C,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,kBAAkB,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC;AACjH,CAAC;AAED;;;;GAIG;AACH,SAAS,eAAe,CAAC,IAAmB;IAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClD,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAChG,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACtD,MAAM,aAAa,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,KAAK,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC9G,MAAM,MAAM,GAAG,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC;IAClF,OAAO,WAAW,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;YAC3B,cAAc,CAAC,IAAI,CAAC;;;;;;uBAMT,MAAM;;;;EAI3B,IAAI;;;;;;;;;YASM,GAAG,aAAa,WAAW;;;uCAGA,GAAG;aAC7B,MAAM,EAAE,CAAC;AACtB,CAAC;AAED,gEAAgE;AAChE,SAAS,QAAQ,CAAC,IAAY;IAC5B,OAAO,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,aAAa,CAAC,IAAmB,EAAE,IAAiB;IAC3D,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC;AAED,SAAS,UAAU,CAAC,KAAsB,EAAE,GAAgB;IAC1D,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,GAAG,GAAG,CAAC;IACzE,MAAM,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtE,MAAM,UAAU,GAAG,cAAc,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC;IAC9E,MAAM,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IAC/C,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACnE,MAAM,YAAY,GAAG,KAAK;SACvB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,kBAAkB,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,yBAAyB,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC;SACtH,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,OAAO;;;;;;;;;;;;;mBAaU,WAAW;OACvB,aAAa,mGAAmG,GAAG;;;wCAGlF,YAAY,CAAC,QAAQ,mBAAmB,YAAY,CAAC,UAAU,aAAa,YAAY,CAAC,IAAI;;;mBAGlH,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC;;;oBAG1B,UAAU;;;OAGvB,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmGd,GAAG;;;;;;;;;;;;;;;;;;;;EAoBH,YAAY;;CAEb,CAAC;AACF,CAAC;AAED,MAAM,OAAO,GAAwB;IACnC,QAAQ;IACR,WAAW,EAAE,SAAS;IACtB,aAAa;IACb,UAAU;CACX,CAAC;AAEF,SAAS,IAAI,CAAC,GAAgB;IAC5B,OAAO,sBAAsB,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;AACrD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAkB;IACtD,QAAQ,EAAE,qBAAqB;IAC/B,aAAa,EAAE,KAAK;IACpB,oBAAoB,EAAE,oBAAoB;IAC1C,YAAY,EAAE,qCAAqC;IACnD,IAAI;CACL,CAAC"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * emit-straightline-rust.ts — Rust 直線 emitter(bc#39 / Layer A2, 脱解釈が目的)。
3
+ *
4
+ * typed-codegen.md §4.1 の rust 具体化。language-neutral な {@link StraightlineDialect} を実装し、
5
+ * component ごとに「plan を `run_plan` primitive で直呼び・各ノードの port 評価と handler 呼びを
6
+ * 直線展開した」ネイティブ rust 関数を emit する。生成コードは A0(#36)の rust primitive 面
7
+ * +`run_plan`+`unproduced_value` を直呼びし、**`run_behavior` の tree-walk(node_kind
8
+ * ディスパッチ / eval_ports / 汎用 exec)を経由しない**。
9
+ *
10
+ * ★ この emitter の主眼(TS oracle との違い — AC#2): **単純式のネイティブ化。**
11
+ * rust は Phase B の脱解釈利得が最大の言語なので、単純 Port は式ツリー解釈(`evaluate`)を
12
+ * 消してネイティブコードに落とす:
13
+ * - `concat` → `primitives::concat_native(&[<part0>?, <part1>?, …])`。各 part は再帰的に
14
+ * native emit した `Value`(`?` 展開)。`concat_native` は `String::push_str` で
15
+ * 連結し `evaluate` を呼ばない(純 concat の式ツリー解釈が消える)。
16
+ * - `ref` / `refOpt`(**静的 string path** のとき)→ `primitives::ref_native(&["a","b"], scope)` /
17
+ * `ref_opt_native`。scope→field を native に歩き `evaluate`/`json!` を呼ばない。
18
+ * これらの native helper は意味論を [`evaluate`] の該当アームから写し取っており(同じ
19
+ * ExprFailureCode)、tests/primitives.rs で差分 pin 済み(別実装ではなく写像)。
20
+ *
21
+ * ★ ネイティブ化しない演算子(fail-closed 意味論の SSoT を一本化): overflow/短絡系
22
+ * (`add`/`sub`/`mul`/`div`/`mod`/`neg`/`and`/`or`/`not`/`cond`/`coalesce`/比較/`obj`/`arr`/
23
+ * リテラル)は A0 の evaluate 委譲 primitive(`primitives::add` 等)を直呼びする。短絡の
24
+ * 被演算子は A0 契約どおり**未評価 IR リテラル**(`json!`)で渡す(primitive 内 `evaluate` が
25
+ * 短絡を保存する)。単純式まで evaluate 委譲 primitive に丸投げしない(=A1 との差 — AC#2)。
26
+ *
27
+ * go/rust/python/php は A2 で同じ枠(StraightlineDialect)に乗る。conformance で
28
+ * 「直線生成 ≡ run_behavior ≡ golden」を実 rust toolchain で pin する(bc#39 AC#3)。
29
+ */
30
+ import type { EmitterPlugin } from "./core.js";
31
+ import { type ComponentPlan, type StraightlineDialect } from "./straightline.js";
32
+ /** string を rust 文字列リテラルへ(path セグメント用。JSON エスケープで安全側)。 */
33
+ declare function rustStrLit(s: string): string;
34
+ /**
35
+ * emitExpr — Expression IR ノードを rust の「scope を受けて `R`(= Result<Value, ExprFailure>)を
36
+ * 返す」式へ落とす。**単純式はネイティブ化**(式ツリー解釈 `evaluate` を消す — bc#39 AC#2 の
37
+ * 脱解釈の実体)、overflow/短絡系のみ A0 primitive SSoT を直呼びする:
38
+ *
39
+ * - `concat` → `primitives::concat_native(&[<part>?, …])`(native 連結。`evaluate` 非経由)
40
+ * - `ref`/`refOpt`(静的 path)→ `primitives::ref_native(&["a","b"], scope)` 等(native scope walk)
41
+ * - それ以外の演算子 → 対応する A0 evaluate 委譲 primitive(被演算子は未評価 IR リテラル)
42
+ * - スカラ/ null / bool リテラルや非静的 path・未知形 → `primitives::eval_expr(&json!(..), scope)`
43
+ * (同一 SSoT。型判定を生成コードに残さない)
44
+ *
45
+ * Portability Guard を通過済み(生成時検査)なので未知 operator はここに来ない。
46
+ * 返り値は必ず `R` 型の rust 式(呼び側が `?` で Value へ展開する)。
47
+ */
48
+ declare function emitExpr(node: unknown, scopeVar: string): string;
49
+ /** component 名 → rust 関数名の一部(決定的・一意は DUPLICATE_COMPONENT で保証)。 */
50
+ declare function sanitize(name: string): string;
51
+ /** ops リテラル(run_plan に渡す OpSpec の Vec を綴じる rust コード)。 */
52
+ declare function emitOpsLiteral(plan: ComponentPlan): string;
53
+ /** plan(ExecutionPlanSpec)リテラルを rust の `Some(&ExecutionPlanSpec{..})` へ(fully-qualified)。 */
54
+ declare function emitPlanLiteral(plan: unknown): string;
55
+ /**
56
+ * rust-typed(bc#48)が struct-native exec を綴じるために再利用する内部 emit ヘルパ。straight-line の
57
+ * plan/handler-dispatch SSoT(run_plan primitive + handlers.exec_ctx + native/primitive port eval)を
58
+ * そのまま使い、「結果を Value scope でなく struct scope に持つ」差分だけを typed 側で足すための seam。
59
+ * primitive namespace(P)と ops/plan リテラル・式 emit・sanitize を共有する(意味論の二重実装を避ける)。
60
+ * go の {@link goStraightlineInternals} と同型(seam が language-neutral であることの担保)。
61
+ */
62
+ export declare const rustStraightlineInternals: {
63
+ P: string;
64
+ SCOPE: string;
65
+ emitExpr: typeof emitExpr;
66
+ emitOpsLiteral: typeof emitOpsLiteral;
67
+ emitPlanLiteral: typeof emitPlanLiteral;
68
+ rustStrLit: typeof rustStrLit;
69
+ sanitize: typeof sanitize;
70
+ dialect: StraightlineDialect;
71
+ };
72
+ /**
73
+ * rustStraightlineEmitter — 言語識別子 `"rust-straightline"` の emitter plugin。既存の `rust`
74
+ * (リテラル焼き込み・endpoint 3・run_behavior 丸投げ)と併存する additive な第2モード。
75
+ */
76
+ export declare const rustStraightlineEmitter: EmitterPlugin;
77
+ export {};
78
+ //# sourceMappingURL=emit-straightline-rust.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit-straightline-rust.d.ts","sourceRoot":"","sources":["../../src/generator/emit-straightline-rust.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,KAAK,EAAe,aAAa,EAAE,MAAM,WAAW,CAAC;AAE5D,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,mBAAmB,EAEzB,MAAM,mBAAmB,CAAC;AAgC3B,0DAA0D;AAC1D,iBAAS,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAErC;AAED;;;;;;;;;;;;;GAaG;AACH,iBAAS,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CA4BzD;AA0CD,kEAAkE;AAClE,iBAAS,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtC;AAED,yDAAyD;AACzD,iBAAS,cAAc,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CAkBnD;AA+SD,6FAA6F;AAC7F,iBAAS,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAK9C;AAyJD;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;;CASrC,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,uBAAuB,EAAE,aAMrC,CAAC"}