@divmain/jdm-asm 0.2.1 → 0.2.3
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/index.js +2227 -29
- package/dist/index.js.map +1 -1
- package/package.json +8 -2
- package/.github/workflows/ci.yml +0 -53
- package/.oxfmtrc.json +0 -16
- package/.oxlintrc.json +0 -183
- package/AGENTS.md +0 -81
- package/asconfig.json +0 -23
- package/benchmarks/fixtures.ts +0 -111
- package/benchmarks/input-fixtures.ts +0 -80
- package/benchmarks/run.ts +0 -913
- package/benchmarks/worker-pool.ts +0 -223
- package/benchmarks/worker.ts +0 -374
- package/scripts/run-all-tests.ts +0 -220
- package/src/compiler/EXPRESSION_SUBSETS.md +0 -228
- package/src/compiler/asc-compiler.ts +0 -315
- package/src/compiler/ast-types.ts +0 -215
- package/src/compiler/build.ts +0 -56
- package/src/compiler/cache.ts +0 -414
- package/src/compiler/code-generators.ts +0 -211
- package/src/compiler/codegen/index.ts +0 -15
- package/src/compiler/codegen/js-marshal.ts +0 -999
- package/src/compiler/codegen/js-validation.ts +0 -243
- package/src/compiler/codegen.ts +0 -19
- package/src/compiler/compile-time-validation.ts +0 -507
- package/src/compiler/cst-visitor.ts +0 -434
- package/src/compiler/errors.ts +0 -227
- package/src/compiler/expression-parser.ts +0 -536
- package/src/compiler/graph.ts +0 -197
- package/src/compiler/index.ts +0 -199
- package/src/compiler/input-validation.ts +0 -33
- package/src/compiler/marshal-gen.ts +0 -21
- package/src/compiler/nodes/context-resolvers.ts +0 -197
- package/src/compiler/nodes/decision-table.ts +0 -507
- package/src/compiler/nodes/decision.ts +0 -292
- package/src/compiler/nodes/expression-compiler.ts +0 -526
- package/src/compiler/nodes/expression.ts +0 -425
- package/src/compiler/nodes/function.ts +0 -316
- package/src/compiler/nodes/input.ts +0 -60
- package/src/compiler/nodes/switch.ts +0 -547
- package/src/compiler/optimizer.ts +0 -948
- package/src/compiler/orchestrator.ts +0 -352
- package/src/compiler/parser.ts +0 -115
- package/src/compiler/result-selection.ts +0 -161
- package/src/compiler/runtime/index.ts +0 -26
- package/src/compiler/runtime-codegen.ts +0 -211
- package/src/compiler/runtime-validation-codegen.ts +0 -294
- package/src/compiler/runtime.ts +0 -452
- package/src/compiler/schema.ts +0 -245
- package/src/compiler/switch-branch-detection.ts +0 -92
- package/src/compiler/types.ts +0 -136
- package/src/compiler/unary-ast-transforms.ts +0 -148
- package/src/compiler/unary-parser.ts +0 -301
- package/src/compiler/unary-transform.ts +0 -161
- package/src/compiler/utils.ts +0 -27
- package/src/compiler/virtual-fs.ts +0 -90
- package/src/compiler/wasm-instantiate.ts +0 -127
- package/src/index.ts +0 -1
- package/src/runtime/arrays.ts +0 -579
- package/src/runtime/context.ts +0 -189
- package/src/runtime/expressions.ts +0 -1811
- package/src/runtime/index.ts +0 -8
- package/src/runtime/memory.ts +0 -607
- package/src/runtime/strings.ts +0 -260
- package/src/runtime/tables.ts +0 -96
- package/src/runtime/tsconfig.json +0 -4
- package/src/runtime/values.ts +0 -209
- package/test-data/README.md +0 -83
- package/test-data/decision-tables/basic/8k.json +0 -87992
- package/test-data/decision-tables/basic/affiliate-commission-calculator.json +0 -228
- package/test-data/decision-tables/basic/airline-loyalty-points-calculations.json +0 -285
- package/test-data/decision-tables/basic/airline-upgrade-eligibility.json +0 -466
- package/test-data/decision-tables/basic/auto-insurance-premium-calculator.json +0 -412
- package/test-data/decision-tables/basic/booking-personalization-system.json +0 -553
- package/test-data/decision-tables/basic/care-team-assignment-system.json +0 -585
- package/test-data/decision-tables/basic/claim-validation-system.json +0 -307
- package/test-data/decision-tables/basic/clinical-lab-result-interpreter.json +0 -433
- package/test-data/decision-tables/basic/clinical-treatment-protocol.json +0 -474
- package/test-data/decision-tables/basic/credit-limit-adjustment.json +0 -479
- package/test-data/decision-tables/basic/customer-eligibility-engine.json +0 -551
- package/test-data/decision-tables/basic/customer-lifetime-value.json +0 -200
- package/test-data/decision-tables/basic/customer-onboarding-kyc-verification.json +0 -611
- package/test-data/decision-tables/basic/customer-service-escalation.json +0 -191
- package/test-data/decision-tables/basic/decision-table-discounts.json +0 -168
- package/test-data/decision-tables/basic/decision-table-shipping.json +0 -398
- package/test-data/decision-tables/basic/delivery-route-optimizer.json +0 -271
- package/test-data/decision-tables/basic/device-compatibility-checker.json +0 -303
- package/test-data/decision-tables/basic/disaster-relief-fund-allocation.json +0 -296
- package/test-data/decision-tables/basic/dynamic-fx-rate-pricing-system.json +0 -237
- package/test-data/decision-tables/basic/dynamic-marketplace-comission-calculator.json +0 -242
- package/test-data/decision-tables/basic/dynamic-shipping-cost-calculator.json +0 -378
- package/test-data/decision-tables/basic/dynamic-tarrif-engine.json +0 -289
- package/test-data/decision-tables/basic/dynamic-ticket-pricing.json +0 -325
- package/test-data/decision-tables/basic/empty-column-with-space.json +0 -100
- package/test-data/decision-tables/basic/empty-column-without-space.json +0 -100
- package/test-data/decision-tables/basic/environment-compliance-assessment.json +0 -386
- package/test-data/decision-tables/basic/expression-table-map.json +0 -313
- package/test-data/decision-tables/basic/flash-sale-eligibility.json +0 -366
- package/test-data/decision-tables/basic/flight-dispatch-decision-system.json +0 -455
- package/test-data/decision-tables/basic/flight-rebooking-fee-calculator.json +0 -406
- package/test-data/decision-tables/basic/government-assistance.json +0 -299
- package/test-data/decision-tables/basic/grant-funding-distribution.json +0 -307
- package/test-data/decision-tables/basic/hazardous-materials-management-system.json +0 -414
- package/test-data/decision-tables/basic/immigration-eligibility-evaluator.json +0 -765
- package/test-data/decision-tables/basic/import-duties-calculator.json +0 -318
- package/test-data/decision-tables/basic/insurance-agent-commission.json +0 -228
- package/test-data/decision-tables/basic/insurance-coverage-calculator.json +0 -362
- package/test-data/decision-tables/basic/insurance-underwriting-risk.json +0 -321
- package/test-data/decision-tables/basic/international-roaming-policy-manager.json +0 -199
- package/test-data/decision-tables/basic/legacy-plan-management.json +0 -434
- package/test-data/decision-tables/basic/marketplace-listing-verification-system.json +0 -334
- package/test-data/decision-tables/basic/medication-dosage-calculator.json +0 -318
- package/test-data/decision-tables/basic/merch-bags.json +0 -171
- package/test-data/decision-tables/basic/municipal-permit-evaluation-system.json +0 -364
- package/test-data/decision-tables/basic/mvno-partner-enablement.json +0 -313
- package/test-data/decision-tables/basic/partner-revenue-sharing.json +0 -244
- package/test-data/decision-tables/basic/payment-routing-and-fee-calculator.json +0 -475
- package/test-data/decision-tables/basic/policy-discount-calculator.json +0 -307
- package/test-data/decision-tables/basic/policy-eligibility-analyzer.json +0 -299
- package/test-data/decision-tables/basic/product-listing-scoring.json +0 -358
- package/test-data/decision-tables/basic/realtime-fraud-detection.json +0 -235
- package/test-data/decision-tables/basic/regional-compliance-manager.json +0 -278
- package/test-data/decision-tables/basic/returns-and-refund-policy.json +0 -366
- package/test-data/decision-tables/basic/returns-processing-system.json +0 -448
- package/test-data/decision-tables/basic/school-district-resource-allocation.json +0 -282
- package/test-data/decision-tables/basic/seat-map-optimization.json +0 -325
- package/test-data/decision-tables/basic/seller-fee-calculator.json +0 -307
- package/test-data/decision-tables/basic/service-level-agreement-enforcement.json +0 -575
- package/test-data/decision-tables/basic/smart-financial-product-matcher.json +0 -249
- package/test-data/decision-tables/basic/supply-chain-risk.json +0 -316
- package/test-data/decision-tables/basic/table-loop.json +0 -93
- package/test-data/decision-tables/basic/table.json +0 -76
- package/test-data/decision-tables/basic/traffic-violation-penalty-calculator.json +0 -436
- package/test-data/decision-tables/basic/transaction-compliance-classifier.json +0 -525
- package/test-data/decision-tables/basic/vehicle-claims-resolution.json +0 -310
- package/test-data/decision-tables/basic/warehouse-storage-location.json +0 -345
- package/test-data/decision-tables/hit-policy-collect/collect-multiple-matches.json +0 -127
- package/test-data/decision-tables/hit-policy-collect/collect-no-match.json +0 -95
- package/test-data/decision-tables/hit-policy-first/first-match.json +0 -103
- package/test-data/decision-tables/hit-policy-first/no-match.json +0 -95
- package/test-data/decision-tables/hit-policy-output-order/output-order-respected.json +0 -94
- package/test-data/decision-tables/hit-policy-output-order/string-output-order.json +0 -94
- package/test-data/decision-tables/hit-policy-priority/priority-respected.json +0 -86
- package/test-data/decision-tables/hit-policy-rule-order/rule-order-respected.json +0 -94
- package/test-data/decision-tables/hit-policy-unique/all-match-error.json +0 -89
- package/test-data/decision-tables/hit-policy-unique/multiple-match-error.json +0 -89
- package/test-data/decision-tables/hit-policy-unique/no-match.json +0 -88
- package/test-data/decision-tables/hit-policy-unique/unique-match.json +0 -99
- package/test-data/expressions/arithmetic/error-cyclic.json +0 -114
- package/test-data/expressions/arithmetic/error-missing-input.json +0 -54
- package/test-data/expressions/arithmetic/error-missing-output.json +0 -54
- package/test-data/expressions/arithmetic/expression-default.json +0 -93
- package/test-data/expressions/arithmetic/expression-fields.json +0 -94
- package/test-data/expressions/arithmetic/expression-loop.json +0 -94
- package/test-data/expressions/arithmetic/expression-passthrough.json +0 -108
- package/test-data/expressions/arithmetic/expression.json +0 -69
- package/test-data/expressions/arithmetic/nested-request.json +0 -125
- package/test-data/expressions/arithmetic/number-function.json +0 -58
- package/test-data/expressions/arithmetic/test-number-functions.json +0 -68
- package/test-data/expressions/functions/all.json +0 -149
- package/test-data/expressions/functions/avg.json +0 -89
- package/test-data/expressions/functions/filter.json +0 -109
- package/test-data/expressions/functions/flat.json +0 -167
- package/test-data/expressions/functions/map-strings.json +0 -65
- package/test-data/expressions/functions/map.json +0 -73
- package/test-data/expressions/functions/reduce.json +0 -49
- package/test-data/expressions/functions/some.json +0 -175
- package/test-data/expressions/functions/sort-strings.json +0 -97
- package/test-data/expressions/functions/sort.json +0 -97
- package/test-data/expressions/logical/logical-and.json +0 -116
- package/test-data/expressions/logical/logical-complex.json +0 -260
- package/test-data/expressions/logical/logical-not.json +0 -111
- package/test-data/expressions/logical/logical-or.json +0 -123
- package/test-data/expressions/string/string-comparison.json +0 -128
- package/test-data/expressions/string/string-concat.json +0 -106
- package/test-data/expressions/string/string-contains.json +0 -125
- package/test-data/expressions/string/string-endsWith.json +0 -113
- package/test-data/expressions/string/string-indexOf.json +0 -131
- package/test-data/expressions/string/string-join.json +0 -92
- package/test-data/expressions/string/string-lower.json +0 -94
- package/test-data/expressions/string/string-replace.json +0 -130
- package/test-data/expressions/string/string-split.json +0 -101
- package/test-data/expressions/string/string-startsWith.json +0 -113
- package/test-data/expressions/string/string-substring.json +0 -138
- package/test-data/expressions/string/string-trim.json +0 -100
- package/test-data/expressions/string/string-upper.json +0 -94
- package/test-data/other/custom.json +0 -51
- package/test-data/other/customer-input-schema.json +0 -34
- package/test-data/other/customer-output-schema.json +0 -34
- package/test-data/other/passthrough.json +0 -31
- package/test-data/sub-decisions/basic/$nodes-child.json +0 -31
- package/test-data/sub-decisions/basic/$nodes-parent.json +0 -49
- package/test-data/sub-decisions/basic/recursive-table1.json +0 -49
- package/test-data/sub-decisions/basic/recursive-table2.json +0 -49
- package/test-data/sub-decisions/complex-multi/approval-decision.json +0 -31
- package/test-data/sub-decisions/complex-multi/complex-dag.json +0 -175
- package/test-data/sub-decisions/complex-multi/credit-check.json +0 -31
- package/test-data/sub-decisions/complex-multi/customer-segmentation.json +0 -31
- package/test-data/sub-decisions/complex-multi/discount-eligibility.json +0 -31
- package/test-data/sub-decisions/complex-multi/eligibility-check.json +0 -31
- package/test-data/sub-decisions/complex-multi/final-offer.json +0 -31
- package/test-data/sub-decisions/complex-multi/income-verification.json +0 -31
- package/test-data/sub-decisions/complex-multi/linear-chain.json +0 -121
- package/test-data/sub-decisions/complex-multi/pricing-calculation.json +0 -31
- package/test-data/sub-decisions/complex-multi/product-eligibility.json +0 -31
- package/test-data/sub-decisions/complex-multi/risk-assessment.json +0 -31
- package/test-data/sub-decisions/complex-multi/shared-validation.json +0 -31
- package/test-data/sub-decisions/complex-multi/validation.json +0 -31
- package/test-data/sub-decisions/diamond/decision-a.json +0 -31
- package/test-data/sub-decisions/diamond/decision-b.json +0 -31
- package/test-data/sub-decisions/diamond/decision-c.json +0 -31
- package/test-data/sub-decisions/diamond/decision-shared.json +0 -31
- package/test-data/sub-decisions/diamond/diamond-pattern.json +0 -109
- package/test-data/sub-decisions/error-propagation/parent-calls-error.json +0 -44
- package/test-data/sub-decisions/error-propagation/sub-decision-with-error.json +0 -60
- package/test-data/switch-nodes/basic/account-dormancy-management.json +0 -245
- package/test-data/switch-nodes/basic/application-risk-assessment.json +0 -474
- package/test-data/switch-nodes/basic/cellular-data-rollover-system.json +0 -281
- package/test-data/switch-nodes/basic/clinical-pathway-selection.json +0 -454
- package/test-data/switch-nodes/basic/insurance-prior-authorization.json +0 -467
- package/test-data/switch-nodes/basic/last-mile-delivery-assignment.json +0 -373
- package/test-data/switch-nodes/basic/loan-approval.json +0 -469
- package/test-data/switch-nodes/basic/multi-switch.json +0 -498
- package/test-data/switch-nodes/basic/online-checkin-eligibility.json +0 -285
- package/test-data/switch-nodes/basic/order-consolidation-system.json +0 -493
- package/test-data/switch-nodes/basic/seller-approval-workflow.json +0 -383
- package/test-data/switch-nodes/basic/set-fee.json +0 -243
- package/test-data/switch-nodes/basic/shipping-carrier-selector.json +0 -379
- package/test-data/switch-nodes/basic/switch-node.json +0 -167
- package/test-data/switch-nodes/basic/switch-performance-2.json +0 -1307
- package/test-data/switch-nodes/basic/switch-performance.json +0 -691
- package/test-data/switch-nodes/basic/tax-exemption.json +0 -295
- package/test-data/switch-nodes/basic/warehouse-cross-docking.json +0 -313
- package/test-data/switch-nodes/default-cases/switch-with-default.json +0 -134
- package/test-data/zen-reference/$nodes-child.json +0 -69
- package/test-data/zen-reference/$nodes-parent.json +0 -34
- package/test-data/zen-reference/8k.json +0 -87992
- package/test-data/zen-reference/credit-analysis.json +0 -324
- package/test-data/zen-reference/custom.json +0 -51
- package/test-data/zen-reference/customer-input-schema.json +0 -34
- package/test-data/zen-reference/customer-output-schema.json +0 -34
- package/test-data/zen-reference/error-cyclic.json +0 -114
- package/test-data/zen-reference/error-missing-input.json +0 -54
- package/test-data/zen-reference/error-missing-output.json +0 -54
- package/test-data/zen-reference/expression.json +0 -69
- package/test-data/zen-reference/function-v2.json +0 -48
- package/test-data/zen-reference/function.json +0 -46
- package/test-data/zen-reference/graphs/account-dormancy-management.json +0 -245
- package/test-data/zen-reference/graphs/affiliate-commission-calculator.json +0 -228
- package/test-data/zen-reference/graphs/airline-loyalty-points-calculations.json +0 -285
- package/test-data/zen-reference/graphs/airline-upgrade-eligibility.json +0 -466
- package/test-data/zen-reference/graphs/aml.json +0 -537
- package/test-data/zen-reference/graphs/application-risk-assessment.json +0 -474
- package/test-data/zen-reference/graphs/auto-insurance-premium-calculator.json +0 -412
- package/test-data/zen-reference/graphs/booking-personalization-system.json +0 -553
- package/test-data/zen-reference/graphs/care-team-assignment-system.json +0 -585
- package/test-data/zen-reference/graphs/cellular-data-rollover-system.json +0 -281
- package/test-data/zen-reference/graphs/claim-validation-system.json +0 -307
- package/test-data/zen-reference/graphs/clinical-lab-result-interpreter.json +0 -433
- package/test-data/zen-reference/graphs/clinical-pathway-selection.json +0 -454
- package/test-data/zen-reference/graphs/clinical-treatment-protocol.json +0 -474
- package/test-data/zen-reference/graphs/company-analysis.json +0 -390
- package/test-data/zen-reference/graphs/credit-limit-adjustment.json +0 -479
- package/test-data/zen-reference/graphs/customer-eligibility-engine.json +0 -551
- package/test-data/zen-reference/graphs/customer-lifetime-value.json +0 -200
- package/test-data/zen-reference/graphs/customer-onboarding-kyc-verification.json +0 -611
- package/test-data/zen-reference/graphs/customer-service-escalation.json +0 -191
- package/test-data/zen-reference/graphs/decision-table-discounts.json +0 -168
- package/test-data/zen-reference/graphs/decision-table-shipping.json +0 -398
- package/test-data/zen-reference/graphs/delivery-route-optimizer.json +0 -271
- package/test-data/zen-reference/graphs/device-compatibility-checker.json +0 -303
- package/test-data/zen-reference/graphs/disaster-relief-fund-allocation.json +0 -296
- package/test-data/zen-reference/graphs/dynamic-fx-rate-pricing-system.json +0 -237
- package/test-data/zen-reference/graphs/dynamic-marketplace-comission-calculator.json +0 -242
- package/test-data/zen-reference/graphs/dynamic-shipping-cost-calculator.json +0 -378
- package/test-data/zen-reference/graphs/dynamic-tarrif-engine.json +0 -289
- package/test-data/zen-reference/graphs/dynamic-ticket-pricing.json +0 -325
- package/test-data/zen-reference/graphs/empty-column-with-space.json +0 -100
- package/test-data/zen-reference/graphs/empty-column-without-space.json +0 -100
- package/test-data/zen-reference/graphs/environment-compliance-assessment.json +0 -386
- package/test-data/zen-reference/graphs/expression-default.json +0 -93
- package/test-data/zen-reference/graphs/expression-fields.json +0 -94
- package/test-data/zen-reference/graphs/expression-loop.json +0 -94
- package/test-data/zen-reference/graphs/expression-passthrough.json +0 -108
- package/test-data/zen-reference/graphs/expression-table-map.json +0 -313
- package/test-data/zen-reference/graphs/flash-sale-eligibility.json +0 -366
- package/test-data/zen-reference/graphs/flight-dispatch-decision-system.json +0 -455
- package/test-data/zen-reference/graphs/flight-rebooking-fee-calculator.json +0 -406
- package/test-data/zen-reference/graphs/government-assistance.json +0 -299
- package/test-data/zen-reference/graphs/grant-funding-distribution.json +0 -307
- package/test-data/zen-reference/graphs/hazardous-materials-management-system.json +0 -414
- package/test-data/zen-reference/graphs/immigration-eligibility-evaluator.json +0 -765
- package/test-data/zen-reference/graphs/import-duties-calculator.json +0 -318
- package/test-data/zen-reference/graphs/insurance-agent-commission.json +0 -228
- package/test-data/zen-reference/graphs/insurance-breakdown.json +0 -421
- package/test-data/zen-reference/graphs/insurance-coverage-calculator.json +0 -362
- package/test-data/zen-reference/graphs/insurance-prior-authorization.json +0 -467
- package/test-data/zen-reference/graphs/insurance-underwriting-risk.json +0 -321
- package/test-data/zen-reference/graphs/international-roaming-policy-manager.json +0 -199
- package/test-data/zen-reference/graphs/last-mile-delivery-assignment.json +0 -373
- package/test-data/zen-reference/graphs/legacy-plan-management.json +0 -434
- package/test-data/zen-reference/graphs/loan-approval.json +0 -469
- package/test-data/zen-reference/graphs/marketplace-listing-verification-system.json +0 -334
- package/test-data/zen-reference/graphs/medication-dosage-calculator.json +0 -318
- package/test-data/zen-reference/graphs/merch-bags.json +0 -171
- package/test-data/zen-reference/graphs/multi-switch.json +0 -498
- package/test-data/zen-reference/graphs/municipal-permit-evaluation-system.json +0 -364
- package/test-data/zen-reference/graphs/mvno-partner-enablement.json +0 -313
- package/test-data/zen-reference/graphs/nested-request.json +0 -125
- package/test-data/zen-reference/graphs/online-checkin-eligibility.json +0 -285
- package/test-data/zen-reference/graphs/order-consolidation-system.json +0 -493
- package/test-data/zen-reference/graphs/partner-revenue-sharing.json +0 -244
- package/test-data/zen-reference/graphs/payment-routing-and-fee-calculator.json +0 -475
- package/test-data/zen-reference/graphs/policy-discount-calculator.json +0 -307
- package/test-data/zen-reference/graphs/policy-eligibility-analyzer.json +0 -299
- package/test-data/zen-reference/graphs/product-listing-scoring.json +0 -358
- package/test-data/zen-reference/graphs/realtime-fraud-detection.json +0 -235
- package/test-data/zen-reference/graphs/regional-compliance-manager.json +0 -278
- package/test-data/zen-reference/graphs/returns-and-refund-policy.json +0 -366
- package/test-data/zen-reference/graphs/returns-processing-system.json +0 -448
- package/test-data/zen-reference/graphs/school-district-resource-allocation.json +0 -282
- package/test-data/zen-reference/graphs/seat-map-optimization.json +0 -325
- package/test-data/zen-reference/graphs/seller-approval-workflow.json +0 -383
- package/test-data/zen-reference/graphs/seller-fee-calculator.json +0 -307
- package/test-data/zen-reference/graphs/service-level-agreement-enforcement.json +0 -575
- package/test-data/zen-reference/graphs/set-fee.json +0 -243
- package/test-data/zen-reference/graphs/shipping-carrier-selector.json +0 -379
- package/test-data/zen-reference/graphs/smart-financial-product-matcher.json +0 -249
- package/test-data/zen-reference/graphs/supply-chain-risk.json +0 -316
- package/test-data/zen-reference/graphs/table-loop.json +0 -93
- package/test-data/zen-reference/graphs/tax-exemption.json +0 -295
- package/test-data/zen-reference/graphs/traffic-violation-penalty-calculator.json +0 -436
- package/test-data/zen-reference/graphs/transaction-compliance-classifier.json +0 -525
- package/test-data/zen-reference/graphs/vehicle-claims-resolution.json +0 -310
- package/test-data/zen-reference/graphs/warehouse-cross-docking.json +0 -313
- package/test-data/zen-reference/graphs/warehouse-storage-location.json +0 -345
- package/test-data/zen-reference/http-function.json +0 -34
- package/test-data/zen-reference/infinite-function.json +0 -46
- package/test-data/zen-reference/js/imports.js +0 -25
- package/test-data/zen-reference/passthrough.json +0 -31
- package/test-data/zen-reference/recursive-table1.json +0 -49
- package/test-data/zen-reference/recursive-table2.json +0 -49
- package/test-data/zen-reference/sleep-function.json +0 -34
- package/test-data/zen-reference/switch-node.json +0 -167
- package/test-data/zen-reference/switch-performance-2.json +0 -1307
- package/test-data/zen-reference/switch-performance.json +0 -691
- package/test-data/zen-reference/table.json +0 -76
- package/tests/helpers/index.ts +0 -73
- package/tests/helpers/mock-context.ts +0 -231
- package/tests/helpers/round-trip.ts +0 -398
- package/tests/helpers/test-harness-comparison.ts +0 -325
- package/tests/helpers/test-harness-wasm.ts +0 -710
- package/tests/helpers/test-harness.ts +0 -28
- package/tests/helpers/wasm-test.ts +0 -659
- package/tests/integration/compilation-errors.test.ts +0 -864
- package/tests/integration/decision-tables.test.ts +0 -531
- package/tests/integration/edge-cases.test.ts +0 -787
- package/tests/integration/expressions.test.ts +0 -513
- package/tests/integration/function-node-integration.test.ts +0 -182
- package/tests/integration/sub-decisions.test.ts +0 -108
- package/tests/integration/switch-nodes.test.ts +0 -399
- package/tests/integration/unary-or-matching.test.ts +0 -53
- package/tests/integration/wasm-data-types.test.ts +0 -398
- package/tests/integration/wasm-errors.test.ts +0 -199
- package/tests/integration/wasm-execution.test.ts +0 -348
- package/tests/integration/wasm-memory.test.ts +0 -228
- package/tests/scripts/analyze-coverage.ts +0 -166
- package/tests/scripts/categorize-tests.ts +0 -396
- package/tests/scripts/coverage-analysis.ts +0 -836
- package/tests/unit/compiler/cache.test.ts +0 -238
- package/tests/unit/compiler/errors.test.ts +0 -316
- package/tests/unit/compiler/graph-scalability.test.ts +0 -510
- package/tests/unit/compiler/graph.test.ts +0 -878
- package/tests/unit/compiler/input-validation.test.ts +0 -447
- package/tests/unit/compiler/logical-and-parser.test.ts +0 -143
- package/tests/unit/compiler/logical-not-parser.test.ts +0 -107
- package/tests/unit/compiler/logical-or-parser.test.ts +0 -236
- package/tests/unit/compiler/marshal-gen/marshal-gen.test.ts +0 -97
- package/tests/unit/compiler/nodes/decision-table.test.ts +0 -103
- package/tests/unit/compiler/nodes/decision.test.ts +0 -182
- package/tests/unit/compiler/nodes/function-compile.test.ts +0 -204
- package/tests/unit/compiler/nodes/function.test.ts +0 -176
- package/tests/unit/compiler/nodes/input.test.ts +0 -30
- package/tests/unit/compiler/nodes/switch.test.ts +0 -127
- package/tests/unit/compiler/optimizer-cache.test.ts +0 -327
- package/tests/unit/compiler/optimizer-implementation.test.ts +0 -625
- package/tests/unit/compiler/parser.test.ts +0 -508
- package/tests/unit/compiler/runtime-error-cleanup.test.ts +0 -426
- package/tests/unit/compiler/runtime-validation.test.ts +0 -303
- package/tests/unit/compiler/runtime.test.ts +0 -221
- package/tests/unit/compiler/schema/schema.test.ts +0 -248
- package/tests/unit/compiler/unary-ast-transforms.test.ts +0 -245
- package/tsconfig.json +0 -27
- package/tsup.config.ts +0 -11
- package/vitest.config.ts +0 -12
|
@@ -1,547 +0,0 @@
|
|
|
1
|
-
import type { JDMNode } from '../parser';
|
|
2
|
-
import type { CompilationContext, AssemblyScriptCode, NoMatchBehavior } from '../types';
|
|
3
|
-
import { compileExpression } from './expression';
|
|
4
|
-
import { sanitizeId } from '../utils';
|
|
5
|
-
import { generateNodeEvaluationCode, generateBuildFinalResultCode } from '../code-generators';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Switch statement definition (from JDM format).
|
|
9
|
-
*/
|
|
10
|
-
interface SwitchStatement {
|
|
11
|
-
id: string;
|
|
12
|
-
condition: string; // Empty string means default case
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Switch node content structure (from JDM format).
|
|
17
|
-
*/
|
|
18
|
-
interface JDMNodeContent {
|
|
19
|
-
statements: SwitchStatement[];
|
|
20
|
-
hitPolicy?: 'first' | 'collect' | 'unique' | 'ruleOrder' | 'outputOrder' | 'priority';
|
|
21
|
-
/** Override the global no-match behavior for this switch */
|
|
22
|
-
noMatchBehavior?: NoMatchBehavior;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Internal switch condition definition.
|
|
27
|
-
*/
|
|
28
|
-
interface SwitchCondition {
|
|
29
|
-
id: string;
|
|
30
|
-
expression: string;
|
|
31
|
-
nodes: string[];
|
|
32
|
-
isDefault: boolean;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Get all nodes reachable from a starting node via BFS, stopping at switch nodes.
|
|
37
|
-
*
|
|
38
|
-
* Each switch evaluates its own branches independently. If we traversed into nested
|
|
39
|
-
* switches, we'd incorrectly include nodes that should be conditionally evaluated by
|
|
40
|
-
* the nested switch, not unconditionally evaluated by the parent branch.
|
|
41
|
-
*/
|
|
42
|
-
function getBranchNodes(startNodeId: string, context: CompilationContext): string[] {
|
|
43
|
-
const nodeMap = new Map(context.jdm.nodes.map((n) => [n.id, n]));
|
|
44
|
-
const visited = new Set<string>();
|
|
45
|
-
const result: string[] = [];
|
|
46
|
-
const queue = [startNodeId];
|
|
47
|
-
|
|
48
|
-
while (queue.length > 0) {
|
|
49
|
-
const currentId = queue.shift()!;
|
|
50
|
-
if (visited.has(currentId)) {
|
|
51
|
-
continue;
|
|
52
|
-
}
|
|
53
|
-
visited.add(currentId);
|
|
54
|
-
result.push(currentId);
|
|
55
|
-
|
|
56
|
-
// Get the current node
|
|
57
|
-
const currentNode = nodeMap.get(currentId);
|
|
58
|
-
|
|
59
|
-
// If node not found in context, just include it and stop traversal
|
|
60
|
-
// (this handles test mocks that don't define all nodes)
|
|
61
|
-
if (!currentNode) {
|
|
62
|
-
continue;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// If this is a switch node, don't traverse its outgoing edges
|
|
66
|
-
// The switch will handle its own branches when it's evaluated
|
|
67
|
-
if (currentNode.type === 'switchNode') {
|
|
68
|
-
continue;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Find outgoing edges from this node
|
|
72
|
-
const outgoingEdges = context.jdm.edges.filter((e) => e.sourceId === currentId);
|
|
73
|
-
for (const edge of outgoingEdges) {
|
|
74
|
-
queue.push(edge.targetId);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return result;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Generate inline code to evaluate an entire branch (all nodes in sequence).
|
|
83
|
-
* Returns the statements and a final result expression.
|
|
84
|
-
*
|
|
85
|
-
* Uses shared node evaluation infrastructure (generateNodeEvaluationCode) to ensure
|
|
86
|
-
* consistent handling of outputPath and passThrough across the codebase.
|
|
87
|
-
*/
|
|
88
|
-
function generateBranchEvaluation(
|
|
89
|
-
branchNodeIds: string[],
|
|
90
|
-
context: CompilationContext,
|
|
91
|
-
): { statements: string; resultExpr: string } {
|
|
92
|
-
const nodeMap = new Map(context.jdm.nodes.map((n) => [n.id, n]));
|
|
93
|
-
|
|
94
|
-
if (branchNodeIds.length === 0) {
|
|
95
|
-
return { statements: '', resultExpr: 'Value.Null()' };
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// Generate evaluation code for each node using shared helper
|
|
99
|
-
const evalStatements = branchNodeIds.map((nodeId) => {
|
|
100
|
-
const node = nodeMap.get(nodeId);
|
|
101
|
-
const nodeName = node?.name || sanitizeId(nodeId);
|
|
102
|
-
return generateNodeEvaluationCode(nodeId, nodeName, node);
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
// Determine result expression based on the last node's type
|
|
106
|
-
const lastNodeId = branchNodeIds[branchNodeIds.length - 1];
|
|
107
|
-
const lastNode = nodeMap.get(lastNodeId);
|
|
108
|
-
const lastNodeName = lastNode?.name || sanitizeId(lastNodeId);
|
|
109
|
-
|
|
110
|
-
// For output nodes or nodes with passThrough, build result from accumulated context
|
|
111
|
-
const shouldUseAccumulatedContext =
|
|
112
|
-
lastNode?.type === 'outputNode' || lastNode?.content?.passThrough === true;
|
|
113
|
-
|
|
114
|
-
if (shouldUseAccumulatedContext) {
|
|
115
|
-
// Use shared helper to build final result from context
|
|
116
|
-
evalStatements.push(generateBuildFinalResultCode('__branchFinalResult', '__branch'));
|
|
117
|
-
return {
|
|
118
|
-
statements: evalStatements.join('\n '),
|
|
119
|
-
resultExpr: 'Value.Object(__branchFinalResult)',
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
return {
|
|
124
|
-
statements: evalStatements.join('\n '),
|
|
125
|
-
resultExpr: `ctx.get("$nodes.${lastNodeName}")`,
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Compile a switch node.
|
|
131
|
-
*
|
|
132
|
-
* Generates conditional chains (switch-like logic) for evaluating multiple
|
|
133
|
-
* conditions and routing to the appropriate target nodes.
|
|
134
|
-
*
|
|
135
|
-
* Supports:
|
|
136
|
-
* - FIRST hit policy: Returns the first matching condition's result
|
|
137
|
-
* - COLLECT hit policy: Aggregates all matching conditions' results
|
|
138
|
-
* - RULE ORDER hit policy: Returns all matching conditions' results in order
|
|
139
|
-
* - UNIQUE hit policy: Returns result if exactly one condition matches
|
|
140
|
-
* - OUTPUT ORDER hit policy: Returns all matching conditions' results sorted by value
|
|
141
|
-
* - PRIORITY hit policy: Returns only the highest-priority matching condition's result
|
|
142
|
-
*
|
|
143
|
-
* Default Cases:
|
|
144
|
-
* - A statement with an empty condition string acts as the default case
|
|
145
|
-
* - When no conditions match, the default case is evaluated (if provided)
|
|
146
|
-
* - Default case has access to the full input context
|
|
147
|
-
* - If no default case is provided, the configured no-match behavior applies
|
|
148
|
-
*
|
|
149
|
-
* @param node - The JDM switch node
|
|
150
|
-
* @param context - The compilation context
|
|
151
|
-
* @returns Generated AssemblyScript code
|
|
152
|
-
*/
|
|
153
|
-
export function compileSwitchNode(node: JDMNode, context: CompilationContext): AssemblyScriptCode {
|
|
154
|
-
const jdmContent = node.content as JDMNodeContent;
|
|
155
|
-
const {
|
|
156
|
-
statements,
|
|
157
|
-
hitPolicy: jdmHitPolicy,
|
|
158
|
-
noMatchBehavior: switchNoMatchBehavior,
|
|
159
|
-
} = jdmContent;
|
|
160
|
-
|
|
161
|
-
const hitPolicy = jdmHitPolicy ?? 'first';
|
|
162
|
-
|
|
163
|
-
// Determine the effective no-match behavior (node-level overrides global)
|
|
164
|
-
const noMatchBehavior = switchNoMatchBehavior ??
|
|
165
|
-
context.options.noMatchBehavior ?? { type: 'returnNull' };
|
|
166
|
-
|
|
167
|
-
// RULE ORDER, COLLECT, OUTPUT ORDER, and PRIORITY all use array collection mode
|
|
168
|
-
const isCollectMode =
|
|
169
|
-
hitPolicy === 'collect' ||
|
|
170
|
-
hitPolicy === 'ruleOrder' ||
|
|
171
|
-
hitPolicy === 'outputOrder' ||
|
|
172
|
-
hitPolicy === 'priority';
|
|
173
|
-
|
|
174
|
-
const nodeMap = new Map(context.jdm.nodes.map((n) => [n.id, n]));
|
|
175
|
-
|
|
176
|
-
// In collect mode, if all branches terminate at output nodes, we can merge their results into
|
|
177
|
-
// a single object instead of returning an array. This allows collect-mode switches to build
|
|
178
|
-
// structured outputs progressively, avoiding unnecessary nesting.
|
|
179
|
-
function checkAllBranchesTerminateAtOutput(): boolean {
|
|
180
|
-
if (!isCollectMode) {
|
|
181
|
-
return false;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
for (const statement of statements) {
|
|
185
|
-
if (statement.condition === '' || statement.condition.trim() === '') {
|
|
186
|
-
continue;
|
|
187
|
-
} // Skip default
|
|
188
|
-
|
|
189
|
-
// Find target edge for this statement
|
|
190
|
-
const edge = context.jdm.edges.find(
|
|
191
|
-
(e) => e.sourceId === node.id && e.sourceHandle === statement.id,
|
|
192
|
-
);
|
|
193
|
-
if (!edge) {
|
|
194
|
-
continue;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
// Get the terminal node(s) for this branch
|
|
198
|
-
const branchNodes = getBranchNodes(edge.targetId, context);
|
|
199
|
-
if (branchNodes.length === 0) {
|
|
200
|
-
return false;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
const lastNodeId = branchNodes[branchNodes.length - 1];
|
|
204
|
-
const lastNode = nodeMap.get(lastNodeId);
|
|
205
|
-
if (!lastNode || lastNode.type !== 'outputNode') {
|
|
206
|
-
return false;
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// Also check default case if exists
|
|
211
|
-
const defaultStatement = statements.find(
|
|
212
|
-
(s) => s.condition === '' || s.condition.trim() === '',
|
|
213
|
-
);
|
|
214
|
-
if (defaultStatement) {
|
|
215
|
-
const edge = context.jdm.edges.find(
|
|
216
|
-
(e) => e.sourceId === node.id && e.sourceHandle === defaultStatement.id,
|
|
217
|
-
);
|
|
218
|
-
if (edge) {
|
|
219
|
-
const branchNodes = getBranchNodes(edge.targetId, context);
|
|
220
|
-
if (branchNodes.length > 0) {
|
|
221
|
-
const lastNodeId = branchNodes[branchNodes.length - 1];
|
|
222
|
-
const lastNode = nodeMap.get(lastNodeId);
|
|
223
|
-
if (!lastNode || lastNode.type !== 'outputNode') {
|
|
224
|
-
return false;
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
return true;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
const shouldMergeCollectResults = checkAllBranchesTerminateAtOutput();
|
|
234
|
-
|
|
235
|
-
// Transform JDM statements to internal conditions format
|
|
236
|
-
const conditions: SwitchCondition[] = statements.map((statement) => {
|
|
237
|
-
// Find target nodes for this statement by looking for edges with this statement as sourceHandle
|
|
238
|
-
const edges = context.jdm.edges.filter(
|
|
239
|
-
(edge) => edge.sourceId === node.id && edge.sourceHandle === statement.id,
|
|
240
|
-
);
|
|
241
|
-
const targetNodeIds = edges.map((edge) => sanitizeId(edge.targetId));
|
|
242
|
-
|
|
243
|
-
return {
|
|
244
|
-
id: statement.id,
|
|
245
|
-
expression: statement.condition,
|
|
246
|
-
nodes: targetNodeIds,
|
|
247
|
-
// In collect mode, all matching conditions execute (empty = always match).
|
|
248
|
-
// In first mode, execution stops at first match, so empty condition acts as fallback "default" case.
|
|
249
|
-
isDefault:
|
|
250
|
-
!isCollectMode && (statement.condition === '' || statement.condition.trim() === ''),
|
|
251
|
-
};
|
|
252
|
-
});
|
|
253
|
-
|
|
254
|
-
// Separate regular conditions from default case
|
|
255
|
-
// In collect mode, there are no defaults - empty conditions are just "always true"
|
|
256
|
-
const regularConditions = conditions.filter((c) => !c.isDefault);
|
|
257
|
-
const defaultCase = isCollectMode ? undefined : conditions.find((c) => c.isDefault);
|
|
258
|
-
|
|
259
|
-
// Generate the result declaration based on hit policy
|
|
260
|
-
const resultDeclaration = isCollectMode ? 'let results = new Array<Value>();' : '';
|
|
261
|
-
|
|
262
|
-
// Generate the no-match handler based on the effective behavior
|
|
263
|
-
function generateNoMatchHandler(): string {
|
|
264
|
-
if (noMatchBehavior.type === 'throwError') {
|
|
265
|
-
return `SetLastErrorWithMessage(RuntimeErrorCode.EVALUATION_ERROR, "Switch node \\"${node.name}\\" (id: ${node.id}): No matching condition found");\n return Value.Null();`;
|
|
266
|
-
} else if (noMatchBehavior.type === 'returnDefault') {
|
|
267
|
-
// Generate the default value as a Value
|
|
268
|
-
const defaultValue = noMatchBehavior.value;
|
|
269
|
-
let defaultValueCode: string;
|
|
270
|
-
switch (typeof defaultValue) {
|
|
271
|
-
case 'string':
|
|
272
|
-
defaultValueCode = `Value.String("${String(defaultValue).replace(/"/g, '\\"')}")`;
|
|
273
|
-
break;
|
|
274
|
-
case 'number':
|
|
275
|
-
defaultValueCode = `Value.Float(${defaultValue})`;
|
|
276
|
-
break;
|
|
277
|
-
case 'boolean':
|
|
278
|
-
defaultValueCode = `Value.Bool(${defaultValue})`;
|
|
279
|
-
break;
|
|
280
|
-
default:
|
|
281
|
-
defaultValueCode = `Value.String("${String(defaultValue)}")`;
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
return isCollectMode
|
|
285
|
-
? `return Value.Array([${defaultValueCode}]);`
|
|
286
|
-
: `return ${defaultValueCode};`;
|
|
287
|
-
} else {
|
|
288
|
-
// Default: returnNull
|
|
289
|
-
return 'return Value.Null();';
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
// Helper function to generate code that evaluates the default case (entire branch)
|
|
294
|
-
function generateDefaultCaseEvaluation(): string {
|
|
295
|
-
if (!defaultCase) {
|
|
296
|
-
return generateNoMatchHandler();
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
// Get the first node ID for the default case
|
|
300
|
-
// If no target node is connected to the default case, use no-match behavior
|
|
301
|
-
if (!defaultCase.nodes || defaultCase.nodes.length === 0) {
|
|
302
|
-
// Default case exists but has no target - treat as no-match
|
|
303
|
-
return generateNoMatchHandler();
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
// Get all nodes in this branch (from target to end)
|
|
307
|
-
const branchStartId = defaultCase.nodes[0]; // Use raw ID, not sanitized
|
|
308
|
-
// Find the raw ID from the edge
|
|
309
|
-
const defaultEdge = context.jdm.edges.find(
|
|
310
|
-
(e) => e.sourceId === node.id && e.sourceHandle === defaultCase.id,
|
|
311
|
-
);
|
|
312
|
-
const rawTargetId = defaultEdge?.targetId || branchStartId;
|
|
313
|
-
const branchNodeIds = getBranchNodes(rawTargetId, context);
|
|
314
|
-
|
|
315
|
-
// Generate code to evaluate the entire branch
|
|
316
|
-
const { statements, resultExpr } = generateBranchEvaluation(branchNodeIds, context);
|
|
317
|
-
|
|
318
|
-
if (isCollectMode) {
|
|
319
|
-
return ` ${statements}\n results.push(${resultExpr});`;
|
|
320
|
-
} else {
|
|
321
|
-
return ` ${statements}\n return ${resultExpr};`;
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
// Generate the conditional branches for each condition (excluding default)
|
|
326
|
-
let conditionBranches: string;
|
|
327
|
-
let finalReturn: string;
|
|
328
|
-
|
|
329
|
-
// Helper to get branch nodes for a condition
|
|
330
|
-
function getBranchNodesForCondition(condition: SwitchCondition): string[] {
|
|
331
|
-
if (!condition.nodes || condition.nodes.length === 0) {
|
|
332
|
-
return [];
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
// Find the edge for this condition to get the raw target ID
|
|
336
|
-
const edge = context.jdm.edges.find(
|
|
337
|
-
(e) => e.sourceId === node.id && e.sourceHandle === condition.id,
|
|
338
|
-
);
|
|
339
|
-
const rawTargetId = edge?.targetId || condition.nodes[0];
|
|
340
|
-
return getBranchNodes(rawTargetId, context);
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
// Handle the case where there are no regular conditions but there is a default case
|
|
344
|
-
if (regularConditions.length === 0) {
|
|
345
|
-
conditionBranches = '';
|
|
346
|
-
if (defaultCase && defaultCase.nodes && defaultCase.nodes.length > 0) {
|
|
347
|
-
// Only default case exists with a target - evaluate the entire branch
|
|
348
|
-
const branchNodeIds = getBranchNodesForCondition(defaultCase);
|
|
349
|
-
const { statements, resultExpr } = generateBranchEvaluation(branchNodeIds, context);
|
|
350
|
-
|
|
351
|
-
if (isCollectMode) {
|
|
352
|
-
finalReturn = `
|
|
353
|
-
${statements}
|
|
354
|
-
results.push(${resultExpr});
|
|
355
|
-
return Value.Array(results);`;
|
|
356
|
-
} else {
|
|
357
|
-
finalReturn = `
|
|
358
|
-
${statements}
|
|
359
|
-
return ${resultExpr};`;
|
|
360
|
-
}
|
|
361
|
-
} else {
|
|
362
|
-
// No conditions and no default case (or default with no target) - use no-match behavior
|
|
363
|
-
finalReturn = `\n ${generateNoMatchHandler()}`;
|
|
364
|
-
}
|
|
365
|
-
} else {
|
|
366
|
-
// Generate the conditional branches for each condition (excluding default)
|
|
367
|
-
conditionBranches = regularConditions
|
|
368
|
-
.map((condition, idx) => {
|
|
369
|
-
// Parse and compile the condition expression
|
|
370
|
-
let compiledExpr: string;
|
|
371
|
-
// Empty condition means "always true" (especially in collect mode)
|
|
372
|
-
if (condition.expression === '' || condition.expression.trim() === '') {
|
|
373
|
-
compiledExpr = 'true';
|
|
374
|
-
} else {
|
|
375
|
-
try {
|
|
376
|
-
const ast = context.parseExpression(condition.expression);
|
|
377
|
-
// Get the conditional value (expects a boolean result)
|
|
378
|
-
const exprCode = compileExpression(ast, context);
|
|
379
|
-
compiledExpr = `${exprCode}.asBool()`;
|
|
380
|
-
} catch {
|
|
381
|
-
// If parsing fails, provide a comment indicating the issue
|
|
382
|
-
// Can fail if expression syntax is invalid (checked at compile time)
|
|
383
|
-
compiledExpr = '/* ERROR: Could not parse expression */ false';
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
// Get all nodes in this branch (from target to end)
|
|
388
|
-
const branchNodeIds = getBranchNodesForCondition(condition);
|
|
389
|
-
const { statements, resultExpr } = generateBranchEvaluation(branchNodeIds, context);
|
|
390
|
-
|
|
391
|
-
// Generate the conditional branch
|
|
392
|
-
if (isCollectMode) {
|
|
393
|
-
// For collect-mode hit policies, evaluate all conditions independently
|
|
394
|
-
if (shouldMergeCollectResults) {
|
|
395
|
-
// When all branches terminate at output nodes, just evaluate (don't collect)
|
|
396
|
-
// The context accumulates all results which get merged at the end
|
|
397
|
-
const branchCode = `\n if (${compiledExpr}) {
|
|
398
|
-
${statements}
|
|
399
|
-
}`;
|
|
400
|
-
return branchCode;
|
|
401
|
-
}
|
|
402
|
-
const branchCode = `\n if (${compiledExpr}) {
|
|
403
|
-
${statements}
|
|
404
|
-
results.push(${resultExpr});
|
|
405
|
-
}`;
|
|
406
|
-
return branchCode;
|
|
407
|
-
} else {
|
|
408
|
-
// For FIRST hit policy, use if/else if chain (short-circuit on first match)
|
|
409
|
-
const prefix = idx === 0 ? '\n if' : '\n else if';
|
|
410
|
-
const branchCode = `${prefix} (${compiledExpr}) {
|
|
411
|
-
${statements}
|
|
412
|
-
return ${resultExpr};
|
|
413
|
-
}`;
|
|
414
|
-
return branchCode;
|
|
415
|
-
}
|
|
416
|
-
})
|
|
417
|
-
.join('');
|
|
418
|
-
|
|
419
|
-
if (isCollectMode) {
|
|
420
|
-
// For OUTPUT ORDER and PRIORITY, sort the results by value (descending)
|
|
421
|
-
if (hitPolicy === 'outputOrder' || hitPolicy === 'priority') {
|
|
422
|
-
if (
|
|
423
|
-
defaultCase ||
|
|
424
|
-
noMatchBehavior.type === 'throwError' ||
|
|
425
|
-
noMatchBehavior.type === 'returnDefault'
|
|
426
|
-
) {
|
|
427
|
-
finalReturn = `
|
|
428
|
-
// Sort by value (descending priority), with rule order as tie-breaker
|
|
429
|
-
// compareValues returns: -1 if a < b, 0 if equal, 1 if a > b
|
|
430
|
-
// For descending order (higher priority first): return inverted comparison
|
|
431
|
-
// Tie-breaker: when equal, return 1 to maintain original rule order (stable sort)
|
|
432
|
-
results.sort((a: Value, b: Value): i32 => {
|
|
433
|
-
let cmp = compareValues(a, b);
|
|
434
|
-
if (cmp == 0) {
|
|
435
|
-
return 1;
|
|
436
|
-
}
|
|
437
|
-
return cmp < 0 ? 1 : -1;
|
|
438
|
-
});
|
|
439
|
-
|
|
440
|
-
if (results.length == 0) {
|
|
441
|
-
${generateDefaultCaseEvaluation()}
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
${hitPolicy === 'priority' ? 'return results[0];' : 'return Value.Array(results);'}`;
|
|
445
|
-
} else {
|
|
446
|
-
finalReturn = `
|
|
447
|
-
// Sort by value (descending priority), with rule order as tie-breaker
|
|
448
|
-
// compareValues returns: -1 if a < b, 0 if equal, 1 if a > b
|
|
449
|
-
// For descending order (higher priority first): return inverted comparison
|
|
450
|
-
// Tie-breaker: when equal, return 1 to maintain original rule order (stable sort)
|
|
451
|
-
results.sort((a: Value, b: Value): i32 => {
|
|
452
|
-
let cmp = compareValues(a, b);
|
|
453
|
-
if (cmp == 0) {
|
|
454
|
-
return 1;
|
|
455
|
-
}
|
|
456
|
-
return cmp < 0 ? 1 : -1;
|
|
457
|
-
});
|
|
458
|
-
|
|
459
|
-
${
|
|
460
|
-
hitPolicy === 'priority'
|
|
461
|
-
? 'return results.length > 0 ? results[0] : Value.Null();'
|
|
462
|
-
: 'return Value.Array(results);'
|
|
463
|
-
}`;
|
|
464
|
-
}
|
|
465
|
-
} else {
|
|
466
|
-
// Collect or rule order without sorting
|
|
467
|
-
if (shouldMergeCollectResults) {
|
|
468
|
-
// When merging results, return the accumulated context (excluding input keys)
|
|
469
|
-
// First check if any branch was evaluated, if not run default
|
|
470
|
-
if (defaultCase) {
|
|
471
|
-
finalReturn = `
|
|
472
|
-
// Build merged result from accumulated context (excluding input keys)
|
|
473
|
-
// Runtime variables: $=context root, #=current array element, acc=reduce accumulator
|
|
474
|
-
let __mergedResult = new Map<string, Value>();
|
|
475
|
-
const __mergedCtxKeys = ctx.data.keys();
|
|
476
|
-
for (let __mergedI = 0; __mergedI < __mergedCtxKeys.length; __mergedI++) {
|
|
477
|
-
const __mergedKey = __mergedCtxKeys[__mergedI];
|
|
478
|
-
// Skip internal entries, special variables, and input keys
|
|
479
|
-
if (!__mergedKey.startsWith("$") && __mergedKey !== "#" && __mergedKey !== "acc" && !ctx.inputKeys.has(__mergedKey)) {
|
|
480
|
-
__mergedResult.set(__mergedKey, ctx.data.get(__mergedKey));
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
// If no output was produced, run default case
|
|
484
|
-
if (__mergedResult.size == 0) {
|
|
485
|
-
${generateDefaultCaseEvaluation()}
|
|
486
|
-
// Rebuild result after default case
|
|
487
|
-
__mergedResult = new Map<string, Value>();
|
|
488
|
-
const __afterDefaultKeys = ctx.data.keys();
|
|
489
|
-
for (let __afterI = 0; __afterI < __afterDefaultKeys.length; __afterI++) {
|
|
490
|
-
const __afterKey = __afterDefaultKeys[__afterI];
|
|
491
|
-
if (!__afterKey.startsWith("$") && __afterKey !== "#" && __afterKey !== "acc" && !ctx.inputKeys.has(__afterKey)) {
|
|
492
|
-
__mergedResult.set(__afterKey, ctx.data.get(__afterKey));
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
return Value.Object(__mergedResult);`;
|
|
497
|
-
} else {
|
|
498
|
-
finalReturn = `
|
|
499
|
-
// Build merged result from accumulated context (excluding input keys)
|
|
500
|
-
// Runtime variables: $=context root, #=current array element, acc=reduce accumulator
|
|
501
|
-
let __mergedResult = new Map<string, Value>();
|
|
502
|
-
const __mergedCtxKeys = ctx.data.keys();
|
|
503
|
-
for (let __mergedI = 0; __mergedI < __mergedCtxKeys.length; __mergedI++) {
|
|
504
|
-
const __mergedKey = __mergedCtxKeys[__mergedI];
|
|
505
|
-
// Skip internal entries, special variables, and input keys
|
|
506
|
-
if (!__mergedKey.startsWith("$") && __mergedKey !== "#" && __mergedKey !== "acc" && !ctx.inputKeys.has(__mergedKey)) {
|
|
507
|
-
__mergedResult.set(__mergedKey, ctx.data.get(__mergedKey));
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
return Value.Object(__mergedResult);`;
|
|
511
|
-
}
|
|
512
|
-
} else if (
|
|
513
|
-
defaultCase ||
|
|
514
|
-
noMatchBehavior.type === 'throwError' ||
|
|
515
|
-
noMatchBehavior.type === 'returnDefault'
|
|
516
|
-
) {
|
|
517
|
-
finalReturn = `
|
|
518
|
-
if (results.length == 0) {
|
|
519
|
-
${generateDefaultCaseEvaluation()}
|
|
520
|
-
}
|
|
521
|
-
return Value.Array(results);`;
|
|
522
|
-
} else {
|
|
523
|
-
finalReturn = '\n return Value.Array(results);';
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
} else {
|
|
527
|
-
// Non-collect mode (FIRST, PRIORITY)
|
|
528
|
-
if (defaultCase) {
|
|
529
|
-
// Use else block to evaluate default case
|
|
530
|
-
// Last branch already has closing brace, so just add else block
|
|
531
|
-
finalReturn = `\n else {\n // Default case - no conditions matched\n${generateDefaultCaseEvaluation()}\n }`;
|
|
532
|
-
} else {
|
|
533
|
-
// Use else block for no-match handling
|
|
534
|
-
finalReturn = `\n else {\n ${generateNoMatchHandler()}\n }`;
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
const sanitizedId = sanitizeId(node.id);
|
|
540
|
-
return `
|
|
541
|
-
export function evaluateNode_${sanitizedId}(ctx: Context): Value {
|
|
542
|
-
${resultDeclaration}
|
|
543
|
-
|
|
544
|
-
${conditionBranches}${finalReturn}
|
|
545
|
-
}
|
|
546
|
-
`;
|
|
547
|
-
}
|