@manifesto-ai/compiler 1.6.2 → 1.8.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.
Files changed (201) hide show
  1. package/README.md +67 -18
  2. package/dist/chunk-BH25NHMN.js +74 -0
  3. package/dist/chunk-BH25NHMN.js.map +1 -0
  4. package/dist/chunk-D62NIFP4.js +33 -0
  5. package/dist/chunk-D62NIFP4.js.map +1 -0
  6. package/dist/chunk-MKLDAZ2Z.js +6920 -0
  7. package/dist/chunk-MKLDAZ2Z.js.map +1 -0
  8. package/dist/esbuild.d.ts +8 -0
  9. package/dist/esbuild.js +14 -0
  10. package/dist/esbuild.js.map +1 -0
  11. package/dist/index.d.ts +2810 -11
  12. package/dist/index.js +2425 -43
  13. package/dist/index.js.map +1 -1
  14. package/dist/node-loader.d.ts +18 -0
  15. package/dist/node-loader.js +47 -0
  16. package/dist/node-loader.js.map +1 -0
  17. package/dist/rollup.d.ts +8 -0
  18. package/dist/rollup.js +14 -0
  19. package/dist/rollup.js.map +1 -0
  20. package/dist/rspack.d.ts +7 -0
  21. package/dist/rspack.js +14 -0
  22. package/dist/rspack.js.map +1 -0
  23. package/dist/unplugin-6wnvFiEo.d.ts +17 -0
  24. package/dist/vite.d.ts +8 -17
  25. package/dist/vite.js +13 -33
  26. package/dist/vite.js.map +1 -1
  27. package/dist/webpack.d.ts +8 -0
  28. package/dist/webpack.js +14 -0
  29. package/dist/webpack.js.map +1 -0
  30. package/package.json +40 -22
  31. package/dist/analyzer/index.d.ts +0 -6
  32. package/dist/analyzer/index.d.ts.map +0 -1
  33. package/dist/analyzer/index.js +0 -6
  34. package/dist/analyzer/index.js.map +0 -1
  35. package/dist/analyzer/scope.d.ts +0 -77
  36. package/dist/analyzer/scope.d.ts.map +0 -1
  37. package/dist/analyzer/scope.js +0 -296
  38. package/dist/analyzer/scope.js.map +0 -1
  39. package/dist/analyzer/validator.d.ts +0 -60
  40. package/dist/analyzer/validator.d.ts.map +0 -1
  41. package/dist/analyzer/validator.js +0 -439
  42. package/dist/analyzer/validator.js.map +0 -1
  43. package/dist/api/compile-mel-patch-collector.d.ts +0 -32
  44. package/dist/api/compile-mel-patch-collector.d.ts.map +0 -1
  45. package/dist/api/compile-mel-patch-collector.js +0 -425
  46. package/dist/api/compile-mel-patch-collector.js.map +0 -1
  47. package/dist/api/compile-mel-patch-expr.d.ts +0 -9
  48. package/dist/api/compile-mel-patch-expr.d.ts.map +0 -1
  49. package/dist/api/compile-mel-patch-expr.js +0 -179
  50. package/dist/api/compile-mel-patch-expr.js.map +0 -1
  51. package/dist/api/compile-mel-patch-location.d.ts +0 -10
  52. package/dist/api/compile-mel-patch-location.d.ts.map +0 -1
  53. package/dist/api/compile-mel-patch-location.js +0 -48
  54. package/dist/api/compile-mel-patch-location.js.map +0 -1
  55. package/dist/api/compile-mel-patch.d.ts +0 -6
  56. package/dist/api/compile-mel-patch.d.ts.map +0 -1
  57. package/dist/api/compile-mel-patch.js +0 -244
  58. package/dist/api/compile-mel-patch.js.map +0 -1
  59. package/dist/api/compile-mel.d.ts +0 -126
  60. package/dist/api/compile-mel.d.ts.map +0 -1
  61. package/dist/api/compile-mel.js +0 -114
  62. package/dist/api/compile-mel.js.map +0 -1
  63. package/dist/api/index.d.ts +0 -10
  64. package/dist/api/index.d.ts.map +0 -1
  65. package/dist/api/index.js +0 -9
  66. package/dist/api/index.js.map +0 -1
  67. package/dist/diagnostics/codes.d.ts +0 -25
  68. package/dist/diagnostics/codes.d.ts.map +0 -1
  69. package/dist/diagnostics/codes.js +0 -154
  70. package/dist/diagnostics/codes.js.map +0 -1
  71. package/dist/diagnostics/index.d.ts +0 -6
  72. package/dist/diagnostics/index.d.ts.map +0 -1
  73. package/dist/diagnostics/index.js +0 -6
  74. package/dist/diagnostics/index.js.map +0 -1
  75. package/dist/diagnostics/types.d.ts +0 -67
  76. package/dist/diagnostics/types.d.ts.map +0 -1
  77. package/dist/diagnostics/types.js +0 -58
  78. package/dist/diagnostics/types.js.map +0 -1
  79. package/dist/evaluation/context.d.ts +0 -91
  80. package/dist/evaluation/context.d.ts.map +0 -1
  81. package/dist/evaluation/context.js +0 -53
  82. package/dist/evaluation/context.js.map +0 -1
  83. package/dist/evaluation/evaluate-expr.d.ts +0 -24
  84. package/dist/evaluation/evaluate-expr.d.ts.map +0 -1
  85. package/dist/evaluation/evaluate-expr.js +0 -577
  86. package/dist/evaluation/evaluate-expr.js.map +0 -1
  87. package/dist/evaluation/evaluate-patch.d.ts +0 -123
  88. package/dist/evaluation/evaluate-patch.d.ts.map +0 -1
  89. package/dist/evaluation/evaluate-patch.js +0 -202
  90. package/dist/evaluation/evaluate-patch.js.map +0 -1
  91. package/dist/evaluation/evaluate-runtime-patch.d.ts +0 -86
  92. package/dist/evaluation/evaluate-runtime-patch.d.ts.map +0 -1
  93. package/dist/evaluation/evaluate-runtime-patch.js +0 -185
  94. package/dist/evaluation/evaluate-runtime-patch.js.map +0 -1
  95. package/dist/evaluation/index.d.ts +0 -15
  96. package/dist/evaluation/index.d.ts.map +0 -1
  97. package/dist/evaluation/index.js +0 -13
  98. package/dist/evaluation/index.js.map +0 -1
  99. package/dist/generator/index.d.ts +0 -7
  100. package/dist/generator/index.d.ts.map +0 -1
  101. package/dist/generator/index.js +0 -7
  102. package/dist/generator/index.js.map +0 -1
  103. package/dist/generator/ir.d.ts +0 -348
  104. package/dist/generator/ir.d.ts.map +0 -1
  105. package/dist/generator/ir.js +0 -715
  106. package/dist/generator/ir.js.map +0 -1
  107. package/dist/generator/lowering.d.ts +0 -11
  108. package/dist/generator/lowering.d.ts.map +0 -1
  109. package/dist/generator/lowering.js +0 -369
  110. package/dist/generator/lowering.js.map +0 -1
  111. package/dist/generator/normalizer.d.ts +0 -16
  112. package/dist/generator/normalizer.d.ts.map +0 -1
  113. package/dist/generator/normalizer.js +0 -181
  114. package/dist/generator/normalizer.js.map +0 -1
  115. package/dist/index.d.ts.map +0 -1
  116. package/dist/lexer/index.d.ts +0 -7
  117. package/dist/lexer/index.d.ts.map +0 -1
  118. package/dist/lexer/index.js +0 -7
  119. package/dist/lexer/index.js.map +0 -1
  120. package/dist/lexer/lexer.d.ts +0 -59
  121. package/dist/lexer/lexer.d.ts.map +0 -1
  122. package/dist/lexer/lexer.js +0 -433
  123. package/dist/lexer/lexer.js.map +0 -1
  124. package/dist/lexer/source-location.d.ts +0 -41
  125. package/dist/lexer/source-location.d.ts.map +0 -1
  126. package/dist/lexer/source-location.js +0 -33
  127. package/dist/lexer/source-location.js.map +0 -1
  128. package/dist/lexer/tokens.d.ts +0 -47
  129. package/dist/lexer/tokens.d.ts.map +0 -1
  130. package/dist/lexer/tokens.js +0 -73
  131. package/dist/lexer/tokens.js.map +0 -1
  132. package/dist/loader.d.ts +0 -23
  133. package/dist/loader.d.ts.map +0 -1
  134. package/dist/loader.js +0 -62
  135. package/dist/loader.js.map +0 -1
  136. package/dist/lowering/context.d.ts +0 -96
  137. package/dist/lowering/context.d.ts.map +0 -1
  138. package/dist/lowering/context.js +0 -42
  139. package/dist/lowering/context.js.map +0 -1
  140. package/dist/lowering/errors.d.ts +0 -84
  141. package/dist/lowering/errors.d.ts.map +0 -1
  142. package/dist/lowering/errors.js +0 -81
  143. package/dist/lowering/errors.js.map +0 -1
  144. package/dist/lowering/index.d.ts +0 -20
  145. package/dist/lowering/index.d.ts.map +0 -1
  146. package/dist/lowering/index.js +0 -13
  147. package/dist/lowering/index.js.map +0 -1
  148. package/dist/lowering/lower-expr.d.ts +0 -76
  149. package/dist/lowering/lower-expr.d.ts.map +0 -1
  150. package/dist/lowering/lower-expr.js +0 -366
  151. package/dist/lowering/lower-expr.js.map +0 -1
  152. package/dist/lowering/lower-patch.d.ts +0 -231
  153. package/dist/lowering/lower-patch.d.ts.map +0 -1
  154. package/dist/lowering/lower-patch.js +0 -146
  155. package/dist/lowering/lower-patch.js.map +0 -1
  156. package/dist/lowering/lower-runtime-patch.d.ts +0 -100
  157. package/dist/lowering/lower-runtime-patch.d.ts.map +0 -1
  158. package/dist/lowering/lower-runtime-patch.js +0 -49
  159. package/dist/lowering/lower-runtime-patch.js.map +0 -1
  160. package/dist/mel-module.d.ts +0 -13
  161. package/dist/mel-module.d.ts.map +0 -1
  162. package/dist/mel-module.js +0 -33
  163. package/dist/mel-module.js.map +0 -1
  164. package/dist/parser/ast.d.ts +0 -344
  165. package/dist/parser/ast.d.ts.map +0 -1
  166. package/dist/parser/ast.js +0 -24
  167. package/dist/parser/ast.js.map +0 -1
  168. package/dist/parser/index.d.ts +0 -7
  169. package/dist/parser/index.d.ts.map +0 -1
  170. package/dist/parser/index.js +0 -7
  171. package/dist/parser/index.js.map +0 -1
  172. package/dist/parser/parser.d.ts +0 -92
  173. package/dist/parser/parser.d.ts.map +0 -1
  174. package/dist/parser/parser.js +0 -892
  175. package/dist/parser/parser.js.map +0 -1
  176. package/dist/parser/precedence.d.ts +0 -44
  177. package/dist/parser/precedence.d.ts.map +0 -1
  178. package/dist/parser/precedence.js +0 -69
  179. package/dist/parser/precedence.js.map +0 -1
  180. package/dist/renderer/expr-node.d.ts +0 -172
  181. package/dist/renderer/expr-node.d.ts.map +0 -1
  182. package/dist/renderer/expr-node.js +0 -218
  183. package/dist/renderer/expr-node.js.map +0 -1
  184. package/dist/renderer/fragment.d.ts +0 -84
  185. package/dist/renderer/fragment.d.ts.map +0 -1
  186. package/dist/renderer/fragment.js +0 -172
  187. package/dist/renderer/fragment.js.map +0 -1
  188. package/dist/renderer/index.d.ts +0 -23
  189. package/dist/renderer/index.d.ts.map +0 -1
  190. package/dist/renderer/index.js +0 -27
  191. package/dist/renderer/index.js.map +0 -1
  192. package/dist/renderer/patch-op.d.ts +0 -82
  193. package/dist/renderer/patch-op.d.ts.map +0 -1
  194. package/dist/renderer/patch-op.js +0 -204
  195. package/dist/renderer/patch-op.js.map +0 -1
  196. package/dist/renderer/type-expr.d.ts +0 -61
  197. package/dist/renderer/type-expr.d.ts.map +0 -1
  198. package/dist/renderer/type-expr.js +0 -131
  199. package/dist/renderer/type-expr.js.map +0 -1
  200. package/dist/vite.d.ts.map +0 -1
  201. package/loader.cjs +0 -22
