@divmain/jdm-asm 0.2.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 (397) hide show
  1. package/.github/workflows/ci.yml +53 -0
  2. package/.oxfmtrc.json +16 -0
  3. package/.oxlintrc.json +183 -0
  4. package/AGENTS.md +81 -0
  5. package/README.md +769 -0
  6. package/asconfig.json +23 -0
  7. package/benchmarks/fixtures.ts +111 -0
  8. package/benchmarks/input-fixtures.ts +80 -0
  9. package/benchmarks/run.ts +913 -0
  10. package/benchmarks/worker-pool.ts +223 -0
  11. package/benchmarks/worker.ts +374 -0
  12. package/dist/index.d.ts +996 -0
  13. package/dist/index.js +12239 -0
  14. package/dist/index.js.map +1 -0
  15. package/package.json +49 -0
  16. package/scripts/run-all-tests.ts +220 -0
  17. package/src/compiler/EXPRESSION_SUBSETS.md +228 -0
  18. package/src/compiler/asc-compiler.ts +315 -0
  19. package/src/compiler/ast-types.ts +215 -0
  20. package/src/compiler/build.ts +56 -0
  21. package/src/compiler/cache.ts +414 -0
  22. package/src/compiler/code-generators.ts +211 -0
  23. package/src/compiler/codegen/index.ts +15 -0
  24. package/src/compiler/codegen/js-marshal.ts +999 -0
  25. package/src/compiler/codegen/js-validation.ts +243 -0
  26. package/src/compiler/codegen.ts +19 -0
  27. package/src/compiler/compile-time-validation.ts +507 -0
  28. package/src/compiler/cst-visitor.ts +434 -0
  29. package/src/compiler/errors.ts +227 -0
  30. package/src/compiler/expression-parser.ts +536 -0
  31. package/src/compiler/graph.ts +197 -0
  32. package/src/compiler/index.ts +199 -0
  33. package/src/compiler/input-validation.ts +33 -0
  34. package/src/compiler/marshal-gen.ts +21 -0
  35. package/src/compiler/nodes/context-resolvers.ts +197 -0
  36. package/src/compiler/nodes/decision-table.ts +507 -0
  37. package/src/compiler/nodes/decision.ts +292 -0
  38. package/src/compiler/nodes/expression-compiler.ts +526 -0
  39. package/src/compiler/nodes/expression.ts +425 -0
  40. package/src/compiler/nodes/function.ts +316 -0
  41. package/src/compiler/nodes/input.ts +60 -0
  42. package/src/compiler/nodes/switch.ts +547 -0
  43. package/src/compiler/optimizer.ts +948 -0
  44. package/src/compiler/orchestrator.ts +352 -0
  45. package/src/compiler/parser.ts +115 -0
  46. package/src/compiler/result-selection.ts +161 -0
  47. package/src/compiler/runtime/index.ts +26 -0
  48. package/src/compiler/runtime-codegen.ts +211 -0
  49. package/src/compiler/runtime-validation-codegen.ts +294 -0
  50. package/src/compiler/runtime.ts +452 -0
  51. package/src/compiler/schema.ts +245 -0
  52. package/src/compiler/switch-branch-detection.ts +92 -0
  53. package/src/compiler/types.ts +136 -0
  54. package/src/compiler/unary-ast-transforms.ts +148 -0
  55. package/src/compiler/unary-parser.ts +301 -0
  56. package/src/compiler/unary-transform.ts +161 -0
  57. package/src/compiler/utils.ts +27 -0
  58. package/src/compiler/virtual-fs.ts +90 -0
  59. package/src/compiler/wasm-instantiate.ts +127 -0
  60. package/src/index.ts +1 -0
  61. package/src/runtime/arrays.ts +579 -0
  62. package/src/runtime/context.ts +189 -0
  63. package/src/runtime/expressions.ts +1811 -0
  64. package/src/runtime/index.ts +8 -0
  65. package/src/runtime/memory.ts +607 -0
  66. package/src/runtime/strings.ts +260 -0
  67. package/src/runtime/tables.ts +96 -0
  68. package/src/runtime/tsconfig.json +4 -0
  69. package/src/runtime/values.ts +209 -0
  70. package/test-data/README.md +83 -0
  71. package/test-data/decision-tables/basic/8k.json +87992 -0
  72. package/test-data/decision-tables/basic/affiliate-commission-calculator.json +228 -0
  73. package/test-data/decision-tables/basic/airline-loyalty-points-calculations.json +285 -0
  74. package/test-data/decision-tables/basic/airline-upgrade-eligibility.json +466 -0
  75. package/test-data/decision-tables/basic/auto-insurance-premium-calculator.json +412 -0
  76. package/test-data/decision-tables/basic/booking-personalization-system.json +553 -0
  77. package/test-data/decision-tables/basic/care-team-assignment-system.json +585 -0
  78. package/test-data/decision-tables/basic/claim-validation-system.json +307 -0
  79. package/test-data/decision-tables/basic/clinical-lab-result-interpreter.json +433 -0
  80. package/test-data/decision-tables/basic/clinical-treatment-protocol.json +474 -0
  81. package/test-data/decision-tables/basic/credit-limit-adjustment.json +479 -0
  82. package/test-data/decision-tables/basic/customer-eligibility-engine.json +551 -0
  83. package/test-data/decision-tables/basic/customer-lifetime-value.json +200 -0
  84. package/test-data/decision-tables/basic/customer-onboarding-kyc-verification.json +611 -0
  85. package/test-data/decision-tables/basic/customer-service-escalation.json +191 -0
  86. package/test-data/decision-tables/basic/decision-table-discounts.json +168 -0
  87. package/test-data/decision-tables/basic/decision-table-shipping.json +398 -0
  88. package/test-data/decision-tables/basic/delivery-route-optimizer.json +271 -0
  89. package/test-data/decision-tables/basic/device-compatibility-checker.json +303 -0
  90. package/test-data/decision-tables/basic/disaster-relief-fund-allocation.json +296 -0
  91. package/test-data/decision-tables/basic/dynamic-fx-rate-pricing-system.json +237 -0
  92. package/test-data/decision-tables/basic/dynamic-marketplace-comission-calculator.json +242 -0
  93. package/test-data/decision-tables/basic/dynamic-shipping-cost-calculator.json +378 -0
  94. package/test-data/decision-tables/basic/dynamic-tarrif-engine.json +289 -0
  95. package/test-data/decision-tables/basic/dynamic-ticket-pricing.json +325 -0
  96. package/test-data/decision-tables/basic/empty-column-with-space.json +100 -0
  97. package/test-data/decision-tables/basic/empty-column-without-space.json +100 -0
  98. package/test-data/decision-tables/basic/environment-compliance-assessment.json +386 -0
  99. package/test-data/decision-tables/basic/expression-table-map.json +313 -0
  100. package/test-data/decision-tables/basic/flash-sale-eligibility.json +366 -0
  101. package/test-data/decision-tables/basic/flight-dispatch-decision-system.json +455 -0
  102. package/test-data/decision-tables/basic/flight-rebooking-fee-calculator.json +406 -0
  103. package/test-data/decision-tables/basic/government-assistance.json +299 -0
  104. package/test-data/decision-tables/basic/grant-funding-distribution.json +307 -0
  105. package/test-data/decision-tables/basic/hazardous-materials-management-system.json +414 -0
  106. package/test-data/decision-tables/basic/immigration-eligibility-evaluator.json +765 -0
  107. package/test-data/decision-tables/basic/import-duties-calculator.json +318 -0
  108. package/test-data/decision-tables/basic/insurance-agent-commission.json +228 -0
  109. package/test-data/decision-tables/basic/insurance-coverage-calculator.json +362 -0
  110. package/test-data/decision-tables/basic/insurance-underwriting-risk.json +321 -0
  111. package/test-data/decision-tables/basic/international-roaming-policy-manager.json +199 -0
  112. package/test-data/decision-tables/basic/legacy-plan-management.json +434 -0
  113. package/test-data/decision-tables/basic/marketplace-listing-verification-system.json +334 -0
  114. package/test-data/decision-tables/basic/medication-dosage-calculator.json +318 -0
  115. package/test-data/decision-tables/basic/merch-bags.json +171 -0
  116. package/test-data/decision-tables/basic/municipal-permit-evaluation-system.json +364 -0
  117. package/test-data/decision-tables/basic/mvno-partner-enablement.json +313 -0
  118. package/test-data/decision-tables/basic/partner-revenue-sharing.json +244 -0
  119. package/test-data/decision-tables/basic/payment-routing-and-fee-calculator.json +475 -0
  120. package/test-data/decision-tables/basic/policy-discount-calculator.json +307 -0
  121. package/test-data/decision-tables/basic/policy-eligibility-analyzer.json +299 -0
  122. package/test-data/decision-tables/basic/product-listing-scoring.json +358 -0
  123. package/test-data/decision-tables/basic/realtime-fraud-detection.json +235 -0
  124. package/test-data/decision-tables/basic/regional-compliance-manager.json +278 -0
  125. package/test-data/decision-tables/basic/returns-and-refund-policy.json +366 -0
  126. package/test-data/decision-tables/basic/returns-processing-system.json +448 -0
  127. package/test-data/decision-tables/basic/school-district-resource-allocation.json +282 -0
  128. package/test-data/decision-tables/basic/seat-map-optimization.json +325 -0
  129. package/test-data/decision-tables/basic/seller-fee-calculator.json +307 -0
  130. package/test-data/decision-tables/basic/service-level-agreement-enforcement.json +575 -0
  131. package/test-data/decision-tables/basic/smart-financial-product-matcher.json +249 -0
  132. package/test-data/decision-tables/basic/supply-chain-risk.json +316 -0
  133. package/test-data/decision-tables/basic/table-loop.json +93 -0
  134. package/test-data/decision-tables/basic/table.json +76 -0
  135. package/test-data/decision-tables/basic/traffic-violation-penalty-calculator.json +436 -0
  136. package/test-data/decision-tables/basic/transaction-compliance-classifier.json +525 -0
  137. package/test-data/decision-tables/basic/vehicle-claims-resolution.json +310 -0
  138. package/test-data/decision-tables/basic/warehouse-storage-location.json +345 -0
  139. package/test-data/decision-tables/hit-policy-collect/collect-multiple-matches.json +127 -0
  140. package/test-data/decision-tables/hit-policy-collect/collect-no-match.json +95 -0
  141. package/test-data/decision-tables/hit-policy-first/first-match.json +103 -0
  142. package/test-data/decision-tables/hit-policy-first/no-match.json +95 -0
  143. package/test-data/decision-tables/hit-policy-output-order/output-order-respected.json +94 -0
  144. package/test-data/decision-tables/hit-policy-output-order/string-output-order.json +94 -0
  145. package/test-data/decision-tables/hit-policy-priority/priority-respected.json +86 -0
  146. package/test-data/decision-tables/hit-policy-rule-order/rule-order-respected.json +94 -0
  147. package/test-data/decision-tables/hit-policy-unique/all-match-error.json +89 -0
  148. package/test-data/decision-tables/hit-policy-unique/multiple-match-error.json +89 -0
  149. package/test-data/decision-tables/hit-policy-unique/no-match.json +88 -0
  150. package/test-data/decision-tables/hit-policy-unique/unique-match.json +99 -0
  151. package/test-data/expressions/arithmetic/error-cyclic.json +114 -0
  152. package/test-data/expressions/arithmetic/error-missing-input.json +54 -0
  153. package/test-data/expressions/arithmetic/error-missing-output.json +54 -0
  154. package/test-data/expressions/arithmetic/expression-default.json +93 -0
  155. package/test-data/expressions/arithmetic/expression-fields.json +94 -0
  156. package/test-data/expressions/arithmetic/expression-loop.json +94 -0
  157. package/test-data/expressions/arithmetic/expression-passthrough.json +108 -0
  158. package/test-data/expressions/arithmetic/expression.json +69 -0
  159. package/test-data/expressions/arithmetic/nested-request.json +125 -0
  160. package/test-data/expressions/arithmetic/number-function.json +58 -0
  161. package/test-data/expressions/arithmetic/test-number-functions.json +68 -0
  162. package/test-data/expressions/functions/all.json +149 -0
  163. package/test-data/expressions/functions/avg.json +89 -0
  164. package/test-data/expressions/functions/filter.json +109 -0
  165. package/test-data/expressions/functions/flat.json +167 -0
  166. package/test-data/expressions/functions/map-strings.json +65 -0
  167. package/test-data/expressions/functions/map.json +73 -0
  168. package/test-data/expressions/functions/reduce.json +49 -0
  169. package/test-data/expressions/functions/some.json +175 -0
  170. package/test-data/expressions/functions/sort-strings.json +97 -0
  171. package/test-data/expressions/functions/sort.json +97 -0
  172. package/test-data/expressions/logical/logical-and.json +116 -0
  173. package/test-data/expressions/logical/logical-complex.json +260 -0
  174. package/test-data/expressions/logical/logical-not.json +111 -0
  175. package/test-data/expressions/logical/logical-or.json +123 -0
  176. package/test-data/expressions/string/string-comparison.json +128 -0
  177. package/test-data/expressions/string/string-concat.json +106 -0
  178. package/test-data/expressions/string/string-contains.json +125 -0
  179. package/test-data/expressions/string/string-endsWith.json +113 -0
  180. package/test-data/expressions/string/string-indexOf.json +131 -0
  181. package/test-data/expressions/string/string-join.json +92 -0
  182. package/test-data/expressions/string/string-lower.json +94 -0
  183. package/test-data/expressions/string/string-replace.json +130 -0
  184. package/test-data/expressions/string/string-split.json +101 -0
  185. package/test-data/expressions/string/string-startsWith.json +113 -0
  186. package/test-data/expressions/string/string-substring.json +138 -0
  187. package/test-data/expressions/string/string-trim.json +100 -0
  188. package/test-data/expressions/string/string-upper.json +94 -0
  189. package/test-data/other/custom.json +51 -0
  190. package/test-data/other/customer-input-schema.json +34 -0
  191. package/test-data/other/customer-output-schema.json +34 -0
  192. package/test-data/other/passthrough.json +31 -0
  193. package/test-data/sub-decisions/basic/$nodes-child.json +31 -0
  194. package/test-data/sub-decisions/basic/$nodes-parent.json +49 -0
  195. package/test-data/sub-decisions/basic/recursive-table1.json +49 -0
  196. package/test-data/sub-decisions/basic/recursive-table2.json +49 -0
  197. package/test-data/sub-decisions/complex-multi/approval-decision.json +31 -0
  198. package/test-data/sub-decisions/complex-multi/complex-dag.json +175 -0
  199. package/test-data/sub-decisions/complex-multi/credit-check.json +31 -0
  200. package/test-data/sub-decisions/complex-multi/customer-segmentation.json +31 -0
  201. package/test-data/sub-decisions/complex-multi/discount-eligibility.json +31 -0
  202. package/test-data/sub-decisions/complex-multi/eligibility-check.json +31 -0
  203. package/test-data/sub-decisions/complex-multi/final-offer.json +31 -0
  204. package/test-data/sub-decisions/complex-multi/income-verification.json +31 -0
  205. package/test-data/sub-decisions/complex-multi/linear-chain.json +121 -0
  206. package/test-data/sub-decisions/complex-multi/pricing-calculation.json +31 -0
  207. package/test-data/sub-decisions/complex-multi/product-eligibility.json +31 -0
  208. package/test-data/sub-decisions/complex-multi/risk-assessment.json +31 -0
  209. package/test-data/sub-decisions/complex-multi/shared-validation.json +31 -0
  210. package/test-data/sub-decisions/complex-multi/validation.json +31 -0
  211. package/test-data/sub-decisions/diamond/decision-a.json +31 -0
  212. package/test-data/sub-decisions/diamond/decision-b.json +31 -0
  213. package/test-data/sub-decisions/diamond/decision-c.json +31 -0
  214. package/test-data/sub-decisions/diamond/decision-shared.json +31 -0
  215. package/test-data/sub-decisions/diamond/diamond-pattern.json +109 -0
  216. package/test-data/sub-decisions/error-propagation/parent-calls-error.json +44 -0
  217. package/test-data/sub-decisions/error-propagation/sub-decision-with-error.json +60 -0
  218. package/test-data/switch-nodes/basic/account-dormancy-management.json +245 -0
  219. package/test-data/switch-nodes/basic/application-risk-assessment.json +474 -0
  220. package/test-data/switch-nodes/basic/cellular-data-rollover-system.json +281 -0
  221. package/test-data/switch-nodes/basic/clinical-pathway-selection.json +454 -0
  222. package/test-data/switch-nodes/basic/insurance-prior-authorization.json +467 -0
  223. package/test-data/switch-nodes/basic/last-mile-delivery-assignment.json +373 -0
  224. package/test-data/switch-nodes/basic/loan-approval.json +469 -0
  225. package/test-data/switch-nodes/basic/multi-switch.json +498 -0
  226. package/test-data/switch-nodes/basic/online-checkin-eligibility.json +285 -0
  227. package/test-data/switch-nodes/basic/order-consolidation-system.json +493 -0
  228. package/test-data/switch-nodes/basic/seller-approval-workflow.json +383 -0
  229. package/test-data/switch-nodes/basic/set-fee.json +243 -0
  230. package/test-data/switch-nodes/basic/shipping-carrier-selector.json +379 -0
  231. package/test-data/switch-nodes/basic/switch-node.json +167 -0
  232. package/test-data/switch-nodes/basic/switch-performance-2.json +1307 -0
  233. package/test-data/switch-nodes/basic/switch-performance.json +691 -0
  234. package/test-data/switch-nodes/basic/tax-exemption.json +295 -0
  235. package/test-data/switch-nodes/basic/warehouse-cross-docking.json +313 -0
  236. package/test-data/switch-nodes/default-cases/switch-with-default.json +134 -0
  237. package/test-data/zen-reference/$nodes-child.json +69 -0
  238. package/test-data/zen-reference/$nodes-parent.json +34 -0
  239. package/test-data/zen-reference/8k.json +87992 -0
  240. package/test-data/zen-reference/credit-analysis.json +324 -0
  241. package/test-data/zen-reference/custom.json +51 -0
  242. package/test-data/zen-reference/customer-input-schema.json +34 -0
  243. package/test-data/zen-reference/customer-output-schema.json +34 -0
  244. package/test-data/zen-reference/error-cyclic.json +114 -0
  245. package/test-data/zen-reference/error-missing-input.json +54 -0
  246. package/test-data/zen-reference/error-missing-output.json +54 -0
  247. package/test-data/zen-reference/expression.json +69 -0
  248. package/test-data/zen-reference/function-v2.json +48 -0
  249. package/test-data/zen-reference/function.json +46 -0
  250. package/test-data/zen-reference/graphs/account-dormancy-management.json +245 -0
  251. package/test-data/zen-reference/graphs/affiliate-commission-calculator.json +228 -0
  252. package/test-data/zen-reference/graphs/airline-loyalty-points-calculations.json +285 -0
  253. package/test-data/zen-reference/graphs/airline-upgrade-eligibility.json +466 -0
  254. package/test-data/zen-reference/graphs/aml.json +537 -0
  255. package/test-data/zen-reference/graphs/application-risk-assessment.json +474 -0
  256. package/test-data/zen-reference/graphs/auto-insurance-premium-calculator.json +412 -0
  257. package/test-data/zen-reference/graphs/booking-personalization-system.json +553 -0
  258. package/test-data/zen-reference/graphs/care-team-assignment-system.json +585 -0
  259. package/test-data/zen-reference/graphs/cellular-data-rollover-system.json +281 -0
  260. package/test-data/zen-reference/graphs/claim-validation-system.json +307 -0
  261. package/test-data/zen-reference/graphs/clinical-lab-result-interpreter.json +433 -0
  262. package/test-data/zen-reference/graphs/clinical-pathway-selection.json +454 -0
  263. package/test-data/zen-reference/graphs/clinical-treatment-protocol.json +474 -0
  264. package/test-data/zen-reference/graphs/company-analysis.json +390 -0
  265. package/test-data/zen-reference/graphs/credit-limit-adjustment.json +479 -0
  266. package/test-data/zen-reference/graphs/customer-eligibility-engine.json +551 -0
  267. package/test-data/zen-reference/graphs/customer-lifetime-value.json +200 -0
  268. package/test-data/zen-reference/graphs/customer-onboarding-kyc-verification.json +611 -0
  269. package/test-data/zen-reference/graphs/customer-service-escalation.json +191 -0
  270. package/test-data/zen-reference/graphs/decision-table-discounts.json +168 -0
  271. package/test-data/zen-reference/graphs/decision-table-shipping.json +398 -0
  272. package/test-data/zen-reference/graphs/delivery-route-optimizer.json +271 -0
  273. package/test-data/zen-reference/graphs/device-compatibility-checker.json +303 -0
  274. package/test-data/zen-reference/graphs/disaster-relief-fund-allocation.json +296 -0
  275. package/test-data/zen-reference/graphs/dynamic-fx-rate-pricing-system.json +237 -0
  276. package/test-data/zen-reference/graphs/dynamic-marketplace-comission-calculator.json +242 -0
  277. package/test-data/zen-reference/graphs/dynamic-shipping-cost-calculator.json +378 -0
  278. package/test-data/zen-reference/graphs/dynamic-tarrif-engine.json +289 -0
  279. package/test-data/zen-reference/graphs/dynamic-ticket-pricing.json +325 -0
  280. package/test-data/zen-reference/graphs/empty-column-with-space.json +100 -0
  281. package/test-data/zen-reference/graphs/empty-column-without-space.json +100 -0
  282. package/test-data/zen-reference/graphs/environment-compliance-assessment.json +386 -0
  283. package/test-data/zen-reference/graphs/expression-default.json +93 -0
  284. package/test-data/zen-reference/graphs/expression-fields.json +94 -0
  285. package/test-data/zen-reference/graphs/expression-loop.json +94 -0
  286. package/test-data/zen-reference/graphs/expression-passthrough.json +108 -0
  287. package/test-data/zen-reference/graphs/expression-table-map.json +313 -0
  288. package/test-data/zen-reference/graphs/flash-sale-eligibility.json +366 -0
  289. package/test-data/zen-reference/graphs/flight-dispatch-decision-system.json +455 -0
  290. package/test-data/zen-reference/graphs/flight-rebooking-fee-calculator.json +406 -0
  291. package/test-data/zen-reference/graphs/government-assistance.json +299 -0
  292. package/test-data/zen-reference/graphs/grant-funding-distribution.json +307 -0
  293. package/test-data/zen-reference/graphs/hazardous-materials-management-system.json +414 -0
  294. package/test-data/zen-reference/graphs/immigration-eligibility-evaluator.json +765 -0
  295. package/test-data/zen-reference/graphs/import-duties-calculator.json +318 -0
  296. package/test-data/zen-reference/graphs/insurance-agent-commission.json +228 -0
  297. package/test-data/zen-reference/graphs/insurance-breakdown.json +421 -0
  298. package/test-data/zen-reference/graphs/insurance-coverage-calculator.json +362 -0
  299. package/test-data/zen-reference/graphs/insurance-prior-authorization.json +467 -0
  300. package/test-data/zen-reference/graphs/insurance-underwriting-risk.json +321 -0
  301. package/test-data/zen-reference/graphs/international-roaming-policy-manager.json +199 -0
  302. package/test-data/zen-reference/graphs/last-mile-delivery-assignment.json +373 -0
  303. package/test-data/zen-reference/graphs/legacy-plan-management.json +434 -0
  304. package/test-data/zen-reference/graphs/loan-approval.json +469 -0
  305. package/test-data/zen-reference/graphs/marketplace-listing-verification-system.json +334 -0
  306. package/test-data/zen-reference/graphs/medication-dosage-calculator.json +318 -0
  307. package/test-data/zen-reference/graphs/merch-bags.json +171 -0
  308. package/test-data/zen-reference/graphs/multi-switch.json +498 -0
  309. package/test-data/zen-reference/graphs/municipal-permit-evaluation-system.json +364 -0
  310. package/test-data/zen-reference/graphs/mvno-partner-enablement.json +313 -0
  311. package/test-data/zen-reference/graphs/nested-request.json +125 -0
  312. package/test-data/zen-reference/graphs/online-checkin-eligibility.json +285 -0
  313. package/test-data/zen-reference/graphs/order-consolidation-system.json +493 -0
  314. package/test-data/zen-reference/graphs/partner-revenue-sharing.json +244 -0
  315. package/test-data/zen-reference/graphs/payment-routing-and-fee-calculator.json +475 -0
  316. package/test-data/zen-reference/graphs/policy-discount-calculator.json +307 -0
  317. package/test-data/zen-reference/graphs/policy-eligibility-analyzer.json +299 -0
  318. package/test-data/zen-reference/graphs/product-listing-scoring.json +358 -0
  319. package/test-data/zen-reference/graphs/realtime-fraud-detection.json +235 -0
  320. package/test-data/zen-reference/graphs/regional-compliance-manager.json +278 -0
  321. package/test-data/zen-reference/graphs/returns-and-refund-policy.json +366 -0
  322. package/test-data/zen-reference/graphs/returns-processing-system.json +448 -0
  323. package/test-data/zen-reference/graphs/school-district-resource-allocation.json +282 -0
  324. package/test-data/zen-reference/graphs/seat-map-optimization.json +325 -0
  325. package/test-data/zen-reference/graphs/seller-approval-workflow.json +383 -0
  326. package/test-data/zen-reference/graphs/seller-fee-calculator.json +307 -0
  327. package/test-data/zen-reference/graphs/service-level-agreement-enforcement.json +575 -0
  328. package/test-data/zen-reference/graphs/set-fee.json +243 -0
  329. package/test-data/zen-reference/graphs/shipping-carrier-selector.json +379 -0
  330. package/test-data/zen-reference/graphs/smart-financial-product-matcher.json +249 -0
  331. package/test-data/zen-reference/graphs/supply-chain-risk.json +316 -0
  332. package/test-data/zen-reference/graphs/table-loop.json +93 -0
  333. package/test-data/zen-reference/graphs/tax-exemption.json +295 -0
  334. package/test-data/zen-reference/graphs/traffic-violation-penalty-calculator.json +436 -0
  335. package/test-data/zen-reference/graphs/transaction-compliance-classifier.json +525 -0
  336. package/test-data/zen-reference/graphs/vehicle-claims-resolution.json +310 -0
  337. package/test-data/zen-reference/graphs/warehouse-cross-docking.json +313 -0
  338. package/test-data/zen-reference/graphs/warehouse-storage-location.json +345 -0
  339. package/test-data/zen-reference/http-function.json +34 -0
  340. package/test-data/zen-reference/infinite-function.json +46 -0
  341. package/test-data/zen-reference/js/imports.js +25 -0
  342. package/test-data/zen-reference/passthrough.json +31 -0
  343. package/test-data/zen-reference/recursive-table1.json +49 -0
  344. package/test-data/zen-reference/recursive-table2.json +49 -0
  345. package/test-data/zen-reference/sleep-function.json +34 -0
  346. package/test-data/zen-reference/switch-node.json +167 -0
  347. package/test-data/zen-reference/switch-performance-2.json +1307 -0
  348. package/test-data/zen-reference/switch-performance.json +691 -0
  349. package/test-data/zen-reference/table.json +76 -0
  350. package/tests/helpers/index.ts +73 -0
  351. package/tests/helpers/mock-context.ts +231 -0
  352. package/tests/helpers/round-trip.ts +398 -0
  353. package/tests/helpers/test-harness-comparison.ts +325 -0
  354. package/tests/helpers/test-harness-wasm.ts +710 -0
  355. package/tests/helpers/test-harness.ts +28 -0
  356. package/tests/helpers/wasm-test.ts +659 -0
  357. package/tests/integration/compilation-errors.test.ts +864 -0
  358. package/tests/integration/decision-tables.test.ts +531 -0
  359. package/tests/integration/edge-cases.test.ts +787 -0
  360. package/tests/integration/expressions.test.ts +513 -0
  361. package/tests/integration/function-node-integration.test.ts +182 -0
  362. package/tests/integration/sub-decisions.test.ts +108 -0
  363. package/tests/integration/switch-nodes.test.ts +399 -0
  364. package/tests/integration/unary-or-matching.test.ts +53 -0
  365. package/tests/integration/wasm-data-types.test.ts +398 -0
  366. package/tests/integration/wasm-errors.test.ts +199 -0
  367. package/tests/integration/wasm-execution.test.ts +348 -0
  368. package/tests/integration/wasm-memory.test.ts +228 -0
  369. package/tests/scripts/analyze-coverage.ts +166 -0
  370. package/tests/scripts/categorize-tests.ts +396 -0
  371. package/tests/scripts/coverage-analysis.ts +836 -0
  372. package/tests/unit/compiler/cache.test.ts +238 -0
  373. package/tests/unit/compiler/errors.test.ts +316 -0
  374. package/tests/unit/compiler/graph-scalability.test.ts +510 -0
  375. package/tests/unit/compiler/graph.test.ts +878 -0
  376. package/tests/unit/compiler/input-validation.test.ts +447 -0
  377. package/tests/unit/compiler/logical-and-parser.test.ts +143 -0
  378. package/tests/unit/compiler/logical-not-parser.test.ts +107 -0
  379. package/tests/unit/compiler/logical-or-parser.test.ts +236 -0
  380. package/tests/unit/compiler/marshal-gen/marshal-gen.test.ts +97 -0
  381. package/tests/unit/compiler/nodes/decision-table.test.ts +103 -0
  382. package/tests/unit/compiler/nodes/decision.test.ts +182 -0
  383. package/tests/unit/compiler/nodes/function-compile.test.ts +204 -0
  384. package/tests/unit/compiler/nodes/function.test.ts +176 -0
  385. package/tests/unit/compiler/nodes/input.test.ts +30 -0
  386. package/tests/unit/compiler/nodes/switch.test.ts +127 -0
  387. package/tests/unit/compiler/optimizer-cache.test.ts +327 -0
  388. package/tests/unit/compiler/optimizer-implementation.test.ts +625 -0
  389. package/tests/unit/compiler/parser.test.ts +508 -0
  390. package/tests/unit/compiler/runtime-error-cleanup.test.ts +426 -0
  391. package/tests/unit/compiler/runtime-validation.test.ts +303 -0
  392. package/tests/unit/compiler/runtime.test.ts +221 -0
  393. package/tests/unit/compiler/schema/schema.test.ts +248 -0
  394. package/tests/unit/compiler/unary-ast-transforms.test.ts +245 -0
  395. package/tsconfig.json +27 -0
  396. package/tsup.config.ts +11 -0
  397. package/vitest.config.ts +12 -0
