solve-engine 1.1.0 → 1.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 (188) hide show
  1. package/dist/{EngineError-B61GS1jp.d.cts → EngineError-CNA_rHY-.d.cts} +6 -0
  2. package/dist/{EngineError-B61GS1jp.d.ts → EngineError-CNA_rHY-.d.ts} +6 -0
  3. package/dist/{Lexer-BOs7euZe.d.cts → Lexer-B4C1qHXu.d.cts} +1 -1
  4. package/dist/{Lexer-CSI_lwbW.d.ts → Lexer-DKMlj7Sy.d.ts} +1 -1
  5. package/dist/{PackageCompatibility-B-7rK1TD.d.cts → PackageCompatibility-B6NX9IaN.d.cts} +1 -1
  6. package/dist/{PackageCompatibility-Dh59eF-X.d.ts → PackageCompatibility-Ceg5XdAp.d.ts} +1 -1
  7. package/dist/{PackageRegistry-BHWJP83F.d.cts → PackageRegistry-DnJYVw9G.d.cts} +55 -8
  8. package/dist/{PackageRegistry-_8rDlvxI.d.ts → PackageRegistry-DrCPQNyy.d.ts} +55 -8
  9. package/dist/{Parselet-BBT8riYh.d.ts → Parselet-Bhf7d0_W.d.ts} +2 -2
  10. package/dist/{Parselet-BHcgK9S7.d.cts → Parselet-Cv7S7KRt.d.cts} +2 -2
  11. package/dist/{ScopeManager-CxA24W5n.d.ts → ScopeManager-Bzq87GfA.d.ts} +10 -3
  12. package/dist/{ScopeManager-8vf02dwj.d.cts → ScopeManager-DRDBVfan.d.cts} +10 -3
  13. package/dist/{Token-B1hdkedD.d.cts → Token-CbP_OutD.d.cts} +9 -0
  14. package/dist/{Token-B1hdkedD.d.ts → Token-CbP_OutD.d.ts} +9 -0
  15. package/dist/{TokenNormalizer-C6VzZgHa.d.ts → TokenNormalizer-DCWdZjGz.d.ts} +1 -1
  16. package/dist/{TokenNormalizer-DRc1Js1V.d.cts → TokenNormalizer-DnlL7_8c.d.cts} +1 -1
  17. package/dist/{VMCheckpoints-MK--EBH2.d.ts → VMCheckpoints-C6c17Hbo.d.ts} +2 -2
  18. package/dist/{VMCheckpoints-ELYqITdF.d.cts → VMCheckpoints-dZxSMGHG.d.cts} +2 -2
  19. package/dist/{Value-BUi1RA3S.d.cts → Value-DZNQ_PU7.d.cts} +32 -5
  20. package/dist/{Value-BUi1RA3S.d.ts → Value-DZNQ_PU7.d.ts} +32 -5
  21. package/dist/{WorkerError-_-RkoQ5P.d.ts → WorkerError-B7t7R2-m.d.ts} +1 -1
  22. package/dist/{WorkerError-gzmaopj2.d.cts → WorkerError-Djd7GGGa.d.cts} +1 -1
  23. package/dist/{chunk-SSV46KFA.cjs → chunk-4K5W7EH2.cjs} +6 -6
  24. package/dist/{chunk-SSV46KFA.cjs.map → chunk-4K5W7EH2.cjs.map} +1 -1
  25. package/dist/{chunk-267JPOTF.js → chunk-5EFKSKMA.js} +11 -4
  26. package/dist/chunk-5EFKSKMA.js.map +1 -0
  27. package/dist/{chunk-536WPM2V.cjs → chunk-7AXJNQMF.cjs} +17 -3
  28. package/dist/chunk-7AXJNQMF.cjs.map +1 -0
  29. package/dist/{chunk-GUG7SNSV.js → chunk-7JM3F4KL.js} +39 -8
  30. package/dist/chunk-7JM3F4KL.js.map +1 -0
  31. package/dist/{chunk-XJGJCF2R.cjs → chunk-7USV76HV.cjs} +6 -6
  32. package/dist/{chunk-XJGJCF2R.cjs.map → chunk-7USV76HV.cjs.map} +1 -1
  33. package/dist/{chunk-HIQ5HSZL.cjs → chunk-A2DZ5BEJ.cjs} +53 -46
  34. package/dist/{chunk-HIQ5HSZL.cjs.map → chunk-A2DZ5BEJ.cjs.map} +1 -1
  35. package/dist/{chunk-CKQMXMHR.cjs → chunk-AKNGX4TZ.cjs} +28 -11
  36. package/dist/chunk-AKNGX4TZ.cjs.map +1 -0
  37. package/dist/{chunk-I4GAWIPW.js → chunk-AOH6UR2L.js} +6 -6
  38. package/dist/{chunk-I4GAWIPW.js.map → chunk-AOH6UR2L.js.map} +1 -1
  39. package/dist/{chunk-MG6Q3DUO.cjs → chunk-BESTLPRK.cjs} +326 -214
  40. package/dist/chunk-BESTLPRK.cjs.map +1 -0
  41. package/dist/{chunk-Z7XGGLI2.js → chunk-BSPXMGIS.js} +3 -3
  42. package/dist/{chunk-Z7XGGLI2.js.map → chunk-BSPXMGIS.js.map} +1 -1
  43. package/dist/{chunk-SRGQ72IR.cjs → chunk-C2OMO3WN.cjs} +376 -370
  44. package/dist/chunk-C2OMO3WN.cjs.map +1 -0
  45. package/dist/{chunk-G7Z4HJQA.js → chunk-CSDQMDU2.js} +4 -4
  46. package/dist/{chunk-G7Z4HJQA.js.map → chunk-CSDQMDU2.js.map} +1 -1
  47. package/dist/{chunk-7KYSUDQO.js → chunk-F4UB4XIL.js} +4 -4
  48. package/dist/{chunk-7KYSUDQO.js.map → chunk-F4UB4XIL.js.map} +1 -1
  49. package/dist/{chunk-WXEHD6TT.js → chunk-FE4RC37D.js} +15 -9
  50. package/dist/chunk-FE4RC37D.js.map +1 -0
  51. package/dist/{chunk-7ZX6B7SY.cjs → chunk-FR7RNOPT.cjs} +637 -556
  52. package/dist/chunk-FR7RNOPT.cjs.map +1 -0
  53. package/dist/{chunk-QFTDTX6K.cjs → chunk-G2YPPLGX.cjs} +29 -2
  54. package/dist/chunk-G2YPPLGX.cjs.map +1 -0
  55. package/dist/{chunk-HVRVSI2Z.cjs → chunk-GDEU72RG.cjs} +86 -86
  56. package/dist/{chunk-HVRVSI2Z.cjs.map → chunk-GDEU72RG.cjs.map} +1 -1
  57. package/dist/{chunk-OTN6SZOD.cjs → chunk-HKTQCQ4Z.cjs} +860 -489
  58. package/dist/chunk-HKTQCQ4Z.cjs.map +1 -0
  59. package/dist/{chunk-XA4CKRML.cjs → chunk-HWHU642X.cjs} +2 -2
  60. package/dist/{chunk-XA4CKRML.cjs.map → chunk-HWHU642X.cjs.map} +1 -1
  61. package/dist/{chunk-C75AFGVD.cjs → chunk-ICEKS6YC.cjs} +11 -11
  62. package/dist/{chunk-C75AFGVD.cjs.map → chunk-ICEKS6YC.cjs.map} +1 -1
  63. package/dist/{chunk-JIPATHVY.js → chunk-IJGOFP2J.js} +138 -26
  64. package/dist/chunk-IJGOFP2J.js.map +1 -0
  65. package/dist/{chunk-ENKKJYD3.js → chunk-IQJGDZOP.js} +4 -4
  66. package/dist/{chunk-ENKKJYD3.js.map → chunk-IQJGDZOP.js.map} +1 -1
  67. package/dist/{chunk-2TZKENDH.cjs → chunk-IT74O4BE.cjs} +15 -7
  68. package/dist/chunk-IT74O4BE.cjs.map +1 -0
  69. package/dist/{chunk-ZVTWQLK4.cjs → chunk-KXDQKVNX.cjs} +10 -10
  70. package/dist/{chunk-ZVTWQLK4.cjs.map → chunk-KXDQKVNX.cjs.map} +1 -1
  71. package/dist/{chunk-JJIXHXFQ.js → chunk-L5YHV6BQ.js} +5 -5
  72. package/dist/{chunk-JJIXHXFQ.js.map → chunk-L5YHV6BQ.js.map} +1 -1
  73. package/dist/{chunk-ZXCESUJS.cjs → chunk-LO7HU5WB.cjs} +8 -8
  74. package/dist/{chunk-ZXCESUJS.cjs.map → chunk-LO7HU5WB.cjs.map} +1 -1
  75. package/dist/{chunk-UO6BUV6K.js → chunk-LSALB3IN.js} +17 -3
  76. package/dist/chunk-LSALB3IN.js.map +1 -0
  77. package/dist/{chunk-J45BCEZ4.cjs → chunk-MI7OTUHL.cjs} +27 -27
  78. package/dist/{chunk-J45BCEZ4.cjs.map → chunk-MI7OTUHL.cjs.map} +1 -1
  79. package/dist/{chunk-B4HBEFTB.cjs → chunk-MIGXCBXT.cjs} +8 -2
  80. package/dist/chunk-MIGXCBXT.cjs.map +1 -0
  81. package/dist/{chunk-ERCOHGXD.js → chunk-N7OA4WPJ.js} +8 -2
  82. package/dist/chunk-N7OA4WPJ.js.map +1 -0
  83. package/dist/{chunk-4D6NIHE2.js → chunk-NAWZATKT.js} +29 -2
  84. package/dist/chunk-NAWZATKT.js.map +1 -0
  85. package/dist/{chunk-GQMUHVE3.js → chunk-ORM7CHYZ.js} +36 -5
  86. package/dist/chunk-ORM7CHYZ.js.map +1 -0
  87. package/dist/{chunk-B7NLZMQ3.cjs → chunk-PCZVMMWU.cjs} +8 -8
  88. package/dist/{chunk-B7NLZMQ3.cjs.map → chunk-PCZVMMWU.cjs.map} +1 -1
  89. package/dist/{chunk-OADDUPT3.js → chunk-RNKDIXDV.js} +4 -4
  90. package/dist/{chunk-OADDUPT3.js.map → chunk-RNKDIXDV.js.map} +1 -1
  91. package/dist/{chunk-SNHVVOJK.cjs → chunk-TC6BTUSU.cjs} +55 -24
  92. package/dist/chunk-TC6BTUSU.cjs.map +1 -0
  93. package/dist/{chunk-RRLHC37V.js → chunk-TPOK3UNI.js} +387 -17
  94. package/dist/chunk-TPOK3UNI.js.map +1 -0
  95. package/dist/{chunk-CCBZZQAE.js → chunk-UF6JG5SG.js} +2 -2
  96. package/dist/{chunk-CCBZZQAE.js.map → chunk-UF6JG5SG.js.map} +1 -1
  97. package/dist/{chunk-NKW7LKYU.js → chunk-WMQRJTAO.js} +88 -7
  98. package/dist/chunk-WMQRJTAO.js.map +1 -0
  99. package/dist/{chunk-YTIYVHL7.cjs → chunk-YJHY7CMN.cjs} +108 -77
  100. package/dist/chunk-YJHY7CMN.cjs.map +1 -0
  101. package/dist/{chunk-3OWCDIPN.js → chunk-YNIWOYW6.js} +21 -4
  102. package/dist/chunk-YNIWOYW6.js.map +1 -0
  103. package/dist/{chunk-WWQEY7BV.js → chunk-ZN6YYPIW.js} +3 -3
  104. package/dist/{chunk-WWQEY7BV.js.map → chunk-ZN6YYPIW.js.map} +1 -1
  105. package/dist/{chunk-NNQ2TYDF.js → chunk-ZNFFTYWH.js} +11 -5
  106. package/dist/chunk-ZNFFTYWH.js.map +1 -0
  107. package/dist/constants.cjs +5 -5
  108. package/dist/constants.js +2 -2
  109. package/dist/engine.cjs +33 -33
  110. package/dist/engine.d.cts +27 -11
  111. package/dist/engine.d.ts +27 -11
  112. package/dist/engine.js +20 -20
  113. package/dist/errors.cjs +26 -26
  114. package/dist/errors.d.cts +3 -3
  115. package/dist/errors.d.ts +3 -3
  116. package/dist/errors.js +2 -2
  117. package/dist/format.cjs +7 -7
  118. package/dist/format.d.cts +1 -1
  119. package/dist/format.d.ts +1 -1
  120. package/dist/format.js +4 -4
  121. package/dist/index.cjs +48 -48
  122. package/dist/index.d.cts +11 -11
  123. package/dist/index.d.ts +11 -11
  124. package/dist/index.js +21 -21
  125. package/dist/language.cjs +7 -7
  126. package/dist/language.d.cts +10 -10
  127. package/dist/language.d.ts +10 -10
  128. package/dist/language.js +2 -2
  129. package/dist/lexer.cjs +16 -16
  130. package/dist/lexer.d.cts +3 -3
  131. package/dist/lexer.d.ts +3 -3
  132. package/dist/lexer.js +5 -5
  133. package/dist/normalizer.cjs +10 -10
  134. package/dist/normalizer.d.cts +3 -3
  135. package/dist/normalizer.d.ts +3 -3
  136. package/dist/normalizer.js +4 -4
  137. package/dist/packages.cjs +40 -36
  138. package/dist/packages.d.cts +37 -11
  139. package/dist/packages.d.ts +37 -11
  140. package/dist/packages.js +11 -11
  141. package/dist/parser.cjs +13 -13
  142. package/dist/parser.d.cts +4 -4
  143. package/dist/parser.d.ts +4 -4
  144. package/dist/parser.js +5 -5
  145. package/dist/{pipeline-CtfJtPQc.d.cts → pipeline-D-PS9gVw.d.ts} +3 -3
  146. package/dist/{pipeline-DCd5M6Gk.d.ts → pipeline-DtSBJ8TS.d.cts} +3 -3
  147. package/dist/resolvers.d.cts +2 -2
  148. package/dist/resolvers.d.ts +2 -2
  149. package/dist/testing.cjs +26 -26
  150. package/dist/testing.d.cts +10 -10
  151. package/dist/testing.d.ts +10 -10
  152. package/dist/testing.js +19 -19
  153. package/dist/uom.cjs +8 -8
  154. package/dist/uom.d.cts +2 -2
  155. package/dist/uom.d.ts +2 -2
  156. package/dist/uom.js +4 -4
  157. package/dist/vm.cjs +32 -32
  158. package/dist/vm.d.cts +7 -7
  159. package/dist/vm.d.ts +7 -7
  160. package/dist/vm.js +7 -7
  161. package/dist/worker.cjs +38 -38
  162. package/dist/worker.d.cts +10 -10
  163. package/dist/worker.d.ts +10 -10
  164. package/dist/worker.js +20 -20
  165. package/package.json +1 -1
  166. package/dist/chunk-267JPOTF.js.map +0 -1
  167. package/dist/chunk-2TZKENDH.cjs.map +0 -1
  168. package/dist/chunk-3OWCDIPN.js.map +0 -1
  169. package/dist/chunk-4D6NIHE2.js.map +0 -1
  170. package/dist/chunk-536WPM2V.cjs.map +0 -1
  171. package/dist/chunk-7ZX6B7SY.cjs.map +0 -1
  172. package/dist/chunk-B4HBEFTB.cjs.map +0 -1
  173. package/dist/chunk-CKQMXMHR.cjs.map +0 -1
  174. package/dist/chunk-ERCOHGXD.js.map +0 -1
  175. package/dist/chunk-GQMUHVE3.js.map +0 -1
  176. package/dist/chunk-GUG7SNSV.js.map +0 -1
  177. package/dist/chunk-JIPATHVY.js.map +0 -1
  178. package/dist/chunk-MG6Q3DUO.cjs.map +0 -1
  179. package/dist/chunk-NKW7LKYU.js.map +0 -1
  180. package/dist/chunk-NNQ2TYDF.js.map +0 -1
  181. package/dist/chunk-OTN6SZOD.cjs.map +0 -1
  182. package/dist/chunk-QFTDTX6K.cjs.map +0 -1
  183. package/dist/chunk-RRLHC37V.js.map +0 -1
  184. package/dist/chunk-SNHVVOJK.cjs.map +0 -1
  185. package/dist/chunk-SRGQ72IR.cjs.map +0 -1
  186. package/dist/chunk-UO6BUV6K.js.map +0 -1
  187. package/dist/chunk-WXEHD6TT.js.map +0 -1
  188. package/dist/chunk-YTIYVHL7.cjs.map +0 -1
