@faicad/faijs 0.18.3 → 0.22.2
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/api/api-namespace.d.ts.map +1 -1
- package/dist/api/api-namespace.js +4 -1
- package/dist/api/api-namespace.js.map +1 -1
- package/dist/api/brep-mirror/joinery-brep.d.ts +1 -1
- package/dist/api/brep-mirror/joinery-brep.d.ts.map +1 -1
- package/dist/api/brep-mirror/joinery-brep.js +22 -20
- package/dist/api/brep-mirror/joinery-brep.js.map +1 -1
- package/dist/api/generated/script-face-manifest.d.ts +4 -0
- package/dist/api/generated/script-face-manifest.d.ts.map +1 -1
- package/dist/api/generated/script-face-manifest.js.map +1 -1
- package/dist/api/index.d.ts +4 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +3 -0
- package/dist/api/index.js.map +1 -1
- package/dist/api/knurl.d.ts.map +1 -1
- package/dist/api/knurl.js +1 -0
- package/dist/api/knurl.js.map +1 -1
- package/dist/api/primitives.d.ts +4 -3
- package/dist/api/primitives.d.ts.map +1 -1
- package/dist/api/primitives.js +9 -3
- package/dist/api/primitives.js.map +1 -1
- package/dist/api/profile.d.ts +34 -5
- package/dist/api/profile.d.ts.map +1 -1
- package/dist/api/profile.js +168 -186
- package/dist/api/profile.js.map +1 -1
- package/dist/api/punch-hole.d.ts +77 -0
- package/dist/api/punch-hole.d.ts.map +1 -0
- package/dist/api/punch-hole.js +207 -0
- package/dist/api/punch-hole.js.map +1 -0
- package/dist/api/sketch-on-face.d.ts +85 -0
- package/dist/api/sketch-on-face.d.ts.map +1 -0
- package/dist/api/sketch-on-face.js +136 -0
- package/dist/api/sketch-on-face.js.map +1 -0
- package/dist/api/sketch-on-plane.d.ts +87 -0
- package/dist/api/sketch-on-plane.d.ts.map +1 -0
- package/dist/api/sketch-on-plane.js +106 -0
- package/dist/api/sketch-on-plane.js.map +1 -0
- package/dist/api/surface/arg-spec.d.ts +8 -0
- package/dist/api/surface/arg-spec.d.ts.map +1 -1
- package/dist/api/surface/arg-spec.js.map +1 -1
- package/dist/api/transform.d.ts +5 -5
- package/dist/api/transform.d.ts.map +1 -1
- package/dist/api/transform.js +12 -10
- package/dist/api/transform.js.map +1 -1
- package/dist/api/xml-dom.d.ts +27 -0
- package/dist/api/xml-dom.d.ts.map +1 -0
- package/dist/api/xml-dom.js +45 -0
- package/dist/api/xml-dom.js.map +1 -0
- package/dist/boolean/csg-backend.d.ts +6 -6
- package/dist/boolean/csg-backend.d.ts.map +1 -1
- package/dist/boolean/csg-backend.js +9 -9
- package/dist/boolean/csg-backend.js.map +1 -1
- package/dist/boolean/csg-core.d.ts +10 -10
- package/dist/boolean/csg-core.d.ts.map +1 -1
- package/dist/boolean/csg-core.js +24 -24
- package/dist/boolean/csg-core.js.map +1 -1
- package/dist/boolean/extrude-helpers.d.ts +8 -8
- package/dist/boolean/extrude-helpers.d.ts.map +1 -1
- package/dist/boolean/extrude-helpers.js +13 -13
- package/dist/boolean/extrude-helpers.js.map +1 -1
- package/dist/brep/brep-ops.d.ts +24 -10
- package/dist/brep/brep-ops.d.ts.map +1 -1
- package/dist/brep/brep-ops.js +46 -18
- package/dist/brep/brep-ops.js.map +1 -1
- package/dist/brep/brep-topology.d.ts.map +1 -1
- package/dist/brep/brep-topology.js +3 -1
- package/dist/brep/brep-topology.js.map +1 -1
- package/dist/brep/export/export-model.d.ts +79 -0
- package/dist/brep/export/export-model.d.ts.map +1 -0
- package/dist/brep/export/export-model.js +335 -0
- package/dist/brep/export/export-model.js.map +1 -0
- package/dist/brep/primitives-brep.d.ts.map +1 -1
- package/dist/brep/primitives-brep.js +3 -1
- package/dist/brep/primitives-brep.js.map +1 -1
- package/dist/brepkit-kernel/brepkitKernel.d.ts.map +1 -1
- package/dist/brepkit-kernel/brepkitKernel.js +4 -2
- package/dist/brepkit-kernel/brepkitKernel.js.map +1 -1
- package/dist/browser-host/csg-worker-protocol.d.ts +3 -3
- package/dist/browser-host/csg-worker-protocol.d.ts.map +1 -1
- package/dist/browser-host/csg-worker-protocol.js.map +1 -1
- package/dist/browser-host/csg-worker.js +3 -3
- package/dist/browser-host/csg-worker.js.map +1 -1
- package/dist/browser-host/inline-csg-backend.d.ts +3 -3
- package/dist/browser-host/inline-csg-backend.d.ts.map +1 -1
- package/dist/browser-host/inline-csg-backend.js +3 -3
- package/dist/browser-host/inline-csg-backend.js.map +1 -1
- package/dist/browser-host/worker-csg-backend.d.ts +3 -3
- package/dist/browser-host/worker-csg-backend.d.ts.map +1 -1
- package/dist/browser-host/worker-csg-backend.js.map +1 -1
- package/dist/cad-runtime/direct-executor.d.ts +4 -0
- package/dist/cad-runtime/direct-executor.d.ts.map +1 -1
- package/dist/cad-runtime/direct-executor.js +17 -1
- package/dist/cad-runtime/direct-executor.js.map +1 -1
- package/dist/cad-runtime/ports.d.ts +3 -3
- package/dist/cad-runtime/ports.d.ts.map +1 -1
- package/dist/cad-runtime/ports.js.map +1 -1
- package/dist/cad-runtime/runtime.d.ts +24 -1
- package/dist/cad-runtime/runtime.d.ts.map +1 -1
- package/dist/cad-runtime/runtime.js +53 -3
- package/dist/cad-runtime/runtime.js.map +1 -1
- package/dist/define-op.d.ts +22 -0
- package/dist/define-op.d.ts.map +1 -1
- package/dist/define-op.js +15 -0
- package/dist/define-op.js.map +1 -1
- package/dist/env-agnostic.d.ts +7 -7
- package/dist/env-agnostic.d.ts.map +1 -1
- package/dist/env-agnostic.js +3 -3
- package/dist/env-agnostic.js.map +1 -1
- package/dist/geometry2d/adapt.d.ts +46 -0
- package/dist/geometry2d/adapt.d.ts.map +1 -0
- package/dist/geometry2d/adapt.js +41 -0
- package/dist/geometry2d/adapt.js.map +1 -0
- package/dist/geometry2d/bbox2d.d.ts +82 -0
- package/dist/geometry2d/bbox2d.d.ts.map +1 -0
- package/dist/geometry2d/bbox2d.js +123 -0
- package/dist/geometry2d/bbox2d.js.map +1 -0
- package/dist/geometry2d/blueprint-sketcher.d.ts +27 -0
- package/dist/geometry2d/blueprint-sketcher.d.ts.map +1 -0
- package/dist/geometry2d/blueprint-sketcher.js +29 -0
- package/dist/geometry2d/blueprint-sketcher.js.map +1 -0
- package/dist/geometry2d/blueprint.d.ts +102 -0
- package/dist/geometry2d/blueprint.d.ts.map +1 -0
- package/dist/geometry2d/blueprint.js +225 -0
- package/dist/geometry2d/blueprint.js.map +1 -0
- package/dist/geometry2d/blueprints.d.ts +58 -0
- package/dist/geometry2d/blueprints.d.ts.map +1 -0
- package/dist/geometry2d/blueprints.js +72 -0
- package/dist/geometry2d/blueprints.js.map +1 -0
- package/dist/geometry2d/bridge/lift-on-plane.d.ts +50 -0
- package/dist/geometry2d/bridge/lift-on-plane.d.ts.map +1 -0
- package/dist/geometry2d/bridge/lift-on-plane.js +78 -0
- package/dist/geometry2d/bridge/lift-on-plane.js.map +1 -0
- package/dist/geometry2d/bridge/on-surface.d.ts +98 -0
- package/dist/geometry2d/bridge/on-surface.d.ts.map +1 -0
- package/dist/geometry2d/bridge/on-surface.js +94 -0
- package/dist/geometry2d/bridge/on-surface.js.map +1 -0
- package/dist/geometry2d/bridge/plane.d.ts +69 -0
- package/dist/geometry2d/bridge/plane.d.ts.map +1 -0
- package/dist/geometry2d/bridge/plane.js +96 -0
- package/dist/geometry2d/bridge/plane.js.map +1 -0
- package/dist/geometry2d/canned-blueprints.d.ts +44 -0
- package/dist/geometry2d/canned-blueprints.d.ts.map +1 -0
- package/dist/geometry2d/canned-blueprints.js +94 -0
- package/dist/geometry2d/canned-blueprints.js.map +1 -0
- package/dist/geometry2d/compound-blueprint.d.ts +72 -0
- package/dist/geometry2d/compound-blueprint.d.ts.map +1 -0
- package/dist/geometry2d/compound-blueprint.js +95 -0
- package/dist/geometry2d/compound-blueprint.js.map +1 -0
- package/dist/geometry2d/curve2d.d.ts +298 -0
- package/dist/geometry2d/curve2d.d.ts.map +1 -0
- package/dist/geometry2d/curve2d.js +1110 -0
- package/dist/geometry2d/curve2d.js.map +1 -0
- package/dist/geometry2d/index.d.ts +22 -0
- package/dist/geometry2d/index.d.ts.map +1 -0
- package/dist/geometry2d/index.js +21 -0
- package/dist/geometry2d/index.js.map +1 -0
- package/dist/geometry2d/organise.d.ts +28 -0
- package/dist/geometry2d/organise.d.ts.map +1 -0
- package/dist/geometry2d/organise.js +108 -0
- package/dist/geometry2d/organise.js.map +1 -0
- package/dist/geometry2d/pen-sketcher.d.ts +365 -0
- package/dist/geometry2d/pen-sketcher.d.ts.map +1 -0
- package/dist/geometry2d/pen-sketcher.js +520 -0
- package/dist/geometry2d/pen-sketcher.js.map +1 -0
- package/dist/geometry2d/point.d.ts +44 -0
- package/dist/geometry2d/point.d.ts.map +1 -0
- package/dist/geometry2d/point.js +57 -0
- package/dist/geometry2d/point.js.map +1 -0
- package/dist/geometry2d/svg-ellipse.d.ts +74 -0
- package/dist/geometry2d/svg-ellipse.d.ts.map +1 -0
- package/dist/geometry2d/svg-ellipse.js +163 -0
- package/dist/geometry2d/svg-ellipse.js.map +1 -0
- package/dist/lang/code-to-args.d.ts +29 -3
- package/dist/lang/code-to-args.d.ts.map +1 -1
- package/dist/lang/code-to-args.js +41 -2
- package/dist/lang/code-to-args.js.map +1 -1
- package/dist/lang/codegen.d.ts +45 -1
- package/dist/lang/codegen.d.ts.map +1 -1
- package/dist/lang/codegen.js +135 -6
- package/dist/lang/codegen.js.map +1 -1
- package/dist/lang/host-arg.d.ts +6 -0
- package/dist/lang/host-arg.d.ts.map +1 -1
- package/dist/lang/host-arg.js.map +1 -1
- package/dist/lang/metadata-extractor.d.ts +25 -0
- package/dist/lang/metadata-extractor.d.ts.map +1 -1
- package/dist/lang/metadata-extractor.js +289 -25
- package/dist/lang/metadata-extractor.js.map +1 -1
- package/dist/lang/parse-error.d.ts +7 -1
- package/dist/lang/parse-error.d.ts.map +1 -1
- package/dist/lang/parse-error.js.map +1 -1
- package/dist/lang/security-scanner.d.ts +9 -1
- package/dist/lang/security-scanner.d.ts.map +1 -1
- package/dist/lang/security-scanner.js +38 -1
- package/dist/lang/security-scanner.js.map +1 -1
- package/dist/lang/symbol-table.generated.d.ts +3 -0
- package/dist/lang/symbol-table.generated.d.ts.map +1 -1
- package/dist/lang/symbol-table.generated.js +3 -0
- package/dist/lang/symbol-table.generated.js.map +1 -1
- package/dist/mesh/io.d.ts +62 -9
- package/dist/mesh/io.d.ts.map +1 -1
- package/dist/mesh/io.js +124 -17
- package/dist/mesh/io.js.map +1 -1
- package/dist/mesh/threemf-loader.d.ts +15 -0
- package/dist/mesh/threemf-loader.d.ts.map +1 -0
- package/dist/mesh/threemf-loader.js +163 -0
- package/dist/mesh/threemf-loader.js.map +1 -0
- package/dist/mesh/transform.d.ts +2 -2
- package/dist/mesh/transform.d.ts.map +1 -1
- package/dist/mesh/transform.js +3 -3
- package/dist/mesh/transform.js.map +1 -1
- package/dist/mesh/types.d.ts +2 -2
- package/dist/mesh/types.d.ts.map +1 -1
- package/dist/mesh/types.js.map +1 -1
- package/dist/node-host/cli.d.ts.map +1 -1
- package/dist/node-host/cli.js +53 -26
- package/dist/node-host/cli.js.map +1 -1
- package/dist/occt-kernel/occtKernel.d.ts.map +1 -1
- package/dist/occt-kernel/occtKernel.js +4 -2
- package/dist/occt-kernel/occtKernel.js.map +1 -1
- package/dist/occt-kernel/topologyExt.d.ts.map +1 -1
- package/dist/occt-kernel/topologyExt.js +4 -1
- package/dist/occt-kernel/topologyExt.js.map +1 -1
- package/dist/runtime-state.d.ts +18 -0
- package/dist/runtime-state.d.ts.map +1 -1
- package/dist/runtime-state.js +23 -0
- package/dist/runtime-state.js.map +1 -1
- package/dist/sdk.d.ts +1 -1
- package/dist/sdk.d.ts.map +1 -1
- package/dist/sdk.js +1 -1
- package/dist/sdk.js.map +1 -1
- package/dist/tolerance.d.ts +38 -0
- package/dist/tolerance.d.ts.map +1 -0
- package/dist/tolerance.js +40 -0
- package/dist/tolerance.js.map +1 -0
- package/dist/topology/naming/score.js +3 -3
- package/dist/topology/naming/score.js.map +1 -1
- package/dist/units.d.ts +248 -0
- package/dist/units.d.ts.map +1 -0
- package/dist/units.js +397 -0
- package/dist/units.js.map +1 -0
- package/package.json +19 -2
package/dist/lang/codegen.js
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
* - 对象字面量 → `{key:value}`(冒号,合法 JS)
|
|
21
21
|
*/
|
|
22
22
|
import { isHostVarRef, isHostParamRef, isHostCallRef, isHostExprRef, isHostRef } from './host-arg.js';
|
|
23
|
+
import { unitFor, fromBase } from '../units.js';
|
|
23
24
|
// ── 数值格式化 ──
|
|
24
25
|
/**
|
|
25
26
|
* Format a number as text: integers emit as-is; decimals retain at most 6
|
|
@@ -57,6 +58,45 @@ function escapeStr(s) {
|
|
|
57
58
|
}
|
|
58
59
|
return out;
|
|
59
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Format a unit literal number using JS shortest-round-trip representation.
|
|
63
|
+
*
|
|
64
|
+
* P7/D10.3 rule 5: unit literal numbers MUST use `String(n)` (e.g.
|
|
65
|
+
* `0.39370078740157477`), NEVER `fmtNum` (which truncates to 6 decimal
|
|
66
|
+
* places and would silently zero out `1e-7`).
|
|
67
|
+
* @param n - the number to format.
|
|
68
|
+
* @returns the shortest JS round-trip text representation.
|
|
69
|
+
*/
|
|
70
|
+
export function fmtUnitNum(n) {
|
|
71
|
+
return String(n);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Reverse lookup: find the script-side unit constant name for a given
|
|
75
|
+
* `UnitName`. Returns the UPPERCASE constant name (e.g. `INCH` for `'inch'`).
|
|
76
|
+
*/
|
|
77
|
+
const NAME_TO_CONST = {
|
|
78
|
+
mm: 'MM', cm: 'CM', m: 'METER', micron: 'MICRON',
|
|
79
|
+
inch: 'INCH', foot: 'FOOT', yard: 'YARD',
|
|
80
|
+
degree: 'DEGREE', radian: 'RADIAN',
|
|
81
|
+
gram: 'GRAM', kilogram: 'KILOGRAM',
|
|
82
|
+
second: 'SECOND',
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Format a base-unit value as a unit literal expression (`n * UNIT`).
|
|
86
|
+
*
|
|
87
|
+
* P7/D10.3: `base` is the base-unit (mm/degree) value; `dim` determines which
|
|
88
|
+
* system display unit to use; `unitName` is the target display unit.
|
|
89
|
+
* The number is formatted with `fmtUnitNum` (not `fmtNum`).
|
|
90
|
+
* @param base - the base-unit numeric value.
|
|
91
|
+
* @param dim - the dimension of the value.
|
|
92
|
+
* @param unitName - the display unit to express the value in.
|
|
93
|
+
* @returns text like `10 * INCH` or `0.39370078740157477 * INCH`.
|
|
94
|
+
*/
|
|
95
|
+
export function formatUnitLiteral(base, dim, unitName) {
|
|
96
|
+
const displayValue = fromBase(base, unitName, dim);
|
|
97
|
+
const constName = NAME_TO_CONST[unitName];
|
|
98
|
+
return `${fmtUnitNum(displayValue)} * ${constName}`;
|
|
99
|
+
}
|
|
60
100
|
/** 参数值 → 文本(递归,HostArg 面) */
|
|
61
101
|
function fmtValue(value) {
|
|
62
102
|
if (value === null)
|
|
@@ -77,7 +117,7 @@ function fmtValue(value) {
|
|
|
77
117
|
return `${namespace ?? 'cad'}.${callee}(${inner})`;
|
|
78
118
|
}
|
|
79
119
|
if (isHostExprRef(value))
|
|
80
|
-
return `(${value.text})`;
|
|
120
|
+
return value.bare ? value.text : `(${value.text})`;
|
|
81
121
|
if (Array.isArray(value))
|
|
82
122
|
return `[${value.map(fmtValue).join(',')}]`;
|
|
83
123
|
if (typeof value === 'object') {
|
|
@@ -91,13 +131,34 @@ function isPlainObjArg(arg) {
|
|
|
91
131
|
return arg !== null && typeof arg === 'object' && !Array.isArray(arg) && !isHostRef(arg);
|
|
92
132
|
}
|
|
93
133
|
/**
|
|
94
|
-
*
|
|
134
|
+
* Recursively format a HostArg value, applying unit wrapping to numbers inside
|
|
135
|
+
* arrays (vec3) and plain objects when a dimension is declared.
|
|
136
|
+
*/
|
|
137
|
+
function fmtValueWithDim(value, dim, opts) {
|
|
138
|
+
if (opts && dim) {
|
|
139
|
+
// Number → unit literal
|
|
140
|
+
if (typeof value === 'number') {
|
|
141
|
+
const unitName = unitFor(dim, opts.units);
|
|
142
|
+
return formatUnitLiteral(value, dim, unitName);
|
|
143
|
+
}
|
|
144
|
+
// Array (vec3) → element-wise
|
|
145
|
+
if (Array.isArray(value)) {
|
|
146
|
+
return `[${value.map((el) => fmtValueWithDim(el, dim, opts)).join(',')}]`;
|
|
147
|
+
}
|
|
148
|
+
// Bare expr-ref already containing a unit literal → keep as-is
|
|
149
|
+
if (isHostExprRef(value) && value.bare)
|
|
150
|
+
return value.text;
|
|
151
|
+
}
|
|
152
|
+
return fmtValue(value);
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Original `formatCodeLine` body without unit support (P7 fast path).
|
|
95
156
|
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
157
|
+
* This is the byte-identical pre-P7 implementation, called when `opts` is
|
|
158
|
+
* absent or has no `dims` field. Kept as a separate function so the
|
|
159
|
+
* unit-aware path can be tested independently.
|
|
99
160
|
*/
|
|
100
|
-
|
|
161
|
+
function formatCodeLineRaw(input) {
|
|
101
162
|
const positional = input.positional;
|
|
102
163
|
const argsInput = input.args ?? {};
|
|
103
164
|
// 位置实参按序打印
|
|
@@ -145,4 +206,72 @@ export function formatCodeLine(input) {
|
|
|
145
206
|
return `${out} = ${nsExpr}(${callArgs})`;
|
|
146
207
|
return `let ${out} = ${nsExpr}(${callArgs})`;
|
|
147
208
|
}
|
|
209
|
+
/**
|
|
210
|
+
* 从纯数据(非 IR 类型)打印一行 faijs 源代码。
|
|
211
|
+
*
|
|
212
|
+
* 宿主 buildCode / 编辑重排行(editStatement → replaceCodeAt)统一走此入口。
|
|
213
|
+
*
|
|
214
|
+
* P7/D10: when `opts` is provided, dimensioned parameters are serialized as
|
|
215
|
+
* unit literals (`n * UNIT`). When `opts` is absent, output is byte-identical
|
|
216
|
+
* to the pre-P7 behavior (zero-impact regression guarantee).
|
|
217
|
+
*
|
|
218
|
+
* @param input - the pure-data line description.
|
|
219
|
+
* @param opts - optional unit serialization options (P7/D10).
|
|
220
|
+
* @returns the printed single-line code text.
|
|
221
|
+
*/
|
|
222
|
+
export function formatCodeLine(input, opts) {
|
|
223
|
+
// Fast path: no unit options → original behavior (byte-identical)
|
|
224
|
+
if (!opts || !opts.dims) {
|
|
225
|
+
return formatCodeLineRaw(input);
|
|
226
|
+
}
|
|
227
|
+
const positional = input.positional;
|
|
228
|
+
const argsInput = input.args ?? {};
|
|
229
|
+
const posDims = opts.dims.positional ?? [];
|
|
230
|
+
const keyDims = opts.dims.byKey ?? {};
|
|
231
|
+
// Positional args with per-index dimension
|
|
232
|
+
const positionalParts = positional.map((arg, i) => {
|
|
233
|
+
const dim = posDims[i] ?? null;
|
|
234
|
+
if (isPlainObjArg(arg)) {
|
|
235
|
+
const entries = Object.entries(arg);
|
|
236
|
+
return `{ ${entries.map(([k, v]) => `${k}:${fmtValueWithDim(v, keyDims[k] ?? null, opts)}`).join(', ')} }`;
|
|
237
|
+
}
|
|
238
|
+
return fmtValueWithDim(arg, dim, opts);
|
|
239
|
+
});
|
|
240
|
+
// args slot (transitional compat: appended as trailing option when last positional is not a plain object)
|
|
241
|
+
const argsParts = Object.entries(argsInput).map(([k, v]) => `${k}:${fmtValueWithDim(v, keyDims[k] ?? null, opts)}`);
|
|
242
|
+
const lastIsPlainObject = positional.length > 0 && isPlainObjArg(positional[positional.length - 1]);
|
|
243
|
+
let callArgs;
|
|
244
|
+
if (positionalParts.length > 0) {
|
|
245
|
+
callArgs = positionalParts.join(', ');
|
|
246
|
+
if (!lastIsPlainObject && argsParts.length > 0) {
|
|
247
|
+
callArgs = [...positionalParts, `{ ${argsParts.join(', ')} }`].join(', ');
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
else if (input.receiver) {
|
|
251
|
+
callArgs = argsParts.length > 0 ? `{ ${argsParts.join(', ')} }` : '';
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
callArgs = argsParts.length > 0 ? `{ ${argsParts.join(', ')} }` : '{}';
|
|
255
|
+
}
|
|
256
|
+
// F2:命名空间前缀(缺省 cad);本机函数调用 callee 无命名空间前缀
|
|
257
|
+
const nsExpr = input.namespace === undefined ? `cad.${input.callee}` : `${input.namespace}.${input.callee}`;
|
|
258
|
+
// 1) 解构:outputKeys + outputs 一一对应
|
|
259
|
+
if (input.outputKeys && input.outputKeys.length > 0) {
|
|
260
|
+
const destructure = input.outputKeys.map((k, i) => `${k}: ${input.outputs[i]}`).join(', ');
|
|
261
|
+
return `const { ${destructure} } = ${nsExpr}(${callArgs})`;
|
|
262
|
+
}
|
|
263
|
+
// 2) 成员调用
|
|
264
|
+
if (input.receiver) {
|
|
265
|
+
return `${input.receiver}.${input.callee}(${callArgs})`;
|
|
266
|
+
}
|
|
267
|
+
// 3) 无赋值调用
|
|
268
|
+
if (input.outputs.length === 0) {
|
|
269
|
+
return `${nsExpr}(${callArgs})`;
|
|
270
|
+
}
|
|
271
|
+
// 4) 赋值:outputDeclared → 裸重赋值;否则 let 声明
|
|
272
|
+
const out = input.outputs[0];
|
|
273
|
+
if (input.outputDeclared)
|
|
274
|
+
return `${out} = ${nsExpr}(${callArgs})`;
|
|
275
|
+
return `let ${out} = ${nsExpr}(${callArgs})`;
|
|
276
|
+
}
|
|
148
277
|
//# sourceMappingURL=codegen.js.map
|
package/dist/lang/codegen.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codegen.js","sourceRoot":"","sources":["../../src/lang/codegen.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * codegen — 纯数据 → 文本 打印工具(宿主编辑器/测试用;L0,仅依赖 host-arg)\n *\n * 宿主 buildCode / 编辑重排行(editStatement → replaceCodeAt)统一走此入口。\n * 输入是纯数据(HostArg 面),不依赖任何 IR 类型。\n *\n * 扁平代码格式(无 export/async/await/return/参数声明):\n * ```js\n * let part0 = cad.box(10, 20, 30)\n * part0 = cad.translate(part0, { offset: [1, 2, 3] })\n * ```\n *\n * 值格式约定(确定性输出):\n * - vec3 → `[1,2,3]`(紧凑无空格)\n * - 数字 → 整数直出;小数最多保留 6 位有效小数并去尾零\n * - 字符串 → 单引号包裹\n * - HostVarRef → 裸变量名(members 元素)\n * - HostCallRef → `cad.faceNormal(part0)`(嵌套调用)\n * - HostExprRef → `(expr text)`(原文加括号)\n * - 对象字面量 → `{key:value}`(冒号,合法 JS)\n */\n\nimport type { HostArg } from './host-arg'\nimport { isHostVarRef, isHostParamRef, isHostCallRef, isHostExprRef, isHostRef } from './host-arg'\n\n// ── 数值格式化 ──\n\n/**\n * Format a number as text: integers emit as-is; decimals retain at most 6\n * significant fractional digits with trailing zeros stripped.\n * @param n - the number to format.\n * @returns the formatted text representation.\n */\nexport function fmtNum(n: number): string {\n if (!Number.isFinite(n)) return String(n)\n if (Number.isInteger(n)) return String(n)\n const s = n.toFixed(6)\n return s.replace(/\\.?0+$/, '')\n}\n\n// ── 字符串转义 ──\n\n/** 字符串转义:转义反斜杠、单引号与控制字符(多行 SDF code 等字符串参数用)。\n * 逐一字符映射(避开 regex 控制字符字面量,满足 eslint no-control-regex),\n * 保证 fmtValue ⇄ analyzeCode 往返一致:嵌入 '…' 后仍是合法 JS,可被精确还原。 */\nconst STRING_ESCAPES: Record<string, string> = {\n '\\\\': '\\\\\\\\',\n \"'\": \"\\\\'\",\n '\\u0008': '\\\\b', // backspace\n '\\u000C': '\\\\f', // form feed\n '\\u000A': '\\\\n', // line feed\n '\\u000D': '\\\\r', // carriage return\n '\\u0009': '\\\\t', // tab\n '\\u000B': '\\\\v', // vertical tab\n}\n\nfunction escapeStr(s: string): string {\n let out = ''\n for (let i = 0; i < s.length; i++) {\n const esc = STRING_ESCAPES[s[i]]\n out += esc ?? s[i]\n }\n return out\n}\n\n/** 参数值 → 文本(递归,HostArg 面) */\nfunction fmtValue(value: HostArg): string {\n if (value === null) return 'null'\n if (typeof value === 'number') return fmtNum(value)\n if (typeof value === 'boolean') return String(value)\n if (typeof value === 'string') return `'${escapeStr(value)}'`\n if (isHostVarRef(value)) return value.name\n if (isHostParamRef(value)) return value.name\n if (isHostCallRef(value)) {\n const { callee, args, namespace } = value\n const inner = args.map(fmtValue).join(', ')\n return `${namespace ?? 'cad'}.${callee}(${inner})`\n }\n if (isHostExprRef(value)) return `(${value.text})`\n if (Array.isArray(value)) return `[${value.map(fmtValue).join(',')}]`\n if (typeof value === 'object') {\n const entries = Object.entries(value as Record<string, HostArg>)\n return `{${entries.map(([k, v]) => `${k}:${fmtValue(v)}`).join(', ')}}`\n }\n return String(value)\n}\n\n// ── 纯数据 → 代码行(宿主代码生成入口) ──\n\n/**\n * Pure-data input for printing one faijs source line, decoupled from IR types.\n *\n * `positional` and `args` use `HostArg` (host-friendly types with `kind`-based\n * discrimination).\n */\nexport interface FormatCodeLineInput {\n callee: string\n /** 成员方法调用接收者变量名 */\n receiver?: string\n /**\n * 位置实参槽(HostArg 形态):宿主可传字面量、\n * 变量引用(`{kind:'var-ref',name}`)、参数引用(`{kind:'param-ref',name}`)、\n * 嵌套调用(`{kind:'call-ref',callee,args,namespace?}`)、\n * 表达式(`{kind:'expr-ref',text,refs,params}`)或纯 JsonValue,按序打印。\n */\n positional: HostArg[]\n /** 产出变量名 */\n outputs: string[]\n /** 解构键(与 outputs 一一对应) */\n outputKeys?: string[]\n /**\n * (过渡兼容)选项对象:positional 末位不是纯对象时追加为尾随选项对象。\n * 新代码应把选项对象直接放进 positional。\n */\n args?: Record<string, HostArg>\n /** 调用命名空间(F2:第三方库 `mech.makeHeadstock(...)` → 'mech';缺省 'cad') */\n namespace?: string\n /**\n * outputs[0] 是否已在代码中声明:true → 裸重赋值(`part0 = ...`),\n * false/省略 → let 声明;解构/成员调用/无输出时忽略。\n */\n outputDeclared?: boolean\n}\n\n/** 检测 HostArg 是否为纯数据对象(非引用形态)。 */\nfunction isPlainObjArg(arg: HostArg): boolean {\n return arg !== null && typeof arg === 'object' && !Array.isArray(arg) && !isHostRef(arg)\n}\n\n/**\n * 从纯数据(非 IR 类型)打印一行 faijs 源代码。\n *\n * 宿主 buildCode / 编辑重排行(editStatement → replaceCodeAt)统一走此入口。\n * @param input - the pure-data line description.\n * @returns the printed single-line code text.\n */\nexport function formatCodeLine(input: FormatCodeLineInput): string {\n const positional = input.positional\n const argsInput: Record<string, HostArg> = input.args ?? {}\n\n // 位置实参按序打印\n const positionalParts = positional.map((arg) => {\n if (isPlainObjArg(arg)) {\n const entries = Object.entries(arg as Record<string, HostArg>)\n return `{ ${entries.map(([k, v]) => `${k}:${fmtValue(v)}`).join(', ')} }`\n }\n return fmtValue(arg)\n })\n\n // args 槽(过渡兼容:positional 末位非纯对象时追加为独立选项槽)\n const argsParts = Object.entries(argsInput).map(([k, v]) => `${k}:${fmtValue(v)}`)\n const lastIsPlainObject = positional.length > 0 && isPlainObjArg(positional[positional.length - 1])\n\n let callArgs: string\n if (positionalParts.length > 0) {\n callArgs = positionalParts.join(', ')\n if (!lastIsPlainObject && argsParts.length > 0) {\n callArgs = [...positionalParts, `{ ${argsParts.join(', ')} }`].join(', ')\n }\n } else if (input.receiver) {\n callArgs = argsParts.length > 0 ? `{ ${argsParts.join(', ')} }` : ''\n } else {\n callArgs = argsParts.length > 0 ? `{ ${argsParts.join(', ')} }` : '{}'\n }\n\n // F2:命名空间前缀(缺省 cad);本机函数调用 callee 无命名空间前缀\n const nsExpr = input.namespace === undefined ? `cad.${input.callee}` : `${input.namespace}.${input.callee}`\n\n // 1) 解构:outputKeys + outputs 一一对应\n if (input.outputKeys && input.outputKeys.length > 0) {\n const destructure = input.outputKeys.map((k, i) => `${k}: ${input.outputs[i]}`).join(', ')\n return `const { ${destructure} } = ${nsExpr}(${callArgs})`\n }\n\n // 2) 成员调用\n if (input.receiver) {\n return `${input.receiver}.${input.callee}(${callArgs})`\n }\n\n // 3) 无赋值调用\n if (input.outputs.length === 0) {\n return `${nsExpr}(${callArgs})`\n }\n\n // 4) 赋值:outputDeclared → 裸重赋值;否则 let 声明\n const out = input.outputs[0]\n if (input.outputDeclared) return `${out} = ${nsExpr}(${callArgs})`\n return `let ${out} = ${nsExpr}(${callArgs})`\n}\n"]}
|
|
1
|
+
{"version":3,"file":"codegen.js","sourceRoot":"","sources":["../../src/lang/codegen.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * codegen — 纯数据 → 文本 打印工具(宿主编辑器/测试用;L0,仅依赖 host-arg)\n *\n * 宿主 buildCode / 编辑重排行(editStatement → replaceCodeAt)统一走此入口。\n * 输入是纯数据(HostArg 面),不依赖任何 IR 类型。\n *\n * 扁平代码格式(无 export/async/await/return/参数声明):\n * ```js\n * let part0 = cad.box(10, 20, 30)\n * part0 = cad.translate(part0, { offset: [1, 2, 3] })\n * ```\n *\n * 值格式约定(确定性输出):\n * - vec3 → `[1,2,3]`(紧凑无空格)\n * - 数字 → 整数直出;小数最多保留 6 位有效小数并去尾零\n * - 字符串 → 单引号包裹\n * - HostVarRef → 裸变量名(members 元素)\n * - HostCallRef → `cad.faceNormal(part0)`(嵌套调用)\n * - HostExprRef → `(expr text)`(原文加括号)\n * - 对象字面量 → `{key:value}`(冒号,合法 JS)\n */\n\nimport type { HostArg } from './host-arg'\nimport { isHostVarRef, isHostParamRef, isHostCallRef, isHostExprRef, isHostRef } from './host-arg'\nimport type { DimName, UnitName, UnitContext } from '../units'\nimport { unitFor, fromBase } from '../units'\n\n// ── 数值格式化 ──\n\n/**\n * Format a number as text: integers emit as-is; decimals retain at most 6\n * significant fractional digits with trailing zeros stripped.\n * @param n - the number to format.\n * @returns the formatted text representation.\n */\nexport function fmtNum(n: number): string {\n if (!Number.isFinite(n)) return String(n)\n if (Number.isInteger(n)) return String(n)\n const s = n.toFixed(6)\n return s.replace(/\\.?0+$/, '')\n}\n\n// ── 字符串转义 ──\n\n/** 字符串转义:转义反斜杠、单引号与控制字符(多行 SDF code 等字符串参数用)。\n * 逐一字符映射(避开 regex 控制字符字面量,满足 eslint no-control-regex),\n * 保证 fmtValue ⇄ analyzeCode 往返一致:嵌入 '…' 后仍是合法 JS,可被精确还原。 */\nconst STRING_ESCAPES: Record<string, string> = {\n '\\\\': '\\\\\\\\',\n \"'\": \"\\\\'\",\n '\\u0008': '\\\\b', // backspace\n '\\u000C': '\\\\f', // form feed\n '\\u000A': '\\\\n', // line feed\n '\\u000D': '\\\\r', // carriage return\n '\\u0009': '\\\\t', // tab\n '\\u000B': '\\\\v', // vertical tab\n}\n\nfunction escapeStr(s: string): string {\n let out = ''\n for (let i = 0; i < s.length; i++) {\n const esc = STRING_ESCAPES[s[i]]\n out += esc ?? s[i]\n }\n return out\n}\n\n/**\n * Format a unit literal number using JS shortest-round-trip representation.\n *\n * P7/D10.3 rule 5: unit literal numbers MUST use `String(n)` (e.g.\n * `0.39370078740157477`), NEVER `fmtNum` (which truncates to 6 decimal\n * places and would silently zero out `1e-7`).\n * @param n - the number to format.\n * @returns the shortest JS round-trip text representation.\n */\nexport function fmtUnitNum(n: number): string {\n return String(n)\n}\n\n/**\n * Reverse lookup: find the script-side unit constant name for a given\n * `UnitName`. Returns the UPPERCASE constant name (e.g. `INCH` for `'inch'`).\n */\nconst NAME_TO_CONST: Readonly<Record<UnitName, string>> = {\n mm: 'MM', cm: 'CM', m: 'METER', micron: 'MICRON',\n inch: 'INCH', foot: 'FOOT', yard: 'YARD',\n degree: 'DEGREE', radian: 'RADIAN',\n gram: 'GRAM', kilogram: 'KILOGRAM',\n second: 'SECOND',\n}\n\n/**\n * Format a base-unit value as a unit literal expression (`n * UNIT`).\n *\n * P7/D10.3: `base` is the base-unit (mm/degree) value; `dim` determines which\n * system display unit to use; `unitName` is the target display unit.\n * The number is formatted with `fmtUnitNum` (not `fmtNum`).\n * @param base - the base-unit numeric value.\n * @param dim - the dimension of the value.\n * @param unitName - the display unit to express the value in.\n * @returns text like `10 * INCH` or `0.39370078740157477 * INCH`.\n */\nexport function formatUnitLiteral(base: number, dim: DimName, unitName: UnitName): string {\n const displayValue = fromBase(base, unitName, dim)\n const constName = NAME_TO_CONST[unitName]\n return `${fmtUnitNum(displayValue)} * ${constName}`\n}\n\n/**\n * P7/D10.3: Options for unit-aware serialization of `formatCodeLine`.\n *\n * When provided, dimensioned parameters are emitted as unit literals\n * (`n * UNIT`). When absent, output is byte-identical to the pre-P7 behavior.\n */\nexport interface UnitSerializeOptions {\n /** System display unit; defaults to base (mm / degree). */\n units?: UnitContext\n /** Parameter dimension declarations (host provides from op paramDims + slotMap). */\n dims?: { positional?: (DimName | null)[]; byKey?: Record<string, DimName> }\n}\n\n/** 参数值 → 文本(递归,HostArg 面) */\nfunction fmtValue(value: HostArg): string {\n if (value === null) return 'null'\n if (typeof value === 'number') return fmtNum(value)\n if (typeof value === 'boolean') return String(value)\n if (typeof value === 'string') return `'${escapeStr(value)}'`\n if (isHostVarRef(value)) return value.name\n if (isHostParamRef(value)) return value.name\n if (isHostCallRef(value)) {\n const { callee, args, namespace } = value\n const inner = args.map(fmtValue).join(', ')\n return `${namespace ?? 'cad'}.${callee}(${inner})`\n }\n if (isHostExprRef(value)) return value.bare ? value.text : `(${value.text})`\n if (Array.isArray(value)) return `[${value.map(fmtValue).join(',')}]`\n if (typeof value === 'object') {\n const entries = Object.entries(value as Record<string, HostArg>)\n return `{${entries.map(([k, v]) => `${k}:${fmtValue(v)}`).join(', ')}}`\n }\n return String(value)\n}\n\n// ── 纯数据 → 代码行(宿主代码生成入口) ──\n\n/**\n * Pure-data input for printing one faijs source line, decoupled from IR types.\n *\n * `positional` and `args` use `HostArg` (host-friendly types with `kind`-based\n * discrimination).\n */\nexport interface FormatCodeLineInput {\n callee: string\n /** 成员方法调用接收者变量名 */\n receiver?: string\n /**\n * 位置实参槽(HostArg 形态):宿主可传字面量、\n * 变量引用(`{kind:'var-ref',name}`)、参数引用(`{kind:'param-ref',name}`)、\n * 嵌套调用(`{kind:'call-ref',callee,args,namespace?}`)、\n * 表达式(`{kind:'expr-ref',text,refs,params}`)或纯 JsonValue,按序打印。\n */\n positional: HostArg[]\n /** 产出变量名 */\n outputs: string[]\n /** 解构键(与 outputs 一一对应) */\n outputKeys?: string[]\n /**\n * (过渡兼容)选项对象:positional 末位不是纯对象时追加为尾随选项对象。\n * 新代码应把选项对象直接放进 positional。\n */\n args?: Record<string, HostArg>\n /** 调用命名空间(F2:第三方库 `mech.makeHeadstock(...)` → 'mech';缺省 'cad') */\n namespace?: string\n /**\n * outputs[0] 是否已在代码中声明:true → 裸重赋值(`part0 = ...`),\n * false/省略 → let 声明;解构/成员调用/无输出时忽略。\n */\n outputDeclared?: boolean\n}\n\n/** 检测 HostArg 是否为纯数据对象(非引用形态)。 */\nfunction isPlainObjArg(arg: HostArg): boolean {\n return arg !== null && typeof arg === 'object' && !Array.isArray(arg) && !isHostRef(arg)\n}\n\n/**\n * Recursively format a HostArg value, applying unit wrapping to numbers inside\n * arrays (vec3) and plain objects when a dimension is declared.\n */\nfunction fmtValueWithDim(value: HostArg, dim: DimName | null | undefined, opts: UnitSerializeOptions | undefined): string {\n if (opts && dim) {\n // Number → unit literal\n if (typeof value === 'number') {\n const unitName = unitFor(dim, opts.units)\n return formatUnitLiteral(value, dim, unitName)\n }\n // Array (vec3) → element-wise\n if (Array.isArray(value)) {\n return `[${value.map((el) => fmtValueWithDim(el, dim, opts)).join(',')}]`\n }\n // Bare expr-ref already containing a unit literal → keep as-is\n if (isHostExprRef(value) && value.bare) return value.text\n }\n return fmtValue(value)\n}\n\n/**\n * Original `formatCodeLine` body without unit support (P7 fast path).\n *\n * This is the byte-identical pre-P7 implementation, called when `opts` is\n * absent or has no `dims` field. Kept as a separate function so the\n * unit-aware path can be tested independently.\n */\nfunction formatCodeLineRaw(input: FormatCodeLineInput): string {\n const positional = input.positional\n const argsInput: Record<string, HostArg> = input.args ?? {}\n\n // 位置实参按序打印\n const positionalParts = positional.map((arg) => {\n if (isPlainObjArg(arg)) {\n const entries = Object.entries(arg as Record<string, HostArg>)\n return `{ ${entries.map(([k, v]) => `${k}:${fmtValue(v)}`).join(', ')} }`\n }\n return fmtValue(arg)\n })\n\n // args 槽(过渡兼容:positional 末位非纯对象时追加为独立选项槽)\n const argsParts = Object.entries(argsInput).map(([k, v]) => `${k}:${fmtValue(v)}`)\n const lastIsPlainObject = positional.length > 0 && isPlainObjArg(positional[positional.length - 1])\n\n let callArgs: string\n if (positionalParts.length > 0) {\n callArgs = positionalParts.join(', ')\n if (!lastIsPlainObject && argsParts.length > 0) {\n callArgs = [...positionalParts, `{ ${argsParts.join(', ')} }`].join(', ')\n }\n } else if (input.receiver) {\n callArgs = argsParts.length > 0 ? `{ ${argsParts.join(', ')} }` : ''\n } else {\n callArgs = argsParts.length > 0 ? `{ ${argsParts.join(', ')} }` : '{}'\n }\n\n // F2:命名空间前缀(缺省 cad);本机函数调用 callee 无命名空间前缀\n const nsExpr = input.namespace === undefined ? `cad.${input.callee}` : `${input.namespace}.${input.callee}`\n\n // 1) 解构:outputKeys + outputs 一一对应\n if (input.outputKeys && input.outputKeys.length > 0) {\n const destructure = input.outputKeys.map((k, i) => `${k}: ${input.outputs[i]}`).join(', ')\n return `const { ${destructure} } = ${nsExpr}(${callArgs})`\n }\n\n // 2) 成员调用\n if (input.receiver) {\n return `${input.receiver}.${input.callee}(${callArgs})`\n }\n\n // 3) 无赋值调用\n if (input.outputs.length === 0) {\n return `${nsExpr}(${callArgs})`\n }\n\n // 4) 赋值:outputDeclared → 裸重赋值;否则 let 声明\n const out = input.outputs[0]\n if (input.outputDeclared) return `${out} = ${nsExpr}(${callArgs})`\n return `let ${out} = ${nsExpr}(${callArgs})`\n}\n\n/**\n * 从纯数据(非 IR 类型)打印一行 faijs 源代码。\n *\n * 宿主 buildCode / 编辑重排行(editStatement → replaceCodeAt)统一走此入口。\n *\n * P7/D10: when `opts` is provided, dimensioned parameters are serialized as\n * unit literals (`n * UNIT`). When `opts` is absent, output is byte-identical\n * to the pre-P7 behavior (zero-impact regression guarantee).\n *\n * @param input - the pure-data line description.\n * @param opts - optional unit serialization options (P7/D10).\n * @returns the printed single-line code text.\n */\nexport function formatCodeLine(input: FormatCodeLineInput, opts?: UnitSerializeOptions): string {\n // Fast path: no unit options → original behavior (byte-identical)\n if (!opts || !opts.dims) {\n return formatCodeLineRaw(input)\n }\n\n const positional = input.positional\n const argsInput: Record<string, HostArg> = input.args ?? {}\n const posDims = opts.dims.positional ?? []\n const keyDims = opts.dims.byKey ?? {}\n\n // Positional args with per-index dimension\n const positionalParts = positional.map((arg, i) => {\n const dim = posDims[i] ?? null\n if (isPlainObjArg(arg)) {\n const entries = Object.entries(arg as Record<string, HostArg>)\n return `{ ${entries.map(([k, v]) => `${k}:${fmtValueWithDim(v, keyDims[k] ?? null, opts)}`).join(', ')} }`\n }\n return fmtValueWithDim(arg, dim, opts)\n })\n\n // args slot (transitional compat: appended as trailing option when last positional is not a plain object)\n const argsParts = Object.entries(argsInput).map(([k, v]) => `${k}:${fmtValueWithDim(v, keyDims[k] ?? null, opts)}`)\n const lastIsPlainObject = positional.length > 0 && isPlainObjArg(positional[positional.length - 1])\n\n let callArgs: string\n if (positionalParts.length > 0) {\n callArgs = positionalParts.join(', ')\n if (!lastIsPlainObject && argsParts.length > 0) {\n callArgs = [...positionalParts, `{ ${argsParts.join(', ')} }`].join(', ')\n }\n } else if (input.receiver) {\n callArgs = argsParts.length > 0 ? `{ ${argsParts.join(', ')} }` : ''\n } else {\n callArgs = argsParts.length > 0 ? `{ ${argsParts.join(', ')} }` : '{}'\n }\n\n // F2:命名空间前缀(缺省 cad);本机函数调用 callee 无命名空间前缀\n const nsExpr = input.namespace === undefined ? `cad.${input.callee}` : `${input.namespace}.${input.callee}`\n\n // 1) 解构:outputKeys + outputs 一一对应\n if (input.outputKeys && input.outputKeys.length > 0) {\n const destructure = input.outputKeys.map((k, i) => `${k}: ${input.outputs[i]}`).join(', ')\n return `const { ${destructure} } = ${nsExpr}(${callArgs})`\n }\n\n // 2) 成员调用\n if (input.receiver) {\n return `${input.receiver}.${input.callee}(${callArgs})`\n }\n\n // 3) 无赋值调用\n if (input.outputs.length === 0) {\n return `${nsExpr}(${callArgs})`\n }\n\n // 4) 赋值:outputDeclared → 裸重赋值;否则 let 声明\n const out = input.outputs[0]\n if (input.outputDeclared) return `${out} = ${nsExpr}(${callArgs})`\n return `let ${out} = ${nsExpr}(${callArgs})`\n}\n"]}
|
package/dist/lang/host-arg.d.ts
CHANGED
|
@@ -66,6 +66,12 @@ export interface HostExprRef {
|
|
|
66
66
|
text: string;
|
|
67
67
|
refs: string[];
|
|
68
68
|
params: string[];
|
|
69
|
+
/**
|
|
70
|
+
* P7/D10: when `true`, `fmtValue` emits the text without surrounding
|
|
71
|
+
* parentheses. Used by machine-generated unit literals (`10 * INCH`)
|
|
72
|
+
* to avoid the visually noisy `(10 * INCH)` form.
|
|
73
|
+
*/
|
|
74
|
+
bare?: boolean;
|
|
69
75
|
}
|
|
70
76
|
/** Union of all host-visible reference shapes. */
|
|
71
77
|
export type HostRef = HostVarRef | HostParamRef | HostCallRef | HostExprRef;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host-arg.d.ts","sourceRoot":"","sources":["../../src/lang/host-arg.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAIxC,wGAAwG;AACxG,UAAU,QAAQ;IAAG,IAAI,EAAE,MAAM,CAAA;CAAE;AACnC,yDAAyD;AACzD,UAAU,UAAU;IAAG,MAAM,EAAE,MAAM,CAAA;CAAE;AACvC,sEAAsE;AACtE,UAAU,SAAS;IAAG,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,EAAE,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE;AACtF,uEAAuE;AACvE,UAAU,SAAS;IAAG,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAA;CAAE;AAEjF,iGAAiG;AACjG,KAAK,KAAK,GAAG,SAAS,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,CAAA;AAiBtE,mFAAmF;AACnF,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,SAAS,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;CACb;AAED,qFAAqF;AACrF,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,WAAW,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;CACb;AAED,6FAA6F;AAC7F,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,UAAU,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,OAAO,EAAE,CAAA;IACf,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,uFAAuF;AACvF,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,UAAU,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,MAAM,EAAE,MAAM,EAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"host-arg.d.ts","sourceRoot":"","sources":["../../src/lang/host-arg.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host-arg.js","sourceRoot":"","sources":["../../src/lang/host-arg.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * host-arg — 宿主友好位置参数类型(IR 屏蔽层)\n *\n * 宿主(3d_editor 等)只接触 `HostArg`,不 import 任何 IR 类型。\n *\n * IR→Host 方向(`argIRToHost`):只认 `$` 前缀标记键(`$ref`/`$param`/`$call`/`$expr`),\n * 不认 `kind`,因此 parser 从 `.fai.js` 源码产生的字面量对象不会被误判。\n *\n * Host→IR 方向(`hostArgToIR`):按 `kind` 字段 + 形状守卫判定。\n *\n * **保留字规则(确定性裁决)**:普通对象若 `kind` 字段的值 ∈ `HOST_REF_KINDS`\n * 且完整匹配对应变体形状,一律按引用处理。即:字面量参数对象中禁止出现\n * 这 4 个 `kind` 值。此约束写入 JSDoc 与 `docs/api-contract.md`。\n *\n * 注意:`HostRef` 在结构上是 `JsonValue` 的子类型,因此 `HostArg` 在 TS 层面\n * 约等于 `JsonValue`,判别依赖运行时守卫而非类型系统——这是有意为之。\n */\n\nimport type { JsonValue } from './types'\n\n// ── 内联 IR 守卫(原 types.ts 的 IR 类型已删除,守卫逻辑内联于此) ──\n\n/** IR marker: variable reference `{$ref: string}` (legacy IR form, still recognized by argIRToHost). */\ninterface IRVarRef { $ref: string }\n/** IR marker: parameter reference `{$param: string}`. */\ninterface IRParamRef { $param: string }\n/** IR marker: nested call `{$call: { callee, args, namespace? }}`. */\ninterface IRCallRef { $call: { callee: string; args: unknown[]; namespace?: string } }\n/** IR marker: runtime expression `{$expr: { text, refs, params }}`. */\ninterface IRExprRef { $expr: { text: string; refs: string[]; params: string[] } }\n\n/** Union of legacy IR marker shapes (used by argIRToHost for backward-compatible conversion). */\ntype ArgIR = JsonValue | IRVarRef | IRParamRef | IRCallRef | IRExprRef\n\nfunction isIRVarRef(arg: unknown): arg is IRVarRef {\n return arg !== null && typeof arg === 'object' && !Array.isArray(arg) && '$ref' in arg\n}\nfunction isIRParamRef(arg: unknown): arg is IRParamRef {\n return arg !== null && typeof arg === 'object' && !Array.isArray(arg) && '$param' in arg\n}\nfunction isIRCallRef(arg: unknown): arg is IRCallRef {\n return arg !== null && typeof arg === 'object' && !Array.isArray(arg) && '$call' in arg\n}\nfunction isIRExprRef(arg: unknown): arg is IRExprRef {\n return arg !== null && typeof arg === 'object' && !Array.isArray(arg) && '$expr' in arg\n}\n\n// ── 宿主友好位置参数类型 ──\n\n/** Variable reference: a reference to a declared shape variable (e.g. `part0`). */\nexport interface HostVarRef {\n kind: 'var-ref'\n name: string\n}\n\n/** Parameter reference: a reference to a script parameter (e.g. `hole_diameter`). */\nexport interface HostParamRef {\n kind: 'param-ref'\n name: string\n}\n\n/** Nested call reference: a `cad.<callee>(...)` or `<ns>.<callee>(...)` embedded in args. */\nexport interface HostCallRef {\n kind: 'call-ref'\n callee: string\n args: HostArg[]\n /** Calling namespace (e.g. `mech.helper(...)` → 'mech'; absent = 'cad'). */\n namespace?: string\n}\n\n/** Runtime expression reference: an expression that could not be statically folded. */\nexport interface HostExprRef {\n kind: 'expr-ref'\n text: string\n refs: string[]\n params: string[]\n}\n\n/** Union of all host-visible reference shapes. */\nexport type HostRef = HostVarRef | HostParamRef | HostCallRef | HostExprRef\n\n/**\n * A host-friendly argument value: either a JSON literal or a host reference shape.\n *\n * **Discrimination relies on runtime guards** (`isHostRef` etc.), not the TS type system —\n * `HostRef` is structurally a subtype of `JsonValue`. This is intentional.\n * Literal parameter objects must not use `kind` values from `HOST_REF_KINDS`.\n */\nexport type HostArg = JsonValue | HostRef\n\n/** The set of `kind` values that identify host reference shapes (reserved words). */\nexport const HOST_REF_KINDS = ['var-ref', 'param-ref', 'call-ref', 'expr-ref'] as const\n/** The `kind` string literal type derived from {@link HOST_REF_KINDS}. */\nexport type HostRefKind = (typeof HOST_REF_KINDS)[number]\n\n// ── 辅助:普通对象检测 ──\n\n/**\n * Check whether a value is a non-null, non-array plain object.\n * @param a - the value to test.\n * @returns true when the value is a plain object (not null, not array).\n */\nfunction isPlainObject(a: unknown): a is Record<string, unknown> {\n return a !== null && typeof a === 'object' && !Array.isArray(a)\n}\n\n/**\n * Map all values of a plain object through a transform function (shallow key copy).\n * @param obj - the plain object to map.\n * @param fn - the transform function applied to each value.\n * @returns a new object with the same keys and transformed values.\n */\nfunction mapValues<T, U>(obj: Record<string, T>, fn: (v: T) => U): Record<string, U> {\n const out: Record<string, U> = {}\n for (const [k, v] of Object.entries(obj)) {\n out[k] = fn(v)\n }\n return out\n}\n\n// ── 守卫 ──\n\n/**\n * Type guard: is the value a `HostVarRef`?\n *\n * Checks `kind === 'var-ref'` and `name: string`. This is the Host→IR direction guard.\n * @param a - the argument value to test.\n * @returns true when the value is a `HostVarRef`.\n */\nexport function isHostVarRef(a: HostArg): a is HostVarRef {\n return isPlainObject(a) && a.kind === 'var-ref' && typeof a.name === 'string'\n}\n\n/**\n * Type guard: is the value a `HostParamRef`?\n * @param a - the argument value to test.\n * @returns true when the value is a `HostParamRef`.\n */\nexport function isHostParamRef(a: HostArg): a is HostParamRef {\n return isPlainObject(a) && a.kind === 'param-ref' && typeof a.name === 'string'\n}\n\n/**\n * Type guard: is the value a `HostCallRef`?\n * @param a - the argument value to test.\n * @returns true when the value is a `HostCallRef`.\n */\nexport function isHostCallRef(a: HostArg): a is HostCallRef {\n return (\n isPlainObject(a) &&\n a.kind === 'call-ref' &&\n typeof a.callee === 'string' &&\n Array.isArray(a.args)\n )\n}\n\n/**\n * Type guard: is the value a `HostExprRef`?\n * @param a - the argument value to test.\n * @returns true when the value is a `HostExprRef`.\n */\nexport function isHostExprRef(a: HostArg): a is HostExprRef {\n return (\n isPlainObject(a) &&\n a.kind === 'expr-ref' &&\n typeof a.text === 'string' &&\n Array.isArray(a.refs) &&\n Array.isArray(a.params)\n )\n}\n\n/**\n * Type guard: is the value any host reference shape?\n * @param a - the argument value to test.\n * @returns true when the value is one of `HostVarRef`/`HostParamRef`/`HostCallRef`/`HostExprRef`.\n */\nexport function isHostRef(a: HostArg): a is HostRef {\n return isHostVarRef(a) || isHostParamRef(a) || isHostCallRef(a) || isHostExprRef(a)\n}\n\n// ── 递归双向转换(core 内部,不导出) ──\n\n/**\n * Convert a legacy IR marker argument (`$`-prefixed) to a `HostArg` (host-friendly).\n *\n * Recursively transforms arrays and plain objects. Recognizes `$`-prefixed\n * marker keys only — `kind` fields are not checked in this direction.\n * @param arg - the IR argument to convert.\n * @returns the host-friendly argument.\n */\nexport function argIRToHost(arg: unknown): HostArg {\n if (isIRVarRef(arg)) return { kind: 'var-ref', name: arg.$ref }\n if (isIRParamRef(arg)) return { kind: 'param-ref', name: arg.$param }\n if (isIRCallRef(arg)) {\n const { callee, args, namespace } = arg.$call\n return {\n kind: 'call-ref',\n callee,\n args: args.map(argIRToHost) as HostArg[],\n ...(namespace !== undefined ? { namespace } : {}),\n }\n }\n if (isIRExprRef(arg)) {\n return {\n kind: 'expr-ref',\n text: arg.$expr.text,\n refs: [...arg.$expr.refs],\n params: [...arg.$expr.params],\n }\n }\n if (Array.isArray(arg)) return arg.map(argIRToHost) as unknown as HostArg\n if (isPlainObject(arg)) return mapValues(arg, argIRToHost) as unknown as HostArg\n return arg as HostArg\n}\n\n/**\n * Convert a `HostArg` (host-friendly) back to a legacy IR marker (`$`-prefixed).\n *\n * Uses `kind`-based guards to identify reference shapes. Literal objects\n * that don't match any reference kind are recursively transformed as plain data.\n * @param arg - the host-friendly argument.\n * @returns the IR marker argument.\n */\nexport function hostArgToIR(arg: HostArg): ArgIR {\n if (isHostVarRef(arg)) return { $ref: arg.name }\n if (isHostParamRef(arg)) return { $param: arg.name }\n if (isHostCallRef(arg)) {\n return {\n $call: {\n callee: arg.callee,\n args: arg.args.map(hostArgToIR) as unknown[],\n ...(arg.namespace !== undefined ? { namespace: arg.namespace } : {}),\n },\n }\n }\n if (isHostExprRef(arg)) {\n return {\n $expr: {\n text: arg.text,\n refs: [...arg.refs],\n params: [...arg.params],\n },\n }\n }\n if (Array.isArray(arg)) return arg.map(hostArgToIR) as unknown as ArgIR\n if (isPlainObject(arg)) return mapValues(arg as Record<string, HostArg>, hostArgToIR) as unknown as ArgIR\n return arg\n}\n\n// ── 导出辅助函数 ──\n\n/**\n * Render a `HostArg` to a human-readable display string (for timeline labels, read-only fields).\n *\n * - Primitives → `String(arg)`\n * - Arrays → `[a, b, …]` (recursive)\n * - var-ref/param-ref → `name`\n * - call-ref → `callee(a, b, …)` (recursive)\n * - expr-ref → `text`\n * - Plain objects → `JSON.stringify`\n * @param arg - the host argument to display.\n * @returns a human-readable string representation.\n */\nexport function hostArgToDisplay(arg: HostArg): string {\n if (isHostVarRef(arg) || isHostParamRef(arg)) return arg.name\n if (isHostCallRef(arg)) {\n const inner = arg.args.map(hostArgToDisplay).join(', ')\n return `${arg.callee}(${inner})`\n }\n if (isHostExprRef(arg)) return arg.text\n if (Array.isArray(arg)) return `[${arg.map(hostArgToDisplay).join(', ')}]`\n if (isPlainObject(arg)) return JSON.stringify(arg)\n return String(arg)\n}\n\n/**\n * Extract the literal value from a `HostArg`, returning `null` for reference shapes.\n * @param arg - the host argument.\n * @returns the literal value if `arg` is not a reference, otherwise `null`.\n */\nexport function hostArgToLiteral(arg: HostArg): JsonValue | null {\n if (isHostRef(arg)) return null\n return arg\n}\n"]}
|
|
1
|
+
{"version":3,"file":"host-arg.js","sourceRoot":"","sources":["../../src/lang/host-arg.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * host-arg — 宿主友好位置参数类型(IR 屏蔽层)\n *\n * 宿主(3d_editor 等)只接触 `HostArg`,不 import 任何 IR 类型。\n *\n * IR→Host 方向(`argIRToHost`):只认 `$` 前缀标记键(`$ref`/`$param`/`$call`/`$expr`),\n * 不认 `kind`,因此 parser 从 `.fai.js` 源码产生的字面量对象不会被误判。\n *\n * Host→IR 方向(`hostArgToIR`):按 `kind` 字段 + 形状守卫判定。\n *\n * **保留字规则(确定性裁决)**:普通对象若 `kind` 字段的值 ∈ `HOST_REF_KINDS`\n * 且完整匹配对应变体形状,一律按引用处理。即:字面量参数对象中禁止出现\n * 这 4 个 `kind` 值。此约束写入 JSDoc 与 `docs/api-contract.md`。\n *\n * 注意:`HostRef` 在结构上是 `JsonValue` 的子类型,因此 `HostArg` 在 TS 层面\n * 约等于 `JsonValue`,判别依赖运行时守卫而非类型系统——这是有意为之。\n */\n\nimport type { JsonValue } from './types'\n\n// ── 内联 IR 守卫(原 types.ts 的 IR 类型已删除,守卫逻辑内联于此) ──\n\n/** IR marker: variable reference `{$ref: string}` (legacy IR form, still recognized by argIRToHost). */\ninterface IRVarRef { $ref: string }\n/** IR marker: parameter reference `{$param: string}`. */\ninterface IRParamRef { $param: string }\n/** IR marker: nested call `{$call: { callee, args, namespace? }}`. */\ninterface IRCallRef { $call: { callee: string; args: unknown[]; namespace?: string } }\n/** IR marker: runtime expression `{$expr: { text, refs, params }}`. */\ninterface IRExprRef { $expr: { text: string; refs: string[]; params: string[] } }\n\n/** Union of legacy IR marker shapes (used by argIRToHost for backward-compatible conversion). */\ntype ArgIR = JsonValue | IRVarRef | IRParamRef | IRCallRef | IRExprRef\n\nfunction isIRVarRef(arg: unknown): arg is IRVarRef {\n return arg !== null && typeof arg === 'object' && !Array.isArray(arg) && '$ref' in arg\n}\nfunction isIRParamRef(arg: unknown): arg is IRParamRef {\n return arg !== null && typeof arg === 'object' && !Array.isArray(arg) && '$param' in arg\n}\nfunction isIRCallRef(arg: unknown): arg is IRCallRef {\n return arg !== null && typeof arg === 'object' && !Array.isArray(arg) && '$call' in arg\n}\nfunction isIRExprRef(arg: unknown): arg is IRExprRef {\n return arg !== null && typeof arg === 'object' && !Array.isArray(arg) && '$expr' in arg\n}\n\n// ── 宿主友好位置参数类型 ──\n\n/** Variable reference: a reference to a declared shape variable (e.g. `part0`). */\nexport interface HostVarRef {\n kind: 'var-ref'\n name: string\n}\n\n/** Parameter reference: a reference to a script parameter (e.g. `hole_diameter`). */\nexport interface HostParamRef {\n kind: 'param-ref'\n name: string\n}\n\n/** Nested call reference: a `cad.<callee>(...)` or `<ns>.<callee>(...)` embedded in args. */\nexport interface HostCallRef {\n kind: 'call-ref'\n callee: string\n args: HostArg[]\n /** Calling namespace (e.g. `mech.helper(...)` → 'mech'; absent = 'cad'). */\n namespace?: string\n}\n\n/** Runtime expression reference: an expression that could not be statically folded. */\nexport interface HostExprRef {\n kind: 'expr-ref'\n text: string\n refs: string[]\n params: string[]\n /**\n * P7/D10: when `true`, `fmtValue` emits the text without surrounding\n * parentheses. Used by machine-generated unit literals (`10 * INCH`)\n * to avoid the visually noisy `(10 * INCH)` form.\n */\n bare?: boolean\n}\n\n/** Union of all host-visible reference shapes. */\nexport type HostRef = HostVarRef | HostParamRef | HostCallRef | HostExprRef\n\n/**\n * A host-friendly argument value: either a JSON literal or a host reference shape.\n *\n * **Discrimination relies on runtime guards** (`isHostRef` etc.), not the TS type system —\n * `HostRef` is structurally a subtype of `JsonValue`. This is intentional.\n * Literal parameter objects must not use `kind` values from `HOST_REF_KINDS`.\n */\nexport type HostArg = JsonValue | HostRef\n\n/** The set of `kind` values that identify host reference shapes (reserved words). */\nexport const HOST_REF_KINDS = ['var-ref', 'param-ref', 'call-ref', 'expr-ref'] as const\n/** The `kind` string literal type derived from {@link HOST_REF_KINDS}. */\nexport type HostRefKind = (typeof HOST_REF_KINDS)[number]\n\n// ── 辅助:普通对象检测 ──\n\n/**\n * Check whether a value is a non-null, non-array plain object.\n * @param a - the value to test.\n * @returns true when the value is a plain object (not null, not array).\n */\nfunction isPlainObject(a: unknown): a is Record<string, unknown> {\n return a !== null && typeof a === 'object' && !Array.isArray(a)\n}\n\n/**\n * Map all values of a plain object through a transform function (shallow key copy).\n * @param obj - the plain object to map.\n * @param fn - the transform function applied to each value.\n * @returns a new object with the same keys and transformed values.\n */\nfunction mapValues<T, U>(obj: Record<string, T>, fn: (v: T) => U): Record<string, U> {\n const out: Record<string, U> = {}\n for (const [k, v] of Object.entries(obj)) {\n out[k] = fn(v)\n }\n return out\n}\n\n// ── 守卫 ──\n\n/**\n * Type guard: is the value a `HostVarRef`?\n *\n * Checks `kind === 'var-ref'` and `name: string`. This is the Host→IR direction guard.\n * @param a - the argument value to test.\n * @returns true when the value is a `HostVarRef`.\n */\nexport function isHostVarRef(a: HostArg): a is HostVarRef {\n return isPlainObject(a) && a.kind === 'var-ref' && typeof a.name === 'string'\n}\n\n/**\n * Type guard: is the value a `HostParamRef`?\n * @param a - the argument value to test.\n * @returns true when the value is a `HostParamRef`.\n */\nexport function isHostParamRef(a: HostArg): a is HostParamRef {\n return isPlainObject(a) && a.kind === 'param-ref' && typeof a.name === 'string'\n}\n\n/**\n * Type guard: is the value a `HostCallRef`?\n * @param a - the argument value to test.\n * @returns true when the value is a `HostCallRef`.\n */\nexport function isHostCallRef(a: HostArg): a is HostCallRef {\n return (\n isPlainObject(a) &&\n a.kind === 'call-ref' &&\n typeof a.callee === 'string' &&\n Array.isArray(a.args)\n )\n}\n\n/**\n * Type guard: is the value a `HostExprRef`?\n * @param a - the argument value to test.\n * @returns true when the value is a `HostExprRef`.\n */\nexport function isHostExprRef(a: HostArg): a is HostExprRef {\n return (\n isPlainObject(a) &&\n a.kind === 'expr-ref' &&\n typeof a.text === 'string' &&\n Array.isArray(a.refs) &&\n Array.isArray(a.params)\n )\n}\n\n/**\n * Type guard: is the value any host reference shape?\n * @param a - the argument value to test.\n * @returns true when the value is one of `HostVarRef`/`HostParamRef`/`HostCallRef`/`HostExprRef`.\n */\nexport function isHostRef(a: HostArg): a is HostRef {\n return isHostVarRef(a) || isHostParamRef(a) || isHostCallRef(a) || isHostExprRef(a)\n}\n\n// ── 递归双向转换(core 内部,不导出) ──\n\n/**\n * Convert a legacy IR marker argument (`$`-prefixed) to a `HostArg` (host-friendly).\n *\n * Recursively transforms arrays and plain objects. Recognizes `$`-prefixed\n * marker keys only — `kind` fields are not checked in this direction.\n * @param arg - the IR argument to convert.\n * @returns the host-friendly argument.\n */\nexport function argIRToHost(arg: unknown): HostArg {\n if (isIRVarRef(arg)) return { kind: 'var-ref', name: arg.$ref }\n if (isIRParamRef(arg)) return { kind: 'param-ref', name: arg.$param }\n if (isIRCallRef(arg)) {\n const { callee, args, namespace } = arg.$call\n return {\n kind: 'call-ref',\n callee,\n args: args.map(argIRToHost) as HostArg[],\n ...(namespace !== undefined ? { namespace } : {}),\n }\n }\n if (isIRExprRef(arg)) {\n return {\n kind: 'expr-ref',\n text: arg.$expr.text,\n refs: [...arg.$expr.refs],\n params: [...arg.$expr.params],\n }\n }\n if (Array.isArray(arg)) return arg.map(argIRToHost) as unknown as HostArg\n if (isPlainObject(arg)) return mapValues(arg, argIRToHost) as unknown as HostArg\n return arg as HostArg\n}\n\n/**\n * Convert a `HostArg` (host-friendly) back to a legacy IR marker (`$`-prefixed).\n *\n * Uses `kind`-based guards to identify reference shapes. Literal objects\n * that don't match any reference kind are recursively transformed as plain data.\n * @param arg - the host-friendly argument.\n * @returns the IR marker argument.\n */\nexport function hostArgToIR(arg: HostArg): ArgIR {\n if (isHostVarRef(arg)) return { $ref: arg.name }\n if (isHostParamRef(arg)) return { $param: arg.name }\n if (isHostCallRef(arg)) {\n return {\n $call: {\n callee: arg.callee,\n args: arg.args.map(hostArgToIR) as unknown[],\n ...(arg.namespace !== undefined ? { namespace: arg.namespace } : {}),\n },\n }\n }\n if (isHostExprRef(arg)) {\n return {\n $expr: {\n text: arg.text,\n refs: [...arg.refs],\n params: [...arg.params],\n },\n }\n }\n if (Array.isArray(arg)) return arg.map(hostArgToIR) as unknown as ArgIR\n if (isPlainObject(arg)) return mapValues(arg as Record<string, HostArg>, hostArgToIR) as unknown as ArgIR\n return arg\n}\n\n// ── 导出辅助函数 ──\n\n/**\n * Render a `HostArg` to a human-readable display string (for timeline labels, read-only fields).\n *\n * - Primitives → `String(arg)`\n * - Arrays → `[a, b, …]` (recursive)\n * - var-ref/param-ref → `name`\n * - call-ref → `callee(a, b, …)` (recursive)\n * - expr-ref → `text`\n * - Plain objects → `JSON.stringify`\n * @param arg - the host argument to display.\n * @returns a human-readable string representation.\n */\nexport function hostArgToDisplay(arg: HostArg): string {\n if (isHostVarRef(arg) || isHostParamRef(arg)) return arg.name\n if (isHostCallRef(arg)) {\n const inner = arg.args.map(hostArgToDisplay).join(', ')\n return `${arg.callee}(${inner})`\n }\n if (isHostExprRef(arg)) return arg.text\n if (Array.isArray(arg)) return `[${arg.map(hostArgToDisplay).join(', ')}]`\n if (isPlainObject(arg)) return JSON.stringify(arg)\n return String(arg)\n}\n\n/**\n * Extract the literal value from a `HostArg`, returning `null` for reference shapes.\n * @param arg - the host argument.\n * @returns the literal value if `arg` is not a reference, otherwise `null`.\n */\nexport function hostArgToLiteral(arg: HostArg): JsonValue | null {\n if (isHostRef(arg)) return null\n return arg\n}\n"]}
|
|
@@ -18,6 +18,7 @@ import type { StatementSummary } from './statement-summary.js';
|
|
|
18
18
|
import type { ScriptMetaIR, TerminalShape } from './types.js';
|
|
19
19
|
import { type StmtId } from '../identity.js';
|
|
20
20
|
import { type SecurityPolicy } from './security-scanner.js';
|
|
21
|
+
import type { DimName } from '../units.js';
|
|
21
22
|
/** 参数表条目(参数面板:const X = <字面量> → 名字/值/是否计算表达式) */
|
|
22
23
|
export interface ParamEntry {
|
|
23
24
|
name: string;
|
|
@@ -179,7 +180,31 @@ export interface ExtractMetadataOptions {
|
|
|
179
180
|
security?: SecurityPolicy;
|
|
180
181
|
/** S7 命名空间保护名(缺省 = namespaces;append 场景可指定更小集合仅命名空间名) */
|
|
181
182
|
nsNames?: string[];
|
|
183
|
+
/**
|
|
184
|
+
* P4/P6 (unit-system D8): callee → 量纲声明的映射,供 dimension pass 做静态
|
|
185
|
+
* 量纲校验。调用方从 op 注册表取出透传(lang 不碰 op 注册表铁律)。
|
|
186
|
+
*/
|
|
187
|
+
opDims?: OpDimMap;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* P4/P6 (unit-system D8): 一个 op 的脚本面量纲声明,供静态 dimension 检查使用。
|
|
191
|
+
* 由调用方(CadRuntime/CLI/codeToArgs)从 op 注册表取出透传,`lang/` 本身不碰
|
|
192
|
+
* op 注册表(铁律:lang 不得依赖 op 注册表)。
|
|
193
|
+
*/
|
|
194
|
+
export interface OpDimDecl {
|
|
195
|
+
/** 参数名 → 量纲;缺省键视为无量纲。 */
|
|
196
|
+
paramDims?: Record<string, DimName>;
|
|
197
|
+
/** 函数调用结果的量纲。 */
|
|
198
|
+
retDim?: DimName;
|
|
199
|
+
/** D11 slot-map(positional→object 装箱表);位置形态校验用。 */
|
|
200
|
+
slotMap?: {
|
|
201
|
+
keys: string[];
|
|
202
|
+
vec3Keys?: string[];
|
|
203
|
+
shapeArity?: number;
|
|
204
|
+
};
|
|
182
205
|
}
|
|
206
|
+
/** P4/P6: callee 名 → 量纲声明(供 extractMetadata 的 dimension pass 消费)。 */
|
|
207
|
+
export type OpDimMap = Record<string, OpDimDecl>;
|
|
183
208
|
/**
|
|
184
209
|
* 从源码文本提取 UI 通道元数据(UiMetadata)。
|
|
185
210
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadata-extractor.d.ts","sourceRoot":"","sources":["../../src/lang/metadata-extractor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAC1D,OAAO,EAAuC,KAAK,MAAM,EAAE,MAAM,aAAa,CAAA;AAK9E,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"metadata-extractor.d.ts","sourceRoot":"","sources":["../../src/lang/metadata-extractor.ts"],"names":[],"mappings":"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"}
|