@@ -0,0 +1,260 @@
1
+ // assembly/runtime/strings.ts (AssemblyScript)
2
+ // UTF-16 string handling for WASM linear memory
3
+
4
+ import { heapAlloc } from './memory';
5
+
6
+ // ============================================================================
7
+ // String Memory Format
8
+ // ============================================================================
9
+
10
+ /**
11
+ * String memory layout: [length: u32][utf16 chars...]
12
+ *
13
+ * We use a length-prefixed format; this allows O(1) length checks and efficient substring
14
+ * operations without scanning for null terminators. Also matches AssemblyScript's native
15
+ * string representation. The first 4 bytes contain the length (number of UTF-16 code units).
16
+ * Following that are the UTF-16 code units, each 2 bytes.
17
+ */
18
+
19
+ // ============================================================================
20
+ // String Constants
21
+ // ============================================================================
22
+
23
+ /**
24
+ * Size of the length field header in bytes.
25
+ */
26
+ export const STRING_LENGTH_SIZE: usize = 4;
27
+
28
+ /**
29
+ * Size of each UTF-16 code unit in bytes.
30
+ */
31
+ export const UTF16_CODE_UNIT_SIZE: usize = 2;
32
+
33
+ /**
34
+ * Minimum string length to use bulk memory operations.
35
+ * For strings shorter than this, character-by-character writes are used
36
+ * as the setup overhead dominates. For longer strings, bulk operations
37
+ * provide significant performance benefits.
38
+ */
39
+ const MIN_BULK_COPY_STRING_LENGTH: usize = 32;
40
+
41
+ // ============================================================================
42
+ // String Writing
43
+ // ============================================================================
44
+
45
+ /**
46
+ * Write a string to memory and return its pointer.
47
+ *
48
+ * Memory is allocated from the runtime heap using heapAlloc().
49
+ * The memory is aligned to 4 bytes for efficient access.
50
+ *
51
+ * @param s - The string to write to memory
52
+ * @returns Pointer to the allocated string data, or 0 if allocation failed
53
+ */
54
+ export function writeString(s: string): usize {
55
+ const len: usize = <usize>s.length;
56
+
57
+ // Calculate total size: length field (4 bytes) + UTF-16 characters (2 bytes each)
58
+ const totalSize = STRING_LENGTH_SIZE + len * UTF16_CODE_UNIT_SIZE;
59
+
60
+ // Four-byte alignment ensures proper alignment for u32 loads/stores, avoiding unaligned access
61
+ // penalties on some architectures. WASM requires aligned memory access for multi-byte types.
62
+ // Allocate memory from heap
63
+ const ptr = heapAlloc(totalSize);
64
+
65
+ // Return 0 if allocation failed
66
+ if (ptr == 0) {
67
+ return 0;
68
+ }
69
+
70
+ // Write length (number of UTF-16 code units)
71
+ store<u32>(ptr, len);
72
+
73
+ // Handle empty string case (len == 0)
74
+ if (len == 0) {
75
+ return ptr;
76
+ }
77
+
78
+ // For long strings, use bulk memory copy for better performance.
79
+ // AssemblyScript strings are internally UTF-16, matching our memory format.
80
+ if (len >= MIN_BULK_COPY_STRING_LENGTH) {
81
+ // Get pointer to the string's internal UTF-16 data
82
+ const srcPtr = changetype<usize>(s);
83
+ // Copy the UTF-16 data directly
84
+ memory.copy(ptr + STRING_LENGTH_SIZE, srcPtr, len * UTF16_CODE_UNIT_SIZE);
85
+ } else {
86
+ // For short strings, character-by-character writes avoid bulk operation overhead
87
+ for (let i: usize = 0; i < len; i++) {
88
+ const codeUnit: u16 = unchecked(<u16>s.charCodeAt(<i32>i));
89
+ store<u16>(ptr + STRING_LENGTH_SIZE + i * UTF16_CODE_UNIT_SIZE, codeUnit);
90
+ }
91
+ }
92
+
93
+ return ptr;
94
+ }
95
+
96
+ // ============================================================================
97
+ // String Reading
98
+ // ============================================================================
99
+
100
+ /**
101
+ * Read a string from memory.
102
+ *
103
+ * @param ptr - Pointer to the string data in memory
104
+ * @returns The read string, or empty string if pointer is null
105
+ */
106
+ export function readString(ptr: usize): string {
107
+ // Return empty string for null pointer
108
+ if (ptr == 0) {
109
+ return '';
110
+ }
111
+
112
+ // Read length (number of UTF-16 code units)
113
+ const len: usize = <usize>load<u32>(ptr);
114
+
115
+ // Handle empty string case
116
+ if (len == 0) {
117
+ return '';
118
+ }
119
+
120
+ // Use bulk memory read for O(n) performance instead of O(n²) string concatenation.
121
+ // String.UTF16.decodeUnsafe reads UTF-16 data directly from memory in a single allocation,
122
+ // avoiding the repeated string allocations that occur with character-by-character concatenation.
123
+ return String.UTF16.decodeUnsafe(ptr + STRING_LENGTH_SIZE, len * UTF16_CODE_UNIT_SIZE);
124
+ }
125
+
126
+ // ============================================================================
127
+ // String Utility Functions
128
+ // ============================================================================
129
+
130
+ /**
131
+ * Calculate the size in bytes needed to store a string in memory.
132
+ *
133
+ * @param len - The length of the string (number of UTF-16 code units)
134
+ * @returns The total size in bytes including the length header
135
+ */
136
+ export function getStringSize(len: usize): usize {
137
+ return STRING_LENGTH_SIZE + len * UTF16_CODE_UNIT_SIZE;
138
+ }
139
+
140
+ /**
141
+ * Calculate the length of a string from its pointer in memory.
142
+ *
143
+ * @param ptr - Pointer to the string data in memory
144
+ * @returns The length of the string (number of UTF-16 code units), or 0 if null
145
+ */
146
+ export function getStringLength(ptr: usize): usize {
147
+ if (ptr == 0) {
148
+ return 0;
149
+ }
150
+ return load<u32>(ptr);
151
+ }
152
+
153
+ /**
154
+ * Check if a string pointer points to an empty string.
155
+ *
156
+ * @param ptr - Pointer to the string data in memory
157
+ * @returns true if the string is empty or pointer is null, false otherwise
158
+ */
159
+ export function isStringEmpty(ptr: usize): bool {
160
+ if (ptr == 0) {
161
+ return true;
162
+ }
163
+ return load<u32>(ptr) == 0;
164
+ }
165
+
166
+ /**
167
+ * Compare two strings in memory.
168
+ *
169
+ * @param ptr1 - Pointer to the first string
170
+ * @param ptr2 - Pointer to the second string
171
+ * @returns true if the strings are equal, false otherwise
172
+ */
173
+ export function stringsEqual(ptr1: usize, ptr2: usize): bool {
174
+ // If both are null, they're equal
175
+ if (ptr1 == 0 && ptr2 == 0) {
176
+ return true;
177
+ }
178
+
179
+ // If only one is null, they're not equal
180
+ if (ptr1 == 0 || ptr2 == 0) {
181
+ return false;
182
+ }
183
+
184
+ // Compare lengths
185
+ const len1 = load<u32>(ptr1);
186
+ const len2 = load<u32>(ptr2);
187
+
188
+ if (len1 != len2) {
189
+ return false;
190
+ }
191
+
192
+ // Compare each UTF-16 code unit
193
+ for (let i: usize = 0; i < <usize>len1; i++) {
194
+ const offset = STRING_LENGTH_SIZE + i * UTF16_CODE_UNIT_SIZE;
195
+ const char1 = load<u16>(ptr1 + offset);
196
+ const char2 = load<u16>(ptr2 + offset);
197
+ if (char1 != char2) {
198
+ return false;
199
+ }
200
+ }
201
+
202
+ return true;
203
+ }
204
+
205
+ /**
206
+ * Calculate a simple hash of a string in memory.
207
+ *
208
+ * This can be used for quick comparisons or deduplication.
209
+ * Uses a simple polynomial rolling hash algorithm.
210
+ *
211
+ * @param ptr - Pointer to the string data in memory
212
+ * @returns A hash value for the string (0 if null)
213
+ */
214
+ export function hashString(ptr: usize): u32 {
215
+ if (ptr == 0) {
216
+ return 0;
217
+ }
218
+
219
+ const len: usize = <usize>load<u32>(ptr);
220
+ let hash: u32 = 5381;
221
+
222
+ for (let i: usize = 0; i < len; i++) {
223
+ const charCode = load<u16>(ptr + STRING_LENGTH_SIZE + i * UTF16_CODE_UNIT_SIZE);
224
+ hash = unchecked((hash << 5) + hash + unchecked(charCode)); // hash * 33 + charCode
225
+ }
226
+
227
+ return hash;
228
+ }
229
+
230
+ /**
231
+ * Copy a string within memory.
232
+ *
233
+ * Creates a new copy of the string at a new location in the heap.
234
+ *
235
+ * @param srcPtr - Pointer to the source string
236
+ * @returns Pointer to the newly allocated copy, or 0 if allocation failed
237
+ */
238
+ export function copyString(srcPtr: usize): usize {
239
+ if (srcPtr == 0) {
240
+ return 0;
241
+ }
242
+
243
+ // Get the length of the source string
244
+ const len: usize = <usize>load<u32>(srcPtr);
245
+
246
+ // Calculate total size
247
+ const totalSize = STRING_LENGTH_SIZE + len * UTF16_CODE_UNIT_SIZE;
248
+
249
+ // Allocate new memory
250
+ const dstPtr = heapAlloc(totalSize);
251
+
252
+ if (dstPtr == 0) {
253
+ return 0;
254
+ }
255
+
256
+ // Copy the entire string data (length header + UTF-16 code units)
257
+ memory.copy(dstPtr, srcPtr, totalSize);
258
+
259
+ return dstPtr;
260
+ }
@@ -0,0 +1,96 @@
1
+ // assembly/runtime/tables.ts (AssemblyScript)
2
+ import { Value } from './values';
3
+ import { Context } from './context';
4
+ import { valuesEqual } from './expressions';
5
+
6
+ /**
7
+ * Condition for decision table row evaluation.
8
+ * Uses Value tagged union consistently.
9
+ */
10
+ export class Condition {
11
+ field: string;
12
+ op: string;
13
+ value: Value;
14
+
15
+ constructor(field: string, op: string, value: Value) {
16
+ this.field = field;
17
+ this.op = op;
18
+ this.value = value;
19
+ }
20
+
21
+ evaluate(ctx: Context): bool {
22
+ const actual = ctx.get(this.field);
23
+ const expected = this.value;
24
+
25
+ // Handle null cases
26
+ if (actual.isNull()) {
27
+ if (this.op == '==' && expected.isNull()) return true;
28
+ if (this.op == '!=' && !expected.isNull()) return true;
29
+ return false;
30
+ }
31
+
32
+ // Numeric comparisons
33
+ if (actual.isNumber() && expected.isNumber()) {
34
+ const a = actual.asFloat();
35
+ const e = expected.asFloat();
36
+
37
+ if (this.op == '==') return a == e;
38
+ if (this.op == '!=') return a != e;
39
+ if (this.op == '<') return a < e;
40
+ if (this.op == '<=') return a <= e;
41
+ if (this.op == '>') return a > e;
42
+ if (this.op == '>=') return a >= e;
43
+ }
44
+
45
+ // String comparisons
46
+ if (actual.isString() && expected.isString()) {
47
+ const a = actual.asString();
48
+ const e = expected.asString();
49
+
50
+ if (this.op == '==') return a == e;
51
+ if (this.op == '!=') return a != e;
52
+ // Lexicographic comparison for strings
53
+ if (this.op == '<') return a < e;
54
+ if (this.op == '<=') return a <= e;
55
+ if (this.op == '>') return a > e;
56
+ if (this.op == '>=') return a >= e;
57
+ }
58
+
59
+ // Boolean equality
60
+ if (actual.isBool() && expected.isBool()) {
61
+ if (this.op == '==') return actual.boolVal == expected.boolVal;
62
+ if (this.op == '!=') return actual.boolVal != expected.boolVal;
63
+ }
64
+
65
+ // Generic equality via valuesEqual
66
+ if (this.op == '==') return valuesEqual(actual, expected);
67
+ if (this.op == '!=') return !valuesEqual(actual, expected);
68
+
69
+ return false;
70
+ }
71
+ }
72
+
73
+ /**
74
+ * Check if a value is within an interval (range).
75
+ * Supports open/closed boundaries: [a..b], (a..b), [a..b), (a..b]
76
+ */
77
+ export function inInterval(
78
+ val: Value,
79
+ start: Value,
80
+ end: Value,
81
+ startInclusive: bool,
82
+ endInclusive: bool,
83
+ ): bool {
84
+ if (!val.isNumber() || !start.isNumber() || !end.isNumber()) {
85
+ return false;
86
+ }
87
+
88
+ const v = val.asFloat();
89
+ const s = start.asFloat();
90
+ const e = end.asFloat();
91
+
92
+ const aboveStart = startInclusive ? v >= s : v > s;
93
+ const belowEnd = endInclusive ? v <= e : v < e;
94
+
95
+ return aboveStart && belowEnd;
96
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": "assemblyscript/std/assembly.json",
3
+ "include": ["./**/*.ts"]
4
+ }
@@ -0,0 +1,209 @@
1
+ // assembly/runtime/values.ts
2
+ // Type tags for runtime type checking
3
+ export const TYPE_NULL: i32 = 0;
4
+ export const TYPE_BOOL: i32 = 1;
5
+ export const TYPE_INT: i32 = 2;
6
+ export const TYPE_FLOAT: i32 = 3;
7
+ export const TYPE_STRING: i32 = 4;
8
+ export const TYPE_ARRAY: i32 = 5;
9
+ export const TYPE_OBJECT: i32 = 6;
10
+
11
+ // Pre-allocated singleton values for frequently used immutable types.
12
+ // This avoids allocations in hot paths for null/boolean/small integer/common float values.
13
+ let _nullSingleton: Value | null = null;
14
+ let _trueSingleton: Value | null = null;
15
+ let _falseSingleton: Value | null = null;
16
+ let _emptyStringSingleton: Value | null = null;
17
+ let _zeroFloatSingleton: Value | null = null;
18
+ let _oneFloatSingleton: Value | null = null;
19
+
20
+ // Cache for small integers (-1 to 10) - covers common array indices, loop counters, etc.
21
+ // Using 12-element array: index 0 = -1, index 1 = 0, ..., index 11 = 10
22
+ const SMALL_INT_CACHE_MIN: i64 = -1;
23
+ const SMALL_INT_CACHE_MAX: i64 = 10;
24
+ const SMALL_INT_CACHE_SIZE: i32 = 12;
25
+ let _smallIntCache: StaticArray<Value | null> | null = null;
26
+
27
+ /**
28
+ * Tagged union for dynamic JSON-like values.
29
+ * Only one field is valid based on the `type` tag.
30
+ */
31
+ export class Value {
32
+ type: i32 = TYPE_NULL;
33
+ boolVal: bool = false;
34
+ intVal: i64 = 0;
35
+ floatVal: f64 = 0.0;
36
+ stringVal: string | null = null;
37
+ arrayVal: Array<Value> | null = null;
38
+ objectVal: Map<string, Value> | null = null;
39
+
40
+ static Null(): Value {
41
+ // Return singleton null value to avoid allocations
42
+ if (_nullSingleton === null) {
43
+ const v = new Value();
44
+ v.type = TYPE_NULL;
45
+ _nullSingleton = v;
46
+ }
47
+ return _nullSingleton!;
48
+ }
49
+
50
+ static Bool(val: bool): Value {
51
+ // Return singleton boolean values to avoid allocations
52
+ if (val) {
53
+ if (_trueSingleton === null) {
54
+ const v = new Value();
55
+ v.type = TYPE_BOOL;
56
+ v.boolVal = true;
57
+ _trueSingleton = v;
58
+ }
59
+ return _trueSingleton!;
60
+ } else {
61
+ if (_falseSingleton === null) {
62
+ const v = new Value();
63
+ v.type = TYPE_BOOL;
64
+ v.boolVal = false;
65
+ _falseSingleton = v;
66
+ }
67
+ return _falseSingleton!;
68
+ }
69
+ }
70
+
71
+ static Int(val: i64): Value {
72
+ // Fast path for common small integers to avoid allocations
73
+ if (val >= SMALL_INT_CACHE_MIN && val <= SMALL_INT_CACHE_MAX) {
74
+ if (_smallIntCache === null) {
75
+ _smallIntCache = new StaticArray<Value | null>(SMALL_INT_CACHE_SIZE);
76
+ }
77
+ const idx = <i32>(val - SMALL_INT_CACHE_MIN);
78
+ if (unchecked(_smallIntCache![idx]) === null) {
79
+ const v = new Value();
80
+ v.type = TYPE_INT;
81
+ v.intVal = val;
82
+ unchecked((_smallIntCache![idx] = v));
83
+ }
84
+ return unchecked(_smallIntCache![idx])!;
85
+ }
86
+ const v = new Value();
87
+ v.type = TYPE_INT;
88
+ v.intVal = val;
89
+ return v;
90
+ }
91
+
92
+ static Float(val: f64): Value {
93
+ // Fast path for common float values (0.0, 1.0) to avoid allocations
94
+ if (val == 0.0) {
95
+ if (_zeroFloatSingleton === null) {
96
+ const v = new Value();
97
+ v.type = TYPE_FLOAT;
98
+ v.floatVal = 0.0;
99
+ _zeroFloatSingleton = v;
100
+ }
101
+ return _zeroFloatSingleton!;
102
+ }
103
+ if (val == 1.0) {
104
+ if (_oneFloatSingleton === null) {
105
+ const v = new Value();
106
+ v.type = TYPE_FLOAT;
107
+ v.floatVal = 1.0;
108
+ _oneFloatSingleton = v;
109
+ }
110
+ return _oneFloatSingleton!;
111
+ }
112
+ const v = new Value();
113
+ v.type = TYPE_FLOAT;
114
+ v.floatVal = val;
115
+ return v;
116
+ }
117
+
118
+ static String(val: string): Value {
119
+ // Fast path for empty string to avoid allocations
120
+ if (val.length == 0) {
121
+ if (_emptyStringSingleton === null) {
122
+ const v = new Value();
123
+ v.type = TYPE_STRING;
124
+ v.stringVal = '';
125
+ _emptyStringSingleton = v;
126
+ }
127
+ return _emptyStringSingleton!;
128
+ }
129
+ const v = new Value();
130
+ v.type = TYPE_STRING;
131
+ v.stringVal = val;
132
+ return v;
133
+ }
134
+
135
+ static Array(val: Array<Value>): Value {
136
+ const v = new Value();
137
+ v.type = TYPE_ARRAY;
138
+ v.arrayVal = val;
139
+ return v;
140
+ }
141
+
142
+ static Object(val: Map<string, Value>): Value {
143
+ const v = new Value();
144
+ v.type = TYPE_OBJECT;
145
+ v.objectVal = val;
146
+ return v;
147
+ }
148
+
149
+ // Type checking
150
+ isNull(): bool {
151
+ return this.type == TYPE_NULL;
152
+ }
153
+ isBool(): bool {
154
+ return this.type == TYPE_BOOL;
155
+ }
156
+ isNumber(): bool {
157
+ return this.type == TYPE_INT || this.type == TYPE_FLOAT;
158
+ }
159
+ isString(): bool {
160
+ return this.type == TYPE_STRING;
161
+ }
162
+ isArray(): bool {
163
+ return this.type == TYPE_ARRAY;
164
+ }
165
+ isObject(): bool {
166
+ return this.type == TYPE_OBJECT;
167
+ }
168
+
169
+ // Returning defaults (0, false, "") instead of throwing errors provides more
170
+ // forgiving evaluation semantics matching JavaScript's type coercion behavior.
171
+ asBool(): bool {
172
+ return this.type == TYPE_BOOL ? this.boolVal : false;
173
+ }
174
+ asInt(): i64 {
175
+ return this.type == TYPE_INT ? this.intVal : 0;
176
+ }
177
+ asFloat(): f64 {
178
+ if (this.type == TYPE_FLOAT) return this.floatVal;
179
+ if (this.type == TYPE_INT) return <f64>this.intVal;
180
+ return 0.0;
181
+ }
182
+ asString(): string {
183
+ // Convert value to string representation
184
+ if (this.type == TYPE_STRING && this.stringVal != null) return this.stringVal!;
185
+ if (this.type == TYPE_NULL) return '';
186
+ if (this.type == TYPE_BOOL) return this.boolVal ? 'true' : 'false';
187
+ if (this.type == TYPE_INT) return this.intVal.toString();
188
+ if (this.type == TYPE_FLOAT) {
189
+ // JavaScript developers expect "3" not "3.0" for integer-valued floats. We check if
190
+ // the float is exactly representable as i64 (no fractional part, within range) and
191
+ // format as integer in that case. Otherwise use AS's default float formatting.
192
+ const f = this.floatVal;
193
+ // Check if it's an integer
194
+ if (f == <f64>(<i64>f) && f >= <f64>i64.MIN_VALUE && f <= <f64>i64.MAX_VALUE) {
195
+ return (<i64>f).toString();
196
+ }
197
+ return f.toString();
198
+ }
199
+ return '';
200
+ }
201
+ asArray(): Array<Value> {
202
+ return this.arrayVal != null ? this.arrayVal! : new Array<Value>();
203
+ }
204
+ asObject(): Map<string, Value> {
205
+ return this.objectVal != null ? this.objectVal! : new Map<string, Value>();
206
+ }
207
+ }
208
+
209
+ export type Result = Map<string, Value>;
@@ -0,0 +1,83 @@
1
+ # Test Data Organization
2
+
3
+ This directory contains test fixtures ported from `@gorules/zen-engine` to ensure compatibility and validate the correctness of the JDM-ASM compiler.
4
+
5
+ ## Test Porting Strategy
6
+
7
+ The test porting process follows a structured approach:
8
+
9
+ 1. **Clone Reference Tests**: Tests are cloned from the `gorules/zen` repository to `test-data/zen-reference/`
10
+ 2. **Analyze Coverage**: The `analyze-coverage.ts` script analyzes JDM files to understand node types and features
11
+ 3. **Categorize Tests**: The `categorize-tests.ts` script automatically categorizes tests based on their node types:
12
+ - Expression nodes → `expressions/`
13
+ - Decision table nodes → `decision-tables/`
14
+ - Switch nodes → `switch-nodes/`
15
+ - Decision nodes (sub-decision references) → `sub-decisions/`
16
+ - Function nodes are currently skipped (not yet supported)
17
+ - Other node types are placed in `other/`
18
+ 4. **Further Organization**: Within each category, tests are organized by feature subsets (e.g., arithmetic, logical, string for expressions)
19
+
20
+
21
+
22
+ ## Directory Structure
23
+
24
+ ### expressions/
25
+ Tests for the ZEN expression language parser and evaluation, including:
26
+ - Arithmetic operations
27
+ - Logical operations
28
+ - String operations
29
+ - Comparisons
30
+ - Function calls
31
+
32
+ ### decision-tables/
33
+ Tests for decision table nodes, including:
34
+ - Simple decision tables
35
+ - Multiple input/output columns
36
+ - Hit policies (First, Collect Sum, Collect Count, etc.)
37
+ - Priority rules
38
+
39
+ ### switch-nodes/
40
+ Tests for switch/case logic, including:
41
+ - String matching
42
+ - Number ranges
43
+ - Multiple conditions
44
+ - Default cases
45
+
46
+ ### sub-decisions/
47
+ Tests for sub-decision nodes and complex decision graphs:
48
+ - Nested decisions
49
+ - Decision calls
50
+ - Result propagation
51
+
52
+ ### other/
53
+ Tests that don't fit into standard categories:
54
+ - Custom node types
55
+ - Simple Input/Output tests
56
+ - Schema-related tests
57
+
58
+ ## Running Test Analysis
59
+
60
+ To analyze test coverage:
61
+ ```bash
62
+ npx tsx tests/scripts/analyze-coverage.ts > test-data/analysis.md
63
+ ```
64
+
65
+ To categorize and organize tests:
66
+ ```bash
67
+ npx tsx tests/scripts/categorize-tests.ts test-data/zen-reference test-data
68
+ ```
69
+
70
+ ## Test Format
71
+
72
+ Each test consists of:
73
+ 1. **JDM JSON**: The decision model definition
74
+ 2. **Input data**: Sample input values (typically from zen-engine test harness)
75
+ 3. **Expected output**: The expected result structure
76
+ 4. (Optional) **Schema**: TypeBox schema for type-safe marshaling
77
+
78
+ See individual test files for examples.
79
+
80
+ ## Reference Source
81
+
82
+ Tests are ported from: https://github.com/gorules/zen
83
+ Reference tests located in: `test-data/zen-reference/`