@@ -1,24 +1,24 @@
1
- import { ParseletRegistry, PrecedenceParser } from './chunk-I4GAWIPW.js';
1
+ import { ParseletRegistry, PrecedenceParser } from './chunk-AOH6UR2L.js';
2
2
  import { ResolverRegistry } from './chunk-3VGDNEE3.js';
3
3
  import { abortLogger } from './chunk-FD5ZZHEU.js';
4
- import { executeBytecode, createVM, DependencyGraph, ScopeManager } from './chunk-WXEHD6TT.js';
5
- import { DiagnosticPipeline, TimelineDiagnosticCollector, DiagnosticEventType } from './chunk-CCBZZQAE.js';
6
- import { formatValue, DEFAULT_FORMATTING_SETTINGS } from './chunk-3OWCDIPN.js';
7
- import { BUILTIN_PACKAGES, containsSymbolicCall } from './chunk-RRLHC37V.js';
8
- import { BytecodeBuilder } from './chunk-ENKKJYD3.js';
9
- import { TokenNormalizer, BUILTIN_PHRASES, implicitMultiplyRule } from './chunk-JJIXHXFQ.js';
4
+ import { executeBytecode, createVM, DependencyGraph, ScopeManager } from './chunk-FE4RC37D.js';
5
+ import { DiagnosticPipeline, TimelineDiagnosticCollector, DiagnosticEventType } from './chunk-UF6JG5SG.js';
6
+ import { formatValue, DEFAULT_FORMATTING_SETTINGS } from './chunk-YNIWOYW6.js';
7
+ import { BUILTIN_PACKAGES, containsSymbolicCall } from './chunk-TPOK3UNI.js';
8
+ import { BytecodeBuilder } from './chunk-IQJGDZOP.js';
9
+ import { TokenNormalizer, BUILTIN_PHRASES, implicitMultiplyRule, createFusedToken } from './chunk-L5YHV6BQ.js';
10
10
  import { countLines } from './chunk-3BOK2LDK.js';