@@ -1,715 +0,0 @@
1
- /**
2
- * IR Generator - Transforms MEL AST to Core DomainSchema
3
- * Based on MEL SPEC v0.3.3 Section 5
4
- */
5
- import { normalizeExpr, normalizeFunctionCall } from "./normalizer.js";
6
- import { hashSchemaSync, sha256Sync } from "@manifesto-ai/core";
7
- function createContext(domainName) {
8
- return {
9
- domainName,
10
- stateFields: new Set(),
11
- computedFields: new Set(),
12
- actionParams: new Map(),
13
- onceIntentCounters: new Map(),
14
- currentAction: null,
15
- diagnostics: [],
16
- typeDefs: new Map(),
17
- };
18
- }
19
- // ============ Main Generator ============
20
- /**
21
- * Generate Core DomainSchema from MEL AST
22
- */
23
- export function generate(program) {
24
- const ctx = createContext(program.domain.name);
25
- // First pass: collect state and computed field names
26
- collectFieldNames(program.domain, ctx);
27
- // v0.3.3: Generate types first
28
- const types = generateTypes(program.domain, ctx);
29
- // Generate schema parts
30
- const state = generateState(program.domain, ctx);
31
- const computed = generateComputed(program.domain, ctx);
32
- const actions = generateActions(program.domain, ctx);
33
- if (ctx.diagnostics.some(d => d.severity === "error")) {
34
- return {
35
- schema: null,
36
- diagnostics: ctx.diagnostics,
37
- };
38
- }
39
- // Create schema
40
- const schemaWithoutHash = {
41
- id: `mel:${program.domain.name.toLowerCase()}`,
42
- version: "1.0.0",
43
- types,
44
- state,
45
- computed,
46
- actions,
47
- meta: {
48
- name: program.domain.name,
49
- },
50
- };
51
- // Compute hash
52
- const hash = computeHash(schemaWithoutHash);
53
- const schema = {
54
- ...schemaWithoutHash,
55
- hash,
56
- };
57
- return {
58
- schema,
59
- diagnostics: ctx.diagnostics,
60
- };
61
- }
62
- // ============ Field Collection ============
63
- function collectFieldNames(domain, ctx) {
64
- // Collect type declarations first
65
- for (const typeDecl of domain.types) {
66
- ctx.typeDefs.set(typeDecl.name, typeDecl);
67
- }
68
- for (const member of domain.members) {
69
- if (member.kind === "state") {
70
- for (const field of member.fields) {
71
- ctx.stateFields.add(field.name);
72
- }
73
- }
74
- else if (member.kind === "computed") {
75
- ctx.computedFields.add(member.name);
76
- }
77
- }
78
- }
79
- // ============ Type Generation (v0.3.3) ============
80
- function generateTypes(domain, _ctx) {
81
- const types = {};
82
- for (const typeDecl of domain.types) {
83
- types[typeDecl.name] = {
84
- name: typeDecl.name,
85
- definition: typeExprToDefinition(typeDecl.typeExpr),
86
- };
87
- }
88
- return types;
89
- }
90
- function typeExprToDefinition(typeExpr) {
91
- switch (typeExpr.kind) {
92
- case "simpleType":
93
- // Primitive types vs type references
94
- if (["string", "number", "boolean", "null"].includes(typeExpr.name)) {
95
- return { kind: "primitive", type: typeExpr.name };
96
- }
97
- // User-defined type reference
98
- return { kind: "ref", name: typeExpr.name };
99
- case "arrayType":
100
- return {
101
- kind: "array",
102
- element: typeExprToDefinition(typeExpr.elementType),
103
- };
104
- case "recordType":
105
- return {
106
- kind: "record",
107
- key: typeExprToDefinition(typeExpr.keyType),
108
- value: typeExprToDefinition(typeExpr.valueType),
109
- };
110
- case "objectType":
111
- const fields = {};
112
- for (const field of typeExpr.fields) {
113
- fields[field.name] = {
114
- type: typeExprToDefinition(field.typeExpr),
115
- optional: field.optional,
116
- };
117
- }
118
- return { kind: "object", fields };
119
- case "unionType":
120
- return {
121
- kind: "union",
122
- types: typeExpr.types.map(typeExprToDefinition),
123
- };
124
- case "literalType":
125
- return { kind: "literal", value: typeExpr.value };
126
- default:
127
- // Exhaustive check
128
- const _exhaustive = typeExpr;
129
- throw new Error(`Unknown type expression kind: ${typeExpr.kind}`);
130
- }
131
- }
132
- // ============ State Generation ============
133
- function generateState(domain, ctx) {
134
- const fields = {};
135
- for (const member of domain.members) {
136
- if (member.kind === "state") {
137
- for (const field of member.fields) {
138
- fields[field.name] = generateFieldSpec(field, ctx);
139
- }
140
- }
141
- }
142
- return { fields };
143
- }
144
- function generateFieldSpec(field, ctx) {
145
- const spec = typeExprToFieldSpec(field.typeExpr, ctx);
146
- const defaultValue = field.initializer
147
- ? evaluateInitializer(field.initializer, ctx)
148
- : undefined;
149
- return {
150
- ...spec,
151
- required: true,
152
- default: defaultValue,
153
- };
154
- }
155
- /**
156
- * Convert TypeExprNode to complete FieldSpec (including nested fields)
157
- * This is the full conversion that includes `fields` for object types
158
- */
159
- function typeExprToFieldSpec(typeExpr, ctx) {
160
- switch (typeExpr.kind) {
161
- case "simpleType":
162
- switch (typeExpr.name) {
163
- case "string": return { type: "string", required: true };
164
- case "number": return { type: "number", required: true };
165
- case "boolean": return { type: "boolean", required: true };
166
- case "null": return { type: "null", required: true };
167
- default: {
168
- // User-defined type - look up and expand
169
- const typeDef = ctx.typeDefs.get(typeExpr.name);
170
- if (typeDef) {
171
- return typeExprToFieldSpec(typeDef.typeExpr, ctx);
172
- }
173
- // Unknown type - treat as opaque object
174
- return { type: "object", required: true };
175
- }
176
- }
177
- case "unionType": {
178
- // Check if it's a literal union (enum)
179
- const literals = [];
180
- let isLiteralUnion = true;
181
- let hasNull = false;
182
- for (const t of typeExpr.types) {
183
- if (t.kind === "literalType") {
184
- if (t.value === null) {
185
- hasNull = true;
186
- }
187
- literals.push(t.value);
188
- continue;
189
- }
190
- if (t.kind === "simpleType" && t.name === "null") {
191
- hasNull = true;
192
- literals.push(null);
193
- continue;
194
- }
195
- isLiteralUnion = false;
196
- }
197
- if (isLiteralUnion && literals.length > 0) {
198
- return { type: { enum: literals }, required: !hasNull };
199
- }
200
- // Nullable type: T | null -> get spec of T
201
- if (hasNull) {
202
- for (const t of typeExpr.types) {
203
- if (t.kind !== "simpleType" || t.name !== "null") {
204
- const innerSpec = typeExprToFieldSpec(t, ctx);
205
- return { ...innerSpec, required: false };
206
- }
207
- }
208
- }
209
- // Mixed union - default to first non-null type
210
- for (const t of typeExpr.types) {
211
- if (t.kind !== "simpleType" || t.name !== "null") {
212
- return typeExprToFieldSpec(t, ctx);
213
- }
214
- }
215
- return { type: "null", required: true };
216
- }
217
- case "arrayType": {
218
- const itemSpec = typeExprToFieldSpec(typeExpr.elementType, ctx);
219
- return {
220
- type: "array",
221
- required: true,
222
- items: itemSpec,
223
- };
224
- }
225
- case "recordType":
226
- return { type: "object", required: true };
227
- case "literalType":
228
- // Single literal type - use its base type
229
- if (typeof typeExpr.value === "string")
230
- return { type: "string", required: true };
231
- if (typeof typeExpr.value === "number")
232
- return { type: "number", required: true };
233
- if (typeof typeExpr.value === "boolean")
234
- return { type: "boolean", required: true };
235
- return { type: "null", required: true };
236
- case "objectType": {
237
- // v0.3.3: Inline object type - expand to fields
238
- const objectFields = {};
239
- for (const field of typeExpr.fields) {
240
- const fieldSpec = typeExprToFieldSpec(field.typeExpr, ctx);
241
- objectFields[field.name] = {
242
- ...fieldSpec,
243
- required: !field.optional,
244
- };
245
- }
246
- return {
247
- type: "object",
248
- required: true,
249
- fields: objectFields,
250
- };
251
- }
252
- }
253
- }
254
- /**
255
- * Simple type extraction (for backward compat with action input specs)
256
- */
257
- function typeExprToFieldType(typeExpr, ctx) {
258
- const spec = typeExprToFieldSpec(typeExpr, ctx);
259
- return spec.type;
260
- }
261
- function evaluateInitializer(expr, ctx) {
262
- // Only evaluate literals and simple expressions for default values
263
- switch (expr.kind) {
264
- case "literal":
265
- return expr.value;
266
- case "arrayLiteral":
267
- return expr.elements.map(e => evaluateInitializer(e, ctx));
268
- case "objectLiteral": {
269
- const obj = {};
270
- for (const prop of expr.properties) {
271
- obj[prop.key] = evaluateInitializer(prop.value, ctx);
272
- }
273
- return obj;
274
- }
275
- default:
276
- // Complex expressions can't be evaluated statically
277
- return undefined;
278
- }
279
- }
280
- // ============ Computed Generation ============
281
- function generateComputed(domain, ctx) {
282
- const fields = {};
283
- for (const member of domain.members) {
284
- if (member.kind === "computed") {
285
- const expr = generateExpr(member.expression, ctx);
286
- const deps = extractDeps(expr);
287
- fields[`computed.${member.name}`] = {
288
- deps,
289
- expr,
290
- };
291
- }
292
- }
293
- return { fields };
294
- }
295
- function extractDeps(expr) {
296
- const deps = new Set();
297
- function visit(node) {
298
- if (node.kind === "get") {
299
- deps.add(node.path);
300
- }
301
- else {
302
- // Visit all nested expressions
303
- for (const value of Object.values(node)) {
304
- if (typeof value === "object" && value !== null) {
305
- if (Array.isArray(value)) {
306
- for (const item of value) {
307
- if (typeof item === "object" && item !== null && "kind" in item) {
308
- visit(item);
309
- }
310
- }
311
- }
312
- else if ("kind" in value) {
313
- visit(value);
314
- }
315
- }
316
- }
317
- }
318
- }
319
- visit(expr);
320
- return Array.from(deps);
321
- }
322
- // ============ Action Generation ============
323
- function generateActions(domain, ctx) {
324
- const actions = {};
325
- for (const member of domain.members) {
326
- if (member.kind === "action") {
327
- ctx.currentAction = member.name;
328
- ctx.onceIntentCounters.set(member.name, 0);
329
- // Collect params
330
- const params = new Set();
331
- for (const param of member.params) {
332
- params.add(param.name);
333
- }
334
- ctx.actionParams.set(member.name, params);
335
- const flow = generateFlow(member.body, ctx);
336
- // Generate input spec if there are params
337
- let input;
338
- if (member.params.length > 0) {
339
- const inputFields = {};
340
- for (const param of member.params) {
341
- const fieldSpec = typeExprToFieldSpec(param.typeExpr, ctx);
342
- const inputField = {
343
- type: fieldSpec.type,
344
- required: fieldSpec.required ?? true,
345
- };
346
- if (fieldSpec.type === "object" && fieldSpec.fields) {
347
- inputField.fields = fieldSpec.fields;
348
- }
349
- if (fieldSpec.type === "array" && fieldSpec.items) {
350
- inputField.items = fieldSpec.items;
351
- }
352
- inputFields[param.name] = inputField;
353
- }
354
- input = {
355
- type: "object",
356
- required: true,
357
- fields: inputFields,
358
- };
359
- }
360
- // v0.3.2: Generate available condition if present
361
- let available;
362
- if (member.available) {
363
- available = generateExpr(member.available, ctx);
364
- }
365
- actions[member.name] = {
366
- flow,
367
- input,
368
- available,
369
- };
370
- ctx.currentAction = null;
371
- }
372
- }
373
- return actions;
374
- }
375
- function generateFlow(stmts, ctx) {
376
- if (stmts.length === 0) {
377
- return { kind: "seq", steps: [] };
378
- }
379
- if (stmts.length === 1) {
380
- return generateStmt(stmts[0], ctx);
381
- }
382
- return {
383
- kind: "seq",
384
- steps: stmts.map(s => generateStmt(s, ctx)),
385
- };
386
- }
387
- function generateStmt(stmt, ctx) {
388
- switch (stmt.kind) {
389
- case "when":
390
- return generateWhen(stmt, ctx);
391
- case "once":
392
- return generateOnce(stmt, ctx);
393
- case "onceIntent":
394
- return generateOnceIntent(stmt, ctx);
395
- case "patch":
396
- return generatePatch(stmt, ctx);
397
- case "effect":
398
- return generateEffect(stmt, ctx);
399
- case "fail":
400
- return generateFail(stmt, ctx);
401
- case "stop":
402
- return generateStop(stmt, ctx);
403
- }
404
- }
405
- function generateWhen(stmt, ctx) {
406
- const cond = generateExpr(stmt.condition, ctx);
407
- const thenFlow = generateFlow(stmt.body, ctx);
408
- return {
409
- kind: "if",
410
- cond,
411
- then: thenFlow,
412
- };
413
- }
414
- function generateOnce(stmt, ctx) {
415
- // Desugar once(marker) { ... } to:
416
- // when neq(marker, $meta.intentId) { patch marker = $meta.intentId; ... }
417
- // Note: Core accesses $meta intent values via meta.*
418
- const markerPath = generatePath(stmt.marker, ctx);
419
- const intentIdExpr = { kind: "get", path: "meta.intentId" };
420
- // Condition: marker != $meta.intentId
421
- let cond = {
422
- kind: "neq",
423
- left: { kind: "get", path: markerPath },
424
- right: intentIdExpr,
425
- };
426
- // Add extra condition if present
427
- if (stmt.condition) {
428
- const extraCond = generateExpr(stmt.condition, ctx);
429
- cond = {
430
- kind: "and",
431
- args: [cond, extraCond],
432
- };
433
- }
434
- // Body: patch marker = $meta.intentId, then rest
435
- const markerPatch = {
436
- kind: "patch",
437
- op: "set",
438
- path: markerPath,
439
- value: intentIdExpr,
440
- };
441
- const bodySteps = stmt.body.map(s => generateStmt(s, ctx));
442
- return {
443
- kind: "if",
444
- cond,
445
- then: {
446
- kind: "seq",
447
- steps: [markerPatch, ...bodySteps],
448
- },
449
- };
450
- }
451
- function generateOnceIntent(stmt, ctx) {
452
- const actionName = ctx.currentAction ?? "unknown";
453
- const nextIndex = ctx.onceIntentCounters.get(actionName) ?? 0;
454
- ctx.onceIntentCounters.set(actionName, nextIndex + 1);
455
- const guardId = sha256Sync(`${actionName}:${nextIndex}:intent`);
456
- const guardPath = `$mel.guards.intent.${guardId}`;
457
- const intentIdExpr = { kind: "get", path: "meta.intentId" };
458
- let cond = {
459
- kind: "neq",
460
- left: { kind: "get", path: guardPath },
461
- right: intentIdExpr,
462
- };
463
- if (stmt.condition) {
464
- const extraCond = generateExpr(stmt.condition, ctx);
465
- cond = {
466
- kind: "and",
467
- args: [cond, extraCond],
468
- };
469
- }
470
- // Guard write: semantic target is guardPath, lowered as map-level merge.
471
- const markerPatch = {
472
- kind: "patch",
473
- op: "merge",
474
- path: "$mel.guards.intent",
475
- value: {
476
- kind: "object",
477
- fields: { [guardId]: intentIdExpr },
478
- },
479
- };
480
- const bodySteps = stmt.body.map(s => generateStmt(s, ctx));
481
- return {
482
- kind: "if",
483
- cond,
484
- then: {
485
- kind: "seq",
486
- steps: [markerPatch, ...bodySteps],
487
- },
488
- };
489
- }
490
- function generatePatch(stmt, ctx) {
491
- const path = generatePath(stmt.path, ctx);
492
- const result = {
493
- kind: "patch",
494
- op: stmt.op,
495
- path,
496
- };
497
- if (stmt.value) {
498
- result.value = generateExpr(stmt.value, ctx);
499
- }
500
- return result;
501
- }
502
- function generateEffect(stmt, ctx) {
503
- const params = {};
504
- for (const arg of stmt.args) {
505
- if (arg.isPath) {
506
- // Path arguments like into:, pass:, fail:
507
- params[arg.name] = { kind: "lit", value: generatePath(arg.value, ctx) };
508
- }
509
- else {
510
- params[arg.name] = generateExpr(arg.value, ctx);
511
- }
512
- }
513
- return {
514
- kind: "effect",
515
- type: stmt.effectType,
516
- params,
517
- };
518
- }
519
- /**
520
- * v0.3.2: Generate fail statement
521
- * fail "CODE" with expr → { kind: "fail", code, message? }
522
- */
523
- function generateFail(stmt, ctx) {
524
- const result = {
525
- kind: "fail",
526
- code: stmt.code,
527
- };
528
- if (stmt.message) {
529
- result.message = generateExpr(stmt.message, ctx);
530
- }
531
- return result;
532
- }
533
- /**
534
- * v0.3.2: Generate stop statement
535
- * stop "reason" → { kind: "halt", reason }
536
- */
537
- function generateStop(stmt, ctx) {
538
- return {
539
- kind: "halt",
540
- reason: stmt.reason,
541
- };
542
- }
543
- // ============ Path Generation ============
544
- function escapePathSegment(segment) {
545
- return segment.replaceAll("\\", "\\\\").replaceAll(".", "\\.");
546
- }
547
- function joinPathPreserveEmptySegments(...segments) {
548
- return segments.map(escapePathSegment).join(".");
549
- }
550
- function generatePath(path, ctx) {
551
- const segments = [];
552
- for (const segment of path.segments) {
553
- if (segment.kind === "propertySegment") {
554
- segments.push(segment.name);
555
- }
556
- else {
557
- // Index segment - for now, stringify the index
558
- // In reality, this would need runtime evaluation
559
- const indexExpr = generateExpr(segment.index, ctx);
560
- if (indexExpr.kind === "lit") {
561
- segments.push(String(indexExpr.value));
562
- }
563
- else {
564
- // Dynamic index - use placeholder
565
- segments.push("*");
566
- }
567
- }
568
- }
569
- // Determine prefix based on first segment
570
- const first = segments[0];
571
- if (ctx.stateFields.has(first)) {
572
- // Core expects state paths without prefix (e.g., "count" not "data.count")
573
- return joinPathPreserveEmptySegments(...segments);
574
- }
575
- if (ctx.computedFields.has(first)) {
576
- return `computed.${joinPathPreserveEmptySegments(...segments)}`;
577
- }
578
- if (ctx.currentAction && ctx.actionParams.get(ctx.currentAction)?.has(first)) {
579
- return `input.${joinPathPreserveEmptySegments(...segments)}`;
580
- }
581
- // Default to plain path (state-like)
582
- return joinPathPreserveEmptySegments(...segments);
583
- }
584
- // ============ Expression Generation ============
585
- function generateExpr(expr, ctx) {
586
- switch (expr.kind) {
587
- case "literal":
588
- return { kind: "lit", value: expr.value };
589
- case "identifier":
590
- return generateIdentifier(expr.name, ctx);
591
- case "systemIdent":
592
- return generateSystemIdent(expr.path, ctx);
593
- case "iterationVar":
594
- // v0.3.2: $item only (reduce pattern deprecated, $acc removed)
595
- // $item is used in filter/map expressions
596
- return { kind: "get", path: `$${expr.name}` };
597
- case "propertyAccess":
598
- return generatePropertyAccess(expr, ctx);
599
- case "indexAccess":
600
- return {
601
- kind: "at",
602
- array: generateExpr(expr.object, ctx),
603
- index: generateExpr(expr.index, ctx),
604
- };
605
- case "functionCall":
606
- return normalizeFunctionCall(expr.name, expr.args.map(a => generateExpr(a, ctx)));
607
- case "binary":
608
- return normalizeExpr(expr.operator, generateExpr(expr.left, ctx), generateExpr(expr.right, ctx));
609
- case "unary":
610
- if (expr.operator === "!") {
611
- return { kind: "not", arg: generateExpr(expr.operand, ctx) };
612
- }
613
- else {
614
- return { kind: "neg", arg: generateExpr(expr.operand, ctx) };
615
- }
616
- case "ternary":
617
- return {
618
- kind: "if",
619
- cond: generateExpr(expr.condition, ctx),
620
- then: generateExpr(expr.consequent, ctx),
621
- else: generateExpr(expr.alternate, ctx),
622
- };
623
- case "objectLiteral": {
624
- const fields = {};
625
- for (const prop of expr.properties) {
626
- fields[prop.key] = generateExpr(prop.value, ctx);
627
- }
628
- return { kind: "object", fields };
629
- }
630
- case "arrayLiteral":
631
- // For array literals, we build using append
632
- if (expr.elements.length === 0) {
633
- return { kind: "lit", value: [] };
634
- }
635
- // Check if all elements are literals
636
- const allLiterals = expr.elements.every(e => e.kind === "literal");
637
- if (allLiterals) {
638
- return { kind: "lit", value: expr.elements.map(e => e.value) };
639
- }
640
- // Otherwise use append
641
- return {
642
- kind: "append",
643
- array: { kind: "lit", value: [] },
644
- items: expr.elements.map(e => generateExpr(e, ctx)),
645
- };
646
- }
647
- }
648
- function generateIdentifier(name, ctx) {
649
- // Resolve identifier to path
650
- if (ctx.stateFields.has(name)) {
651
- // Core expects state paths without prefix (e.g., "count" not "data.count")
652
- return { kind: "get", path: name };
653
- }
654
- if (ctx.computedFields.has(name)) {
655
- return { kind: "get", path: `computed.${name}` };
656
- }
657
- if (ctx.currentAction && ctx.actionParams.get(ctx.currentAction)?.has(name)) {
658
- return { kind: "get", path: `input.${name}` };
659
- }
660
- // Unknown identifier - report error and default to plain path
661
- ctx.diagnostics.push({
662
- severity: "error",
663
- code: "E_UNKNOWN_IDENT",
664
- message: `Unknown identifier '${name}'`,
665
- location: { start: { line: 0, column: 0, offset: 0 }, end: { line: 0, column: 0, offset: 0 } },
666
- });
667
- return { kind: "get", path: name };
668
- }
669
- function generateSystemIdent(path, ctx) {
670
- // $system.uuid -> will be lowered later
671
- // $meta.intentId -> meta.intentId
672
- // $input.* -> input.*
673
- const [namespace, ...rest] = path;
674
- switch (namespace) {
675
- case "system":
676
- // $system values are placeholders - will be lowered in the lowering pass
677
- return { kind: "get", path: `$system.${rest.join(".")}` };
678
- case "meta":
679
- return { kind: "get", path: `meta.${rest.join(".")}` };
680
- case "input":
681
- return { kind: "get", path: `input.${rest.join(".")}` };
682
- default:
683
- ctx.diagnostics.push({
684
- severity: "error",
685
- code: "E_INVALID_SYSTEM",
686
- message: `Invalid system identifier namespace '$${namespace}'`,
687
- location: { start: { line: 0, column: 0, offset: 0 }, end: { line: 0, column: 0, offset: 0 } },
688
- });
689
- return { kind: "lit", value: null };
690
- }
691
- }
692
- function generatePropertyAccess(expr, ctx) {
693
- // Handle chained property access
694
- const objectExpr = generateExpr(expr.object, ctx);
695
- // If the object is a get expression, we can extend the path
696
- if (objectExpr.kind === "get") {
697
- return { kind: "get", path: `${objectExpr.path}.${expr.property}` };
698
- }
699
- // Static member access: use field() to access a known property on a computed object.
700
- // This is semantically distinct from at() (array indexing) and get() (snapshot path lookup).
701
- return {
702
- kind: "field",
703
- object: objectExpr,
704
- property: expr.property,
705
- };
706
- }
707
- // ============ Hash Computation ============
708
- /**
709
- * Compute schema hash using browser-compatible SHA-256.
710
- * Uses @manifesto-ai/core's sha256Sync for universal compatibility.
711
- */
712
- function computeHash(schema) {
713
- return hashSchemaSync(schema);
714
- }
715
- //# sourceMappingURL=ir.js.map