behavior-contracts 0.2.5 → 0.3.0
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.
- package/dist/expr-eval.d.ts +28 -0
- package/dist/expr-eval.d.ts.map +1 -1
- package/dist/expr-eval.js +150 -90
- package/dist/expr-eval.js.map +1 -1
- package/dist/generator/emit-raw-abi-go.d.ts +45 -0
- package/dist/generator/emit-raw-abi-go.d.ts.map +1 -0
- package/dist/generator/emit-raw-abi-go.js +345 -0
- package/dist/generator/emit-raw-abi-go.js.map +1 -0
- package/dist/generator/emit-raw-abi-rust.d.ts +45 -0
- package/dist/generator/emit-raw-abi-rust.d.ts.map +1 -0
- package/dist/generator/emit-raw-abi-rust.js +380 -0
- package/dist/generator/emit-raw-abi-rust.js.map +1 -0
- package/dist/generator/emit-straightline-go.d.ts.map +1 -1
- package/dist/generator/emit-straightline-go.js +63 -31
- package/dist/generator/emit-straightline-go.js.map +1 -1
- package/dist/generator/emit-straightline-php.d.ts.map +1 -1
- package/dist/generator/emit-straightline-php.js +13 -4
- package/dist/generator/emit-straightline-php.js.map +1 -1
- package/dist/generator/emit-straightline-python.d.ts.map +1 -1
- package/dist/generator/emit-straightline-python.js +14 -4
- package/dist/generator/emit-straightline-python.js.map +1 -1
- package/dist/generator/emit-straightline-rust.d.ts.map +1 -1
- package/dist/generator/emit-straightline-rust.js +111 -43
- package/dist/generator/emit-straightline-rust.js.map +1 -1
- package/dist/generator/emit-straightline-typed-go.d.ts +95 -2
- package/dist/generator/emit-straightline-typed-go.d.ts.map +1 -1
- package/dist/generator/emit-straightline-typed-go.js +31 -0
- package/dist/generator/emit-straightline-typed-go.js.map +1 -1
- package/dist/generator/emit-straightline-typed-rust.d.ts +98 -2
- package/dist/generator/emit-straightline-typed-rust.d.ts.map +1 -1
- package/dist/generator/emit-straightline-typed-rust.js +30 -0
- package/dist/generator/emit-straightline-typed-rust.js.map +1 -1
- package/dist/generator/emit-straightline-typescript.d.ts.map +1 -1
- package/dist/generator/emit-straightline-typescript.js +81 -45
- package/dist/generator/emit-straightline-typescript.js.map +1 -1
- package/dist/generator/index.d.ts +4 -2
- package/dist/generator/index.d.ts.map +1 -1
- package/dist/generator/index.js +11 -2
- package/dist/generator/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/primitives.d.ts +53 -62
- package/dist/primitives.d.ts.map +1 -1
- package/dist/primitives.js +85 -91
- package/dist/primitives.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
import { GeneratorFailure } from "./core.js";
|
|
2
|
+
import { buildTypePlan, deriveTypeRef } from "./typed.js";
|
|
3
|
+
import { buildComponentPlan } from "./straightline.js";
|
|
4
|
+
import { rustTypedInternals } from "./emit-straightline-typed-rust.js";
|
|
5
|
+
const PORT_SCOPE = "port_scope()";
|
|
6
|
+
const { sanitize, rustFieldName, rustStrLit, renderTypeRef, rustScalar, typedCell, isTypedComponent, hasAnyTypeAnnotation, collectTypedNodes, emitTypeDecls, emitDefaults, emitSerializers, emitMarshallers, emitMarshalHelpers, serializeTyped, emitTypedValue, indentBlock, emitOpsLiteral, emitPlanLiteral, rustStraightlineEmitter, setRustForceRunPlanImports, } = rustTypedInternals;
|
|
7
|
+
// ── RAW marshallers (the de-box): read a RawValue field-by-field into a concrete struct ──
|
|
8
|
+
function emitRawMarshallers(plan) {
|
|
9
|
+
if (plan.decls.length === 0)
|
|
10
|
+
return "";
|
|
11
|
+
return plan.decls.map((d) => emitOneRawMarshaller(d, plan)).join("\n\n");
|
|
12
|
+
}
|
|
13
|
+
function emitOneRawMarshaller(d, plan) {
|
|
14
|
+
const lines = [];
|
|
15
|
+
lines.push(`#[allow(dead_code)]`);
|
|
16
|
+
lines.push(`fn marshal_raw_${d.name}(raw: &RawValue) -> Result<${d.name}, BehaviorError> {`);
|
|
17
|
+
// The row seam: a RawRow (native accessor), NOT a Value::Obj. This IS the de-box.
|
|
18
|
+
lines.push(` let row = match raw {`);
|
|
19
|
+
lines.push(` RawValue::Row(r) => r,`);
|
|
20
|
+
lines.push(` other => return Err(raw_type_mismatch(${rustStrLit("obj")}, other.type_name())),`);
|
|
21
|
+
lines.push(` };`);
|
|
22
|
+
const fieldInits = [];
|
|
23
|
+
for (const f of d.fields) {
|
|
24
|
+
const fieldVar = `field_${rustFieldName(f.name).replace(/^r#/, "")}`;
|
|
25
|
+
const keyLit = rustStrLit(f.name);
|
|
26
|
+
lines.push(` let ${fieldVar} = {`);
|
|
27
|
+
lines.push(` let fv = match row.field(${keyLit}) {`);
|
|
28
|
+
lines.push(` Some(v) => v,`);
|
|
29
|
+
lines.push(` None => return Err(raw_missing_prop(${rustStrLit(d.name)}, ${keyLit})),`);
|
|
30
|
+
lines.push(` };`);
|
|
31
|
+
lines.push(indentBlock(emitRawFieldMaterialize("fv", f.type, plan), 2));
|
|
32
|
+
lines.push(` };`);
|
|
33
|
+
fieldInits.push(` ${rustFieldName(f.name)}: ${fieldVar},`);
|
|
34
|
+
}
|
|
35
|
+
lines.push(` Ok(${d.name} {`);
|
|
36
|
+
lines.push(...fieldInits);
|
|
37
|
+
lines.push(` })`);
|
|
38
|
+
lines.push(`}`);
|
|
39
|
+
return lines.join("\n");
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* emitRawFieldMaterialize — materialize `src` (a `&RawValue` expr) into a concrete typed value
|
|
43
|
+
* per `ref` (a value-returning block). scalar -> RawValue match, named -> marshal_raw_T*, arr
|
|
44
|
+
* -> RawValue::Arr loop, opt -> RawValue::Null branch. No Value::Obj/Value ever built.
|
|
45
|
+
*/
|
|
46
|
+
function emitRawFieldMaterialize(src, ref, plan) {
|
|
47
|
+
switch (ref.kind) {
|
|
48
|
+
case "scalar": {
|
|
49
|
+
if (ref.scalar === "null") {
|
|
50
|
+
// null-only field stays a Value::Null (the struct field type is Value for null-only).
|
|
51
|
+
return `Value::Null`;
|
|
52
|
+
}
|
|
53
|
+
const variant = ref.scalar === "int" ? "Int" : ref.scalar === "float" ? "Float" : ref.scalar === "bool" ? "Bool" : "Str";
|
|
54
|
+
const bind = ref.scalar === "string" ? "s.clone()" : "*s";
|
|
55
|
+
return [
|
|
56
|
+
`match ${src} {`,
|
|
57
|
+
` RawValue::${variant}(s) => ${bind},`,
|
|
58
|
+
` other => return Err(raw_type_mismatch(${rustStrLit(ref.scalar)}, other.type_name())),`,
|
|
59
|
+
`}`,
|
|
60
|
+
].join("\n");
|
|
61
|
+
}
|
|
62
|
+
case "named": {
|
|
63
|
+
return `marshal_raw_${ref.name}(${src})?`;
|
|
64
|
+
}
|
|
65
|
+
case "arr": {
|
|
66
|
+
const elemTy = renderTypeRef(ref.elem);
|
|
67
|
+
const inner = emitRawFieldMaterialize("elem_raw", ref.elem, plan);
|
|
68
|
+
return [
|
|
69
|
+
`match ${src} {`,
|
|
70
|
+
` RawValue::Arr(items) => {`,
|
|
71
|
+
` let mut out: Vec<${elemTy}> = Vec::with_capacity(items.len());`,
|
|
72
|
+
` for elem_raw in items.iter() {`,
|
|
73
|
+
` let elem_out = ${indentBlock(inner, 3).trimStart()};`,
|
|
74
|
+
` out.push(elem_out);`,
|
|
75
|
+
` }`,
|
|
76
|
+
` out`,
|
|
77
|
+
` }`,
|
|
78
|
+
` other => return Err(raw_type_mismatch(${rustStrLit("arr")}, other.type_name())),`,
|
|
79
|
+
`}`,
|
|
80
|
+
].join("\n");
|
|
81
|
+
}
|
|
82
|
+
case "opt": {
|
|
83
|
+
const inner = emitRawFieldMaterialize("inner_raw", ref.inner, plan);
|
|
84
|
+
return [
|
|
85
|
+
`match ${src} {`,
|
|
86
|
+
` RawValue::Null => None,`,
|
|
87
|
+
` inner_raw => {`,
|
|
88
|
+
` let inner_out = ${indentBlock(inner, 2).trimStart()};`,
|
|
89
|
+
` Some(inner_out)`,
|
|
90
|
+
` }`,
|
|
91
|
+
`}`,
|
|
92
|
+
].join("\n");
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/** scalar/arr/opt node RAW materializer name. */
|
|
97
|
+
function rawNodeMaterializerName(nodeId) {
|
|
98
|
+
return `materialize_raw_node_${typedCell(nodeId)}`;
|
|
99
|
+
}
|
|
100
|
+
function emitRawNodeMaterializers(comp, typedNodes, plan) {
|
|
101
|
+
const parts = [];
|
|
102
|
+
for (const [id, ref] of typedNodes.entries()) {
|
|
103
|
+
if (ref.kind === "named")
|
|
104
|
+
continue;
|
|
105
|
+
const ty = renderTypeRef(ref);
|
|
106
|
+
const body = emitRawFieldMaterialize("raw", ref, plan);
|
|
107
|
+
parts.push(`#[allow(dead_code)]\nfn ${rawNodeMaterializerName(id)}(raw: &RawValue) -> Result<${ty}, BehaviorError> {\n Ok(${indentBlock(body, 1).trimStart()})\n}`);
|
|
108
|
+
}
|
|
109
|
+
return parts.join("\n\n");
|
|
110
|
+
}
|
|
111
|
+
// ── RAW runner ────────────────────────────────────────────────────────────────────────
|
|
112
|
+
function assertRawSupported(comp) {
|
|
113
|
+
for (const n of comp.body) {
|
|
114
|
+
if ("map" in n || "cond" in n) {
|
|
115
|
+
const ot = n.outType;
|
|
116
|
+
if (ot !== undefined) {
|
|
117
|
+
throw new GeneratorFailure("UNSUPPORTED_NODE_STRAIGHTLINE", `rust raw ABI (bc#76): component '${comp.name}' node '${n.id}' is a typed ${"map" in n ? "map" : "cond"} node. The raw handler ABI de-box currently covers the componentRef read-handler shape (graphddb's row hydrator). Regenerate this component on the boxed typed path (rust-typed) — do NOT emit a raw module that re-boxes map/cond results.`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function emitStoreRawNode(nodeId, srcExpr, ref, indent, producedCell) {
|
|
123
|
+
const pad = " ".repeat(indent);
|
|
124
|
+
if (ref === undefined)
|
|
125
|
+
return `${pad}let _ = ${srcExpr};`;
|
|
126
|
+
const call = ref.kind === "named" ? `marshal_raw_${ref.name}(${srcExpr})` : `${rawNodeMaterializerName(nodeId)}(${srcExpr})`;
|
|
127
|
+
const prod = ` ${producedCell(nodeId)}.set(true);`;
|
|
128
|
+
return `${pad}match ${call} {
|
|
129
|
+
${pad} Ok(tv) => { *${typedCell(nodeId)}.borrow_mut() = tv;${prod} }
|
|
130
|
+
${pad} Err(e) => {
|
|
131
|
+
${pad} *err_cell = Some(e);
|
|
132
|
+
${pad} return ExecOutcome::Error("aborted".to_string());
|
|
133
|
+
${pad} }
|
|
134
|
+
${pad}}`;
|
|
135
|
+
}
|
|
136
|
+
function producedCellName(id) {
|
|
137
|
+
return `produced_${typedCell(id)}`;
|
|
138
|
+
}
|
|
139
|
+
function emitRawExecArm(op, typedNodes, plan) {
|
|
140
|
+
if (op.kind !== "componentRef") {
|
|
141
|
+
throw new GeneratorFailure("UNSUPPORTED_NODE_STRAIGHTLINE", `rust raw ABI (bc#76): node '${op.id}' kind '${op.kind}' is not supported on the raw path (componentRef only). Regenerate on rust-typed.`);
|
|
142
|
+
}
|
|
143
|
+
const portRows = op.ports.length === 0
|
|
144
|
+
? " Ok(Vec::new())"
|
|
145
|
+
: ` Ok(vec![\n${op.ports
|
|
146
|
+
.map((pt) => ` (${rustStrLit(pt.name)}.to_string(), (${pt.expr})?),`)
|
|
147
|
+
.join("\n")}\n ])`;
|
|
148
|
+
const ref = typedNodes.get(op.id);
|
|
149
|
+
const materialize = emitStoreRawNode(op.id, "v", ref, 4, producedCellName);
|
|
150
|
+
return ` if i == ${op.index} {
|
|
151
|
+
let eval_ports = || -> Result<Vec<(String, Value)>, behavior_contracts::ExprFailure> {
|
|
152
|
+
${portRows}
|
|
153
|
+
};
|
|
154
|
+
let ports = match eval_ports() {
|
|
155
|
+
Ok(p) => p,
|
|
156
|
+
Err(e) => {
|
|
157
|
+
*err_cell = Some(e.into());
|
|
158
|
+
return ExecOutcome::Error("aborted".to_string());
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
let outcome = match handlers.exec_raw_ctx(${rustStrLit(op.id)}, ${rustStrLit(op.component ?? "")}, &ports, None) {
|
|
162
|
+
Some(o) => o,
|
|
163
|
+
None => {
|
|
164
|
+
*err_cell = Some(BehaviorError::new("UNKNOWN_COMPONENT", format!("component '{}' has no handler (fail-closed)", ${rustStrLit(op.component ?? "")})));
|
|
165
|
+
return ExecOutcome::Error("aborted".to_string());
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
let v = match &outcome {
|
|
169
|
+
RawOutcome::Ok(v) => v,
|
|
170
|
+
RawOutcome::Error(e) => {
|
|
171
|
+
*err_cell = Some(BehaviorError::new("OP_FAILED", e.clone()));
|
|
172
|
+
return ExecOutcome::Error("aborted".to_string());
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
${materialize}
|
|
176
|
+
return ExecOutcome::Ok(Value::Null);
|
|
177
|
+
}`;
|
|
178
|
+
}
|
|
179
|
+
function emitRawRunner(comp, plan) {
|
|
180
|
+
assertRawSupported(comp);
|
|
181
|
+
const fn = sanitize(comp.name);
|
|
182
|
+
const plans = buildComponentPlan(comp, rustTypedInternals.rustStraightlineInternals.dialect, PORT_SCOPE);
|
|
183
|
+
const typedNodes = collectTypedNodes(comp, plan);
|
|
184
|
+
const cellDecls = [...typedNodes.entries()]
|
|
185
|
+
.map(([id, ref]) => ` let ${typedCell(id)}: RefCell<${renderTypeRef(ref)}> = RefCell::new(Default::default());`)
|
|
186
|
+
.join("\n");
|
|
187
|
+
const producedDecls = [...typedNodes.keys()]
|
|
188
|
+
.map((id) => ` let ${producedCellName(id)} = std::cell::Cell::new(false);`)
|
|
189
|
+
.join("\n");
|
|
190
|
+
const portScopeNodeInjections = [...typedNodes.entries()]
|
|
191
|
+
.map(([id, ref]) => {
|
|
192
|
+
const isBareCopyScalar = ref.kind === "scalar" && (ref.scalar === "int" || ref.scalar === "float" || ref.scalar === "bool");
|
|
193
|
+
const owned = isBareCopyScalar ? `*${typedCell(id)}.borrow()` : `${typedCell(id)}.borrow().clone()`;
|
|
194
|
+
const ser = serializeTyped(owned, ref, plan);
|
|
195
|
+
return ` if ${producedCellName(id)}.get() {\n s.push((${rustStrLit(id)}.to_string(), ${ser}));\n }`;
|
|
196
|
+
})
|
|
197
|
+
.join("\n");
|
|
198
|
+
const arms = plans.ops.map((op) => emitRawExecArm(op, typedNodes, plan)).join("\n");
|
|
199
|
+
const planExpr = comp.plan ? emitPlanLiteral(comp.plan) : "None";
|
|
200
|
+
const outRef = comp.outputType !== undefined ? deriveTypeRef(comp.outputType, plan) : undefined;
|
|
201
|
+
const out = emitTypedValue(comp.output, outRef, typedNodes, plan);
|
|
202
|
+
const outRefFinal = out.ref ?? outRef;
|
|
203
|
+
const serialized = outRefFinal ? serializeTyped("__typed_out", outRefFinal, plan) : "__typed_out";
|
|
204
|
+
const opsLiteral = emitOpsLiteral(plans);
|
|
205
|
+
return `// run_typed_raw_${fn} — RAW-ABI STRUCT-NATIVE exec (bc#76 de-box): the run_plan primitive drives the
|
|
206
|
+
// plan (plan SSoT); per-node arms call the RAW handler (exec_raw_ctx -> RawValue, NOT a boxed Value) and
|
|
207
|
+
// materialize the node's outType struct DIRECTLY from the RawValue via marshal_raw_T*. The dynamic
|
|
208
|
+
// Value/Value::Obj tree is NEVER built on the row data plane — that is the de-box the boxed typed path
|
|
209
|
+
// only LAYERED. Output is assembled as a struct and serialized to a Value ONLY at the final return
|
|
210
|
+
// boundary (the equivalence pin), so the OBSERVED result equals run_behavior. Called by bind_raw.
|
|
211
|
+
fn run_typed_raw_${fn}<H: RawComponentExec>(
|
|
212
|
+
handlers: &mut H,
|
|
213
|
+
input: &[(String, Value)],
|
|
214
|
+
) -> Result<Value, BehaviorError> {
|
|
215
|
+
let ops: Vec<OpSpec> = ${opsLiteral};
|
|
216
|
+
${cellDecls ? cellDecls + "\n" : ""}${producedDecls ? producedDecls + "\n" : ""} let port_scope = || -> Vec<(String, Value)> {
|
|
217
|
+
let mut s = input.to_vec();
|
|
218
|
+
${portScopeNodeInjections ? portScopeNodeInjections + "\n" : ""} s
|
|
219
|
+
};
|
|
220
|
+
let _ = &port_scope;
|
|
221
|
+
let mut pending_err: Option<BehaviorError> = None;
|
|
222
|
+
|
|
223
|
+
let run = {
|
|
224
|
+
let err_cell = &mut pending_err;
|
|
225
|
+
let exec = |op: &OpSpec, _bound: Option<&Value>| -> ExecOutcome {
|
|
226
|
+
if err_cell.is_some() {
|
|
227
|
+
return ExecOutcome::Error("aborted".to_string());
|
|
228
|
+
}
|
|
229
|
+
let i = match ops.iter().position(|o| o.id == op.id) {
|
|
230
|
+
Some(i) => i,
|
|
231
|
+
None => {
|
|
232
|
+
*err_cell = Some(no_typed_exec_arm(&op.id));
|
|
233
|
+
return ExecOutcome::Error("aborted".to_string());
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
let _ = i;
|
|
237
|
+
${arms}
|
|
238
|
+
*err_cell = Some(BehaviorError::new("UNKNOWN_NODE_KIND", format!("op '{}' has no generated raw exec arm (fail-closed)", op.id)));
|
|
239
|
+
ExecOutcome::Error("aborted".to_string())
|
|
240
|
+
};
|
|
241
|
+
run_plan(${planExpr}, &ops, exec)
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
if let Some(e) = pending_err {
|
|
245
|
+
return Err(e);
|
|
246
|
+
}
|
|
247
|
+
let _run = run?;
|
|
248
|
+
|
|
249
|
+
let __typed_out = ${out.expr};
|
|
250
|
+
Ok(${serialized})
|
|
251
|
+
}`;
|
|
252
|
+
}
|
|
253
|
+
// ── bind_raw dispatch surface ───────────────────────────────────────────────────────
|
|
254
|
+
function emitBindRaw(ctx) {
|
|
255
|
+
const typedComps = ctx.ir.components.filter((c) => isTypedComponent(c));
|
|
256
|
+
const names = typedComps.map((c) => rustStrLit(c.name));
|
|
257
|
+
const arms = typedComps
|
|
258
|
+
.map((c) => ` ${rustStrLit(c.name)} => run_typed_raw_${sanitize(c.name)}(&mut self.handlers, input),`)
|
|
259
|
+
.join("\n");
|
|
260
|
+
return `// COMPONENT_NAMES_RAW — typed components exposed on the RAW-ABI de-boxed path.
|
|
261
|
+
pub const COMPONENT_NAMES_RAW: [&str; ${names.length}] = [${names.join(", ")}];
|
|
262
|
+
|
|
263
|
+
// bind_raw / BoundRaw — the RAW-ABI dispatch surface (bc#76): binds a RawComponentExec (native-backed
|
|
264
|
+
// handler results) to the de-boxed struct-native runners. Mirrors bind/Bound::call but drives the raw
|
|
265
|
+
// runner. Untyped components stay on the boxed bind.
|
|
266
|
+
pub fn bind_raw<H: RawComponentExec>(handlers: H) -> BoundRaw<H> {
|
|
267
|
+
BoundRaw { handlers }
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
pub struct BoundRaw<H: RawComponentExec> {
|
|
271
|
+
handlers: H,
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
impl<H: RawComponentExec> BoundRaw<H> {
|
|
275
|
+
pub fn call(&mut self, name: &str, input: &[(String, Value)]) -> Result<Value, BehaviorError> {
|
|
276
|
+
match name {
|
|
277
|
+
${arms}
|
|
278
|
+
other => Err(BehaviorError::new("UNKNOWN_ENTRY", format!("component '{other}' is not a raw-typed entry (fail-closed)"))),
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}`;
|
|
282
|
+
}
|
|
283
|
+
// ── module assembly ──────────────────────────────────────────────────────────────────
|
|
284
|
+
function emit(ctx) {
|
|
285
|
+
const typed = hasAnyTypeAnnotation(ctx);
|
|
286
|
+
if (!typed) {
|
|
287
|
+
throw new GeneratorFailure("UNSUPPORTED_NODE_STRAIGHTLINE", "rust raw ABI (bc#76): the IR has no outType/outputType annotations — there is nothing to de-box. Use rust-straightline for untyped IR.");
|
|
288
|
+
}
|
|
289
|
+
const plan = buildTypePlan(ctx.ir);
|
|
290
|
+
const decls = emitTypeDecls(plan);
|
|
291
|
+
const defaults = emitDefaults(plan);
|
|
292
|
+
const rawMarshallers = emitRawMarshallers(plan);
|
|
293
|
+
const serializers = emitSerializers(plan);
|
|
294
|
+
// Boxed marshallers + helpers exist ONLY for the Value-space output-assembly fallback
|
|
295
|
+
// (materializeExpr on an output that directly refs an input param of a named type — a Value
|
|
296
|
+
// boundary read, NOT the row data plane). The ROW data plane is de-boxed via marshal_raw_* in
|
|
297
|
+
// the runner (asserted by the anti-sham gate).
|
|
298
|
+
const boxedMarshallers = emitMarshallers(plan);
|
|
299
|
+
const marshalHelpers = emitMarshalHelpers();
|
|
300
|
+
const nodeMaterializers = [];
|
|
301
|
+
for (const comp of ctx.ir.components) {
|
|
302
|
+
if (!isTypedComponent(comp))
|
|
303
|
+
continue;
|
|
304
|
+
const typedNodes = new Map();
|
|
305
|
+
for (const n of comp.body) {
|
|
306
|
+
if ("map" in n)
|
|
307
|
+
continue;
|
|
308
|
+
const ot = n.outType;
|
|
309
|
+
if (ot !== undefined)
|
|
310
|
+
typedNodes.set(n.id, deriveTypeRef(ot, plan));
|
|
311
|
+
}
|
|
312
|
+
const nm = emitRawNodeMaterializers(comp, typedNodes, plan);
|
|
313
|
+
if (nm)
|
|
314
|
+
nodeMaterializers.push(nm);
|
|
315
|
+
}
|
|
316
|
+
const runners = ctx.ir.components
|
|
317
|
+
.filter((c) => isTypedComponent(c))
|
|
318
|
+
.map((c) => emitRawRunner(c, plan))
|
|
319
|
+
.join("\n\n");
|
|
320
|
+
const bindRaw = emitBindRaw(ctx);
|
|
321
|
+
const banner = `// ── RAW handler ABI layer (bc#76 — Rust de-box: struct materialized DIRECTLY from the wire payload) ──
|
|
322
|
+
// This layer is ADDITIVE to the straight-line body above. A RawComponentExec handler returns a RawValue
|
|
323
|
+
// (native-backed, NOT a Value::Obj tree — see rust/src/rawabi.rs). marshal_raw_T* matches on it straight
|
|
324
|
+
// into the concrete struct: the dynamic Value tree the boxed typed path built and then re-walked NEVER
|
|
325
|
+
// exists here. bind_raw drives the de-boxed runners.
|
|
326
|
+
use std::cell::RefCell;
|
|
327
|
+
use behavior_contracts::{RawComponentExec, RawOutcome, RawValue, raw_missing_prop, raw_type_mismatch};`;
|
|
328
|
+
const sections = [
|
|
329
|
+
banner,
|
|
330
|
+
decls || undefined,
|
|
331
|
+
defaults || undefined,
|
|
332
|
+
rawMarshallers
|
|
333
|
+
? `// RAW marshallers (§4.4, de-box): materialize a concrete struct field-by-field from a native RawValue.\n// NO Value::Obj on this data plane — that is the whole point of #76.\n${rawMarshallers}`
|
|
334
|
+
: undefined,
|
|
335
|
+
marshalHelpers,
|
|
336
|
+
boxedMarshallers
|
|
337
|
+
? `// Value-space output-assembly fallback (marshal_*): reached ONLY when an output directly refs an\n// input param of a named type (a Value boundary read, not the row data plane). Off the de-box hot path.\n${boxedMarshallers}`
|
|
338
|
+
: undefined,
|
|
339
|
+
nodeMaterializers.length
|
|
340
|
+
? `// scalar/arr/opt node RAW materializers: FAIL-CLOSED de-box (TYPE_MISMATCH/MISSING_PROP) from RawValue.\n${nodeMaterializers.join("\n\n")}`
|
|
341
|
+
: undefined,
|
|
342
|
+
serializers
|
|
343
|
+
? `// typed -> Value serializers (final return boundary only): canonical observation for the equivalence pin.\n${serializers}`
|
|
344
|
+
: undefined,
|
|
345
|
+
`// RAW-ABI struct-native runners: the REAL de-box exec path (called by bind_raw).\n${runners}`,
|
|
346
|
+
bindRaw,
|
|
347
|
+
];
|
|
348
|
+
const typedBody = sections.filter((s) => !!s).join("\n\n");
|
|
349
|
+
// Force the RunPlan-path imports the raw runner needs (run_plan/OpSpec/ExecOutcome). Ports are
|
|
350
|
+
// Value-space, so the straight-line body's expression helpers are reused unchanged. relationKind
|
|
351
|
+
// is needed when a raw op literal carries a relationKind (parent-field child/relation nodes, #74).
|
|
352
|
+
setRustForceRunPlanImports({
|
|
353
|
+
runPlan: true,
|
|
354
|
+
relationKind: /\bRelationKind\b/.test(typedBody),
|
|
355
|
+
json: /\bjson!\(/.test(typedBody),
|
|
356
|
+
});
|
|
357
|
+
const straightlineCode = rustStraightlineEmitter.emit(ctx);
|
|
358
|
+
setRustForceRunPlanImports(null);
|
|
359
|
+
// The RAW module reuses the straight-line body as a SUBSTRATE (its expression helpers drive the
|
|
360
|
+
// Value-space ports), but drives dispatch through bind_raw — so the boxed bind/Bound/run_* and the
|
|
361
|
+
// boxed-only marshal helpers are unused in this artifact. A module-level allow keeps the generated
|
|
362
|
+
// RAW module clippy -D warnings clean without hand-editing the shared straight-line emitter. This
|
|
363
|
+
// is a GENERATED-TOOLKIT allowance on dead SUBSTRATE, not a blanket allow on the de-box path: the
|
|
364
|
+
// de-box (marshal_raw_*, run_typed_raw_*, bind_raw) is exercised and asserted by the anti-sham gate.
|
|
365
|
+
const moduleAllow = `#![allow(dead_code, unused_imports)]\n`;
|
|
366
|
+
return `${moduleAllow}${straightlineCode.replace(/\n+$/, "\n")}\n${typedBody}\n`;
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* rustRawAbiEmitter — language id `rust-typed-raw` (bc#76). Emits the straight-line body (for
|
|
370
|
+
* untyped components / helpers) plus the RAW-ABI de-boxed layer (struct materialized directly from
|
|
371
|
+
* RawValue) and the bind_raw surface. Requires at least one outType/outputType annotation.
|
|
372
|
+
*/
|
|
373
|
+
export const rustRawAbiEmitter = {
|
|
374
|
+
language: "rust-typed-raw",
|
|
375
|
+
fileExtension: ".rs",
|
|
376
|
+
defaultRuntimeImport: "behavior_contracts",
|
|
377
|
+
filenameHint: "behaviors_typed_raw_generated.rs",
|
|
378
|
+
emit,
|
|
379
|
+
};
|
|
380
|
+
//# sourceMappingURL=emit-raw-abi-rust.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emit-raw-abi-rust.js","sourceRoot":"","sources":["../../src/generator/emit-raw-abi-rust.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emit-straightline-go.d.ts","sourceRoot":"","sources":["../../src/generator/emit-straightline-go.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,KAAK,EAAe,aAAa,EAAE,MAAM,WAAW,CAAC;AAG5D,OAAO,EAQL,KAAK,aAAa,EAIlB,KAAK,mBAAmB,EACzB,MAAM,mBAAmB,CAAC;AA+B3B,wBAAgB,wBAAwB,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,CAE1D;
|
|
1
|
+
{"version":3,"file":"emit-straightline-go.d.ts","sourceRoot":"","sources":["../../src/generator/emit-straightline-go.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,KAAK,EAAe,aAAa,EAAE,MAAM,WAAW,CAAC;AAG5D,OAAO,EAQL,KAAK,aAAa,EAIlB,KAAK,mBAAmB,EACzB,MAAM,mBAAmB,CAAC;AA+B3B,wBAAgB,wBAAwB,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,CAE1D;AA8ED;;;GAGG;AACH,iBAAS,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CA4BzD;AAgHD,oEAAoE;AACpE,iBAAS,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtC;AAkZD,oDAAoD;AACpD,iBAAS,cAAc,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CASnD;AAmCD,iCAAiC;AACjC,iBAAS,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvC;AAgND,yEAAyE;AACzE,iBAAS,uBAAuB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAMtD;AA0PD;;GAEG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;CAQnC,CAAC;AAMF,eAAO,MAAM,qBAAqB,EAAE,aAMnC,CAAC"}
|
|
@@ -34,54 +34,85 @@ function resetUsage() {
|
|
|
34
34
|
for (const k of Object.keys(usage))
|
|
35
35
|
usage[k] = false;
|
|
36
36
|
}
|
|
37
|
-
/**
|
|
37
|
+
/**
|
|
38
|
+
* bc: codegen は IR を出力してはならない(no-ir invariant)。
|
|
39
|
+
* かつては非脱解釈の式(obj/arr/scalar/演算子被演算子)を IR リテラルとして埋め込み、
|
|
40
|
+
* A0 primitive(EvalExpr 等)に実行時解釈させていた=インタプリタの松葉杖(=癌)。撤去する。
|
|
41
|
+
* ここに来る式はまだネイティブ脱解釈されていない = ネイティブコードで emit すべき(次タスク)。
|
|
42
|
+
*/
|
|
38
43
|
function lit(node) {
|
|
39
|
-
|
|
44
|
+
throw new Error(`codegen no-ir invariant: refusing to emit IR literal for ${JSON.stringify(node).slice(0, 100)} — de-interpret this expression to native code (next task)`);
|
|
40
45
|
}
|
|
41
|
-
/**
|
|
42
|
-
function
|
|
43
|
-
return
|
|
46
|
+
/** 被演算子 node を native ExprFn thunk(scope→評価済み Value)へ。primitive が短絡/評価順を制御。 */
|
|
47
|
+
function thunk(node) {
|
|
48
|
+
return `func(s *${PKG}.Obj) (${PKG}.Value, error) { return ${emitExpr(node, "s")} }`;
|
|
49
|
+
}
|
|
50
|
+
/** JS number → Go float64 リテラル(整数表記には `.0` を補う。指数/小数はそのまま)。 */
|
|
51
|
+
function goFloatLit(n) {
|
|
52
|
+
const s = String(n);
|
|
53
|
+
return /[.eE]/.test(s) ? s : `${s}.0`;
|
|
44
54
|
}
|
|
45
55
|
/**
|
|
46
|
-
* OP_PRIM —
|
|
47
|
-
*
|
|
48
|
-
*
|
|
56
|
+
* OP_PRIM — op → native Go 式(bc no-ir invariant: IR は一切 emit しない)。被演算子は
|
|
57
|
+
* `thunk()` で native emit した評価済み Value を返すクロージャにして `*Native` primitive へ渡す。
|
|
58
|
+
* 短絡(and/or/coalesce/cond)は primitive が thunk を条件付きで呼ぶ(採用側のみ評価)。意味論 SSoT
|
|
59
|
+
* は go/expr.go の value-core(native primitive が委譲)。`ref`/`refOpt`/`concat` は上で native 化済み。
|
|
49
60
|
*/
|
|
61
|
+
const bin = (fn) => (a, s) => {
|
|
62
|
+
const [x, y] = a;
|
|
63
|
+
return `${PKG}.${fn}(${thunk(x)}, ${thunk(y)}, ${s})`;
|
|
64
|
+
};
|
|
65
|
+
const un = (fn) => (a, s) => {
|
|
66
|
+
const [x] = a;
|
|
67
|
+
return `${PKG}.${fn}(${thunk(x)}, ${s})`;
|
|
68
|
+
};
|
|
50
69
|
const OP_PRIM = {
|
|
51
|
-
int: (a
|
|
52
|
-
float: (a
|
|
53
|
-
obj: (a, s) =>
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
int: (a) => `${PKG}.IntLitNative(${JSON.stringify(a)})`,
|
|
71
|
+
float: (a) => `${PKG}.FloatLitNative(${goFloatLit(a)})`,
|
|
72
|
+
obj: (a, s) => {
|
|
73
|
+
const obj = a;
|
|
74
|
+
const keys = Object.keys(obj);
|
|
75
|
+
const keyLits = keys.map((k) => JSON.stringify(k)).join(", ");
|
|
76
|
+
const vals = keys.map((k) => thunk(obj[k])).join(", ");
|
|
77
|
+
return `${PKG}.ObjNative([]string{${keyLits}}, []${PKG}.ExprFn{${vals}}, ${s})`;
|
|
78
|
+
},
|
|
79
|
+
arr: (a, s) => `${PKG}.ArrNative([]${PKG}.ExprFn{${a.map((e) => thunk(e)).join(", ")}}, ${s})`,
|
|
80
|
+
add: bin("AddNative"),
|
|
81
|
+
sub: bin("SubNative"),
|
|
82
|
+
mul: bin("MulNative"),
|
|
83
|
+
neg: un("NegNative"),
|
|
84
|
+
div: bin("DivNative"),
|
|
85
|
+
mod: bin("ModNative"),
|
|
86
|
+
eq: bin("EqNative"),
|
|
87
|
+
ne: bin("NeNative"),
|
|
88
|
+
lt: bin("LtNative"),
|
|
89
|
+
le: bin("LeNative"),
|
|
90
|
+
gt: bin("GtNative"),
|
|
91
|
+
ge: bin("GeNative"),
|
|
92
|
+
and: bin("AndNative"),
|
|
93
|
+
or: bin("OrNative"),
|
|
94
|
+
not: un("NotNative"),
|
|
95
|
+
coalesce: bin("CoalesceNative"),
|
|
96
|
+
cond: (a, s) => {
|
|
97
|
+
const [c, t, e] = a;
|
|
98
|
+
return `${PKG}.CondNative(${thunk(c)}, ${thunk(t)}, ${thunk(e)}, ${s})`;
|
|
99
|
+
},
|
|
100
|
+
len: un("LenNative"),
|
|
73
101
|
};
|
|
74
102
|
/**
|
|
75
103
|
* emitExpr — Expression IR ノードを「scope を受けて (Value, error) を返す」Go 式に落とす
|
|
76
104
|
* (**dynamic 式専用**の legacy 経路 — RunPlan 経路と typed emitter が流用する seam)。
|
|
77
105
|
*/
|
|
78
106
|
function emitExpr(node, scopeVar) {
|
|
107
|
+
// bare スカラリテラル → native Value(evaluate 非経由)。
|
|
79
108
|
if (node === null)
|
|
80
109
|
return `slVal(nil)`;
|
|
81
110
|
if (typeof node === "boolean")
|
|
82
111
|
return `slVal(${node ? "true" : "false"})`;
|
|
83
112
|
if (typeof node === "string")
|
|
84
113
|
return `slVal(${JSON.stringify(node)})`;
|
|
114
|
+
if (typeof node === "number")
|
|
115
|
+
return `${PKG}.NumberLitNative(${goFloatLit(node)})`;
|
|
85
116
|
if (node !== null && typeof node === "object" && !Array.isArray(node)) {
|
|
86
117
|
const keys = Object.keys(node);
|
|
87
118
|
if (keys.length === 1) {
|
|
@@ -101,7 +132,8 @@ function emitExpr(node, scopeVar) {
|
|
|
101
132
|
return prim(arg, scopeVar);
|
|
102
133
|
}
|
|
103
134
|
}
|
|
104
|
-
|
|
135
|
+
// 未知形(Portability Guard 通過済みなので通常到達しない)。IR は出力せず生成時に loud に落とす。
|
|
136
|
+
throw new Error(`straight-line go: cannot de-interpret node to native (no IR output): ${JSON.stringify(node).slice(0, 100)}`);
|
|
105
137
|
}
|
|
106
138
|
/** ref/refOpt の path(string リテラル配列)を Go の `[]string{...}` へ。非 string は不正 IR。 */
|
|
107
139
|
function emitStringPath(arg) {
|