11
11
  import { createQueryClient, setActiveQueryClient, getActiveQueryClient } from './chunk-NLNDMWZC.js';
12
- import { sharedOpRegistry, createEngineContext, registerAsConverter, unregisterAsConverter, solveEquationValues, globalDagKey } from './chunk-NKW7LKYU.js';
13
- import { matrixMultiply, inverse } from './chunk-NNQ2TYDF.js';
14
- import { errorValue, pendingValue, stringValue, numberValue, freezeIfDev, Value, boolValue, uomValue, percentageValue, datetimeValue, bigIntValue, hexValue, ValueType } from './chunk-267JPOTF.js';
15
- import { mergeEngineConfig, DEFAULT_CONFIG, ENGINE_VERSION } from './chunk-G7Z4HJQA.js';
16
- import { Lexer, buildTokenLookup, sharedLexer } from './chunk-OADDUPT3.js';
17
- import { registerTokenCategory, unregisterTokenCategory } from './chunk-UO6BUV6K.js';
18
- import { LexerToken } from './chunk-GQMUHVE3.js';
19
- import { TokenTypes, tokenTypeId } from './chunk-4D6NIHE2.js';
12
+ import { sharedOpRegistry, createEngineContext, registerAsConverter, unregisterAsConverter, solveEquationValues, globalDagKey } from './chunk-WMQRJTAO.js';
13
+ import { matrixMultiply, inverse } from './chunk-ZNFFTYWH.js';
14
+ import { errorValue, pendingValue, stringValue, numberValue, freezeIfDev, Value, boolValue, uomValue, percentageValue, datetimeValue, bigIntValue, hexValue, ValueType } from './chunk-5EFKSKMA.js';
15
+ import { mergeEngineConfig, DEFAULT_CONFIG, ENGINE_VERSION } from './chunk-CSDQMDU2.js';
16
+ import { Lexer, buildTokenLookup, sharedLexer } from './chunk-RNKDIXDV.js';
17
+ import { registerTokenCategory, unregisterTokenCategory } from './chunk-LSALB3IN.js';
18
+ import { LexerToken } from './chunk-ORM7CHYZ.js';
19
+ import { TokenTypes, tokenTypeId } from './chunk-NAWZATKT.js';
20
20
  import { getLocale } from './chunk-XBTEO4OB.js';
21
- import { normalizeUnknownError, ErrorFactory, EngineError } from './chunk-ERCOHGXD.js';
21
+ import { normalizeUnknownError, ErrorFactory, EngineError } from './chunk-N7OA4WPJ.js';
22
22
  import { __commonJS, __toESM } from './chunk-YLJ4XMA6.js';
23
23
 
24
24
  // node_modules/semver/internal/constants.js
@@ -2769,7 +2769,8 @@ function extractReadsAndWrites(tokens) {
2769
2769
  }
2770
2770
  }
2771
2771
  reads.push(t.value);
2772
- if (i + 1 < tokens.length && tokens[i + 1].type === "EQUALS") {
2772
+ const next = tokens[i + 1]?.type;
2773
+ if (next === "EQUALS" || next === "PLUS_EQUALS" || next === "MINUS_EQUALS") {
2773
2774
  writes.push(t.value);
2774
2775
  }
2775
2776
  }
@@ -3109,6 +3110,14 @@ var _ExpressionEngine = class _ExpressionEngine {
3109
3110
  //#region Private Properties
3110
3111
  this.dag = new DependencyGraph();
3111
3112
  this.lineCache = new LineCache();
3113
+ /**
3114
+ * Names ever used as a running-total target (`total += 5`). A document is
3115
+ * re-parsed top-to-bottom on every keystroke, so each accumulator is reset
3116
+ * to undefined at the start of a batch pass and re-seeds from its opening
3117
+ * `+=`/`-=` this pass, rather than reading its own previous pass's value
3118
+ * (which grew the total without bound). See {@link tryCompoundAssignment}.
3119
+ */
3120
+ this.accumulatorNames = /* @__PURE__ */ new Set();
3112
3121
  this.scopeManager = new ScopeManager();
3113
3122
  /** Registry of async resolvers from registered packages. */
3114
3123
  this.resolverRegistry = new ResolverRegistry();
@@ -3757,6 +3766,7 @@ var _ExpressionEngine = class _ExpressionEngine {
3757
3766
  }
3758
3767
  if (!this.userUnits.isEmpty) this.bytecodeCache.clear();
3759
3768
  this.userUnits.clear();
3769
+ this.resetAccumulators();
3760
3770
  const scanResults = this.lexer.scanDocument(input);
3761
3771
  const processedLines = this.processScanResults(scanResults);
3762
3772
  const result = {
@@ -3804,6 +3814,7 @@ var _ExpressionEngine = class _ExpressionEngine {
3804
3814
  evaluateLines(lines) {
3805
3815
  if (!this.userUnits.isEmpty) this.bytecodeCache.clear();
3806
3816
  this.userUnits.clear();
3817
+ this.resetAccumulators();
3807
3818
  const documentText = lines.join("\n");
3808
3819
  const scanResults = this.lexer.scanDocument(documentText);
3809
3820
  return this.processScanResults(scanResults);
@@ -4172,6 +4183,90 @@ var _ExpressionEngine = class _ExpressionEngine {
4172
4183
  this.bytecodeCache.clear();
4173
4184
  return stringValue(`${nameWords.join(" ")} defined`);
4174
4185
  }
4186
+ /**
4187
+ * `name += expr` / `name -= expr`, a running total. The accumulator reads
4188
+ * its current value, adds or subtracts the right-hand side, stores the
4189
+ * result, and answers with the new value, so a note becomes a live ledger
4190
+ * where each line adjusts a balance in place. Returns null to decline
4191
+ * anything that is not the compound shape.
4192
+ *
4193
+ * Handled here, in the same effectful, cache-bypassing channel as
4194
+ * {@link tryDefineUserUnit} and the bare `count = 10` assignment (see
4195
+ * {@link trySymbolicGrammar}), rather than as a parselet: a bare identifier
4196
+ * is a Tier-1 prefix that emits `LOAD_VAR name` before any infix parselet on
4197
+ * `+=` could run, and that pre-emitted load throws UNDEFINED_VARIABLE for a
4198
+ * first-use accumulator. Seeding 0 for a first `+=`/`-=` is a one-line
4199
+ * `getVar`/`setVar` here where it cannot be from a parselet, a deliberate
4200
+ * departure from a plain reference, which still reports the undefined name.
4201
+ *
4202
+ * The right-hand side is parenthesised and run through the ORDINARY (not
4203
+ * symbolic-tolerant) path, so `bal += 3 * 4` is `bal + 12`, a genuine typo in
4204
+ * it (`total += nope`) is a real UNDEFINED_VARIABLE, and the accumulation
4205
+ * goes through the VM's own ADD/SUB: money stays money, a unit stays its
4206
+ * unit, and the seed 0 added to a typed right-hand side takes that type on
4207
+ * first use. The colon (`:name`) and `global :name` grammars are untouched:
4208
+ * they lex their own leading token, never IDENT/UNIT, so they decline here.
4209
+ */
4210
+ tryCompoundAssignment(tokens, lineNumber = -1) {
4211
+ if (tokens.length < 2) return null;
4212
+ const nameTok = tokens[0];
4213
+ const opTok = tokens[1];
4214
+ const isName = nameTok.type === "IDENT" || nameTok.type === "UNIT";
4215
+ const isCompound = opTok.type === "PLUS_EQUALS" || opTok.type === "MINUS_EQUALS";
4216
+ if (!isName || !isCompound) return null;
4217
+ const rhs = tokens.slice(2);
4218
+ if (rhs.length === 0) {
4219
+ throw ErrorFactory.parsing(
4220
+ "COMPOUND_ASSIGN_REQUIRES_EXPRESSION",
4221
+ `"${nameTok.value} ${opTok.value}" needs an expression on the right, e.g. "${nameTok.value} ${opTok.value} 10".`
4222
+ );
4223
+ }
4224
+ const name = nameTok.value;
4225
+ this.accumulatorNames.add(name);
4226
+ if (this.vm.getVar(name) === void 0) this.vm.setVar(name, numberValue(0));
4227
+ const op = opTok.type === "PLUS_EQUALS" ? { type: "PLUS", text: "+" } : { type: "MINUS", text: "-" };
4228
+ const accTokens = [
4229
+ createFusedToken("IDENT", name, [nameTok]),
4230
+ createFusedToken(op.type, op.text, [opTok]),
4231
+ createFusedToken("LPAREN", "(", [opTok]),
4232
+ ...rhs,
4233
+ createFusedToken("RPAREN", ")", [opTok])
4234
+ ];
4235
+ const result = executeBytecode(
4236
+ this.compileAdHoc(accTokens),
4237
+ this.vm,
4238
+ void 0,
4239
+ void 0,
4240
+ this.makeLineContext(lineNumber),
4241
+ false
4242
+ );
4243
+ if (result.type === "error") throw result.error;
4244
+ if (result.type === "pending") {
4245
+ throw ErrorFactory.execution(
4246
+ "COMPOUND_ASSIGN_ASYNC_UNSUPPORTED",
4247
+ `A running total (+= / -=) cannot use an async operation (weather/stocks/currency) on its right-hand side.`
4248
+ );
4249
+ }
4250
+ this.vm.setVar(name, result.value);
4251
+ return result.value;
4252
+ }
4253
+ /**
4254
+ * Reset every running-total accumulator (`total += 5`) to undefined, and
4255
+ * return their names.
4256
+ *
4257
+ * An accumulator seeds 0 only while its name is undefined, then reads that
4258
+ * value on each `+=`/`-=`. A document is re-evaluated top-to-bottom on
4259
+ * every keystroke, so unless the name is cleared first the total reads its
4260
+ * own previous evaluation's value and grows without bound. The batch
4261
+ * document pass (`parseDocument`/`evaluateLines`) calls this at the start
4262
+ * of each pass; the incremental {@link ThreeTierEvaluator} calls it and
4263
+ * then marks the lines that touch each name dirty, since it re-runs lines
4264
+ * selectively rather than replaying the whole document.
4265
+ */
4266
+ resetAccumulators() {
4267
+ for (const name of this.accumulatorNames) this.vm.deleteVar(name);
4268
+ return this.accumulatorNames;
4269
+ }
4175
4270
  trySymbolicGrammar(normalizedTokens, lineNumber = -1) {
4176
4271
  if (normalizedTokens.length === 0) return null;
4177
4272
  const last = normalizedTokens[normalizedTokens.length - 1];
@@ -4389,14 +4484,25 @@ var _ExpressionEngine = class _ExpressionEngine {
4389
4484
  return { kind: "error", stage: "complexity", error: complexityCheck.engineError, normalizedTokens };
4390
4485
  }
4391
4486
  let symbolicResult;
4487
+ let compoundReadsWrites = null;
4392
4488
  try {
4393
- symbolicResult = this.tryDefineUserUnit(normalizedTokens) ?? this.trySymbolicGrammar(normalizedTokens, lineNumber);
4489
+ symbolicResult = this.tryDefineUserUnit(normalizedTokens);
4490
+ if (symbolicResult === null) {
4491
+ const compound = this.tryCompoundAssignment(normalizedTokens, lineNumber);
4492
+ if (compound !== null) {
4493
+ symbolicResult = compound;
4494
+ compoundReadsWrites = extractReadsAndWrites(normalizedTokens);
4495
+ }
4496
+ }
4497
+ if (symbolicResult === null) {
4498
+ symbolicResult = this.trySymbolicGrammar(normalizedTokens, lineNumber);
4499
+ }
4394
4500
  } catch (e) {
4395
4501
  const { reads: reads2, writes: writes2 } = extractReadsAndWrites(normalizedTokens);
4396
4502
  return { kind: "error", stage: "parse", error: normalizeUnknownError(e), reads: reads2, writes: writes2, normalizedTokens };
4397
4503
  }
4398
4504
  if (symbolicResult !== null) {
4399
- return { kind: "symbolic-solve", normalizedTokens, value: symbolicResult };
4505
+ return { kind: "symbolic-solve", normalizedTokens, value: symbolicResult, reads: compoundReadsWrites?.reads, writes: compoundReadsWrites?.writes };
4400
4506
  }
4401
4507
  const { reads, writes } = extractReadsAndWrites(normalizedTokens);
4402
4508
  const cachedProgram = this.bytecodeCache.get(expression);
@@ -4511,7 +4617,7 @@ var _ExpressionEngine = class _ExpressionEngine {
4511
4617
  throw prep.error;
4512
4618
  }
4513
4619
  if (prep.kind === "symbolic-solve") {
4514
- this.storeLineResult(lineNumber, prep.value, { opcodes: new Uint8Array(0), numbers: new Float64Array(0), strings: [], hasAsync: false }, [], [], expression);
4620
+ this.storeLineResult(lineNumber, prep.value, { opcodes: new Uint8Array(0), numbers: new Float64Array(0), strings: [], hasAsync: false }, prep.reads ?? [], prep.writes ?? [], expression);
4515
4621
  return prep.value;
4516
4622
  }
4517
4623
  const { normalizedTokens, reads, writes, program } = prep;
@@ -4953,7 +5059,7 @@ var _ExpressionEngine = class _ExpressionEngine {
4953
5059
  });
4954
5060
  }
4955
5061
  const emptyProgram = { opcodes: new Uint8Array(0), numbers: new Float64Array(0), strings: [], hasAsync: false };
4956
- this.storeLineResult(lineNumber, prep.value, emptyProgram, [], [], expression);
5062
+ this.storeLineResult(lineNumber, prep.value, emptyProgram, prep.reads ?? [], prep.writes ?? [], expression);
4957
5063
  return {
4958
5064
  value: prep.value,
4959
5065
  tokens: normalizedTokens,
@@ -5653,8 +5759,8 @@ var _ExpressionEngine = class _ExpressionEngine {
5653
5759
  return {
5654
5760
  program: { opcodes: new Uint8Array(0), numbers: new Float64Array(0), strings: [], hasAsync: false },
5655
5761
  tokens: prep.normalizedTokens,
5656
- reads: [],
5657
- writes: []
5762
+ reads: prep.reads ?? [],
5763
+ writes: prep.writes ?? []
5658
5764
  };
5659
5765
  }
5660
5766
  return { program: prep.program, tokens, reads: prep.reads, writes: prep.writes };
@@ -5778,6 +5884,7 @@ var _ExpressionEngine = class _ExpressionEngine {
5778
5884
  this.bytecodeCache.clear();
5779
5885
  this.vm.reset();
5780
5886
  this.userUnits.clear();
5887
+ this.accumulatorNames.clear();
5781
5888
  this.lastTelemetry = null;
5782
5889
  }
5783
5890
  //#endregion
@@ -5836,7 +5943,12 @@ var _ExpressionEngine = class _ExpressionEngine {
5836
5943
  for (const [name, value] of this.vm.getVariableEntries()) {
5837
5944
  if (value.type === 12 /* Pending */) continue;
5838
5945
  if (latestWriter.get(name)?.async) continue;
5839
- variables[name] = serializeValue(value, `variable "${name}"`);
5946
+ try {
5947
+ variables[name] = serializeValue(value, `variable "${name}"`);
5948
+ } catch (e) {
5949
+ if (e instanceof EngineError && e.code === SnapshotErrorCodes.SNAPSHOT_UNSUPPORTED_VALUE) continue;
5950
+ throw e;
5951
+ }
5840
5952
  }
5841
5953
  const userFunctions = this.vm.getUserFunctionDefs().map(serializeUserFunction);
5842
5954
  const lineCache = [];
@@ -6788,5 +6900,5 @@ _AsyncResolutionBatcher.DEFAULT_HIGH_WATER_MARK = 64;
6788
6900
  var AsyncResolutionBatcher = _AsyncResolutionBatcher;
6789
6901
 
6790
6902
  export { AsyncResolutionBatcher, ExpressionEngine, SNAPSHOT_FORMAT, SNAPSHOT_VERSION, SnapshotErrorCodes, assertEngineVersionCompatible, checkEngineVersionCompatibility, checkExpressionComplexity, checkExpressionLength, checkPackageCompatibility, engine_worker_default, extractReadsAndWrites, findInlineSolvesInLine, isEmptyLine };
6791
- //# sourceMappingURL=chunk-JIPATHVY.js.map
6792
- //# sourceMappingURL=chunk-JIPATHVY.js.map
6903
+ //# sourceMappingURL=chunk-IJGOFP2J.js.map
6904
+ //# sourceMappingURL=chunk-IJGOFP2J.js.map