@ricsam/formula-engine 0.0.1

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 (569) hide show
  1. package/README.md +100 -0
  2. package/dist/cjs/core/ast-traverser.cjs +124 -0
  3. package/dist/cjs/core/ast-traverser.cjs.map +10 -0
  4. package/dist/cjs/core/autofill-utils.cjs +304 -0
  5. package/dist/cjs/core/autofill-utils.cjs.map +10 -0
  6. package/dist/cjs/core/engine.cjs +390 -0
  7. package/dist/cjs/core/engine.cjs.map +10 -0
  8. package/dist/cjs/core/managers/cache-manager.cjs +58 -0
  9. package/dist/cjs/core/managers/cache-manager.cjs.map +10 -0
  10. package/dist/cjs/core/managers/dependency-manager.cjs +620 -0
  11. package/dist/cjs/core/managers/dependency-manager.cjs.map +10 -0
  12. package/dist/cjs/core/managers/dependency-node.cjs +24 -0
  13. package/dist/cjs/core/managers/dependency-node.cjs.map +9 -0
  14. package/dist/cjs/core/managers/evaluation-manager.cjs +433 -0
  15. package/dist/cjs/core/managers/evaluation-manager.cjs.map +10 -0
  16. package/dist/cjs/core/managers/event-manager.cjs +49 -0
  17. package/dist/cjs/core/managers/event-manager.cjs.map +10 -0
  18. package/dist/cjs/core/managers/frontier-dependency-manager.cjs +181 -0
  19. package/dist/cjs/core/managers/frontier-dependency-manager.cjs.map +10 -0
  20. package/dist/cjs/core/managers/index.cjs +49 -0
  21. package/dist/cjs/core/managers/index.cjs.map +10 -0
  22. package/dist/cjs/core/managers/isDependencyNode.cjs +44 -0
  23. package/dist/cjs/core/managers/isDependencyNode.cjs.map +10 -0
  24. package/dist/cjs/core/managers/named-expression-manager.cjs +379 -0
  25. package/dist/cjs/core/managers/named-expression-manager.cjs.map +10 -0
  26. package/dist/cjs/core/managers/range-eval-order-builder.cjs +644 -0
  27. package/dist/cjs/core/managers/range-eval-order-builder.cjs.map +10 -0
  28. package/dist/cjs/core/managers/table-manager.cjs +254 -0
  29. package/dist/cjs/core/managers/table-manager.cjs.map +10 -0
  30. package/dist/cjs/core/managers/workbook-manager.cjs +474 -0
  31. package/dist/cjs/core/managers/workbook-manager.cjs.map +10 -0
  32. package/dist/cjs/core/map-serializer.cjs +69 -0
  33. package/dist/cjs/core/map-serializer.cjs.map +10 -0
  34. package/dist/cjs/core/named-expression-renamer.cjs +88 -0
  35. package/dist/cjs/core/named-expression-renamer.cjs.map +10 -0
  36. package/dist/cjs/core/sheet-renamer.cjs +89 -0
  37. package/dist/cjs/core/sheet-renamer.cjs.map +10 -0
  38. package/dist/cjs/core/sheet-utils.cjs +39 -0
  39. package/dist/cjs/core/sheet-utils.cjs.map +10 -0
  40. package/dist/cjs/core/table-renamer.cjs +88 -0
  41. package/dist/cjs/core/table-renamer.cjs.map +10 -0
  42. package/dist/cjs/core/types.cjs +48 -0
  43. package/dist/cjs/core/types.cjs.map +10 -0
  44. package/dist/cjs/core/utils/range-serializer.cjs +65 -0
  45. package/dist/cjs/core/utils/range-serializer.cjs.map +10 -0
  46. package/dist/cjs/core/utils/spreadsheet-visualizer.cjs +142 -0
  47. package/dist/cjs/core/utils/spreadsheet-visualizer.cjs.map +10 -0
  48. package/dist/cjs/core/utils.cjs +434 -0
  49. package/dist/cjs/core/utils.cjs.map +10 -0
  50. package/dist/cjs/core/workbook-renamer.cjs +106 -0
  51. package/dist/cjs/core/workbook-renamer.cjs.map +10 -0
  52. package/dist/cjs/debug/flags.cjs +47 -0
  53. package/dist/cjs/debug/flags.cjs.map +10 -0
  54. package/dist/cjs/evaluator/arithmetic/add/add.cjs +82 -0
  55. package/dist/cjs/evaluator/arithmetic/add/add.cjs.map +10 -0
  56. package/dist/cjs/evaluator/arithmetic/divide/divide.cjs +107 -0
  57. package/dist/cjs/evaluator/arithmetic/divide/divide.cjs.map +10 -0
  58. package/dist/cjs/evaluator/arithmetic/multiply/multiply.cjs +93 -0
  59. package/dist/cjs/evaluator/arithmetic/multiply/multiply.cjs.map +10 -0
  60. package/dist/cjs/evaluator/arithmetic/power/power.cjs +125 -0
  61. package/dist/cjs/evaluator/arithmetic/power/power.cjs.map +10 -0
  62. package/dist/cjs/evaluator/arithmetic/subtract/subtract.cjs +84 -0
  63. package/dist/cjs/evaluator/arithmetic/subtract/subtract.cjs.map +10 -0
  64. package/dist/cjs/evaluator/comparison/equals.cjs +64 -0
  65. package/dist/cjs/evaluator/comparison/equals.cjs.map +10 -0
  66. package/dist/cjs/evaluator/comparison/greater-than-or-equal.cjs +61 -0
  67. package/dist/cjs/evaluator/comparison/greater-than-or-equal.cjs.map +10 -0
  68. package/dist/cjs/evaluator/comparison/greater-than.cjs +61 -0
  69. package/dist/cjs/evaluator/comparison/greater-than.cjs.map +10 -0
  70. package/dist/cjs/evaluator/comparison/less-than-or-equal.cjs +69 -0
  71. package/dist/cjs/evaluator/comparison/less-than-or-equal.cjs.map +10 -0
  72. package/dist/cjs/evaluator/comparison/less-than.cjs +68 -0
  73. package/dist/cjs/evaluator/comparison/less-than.cjs.map +10 -0
  74. package/dist/cjs/evaluator/comparison/not-equals.cjs +53 -0
  75. package/dist/cjs/evaluator/comparison/not-equals.cjs.map +10 -0
  76. package/dist/cjs/evaluator/concatenation/concatenate.cjs +72 -0
  77. package/dist/cjs/evaluator/concatenation/concatenate.cjs.map +10 -0
  78. package/dist/cjs/evaluator/dependency-nodes/ast-evaluation-node.cjs +58 -0
  79. package/dist/cjs/evaluator/dependency-nodes/ast-evaluation-node.cjs.map +10 -0
  80. package/dist/cjs/evaluator/dependency-nodes/base-eval-node.cjs +112 -0
  81. package/dist/cjs/evaluator/dependency-nodes/base-eval-node.cjs.map +10 -0
  82. package/dist/cjs/evaluator/dependency-nodes/cell-value-node.cjs +54 -0
  83. package/dist/cjs/evaluator/dependency-nodes/cell-value-node.cjs.map +10 -0
  84. package/dist/cjs/evaluator/dependency-nodes/empty-cell-evaluation-node.cjs +108 -0
  85. package/dist/cjs/evaluator/dependency-nodes/empty-cell-evaluation-node.cjs.map +10 -0
  86. package/dist/cjs/evaluator/dependency-nodes/spill-meta-node.cjs +50 -0
  87. package/dist/cjs/evaluator/dependency-nodes/spill-meta-node.cjs.map +10 -0
  88. package/dist/cjs/evaluator/evaluate-scalar-operator.cjs +254 -0
  89. package/dist/cjs/evaluator/evaluate-scalar-operator.cjs.map +10 -0
  90. package/dist/cjs/evaluator/evaluation-context.cjs +154 -0
  91. package/dist/cjs/evaluator/evaluation-context.cjs.map +10 -0
  92. package/dist/cjs/evaluator/evaluation-error.cjs +75 -0
  93. package/dist/cjs/evaluator/evaluation-error.cjs.map +10 -0
  94. package/dist/cjs/evaluator/formula-evaluator.cjs +797 -0
  95. package/dist/cjs/evaluator/formula-evaluator.cjs.map +10 -0
  96. package/dist/cjs/evaluator/range-evaluation-node.cjs +88 -0
  97. package/dist/cjs/evaluator/range-evaluation-node.cjs.map +10 -0
  98. package/dist/cjs/functions/_template/template.cjs +42 -0
  99. package/dist/cjs/functions/_template/template.cjs.map +10 -0
  100. package/dist/cjs/functions/array/sequence/sequence.cjs +315 -0
  101. package/dist/cjs/functions/array/sequence/sequence.cjs.map +10 -0
  102. package/dist/cjs/functions/criteria-parser.cjs +217 -0
  103. package/dist/cjs/functions/criteria-parser.cjs.map +10 -0
  104. package/dist/cjs/functions/criteria-utils.cjs +291 -0
  105. package/dist/cjs/functions/criteria-utils.cjs.map +10 -0
  106. package/dist/cjs/functions/function-utils.cjs +63 -0
  107. package/dist/cjs/functions/function-utils.cjs.map +10 -0
  108. package/dist/cjs/functions/index.cjs +125 -0
  109. package/dist/cjs/functions/index.cjs.map +10 -0
  110. package/dist/cjs/functions/information/cell/cell.cjs +196 -0
  111. package/dist/cjs/functions/information/cell/cell.cjs.map +10 -0
  112. package/dist/cjs/functions/information/column/column.cjs +144 -0
  113. package/dist/cjs/functions/information/column/column.cjs.map +10 -0
  114. package/dist/cjs/functions/information/row/row.cjs +150 -0
  115. package/dist/cjs/functions/information/row/row.cjs.map +10 -0
  116. package/dist/cjs/functions/logical/and/and.cjs +112 -0
  117. package/dist/cjs/functions/logical/and/and.cjs.map +10 -0
  118. package/dist/cjs/functions/logical/if/if.cjs +195 -0
  119. package/dist/cjs/functions/logical/if/if.cjs.map +10 -0
  120. package/dist/cjs/functions/logical/iferror/iferror.cjs +126 -0
  121. package/dist/cjs/functions/logical/iferror/iferror.cjs.map +10 -0
  122. package/dist/cjs/functions/logical/or/or.cjs +112 -0
  123. package/dist/cjs/functions/logical/or/or.cjs.map +10 -0
  124. package/dist/cjs/functions/lookup/count/count-utils.cjs +65 -0
  125. package/dist/cjs/functions/lookup/count/count-utils.cjs.map +10 -0
  126. package/dist/cjs/functions/lookup/count/count.cjs +48 -0
  127. package/dist/cjs/functions/lookup/count/count.cjs.map +10 -0
  128. package/dist/cjs/functions/lookup/count/countif.cjs +94 -0
  129. package/dist/cjs/functions/lookup/count/countif.cjs.map +10 -0
  130. package/dist/cjs/functions/lookup/count/countifs.cjs +63 -0
  131. package/dist/cjs/functions/lookup/count/countifs.cjs.map +10 -0
  132. package/dist/cjs/functions/lookup/index-lookup/index-lookup.cjs +187 -0
  133. package/dist/cjs/functions/lookup/index-lookup/index-lookup.cjs.map +10 -0
  134. package/dist/cjs/functions/lookup/match/match.cjs +168 -0
  135. package/dist/cjs/functions/lookup/match/match.cjs.map +10 -0
  136. package/dist/cjs/functions/lookup/xlookup/xlookup.cjs +410 -0
  137. package/dist/cjs/functions/lookup/xlookup/xlookup.cjs.map +10 -0
  138. package/dist/cjs/functions/math/average/average-utils.cjs +72 -0
  139. package/dist/cjs/functions/math/average/average-utils.cjs.map +10 -0
  140. package/dist/cjs/functions/math/average/average.cjs +48 -0
  141. package/dist/cjs/functions/math/average/average.cjs.map +10 -0
  142. package/dist/cjs/functions/math/average/averageif.cjs +83 -0
  143. package/dist/cjs/functions/math/average/averageif.cjs.map +10 -0
  144. package/dist/cjs/functions/math/average/averageifs.cjs +61 -0
  145. package/dist/cjs/functions/math/average/averageifs.cjs.map +10 -0
  146. package/dist/cjs/functions/math/ceiling/ceiling.cjs +219 -0
  147. package/dist/cjs/functions/math/ceiling/ceiling.cjs.map +10 -0
  148. package/dist/cjs/functions/math/max/max-utils.cjs +71 -0
  149. package/dist/cjs/functions/math/max/max-utils.cjs.map +10 -0
  150. package/dist/cjs/functions/math/max/max.cjs +48 -0
  151. package/dist/cjs/functions/math/max/max.cjs.map +10 -0
  152. package/dist/cjs/functions/math/max/maxif.cjs +83 -0
  153. package/dist/cjs/functions/math/max/maxif.cjs.map +10 -0
  154. package/dist/cjs/functions/math/max/maxifs.cjs +61 -0
  155. package/dist/cjs/functions/math/max/maxifs.cjs.map +10 -0
  156. package/dist/cjs/functions/math/min/min-utils.cjs +71 -0
  157. package/dist/cjs/functions/math/min/min-utils.cjs.map +10 -0
  158. package/dist/cjs/functions/math/min/min.cjs +48 -0
  159. package/dist/cjs/functions/math/min/min.cjs.map +10 -0
  160. package/dist/cjs/functions/math/min/minif.cjs +83 -0
  161. package/dist/cjs/functions/math/min/minif.cjs.map +10 -0
  162. package/dist/cjs/functions/math/min/minifs.cjs +61 -0
  163. package/dist/cjs/functions/math/min/minifs.cjs.map +10 -0
  164. package/dist/cjs/functions/math/sum/sum.cjs +48 -0
  165. package/dist/cjs/functions/math/sum/sum.cjs.map +10 -0
  166. package/dist/cjs/functions/math/sum/sumif.cjs +83 -0
  167. package/dist/cjs/functions/math/sum/sumif.cjs.map +10 -0
  168. package/dist/cjs/functions/math/sum/sumifs.cjs +60 -0
  169. package/dist/cjs/functions/math/sum/sumifs.cjs.map +10 -0
  170. package/dist/cjs/functions/math/sum/summation-utils.cjs +57 -0
  171. package/dist/cjs/functions/math/sum/summation-utils.cjs.map +10 -0
  172. package/dist/cjs/functions/reference/address/address.cjs +163 -0
  173. package/dist/cjs/functions/reference/address/address.cjs.map +10 -0
  174. package/dist/cjs/functions/reference/indirect/indirect.cjs +102 -0
  175. package/dist/cjs/functions/reference/indirect/indirect.cjs.map +10 -0
  176. package/dist/cjs/functions/reference/offset/offset.cjs +233 -0
  177. package/dist/cjs/functions/reference/offset/offset.cjs.map +10 -0
  178. package/dist/cjs/functions/text/concatenate/concatenate.cjs +167 -0
  179. package/dist/cjs/functions/text/concatenate/concatenate.cjs.map +10 -0
  180. package/dist/cjs/functions/text/exact/exact.cjs +171 -0
  181. package/dist/cjs/functions/text/exact/exact.cjs.map +10 -0
  182. package/dist/cjs/functions/text/find/find.cjs +397 -0
  183. package/dist/cjs/functions/text/find/find.cjs.map +10 -0
  184. package/dist/cjs/functions/text/left/left.cjs +109 -0
  185. package/dist/cjs/functions/text/left/left.cjs.map +10 -0
  186. package/dist/cjs/functions/text/len/len.cjs +119 -0
  187. package/dist/cjs/functions/text/len/len.cjs.map +10 -0
  188. package/dist/cjs/functions/text/mid/mid.cjs +103 -0
  189. package/dist/cjs/functions/text/mid/mid.cjs.map +10 -0
  190. package/dist/cjs/functions/text/right/right.cjs +167 -0
  191. package/dist/cjs/functions/text/right/right.cjs.map +10 -0
  192. package/dist/cjs/functions/text/text-helpers.cjs +179 -0
  193. package/dist/cjs/functions/text/text-helpers.cjs.map +10 -0
  194. package/dist/cjs/functions/text/textjoin/textjoin.cjs +173 -0
  195. package/dist/cjs/functions/text/textjoin/textjoin.cjs.map +10 -0
  196. package/dist/cjs/package.json +5 -0
  197. package/dist/cjs/parser/ast.cjs +175 -0
  198. package/dist/cjs/parser/ast.cjs.map +10 -0
  199. package/dist/cjs/parser/formatter.cjs +319 -0
  200. package/dist/cjs/parser/formatter.cjs.map +10 -0
  201. package/dist/cjs/parser/grammar.cjs +375 -0
  202. package/dist/cjs/parser/grammar.cjs.map +10 -0
  203. package/dist/cjs/parser/lexer.cjs +443 -0
  204. package/dist/cjs/parser/lexer.cjs.map +10 -0
  205. package/dist/cjs/parser/parser.cjs +1700 -0
  206. package/dist/cjs/parser/parser.cjs.map +10 -0
  207. package/dist/cjs/react/hooks.cjs +59 -0
  208. package/dist/cjs/react/hooks.cjs.map +10 -0
  209. package/dist/mjs/core/ast-traverser.mjs +94 -0
  210. package/dist/mjs/core/ast-traverser.mjs.map +10 -0
  211. package/dist/mjs/core/autofill-utils.mjs +274 -0
  212. package/dist/mjs/core/autofill-utils.mjs.map +10 -0
  213. package/dist/mjs/core/engine.mjs +366 -0
  214. package/dist/mjs/core/engine.mjs.map +10 -0
  215. package/dist/mjs/core/managers/cache-manager.mjs +27 -0
  216. package/dist/mjs/core/managers/cache-manager.mjs.map +10 -0
  217. package/dist/mjs/core/managers/dependency-manager.mjs +593 -0
  218. package/dist/mjs/core/managers/dependency-manager.mjs.map +10 -0
  219. package/dist/mjs/core/managers/dependency-node.mjs +2 -0
  220. package/dist/mjs/core/managers/dependency-node.mjs.map +9 -0
  221. package/dist/mjs/core/managers/evaluation-manager.mjs +415 -0
  222. package/dist/mjs/core/managers/evaluation-manager.mjs.map +10 -0
  223. package/dist/mjs/core/managers/event-manager.mjs +18 -0
  224. package/dist/mjs/core/managers/event-manager.mjs.map +10 -0
  225. package/dist/mjs/core/managers/frontier-dependency-manager.mjs +151 -0
  226. package/dist/mjs/core/managers/frontier-dependency-manager.mjs.map +10 -0
  227. package/dist/mjs/core/managers/index.mjs +21 -0
  228. package/dist/mjs/core/managers/index.mjs.map +10 -0
  229. package/dist/mjs/core/managers/isDependencyNode.mjs +14 -0
  230. package/dist/mjs/core/managers/isDependencyNode.mjs.map +10 -0
  231. package/dist/mjs/core/managers/named-expression-manager.mjs +348 -0
  232. package/dist/mjs/core/managers/named-expression-manager.mjs.map +10 -0
  233. package/dist/mjs/core/managers/range-eval-order-builder.mjs +618 -0
  234. package/dist/mjs/core/managers/range-eval-order-builder.mjs.map +10 -0
  235. package/dist/mjs/core/managers/table-manager.mjs +224 -0
  236. package/dist/mjs/core/managers/table-manager.mjs.map +10 -0
  237. package/dist/mjs/core/managers/workbook-manager.mjs +447 -0
  238. package/dist/mjs/core/managers/workbook-manager.mjs.map +10 -0
  239. package/dist/mjs/core/map-serializer.mjs +39 -0
  240. package/dist/mjs/core/map-serializer.mjs.map +10 -0
  241. package/dist/mjs/core/named-expression-renamer.mjs +58 -0
  242. package/dist/mjs/core/named-expression-renamer.mjs.map +10 -0
  243. package/dist/mjs/core/sheet-renamer.mjs +59 -0
  244. package/dist/mjs/core/sheet-renamer.mjs.map +10 -0
  245. package/dist/mjs/core/sheet-utils.mjs +8 -0
  246. package/dist/mjs/core/sheet-utils.mjs.map +10 -0
  247. package/dist/mjs/core/table-renamer.mjs +58 -0
  248. package/dist/mjs/core/table-renamer.mjs.map +10 -0
  249. package/dist/mjs/core/types.mjs +18 -0
  250. package/dist/mjs/core/types.mjs.map +10 -0
  251. package/dist/mjs/core/utils/range-serializer.mjs +35 -0
  252. package/dist/mjs/core/utils/range-serializer.mjs.map +10 -0
  253. package/dist/mjs/core/utils/spreadsheet-visualizer.mjs +112 -0
  254. package/dist/mjs/core/utils/spreadsheet-visualizer.mjs.map +10 -0
  255. package/dist/mjs/core/utils.mjs +409 -0
  256. package/dist/mjs/core/utils.mjs.map +10 -0
  257. package/dist/mjs/core/workbook-renamer.mjs +76 -0
  258. package/dist/mjs/core/workbook-renamer.mjs.map +10 -0
  259. package/dist/mjs/debug/flags.mjs +17 -0
  260. package/dist/mjs/debug/flags.mjs.map +10 -0
  261. package/dist/mjs/evaluator/arithmetic/add/add.mjs +52 -0
  262. package/dist/mjs/evaluator/arithmetic/add/add.mjs.map +10 -0
  263. package/dist/mjs/evaluator/arithmetic/divide/divide.mjs +77 -0
  264. package/dist/mjs/evaluator/arithmetic/divide/divide.mjs.map +10 -0
  265. package/dist/mjs/evaluator/arithmetic/multiply/multiply.mjs +63 -0
  266. package/dist/mjs/evaluator/arithmetic/multiply/multiply.mjs.map +10 -0
  267. package/dist/mjs/evaluator/arithmetic/power/power.mjs +95 -0
  268. package/dist/mjs/evaluator/arithmetic/power/power.mjs.map +10 -0
  269. package/dist/mjs/evaluator/arithmetic/subtract/subtract.mjs +54 -0
  270. package/dist/mjs/evaluator/arithmetic/subtract/subtract.mjs.map +10 -0
  271. package/dist/mjs/evaluator/comparison/equals.mjs +34 -0
  272. package/dist/mjs/evaluator/comparison/equals.mjs.map +10 -0
  273. package/dist/mjs/evaluator/comparison/greater-than-or-equal.mjs +31 -0
  274. package/dist/mjs/evaluator/comparison/greater-than-or-equal.mjs.map +10 -0
  275. package/dist/mjs/evaluator/comparison/greater-than.mjs +31 -0
  276. package/dist/mjs/evaluator/comparison/greater-than.mjs.map +10 -0
  277. package/dist/mjs/evaluator/comparison/less-than-or-equal.mjs +39 -0
  278. package/dist/mjs/evaluator/comparison/less-than-or-equal.mjs.map +10 -0
  279. package/dist/mjs/evaluator/comparison/less-than.mjs +38 -0
  280. package/dist/mjs/evaluator/comparison/less-than.mjs.map +10 -0
  281. package/dist/mjs/evaluator/comparison/not-equals.mjs +23 -0
  282. package/dist/mjs/evaluator/comparison/not-equals.mjs.map +10 -0
  283. package/dist/mjs/evaluator/concatenation/concatenate.mjs +42 -0
  284. package/dist/mjs/evaluator/concatenation/concatenate.mjs.map +10 -0
  285. package/dist/mjs/evaluator/dependency-nodes/ast-evaluation-node.mjs +28 -0
  286. package/dist/mjs/evaluator/dependency-nodes/ast-evaluation-node.mjs.map +10 -0
  287. package/dist/mjs/evaluator/dependency-nodes/base-eval-node.mjs +81 -0
  288. package/dist/mjs/evaluator/dependency-nodes/base-eval-node.mjs.map +10 -0
  289. package/dist/mjs/evaluator/dependency-nodes/cell-value-node.mjs +24 -0
  290. package/dist/mjs/evaluator/dependency-nodes/cell-value-node.mjs.map +10 -0
  291. package/dist/mjs/evaluator/dependency-nodes/empty-cell-evaluation-node.mjs +78 -0
  292. package/dist/mjs/evaluator/dependency-nodes/empty-cell-evaluation-node.mjs.map +10 -0
  293. package/dist/mjs/evaluator/dependency-nodes/spill-meta-node.mjs +20 -0
  294. package/dist/mjs/evaluator/dependency-nodes/spill-meta-node.mjs.map +10 -0
  295. package/dist/mjs/evaluator/evaluate-scalar-operator.mjs +226 -0
  296. package/dist/mjs/evaluator/evaluate-scalar-operator.mjs.map +10 -0
  297. package/dist/mjs/evaluator/evaluation-context.mjs +123 -0
  298. package/dist/mjs/evaluator/evaluation-context.mjs.map +10 -0
  299. package/dist/mjs/evaluator/evaluation-error.mjs +44 -0
  300. package/dist/mjs/evaluator/evaluation-error.mjs.map +10 -0
  301. package/dist/mjs/evaluator/formula-evaluator.mjs +780 -0
  302. package/dist/mjs/evaluator/formula-evaluator.mjs.map +10 -0
  303. package/dist/mjs/evaluator/range-evaluation-node.mjs +58 -0
  304. package/dist/mjs/evaluator/range-evaluation-node.mjs.map +10 -0
  305. package/dist/mjs/functions/_template/template.mjs +12 -0
  306. package/dist/mjs/functions/_template/template.mjs.map +10 -0
  307. package/dist/mjs/functions/array/sequence/sequence.mjs +287 -0
  308. package/dist/mjs/functions/array/sequence/sequence.mjs.map +10 -0
  309. package/dist/mjs/functions/criteria-parser.mjs +187 -0
  310. package/dist/mjs/functions/criteria-parser.mjs.map +10 -0
  311. package/dist/mjs/functions/criteria-utils.mjs +268 -0
  312. package/dist/mjs/functions/criteria-utils.mjs.map +10 -0
  313. package/dist/mjs/functions/function-utils.mjs +33 -0
  314. package/dist/mjs/functions/function-utils.mjs.map +10 -0
  315. package/dist/mjs/functions/index.mjs +95 -0
  316. package/dist/mjs/functions/index.mjs.map +10 -0
  317. package/dist/mjs/functions/information/cell/cell.mjs +168 -0
  318. package/dist/mjs/functions/information/cell/cell.mjs.map +10 -0
  319. package/dist/mjs/functions/information/column/column.mjs +120 -0
  320. package/dist/mjs/functions/information/column/column.mjs.map +10 -0
  321. package/dist/mjs/functions/information/row/row.mjs +126 -0
  322. package/dist/mjs/functions/information/row/row.mjs.map +10 -0
  323. package/dist/mjs/functions/logical/and/and.mjs +84 -0
  324. package/dist/mjs/functions/logical/and/and.mjs.map +10 -0
  325. package/dist/mjs/functions/logical/if/if.mjs +167 -0
  326. package/dist/mjs/functions/logical/if/if.mjs.map +10 -0
  327. package/dist/mjs/functions/logical/iferror/iferror.mjs +98 -0
  328. package/dist/mjs/functions/logical/iferror/iferror.mjs.map +10 -0
  329. package/dist/mjs/functions/logical/or/or.mjs +84 -0
  330. package/dist/mjs/functions/logical/or/or.mjs.map +10 -0
  331. package/dist/mjs/functions/lookup/count/count-utils.mjs +35 -0
  332. package/dist/mjs/functions/lookup/count/count-utils.mjs.map +10 -0
  333. package/dist/mjs/functions/lookup/count/count.mjs +18 -0
  334. package/dist/mjs/functions/lookup/count/count.mjs.map +10 -0
  335. package/dist/mjs/functions/lookup/count/countif.mjs +68 -0
  336. package/dist/mjs/functions/lookup/count/countif.mjs.map +10 -0
  337. package/dist/mjs/functions/lookup/count/countifs.mjs +37 -0
  338. package/dist/mjs/functions/lookup/count/countifs.mjs.map +10 -0
  339. package/dist/mjs/functions/lookup/index-lookup/index-lookup.mjs +159 -0
  340. package/dist/mjs/functions/lookup/index-lookup/index-lookup.mjs.map +10 -0
  341. package/dist/mjs/functions/lookup/match/match.mjs +140 -0
  342. package/dist/mjs/functions/lookup/match/match.mjs.map +10 -0
  343. package/dist/mjs/functions/lookup/xlookup/xlookup.mjs +382 -0
  344. package/dist/mjs/functions/lookup/xlookup/xlookup.mjs.map +10 -0
  345. package/dist/mjs/functions/math/average/average-utils.mjs +44 -0
  346. package/dist/mjs/functions/math/average/average-utils.mjs.map +10 -0
  347. package/dist/mjs/functions/math/average/average.mjs +18 -0
  348. package/dist/mjs/functions/math/average/average.mjs.map +10 -0
  349. package/dist/mjs/functions/math/average/averageif.mjs +58 -0
  350. package/dist/mjs/functions/math/average/averageif.mjs.map +10 -0
  351. package/dist/mjs/functions/math/average/averageifs.mjs +35 -0
  352. package/dist/mjs/functions/math/average/averageifs.mjs.map +10 -0
  353. package/dist/mjs/functions/math/ceiling/ceiling.mjs +191 -0
  354. package/dist/mjs/functions/math/ceiling/ceiling.mjs.map +10 -0
  355. package/dist/mjs/functions/math/max/max-utils.mjs +43 -0
  356. package/dist/mjs/functions/math/max/max-utils.mjs.map +10 -0
  357. package/dist/mjs/functions/math/max/max.mjs +18 -0
  358. package/dist/mjs/functions/math/max/max.mjs.map +10 -0
  359. package/dist/mjs/functions/math/max/maxif.mjs +58 -0
  360. package/dist/mjs/functions/math/max/maxif.mjs.map +10 -0
  361. package/dist/mjs/functions/math/max/maxifs.mjs +35 -0
  362. package/dist/mjs/functions/math/max/maxifs.mjs.map +10 -0
  363. package/dist/mjs/functions/math/min/min-utils.mjs +43 -0
  364. package/dist/mjs/functions/math/min/min-utils.mjs.map +10 -0
  365. package/dist/mjs/functions/math/min/min.mjs +18 -0
  366. package/dist/mjs/functions/math/min/min.mjs.map +10 -0
  367. package/dist/mjs/functions/math/min/minif.mjs +58 -0
  368. package/dist/mjs/functions/math/min/minif.mjs.map +10 -0
  369. package/dist/mjs/functions/math/min/minifs.mjs +35 -0
  370. package/dist/mjs/functions/math/min/minifs.mjs.map +10 -0
  371. package/dist/mjs/functions/math/sum/sum.mjs +18 -0
  372. package/dist/mjs/functions/math/sum/sum.mjs.map +10 -0
  373. package/dist/mjs/functions/math/sum/sumif.mjs +58 -0
  374. package/dist/mjs/functions/math/sum/sumif.mjs.map +10 -0
  375. package/dist/mjs/functions/math/sum/sumifs.mjs +34 -0
  376. package/dist/mjs/functions/math/sum/sumifs.mjs.map +10 -0
  377. package/dist/mjs/functions/math/sum/summation-utils.mjs +27 -0
  378. package/dist/mjs/functions/math/sum/summation-utils.mjs.map +10 -0
  379. package/dist/mjs/functions/reference/address/address.mjs +135 -0
  380. package/dist/mjs/functions/reference/address/address.mjs.map +10 -0
  381. package/dist/mjs/functions/reference/indirect/indirect.mjs +74 -0
  382. package/dist/mjs/functions/reference/indirect/indirect.mjs.map +10 -0
  383. package/dist/mjs/functions/reference/offset/offset.mjs +205 -0
  384. package/dist/mjs/functions/reference/offset/offset.mjs.map +10 -0
  385. package/dist/mjs/functions/text/concatenate/concatenate.mjs +139 -0
  386. package/dist/mjs/functions/text/concatenate/concatenate.mjs.map +10 -0
  387. package/dist/mjs/functions/text/exact/exact.mjs +143 -0
  388. package/dist/mjs/functions/text/exact/exact.mjs.map +10 -0
  389. package/dist/mjs/functions/text/find/find.mjs +369 -0
  390. package/dist/mjs/functions/text/find/find.mjs.map +10 -0
  391. package/dist/mjs/functions/text/left/left.mjs +81 -0
  392. package/dist/mjs/functions/text/left/left.mjs.map +10 -0
  393. package/dist/mjs/functions/text/len/len.mjs +91 -0
  394. package/dist/mjs/functions/text/len/len.mjs.map +10 -0
  395. package/dist/mjs/functions/text/mid/mid.mjs +75 -0
  396. package/dist/mjs/functions/text/mid/mid.mjs.map +10 -0
  397. package/dist/mjs/functions/text/right/right.mjs +143 -0
  398. package/dist/mjs/functions/text/right/right.mjs.map +10 -0
  399. package/dist/mjs/functions/text/text-helpers.mjs +151 -0
  400. package/dist/mjs/functions/text/text-helpers.mjs.map +10 -0
  401. package/dist/mjs/functions/text/textjoin/textjoin.mjs +145 -0
  402. package/dist/mjs/functions/text/textjoin/textjoin.mjs.map +10 -0
  403. package/dist/mjs/package.json +5 -0
  404. package/dist/mjs/parser/ast.mjs +145 -0
  405. package/dist/mjs/parser/ast.mjs.map +10 -0
  406. package/dist/mjs/parser/formatter.mjs +289 -0
  407. package/dist/mjs/parser/formatter.mjs.map +10 -0
  408. package/dist/mjs/parser/grammar.mjs +345 -0
  409. package/dist/mjs/parser/grammar.mjs.map +10 -0
  410. package/dist/mjs/parser/lexer.mjs +412 -0
  411. package/dist/mjs/parser/lexer.mjs.map +10 -0
  412. package/dist/mjs/parser/parser.mjs +1692 -0
  413. package/dist/mjs/parser/parser.mjs.map +10 -0
  414. package/dist/mjs/react/hooks.mjs +16 -0
  415. package/dist/mjs/react/hooks.mjs.map +10 -0
  416. package/dist/types/core/ast-traverser.d.ts +28 -0
  417. package/dist/types/core/autofill-utils.d.ts +32 -0
  418. package/dist/types/core/engine.d.ts +184 -0
  419. package/dist/types/core/managers/cache-manager.d.ts +14 -0
  420. package/dist/types/core/managers/dependency-manager.d.ts +147 -0
  421. package/dist/types/core/managers/dependency-node.d.ts +13 -0
  422. package/dist/types/core/managers/evaluation-manager.d.ts +30 -0
  423. package/dist/types/core/managers/event-manager.d.ts +8 -0
  424. package/dist/types/core/managers/frontier-dependency-manager.d.ts +69 -0
  425. package/dist/types/core/managers/index.d.ts +7 -0
  426. package/dist/types/core/managers/isDependencyNode.d.ts +2 -0
  427. package/dist/types/core/managers/named-expression-manager.d.ts +101 -0
  428. package/dist/types/core/managers/range-eval-order-builder.d.ts +33 -0
  429. package/dist/types/core/managers/table-manager.d.ts +84 -0
  430. package/dist/types/core/managers/workbook-manager.d.ts +136 -0
  431. package/dist/types/core/map-serializer.d.ts +4 -0
  432. package/dist/types/core/named-expression-renamer.d.ts +21 -0
  433. package/dist/types/core/sheet-renamer.d.ts +28 -0
  434. package/dist/types/core/sheet-utils.d.ts +2 -0
  435. package/dist/types/core/table-renamer.d.ts +21 -0
  436. package/dist/types/core/types.d.ts +272 -0
  437. package/dist/types/core/utils/cell-address-parsing.test.d.ts +1 -0
  438. package/dist/types/core/utils/range-serializer.d.ts +22 -0
  439. package/dist/types/core/utils/range-serializer.test.d.ts +1 -0
  440. package/dist/types/core/utils/spreadsheet-visualizer.d.ts +30 -0
  441. package/dist/types/core/utils.d.ts +48 -0
  442. package/dist/types/core/workbook-renamer.d.ts +28 -0
  443. package/dist/types/debug/flags.d.ts +11 -0
  444. package/dist/types/evaluator/arithmetic/add/add.d.ts +2 -0
  445. package/dist/types/evaluator/arithmetic/add/add.test.d.ts +1 -0
  446. package/dist/types/evaluator/arithmetic/divide/divide.d.ts +2 -0
  447. package/dist/types/evaluator/arithmetic/divide/divide.test.d.ts +1 -0
  448. package/dist/types/evaluator/arithmetic/multiply/multiply.d.ts +2 -0
  449. package/dist/types/evaluator/arithmetic/multiply/multiply.test.d.ts +1 -0
  450. package/dist/types/evaluator/arithmetic/power/power.d.ts +2 -0
  451. package/dist/types/evaluator/arithmetic/power/power.test.d.ts +1 -0
  452. package/dist/types/evaluator/arithmetic/subtract/subtract.d.ts +2 -0
  453. package/dist/types/evaluator/arithmetic/subtract/subtract.test.d.ts +1 -0
  454. package/dist/types/evaluator/comparison/comparison-operators.test.d.ts +1 -0
  455. package/dist/types/evaluator/comparison/equals.d.ts +6 -0
  456. package/dist/types/evaluator/comparison/greater-than-or-equal.d.ts +6 -0
  457. package/dist/types/evaluator/comparison/greater-than.d.ts +6 -0
  458. package/dist/types/evaluator/comparison/less-than-or-equal.d.ts +6 -0
  459. package/dist/types/evaluator/comparison/less-than.d.ts +6 -0
  460. package/dist/types/evaluator/comparison/not-equals.d.ts +6 -0
  461. package/dist/types/evaluator/concatenation/concatenate.d.ts +6 -0
  462. package/dist/types/evaluator/concatenation/concatenate.test.d.ts +1 -0
  463. package/dist/types/evaluator/dependency-nodes/ast-evaluation-node.d.ts +12 -0
  464. package/dist/types/evaluator/dependency-nodes/base-eval-node.d.ts +31 -0
  465. package/dist/types/evaluator/dependency-nodes/cell-value-node.d.ts +10 -0
  466. package/dist/types/evaluator/dependency-nodes/empty-cell-evaluation-node.d.ts +17 -0
  467. package/dist/types/evaluator/dependency-nodes/spill-meta-node.d.ts +7 -0
  468. package/dist/types/evaluator/evaluate-scalar-operator.d.ts +12 -0
  469. package/dist/types/evaluator/evaluation-context.d.ts +66 -0
  470. package/dist/types/evaluator/evaluation-error.d.ts +20 -0
  471. package/dist/types/evaluator/formula-evaluator.d.ts +67 -0
  472. package/dist/types/evaluator/open-range-evaluator.test.d.ts +1 -0
  473. package/dist/types/evaluator/range-evaluation-node.d.ts +16 -0
  474. package/dist/types/functions/_template/template.d.ts +5 -0
  475. package/dist/types/functions/_template/template.test.d.ts +1 -0
  476. package/dist/types/functions/array/sequence/performance-test.d.ts +1 -0
  477. package/dist/types/functions/array/sequence/sequence.d.ts +14 -0
  478. package/dist/types/functions/array/sequence/sequence.test.d.ts +1 -0
  479. package/dist/types/functions/criteria-parser.d.ts +27 -0
  480. package/dist/types/functions/criteria-utils.d.ts +61 -0
  481. package/dist/types/functions/function-utils.d.ts +21 -0
  482. package/dist/types/functions/index.d.ts +2 -0
  483. package/dist/types/functions/information/cell/cell.d.ts +24 -0
  484. package/dist/types/functions/information/cell/cell.test.d.ts +1 -0
  485. package/dist/types/functions/information/column/column.d.ts +14 -0
  486. package/dist/types/functions/information/column/column.test.d.ts +1 -0
  487. package/dist/types/functions/information/row/row.d.ts +14 -0
  488. package/dist/types/functions/information/row/row.test.d.ts +1 -0
  489. package/dist/types/functions/logical/and/and.d.ts +5 -0
  490. package/dist/types/functions/logical/and/and.test.d.ts +1 -0
  491. package/dist/types/functions/logical/if/if.d.ts +5 -0
  492. package/dist/types/functions/logical/if/if.test.d.ts +1 -0
  493. package/dist/types/functions/logical/iferror/iferror.d.ts +5 -0
  494. package/dist/types/functions/logical/iferror/iferror.test.d.ts +1 -0
  495. package/dist/types/functions/logical/or/or.d.ts +5 -0
  496. package/dist/types/functions/logical/or/or.test.d.ts +1 -0
  497. package/dist/types/functions/lookup/count/count-utils.d.ts +14 -0
  498. package/dist/types/functions/lookup/count/count.d.ts +21 -0
  499. package/dist/types/functions/lookup/count/count.test.d.ts +1 -0
  500. package/dist/types/functions/lookup/count/countif.d.ts +26 -0
  501. package/dist/types/functions/lookup/count/countif.test.d.ts +1 -0
  502. package/dist/types/functions/lookup/count/countifs.d.ts +21 -0
  503. package/dist/types/functions/lookup/count/countifs.test.d.ts +1 -0
  504. package/dist/types/functions/lookup/index-lookup/index-lookup.d.ts +2 -0
  505. package/dist/types/functions/lookup/index-lookup/index-lookup.test.d.ts +1 -0
  506. package/dist/types/functions/lookup/match/match.d.ts +2 -0
  507. package/dist/types/functions/lookup/match/match.test.d.ts +1 -0
  508. package/dist/types/functions/lookup/xlookup/xlookup.d.ts +2 -0
  509. package/dist/types/functions/lookup/xlookup/xlookup.test.d.ts +1 -0
  510. package/dist/types/functions/math/average/average-utils.d.ts +10 -0
  511. package/dist/types/functions/math/average/average.d.ts +18 -0
  512. package/dist/types/functions/math/average/average.test.d.ts +1 -0
  513. package/dist/types/functions/math/average/averageif.d.ts +23 -0
  514. package/dist/types/functions/math/average/averageif.test.d.ts +1 -0
  515. package/dist/types/functions/math/average/averageifs.d.ts +21 -0
  516. package/dist/types/functions/math/average/averageifs.test.d.ts +1 -0
  517. package/dist/types/functions/math/ceiling/ceiling.d.ts +5 -0
  518. package/dist/types/functions/math/ceiling/ceiling.test.d.ts +1 -0
  519. package/dist/types/functions/math/max/max-utils.d.ts +20 -0
  520. package/dist/types/functions/math/max/max.d.ts +18 -0
  521. package/dist/types/functions/math/max/max.test.d.ts +1 -0
  522. package/dist/types/functions/math/max/maxif.d.ts +23 -0
  523. package/dist/types/functions/math/max/maxif.test.d.ts +1 -0
  524. package/dist/types/functions/math/max/maxifs.d.ts +21 -0
  525. package/dist/types/functions/math/max/maxifs.test.d.ts +1 -0
  526. package/dist/types/functions/math/min/min-utils.d.ts +20 -0
  527. package/dist/types/functions/math/min/min.d.ts +5 -0
  528. package/dist/types/functions/math/min/min.test.d.ts +1 -0
  529. package/dist/types/functions/math/min/minif.d.ts +23 -0
  530. package/dist/types/functions/math/min/minif.test.d.ts +1 -0
  531. package/dist/types/functions/math/min/minifs.d.ts +21 -0
  532. package/dist/types/functions/math/min/minifs.test.d.ts +1 -0
  533. package/dist/types/functions/math/sum/sum.d.ts +5 -0
  534. package/dist/types/functions/math/sum/sum.test.d.ts +1 -0
  535. package/dist/types/functions/math/sum/sumif.d.ts +23 -0
  536. package/dist/types/functions/math/sum/sumif.test.d.ts +1 -0
  537. package/dist/types/functions/math/sum/sumifs.d.ts +21 -0
  538. package/dist/types/functions/math/sum/sumifs.test.d.ts +1 -0
  539. package/dist/types/functions/math/sum/summation-utils.d.ts +19 -0
  540. package/dist/types/functions/reference/address/address.d.ts +18 -0
  541. package/dist/types/functions/reference/address/address.test.d.ts +1 -0
  542. package/dist/types/functions/reference/indirect/indirect.d.ts +20 -0
  543. package/dist/types/functions/reference/indirect/indirect.test.d.ts +1 -0
  544. package/dist/types/functions/reference/offset/offset.d.ts +23 -0
  545. package/dist/types/functions/reference/offset/offset.test.d.ts +1 -0
  546. package/dist/types/functions/text/concatenate/concatenate.d.ts +5 -0
  547. package/dist/types/functions/text/concatenate/concatenate.test.d.ts +1 -0
  548. package/dist/types/functions/text/exact/exact.d.ts +5 -0
  549. package/dist/types/functions/text/exact/exact.test.d.ts +1 -0
  550. package/dist/types/functions/text/find/find.d.ts +20 -0
  551. package/dist/types/functions/text/find/find.test.d.ts +1 -0
  552. package/dist/types/functions/text/left/left.d.ts +19 -0
  553. package/dist/types/functions/text/left/left.test.d.ts +1 -0
  554. package/dist/types/functions/text/len/len.d.ts +16 -0
  555. package/dist/types/functions/text/len/len.test.d.ts +1 -0
  556. package/dist/types/functions/text/mid/mid.d.ts +20 -0
  557. package/dist/types/functions/text/mid/mid.test.d.ts +1 -0
  558. package/dist/types/functions/text/right/right.d.ts +2 -0
  559. package/dist/types/functions/text/right/right.test.d.ts +1 -0
  560. package/dist/types/functions/text/text-helpers.d.ts +27 -0
  561. package/dist/types/functions/text/textjoin/textjoin.d.ts +5 -0
  562. package/dist/types/functions/text/textjoin/textjoin.test.d.ts +1 -0
  563. package/dist/types/parser/ast.d.ts +275 -0
  564. package/dist/types/parser/formatter.d.ts +6 -0
  565. package/dist/types/parser/grammar.d.ts +203 -0
  566. package/dist/types/parser/lexer.d.ts +144 -0
  567. package/dist/types/parser/parser.d.ts +159 -0
  568. package/dist/types/react/hooks.d.ts +5 -0
  569. package/package.json +41 -0
@@ -0,0 +1,1692 @@
1
+ // src/parser/parser.ts
2
+ import { columnToIndex } from "../core/utils.mjs";
3
+ import { FormulaError } from "../core/types.mjs";
4
+ import {
5
+ createArrayNode,
6
+ createBinaryOpNode,
7
+ createEmptyNode,
8
+ createErrorNode,
9
+ createFunctionNode,
10
+ createInfinityNode,
11
+ createNamedExpressionNode,
12
+ createRangeNode,
13
+ createReferenceNode,
14
+ createStructuredReferenceNode,
15
+ createThreeDRangeNode,
16
+ createUnaryOpNode,
17
+ createValueNode
18
+ } from "./ast.mjs";
19
+ import {
20
+ getOperatorAssociativity,
21
+ getOperatorPrecedence,
22
+ isBinaryOperator,
23
+ parseCellReference,
24
+ parseInfiniteRange,
25
+ parseOpenEndedRange,
26
+ SPECIAL_FUNCTIONS
27
+ } from "./grammar.mjs";
28
+ import { Lexer, TokenStream } from "./lexer.mjs";
29
+
30
+ class ParseError extends Error {
31
+ position;
32
+ constructor(message, position) {
33
+ super(message);
34
+ this.position = position;
35
+ this.name = "ParseError";
36
+ }
37
+ }
38
+
39
+ class Parser {
40
+ tokens;
41
+ input;
42
+ constructor(tokens, input) {
43
+ this.tokens = new TokenStream(tokens);
44
+ this.input = input || "";
45
+ }
46
+ lookAheadForWorkbookReference() {
47
+ let pos = 1;
48
+ while (pos < 10) {
49
+ const token = this.tokens.peekAhead(pos);
50
+ if (!token || token.type === "EOF") {
51
+ return { isWorkbookReference: false };
52
+ }
53
+ if (token.type === "RBRACKET") {
54
+ const nextToken = this.tokens.peekAhead(pos + 1);
55
+ if (nextToken && nextToken.type === "IDENTIFIER") {
56
+ let lookPos = pos + 2;
57
+ while (lookPos < pos + 10) {
58
+ const lookToken = this.tokens.peekAhead(lookPos);
59
+ if (!lookToken || lookToken.type === "EOF") {
60
+ return { isWorkbookReference: true };
61
+ }
62
+ if (lookToken.type === "EXCLAMATION") {
63
+ return { isWorkbookReference: true };
64
+ }
65
+ lookPos++;
66
+ }
67
+ }
68
+ return { isWorkbookReference: false };
69
+ }
70
+ if (token.type === "IDENTIFIER" || token.type === "FUNCTION" || token.type === "NUMBER" || token.type === "OPERATOR" && (token.value === "-" || token.value === "=" || token.value === "%") || token.type === "LPAREN" || token.type === "RPAREN") {
71
+ pos++;
72
+ continue;
73
+ }
74
+ return { isWorkbookReference: false };
75
+ }
76
+ return { isWorkbookReference: false };
77
+ }
78
+ parseWorkbookReference() {
79
+ const start = this.tokens.peek().position.start;
80
+ this.tokens.consume();
81
+ const workbookStartPos = this.tokens.peek().position.start;
82
+ let workbookEndPos = workbookStartPos;
83
+ while (!this.tokens.match("RBRACKET")) {
84
+ if (this.tokens.isAtEnd()) {
85
+ throw new ParseError("Expected ] to close workbook reference", this.tokens.peek().position);
86
+ }
87
+ const token = this.tokens.peek();
88
+ if (token.type === "IDENTIFIER" || token.type === "FUNCTION" || token.type === "NUMBER" || token.type === "OPERATOR" && (token.value === "-" || token.value === "=" || token.value === "%") || token.type === "LPAREN" || token.type === "RPAREN") {
89
+ const consumedToken = this.tokens.consume();
90
+ workbookEndPos = consumedToken.position.end;
91
+ } else {
92
+ throw new ParseError(`Invalid character in workbook name: ${token.value}`, token.position);
93
+ }
94
+ }
95
+ const workbookName = this.input.substring(workbookStartPos, workbookEndPos);
96
+ this.tokens.consume();
97
+ if (!this.tokens.match("IDENTIFIER")) {
98
+ throw new ParseError("Expected sheet name after workbook reference", this.tokens.peek().position);
99
+ }
100
+ const sheetToken = this.tokens.consume();
101
+ let sheetName = sheetToken.value;
102
+ if (sheetName.startsWith("'") && sheetName.endsWith("'")) {
103
+ sheetName = sheetName.slice(1, -1).replace(/''/g, "'");
104
+ }
105
+ if (this.tokens.match("COLON")) {
106
+ const nextToken = this.tokens.peekAhead(1);
107
+ const tokenAfterNext = this.tokens.peekAhead(2);
108
+ if (nextToken?.type === "IDENTIFIER" && tokenAfterNext?.type === "EXCLAMATION") {
109
+ this.tokens.consume();
110
+ const endSheetToken = this.tokens.consume();
111
+ let endSheetName = endSheetToken.value;
112
+ if (endSheetName.startsWith("'") && endSheetName.endsWith("'")) {
113
+ endSheetName = endSheetName.slice(1, -1).replace(/''/g, "'");
114
+ }
115
+ this.tokens.consume();
116
+ const ref = this.parseCellOrRangeAfterSheets();
117
+ return createThreeDRangeNode(sheetName, endSheetName, ref, {
118
+ start,
119
+ end: this.tokens.peek().position?.end ?? 0
120
+ }, workbookName);
121
+ }
122
+ }
123
+ if (this.tokens.match("EXCLAMATION")) {
124
+ this.tokens.consume();
125
+ const cellRef = this.parseCellOrRangeWithWorkbookAndSheet(workbookName, sheetName, start);
126
+ return cellRef;
127
+ } else {
128
+ const range = {
129
+ start: {
130
+ col: 0,
131
+ row: 0
132
+ },
133
+ end: {
134
+ col: {
135
+ type: "infinity",
136
+ sign: "positive"
137
+ },
138
+ row: {
139
+ type: "infinity",
140
+ sign: "positive"
141
+ }
142
+ }
143
+ };
144
+ return createRangeNode({
145
+ workbookName,
146
+ sheetName,
147
+ range,
148
+ isAbsolute: {
149
+ start: { col: false, row: false },
150
+ end: { col: false, row: false }
151
+ },
152
+ position: {
153
+ start,
154
+ end: this.tokens.peek().position?.start ?? 0
155
+ }
156
+ });
157
+ }
158
+ }
159
+ parseBareColumnReference() {
160
+ const startPos = this.tokens.peek().position.start;
161
+ this.tokens.consume();
162
+ let selector;
163
+ let cols;
164
+ let isCurrentRow = false;
165
+ if (this.tokens.match("HASH")) {
166
+ this.tokens.consume();
167
+ if (!this.tokens.match("IDENTIFIER")) {
168
+ throw new ParseError("Expected selector name after #", this.tokens.peek().position);
169
+ }
170
+ const selectorName = this.tokens.consume().value;
171
+ selector = `#${selectorName}`;
172
+ } else if (this.tokens.match("IDENTIFIER")) {
173
+ const colStart = this.parseColumnName();
174
+ if (this.tokens.match("COLON")) {
175
+ this.tokens.consume();
176
+ const colEnd = this.parseColumnName();
177
+ cols = {
178
+ startCol: colStart,
179
+ endCol: colEnd
180
+ };
181
+ } else {
182
+ cols = {
183
+ startCol: colStart,
184
+ endCol: colStart
185
+ };
186
+ }
187
+ } else {
188
+ throw new ParseError("Expected column name or selector in bare column reference", this.tokens.peek().position);
189
+ }
190
+ if (!this.tokens.match("RBRACKET")) {
191
+ throw new ParseError("Expected ] to close column reference", this.tokens.peek().position);
192
+ }
193
+ this.tokens.consume();
194
+ return createStructuredReferenceNode({
195
+ tableName: undefined,
196
+ cols,
197
+ selector,
198
+ isCurrentRow,
199
+ position: {
200
+ start: startPos,
201
+ end: this.tokens.peek().position?.end ?? 0
202
+ }
203
+ });
204
+ }
205
+ parseColumnName() {
206
+ if (!this.tokens.match("IDENTIFIER") && !this.tokens.match("FUNCTION") && !this.tokens.match("NUMBER") && !this.tokens.match("OPERATOR")) {
207
+ throw new ParseError("Expected column name", this.tokens.peek().position);
208
+ }
209
+ const startToken = this.tokens.peek();
210
+ const startPos = startToken.position.start;
211
+ this.tokens.consume();
212
+ const endTokens = new Set([
213
+ "RBRACKET",
214
+ "COMMA",
215
+ "EOF"
216
+ ]);
217
+ while (!endTokens.has(this.tokens.peek().type)) {
218
+ if (this.tokens.match("OPERATOR")) {
219
+ this.tokens.consume();
220
+ } else {
221
+ this.tokens.consume();
222
+ }
223
+ }
224
+ const currentPos = this.tokens.getPosition();
225
+ let endPos = currentPos > 0 ? this.tokens.getTokens()[currentPos - 1]?.position?.end || startPos : startPos;
226
+ if (this.tokens.match("RBRACKET")) {
227
+ const nextTokenPos = this.tokens.peek().position.start;
228
+ endPos = nextTokenPos;
229
+ }
230
+ const columnName = this.input.substring(startPos, endPos);
231
+ return columnName;
232
+ }
233
+ static parse(formula) {
234
+ const lexer = new Lexer(formula);
235
+ const tokens = lexer.tokenize();
236
+ const parser = new Parser(tokens, formula);
237
+ return parser.parseFormula();
238
+ }
239
+ parseFormula() {
240
+ if (this.tokens.isAtEnd()) {
241
+ return createEmptyNode();
242
+ }
243
+ if (this.tokens.peek().type === "EOF") {
244
+ return createErrorNode(FormulaError.ERROR, "Empty formula");
245
+ }
246
+ try {
247
+ const expr = this.parseExpression();
248
+ if (!this.tokens.isAtEnd()) {
249
+ throw new ParseError(`Unexpected token: ${this.tokens.peek().value}`, this.tokens.peek().position);
250
+ }
251
+ return expr;
252
+ } catch (error) {
253
+ if (error instanceof ParseError) {
254
+ throw error;
255
+ }
256
+ throw new ParseError(String(error));
257
+ }
258
+ }
259
+ parseExpression() {
260
+ return this.parseBinaryExpression(0);
261
+ }
262
+ parseBinaryExpression(minPrecedence) {
263
+ let left = this.parseUnaryExpression();
264
+ while (true) {
265
+ const token = this.tokens.peek();
266
+ if (token.type !== "OPERATOR" || !isBinaryOperator(token.value)) {
267
+ break;
268
+ }
269
+ const precedence = getOperatorPrecedence(token.value);
270
+ if (precedence < minPrecedence) {
271
+ break;
272
+ }
273
+ const operator = token.value;
274
+ const associativity = getOperatorAssociativity(operator);
275
+ const start = token.position.start;
276
+ this.tokens.consume();
277
+ const nextMinPrecedence = associativity === "right" ? precedence : precedence + 1;
278
+ const right = this.parseBinaryExpression(nextMinPrecedence);
279
+ left = createBinaryOpNode(operator, left, right, right.position?.end ? {
280
+ start,
281
+ end: right.position.end
282
+ } : undefined);
283
+ }
284
+ return left;
285
+ }
286
+ parseUnaryExpression() {
287
+ const token = this.tokens.peek();
288
+ if (token.type === "OPERATOR" && (token.value === "+" || token.value === "-")) {
289
+ const start = token.position.start;
290
+ const operator = token.value;
291
+ this.tokens.consume();
292
+ const operand = this.parseUnaryExpression();
293
+ return createUnaryOpNode(operator, operand, operand.position ? {
294
+ start,
295
+ end: operand.position.end
296
+ } : undefined);
297
+ }
298
+ return this.parsePostfixExpression();
299
+ }
300
+ parsePostfixExpression() {
301
+ let expr = this.parsePrimaryExpression();
302
+ if (this.tokens.match("OPERATOR") && this.tokens.peek().value === "%") {
303
+ const token = this.tokens.consume();
304
+ expr = createUnaryOpNode("%", expr, expr.position ? {
305
+ start: expr.position.start,
306
+ end: token.position.end
307
+ } : undefined);
308
+ }
309
+ return expr;
310
+ }
311
+ parsePrimaryExpression() {
312
+ const token = this.tokens.peek();
313
+ const start = token.position.start;
314
+ switch (token.type) {
315
+ case "NUMBER":
316
+ return this.parseNumber();
317
+ case "STRING":
318
+ return this.parseString();
319
+ case "BOOLEAN":
320
+ return this.parseBoolean();
321
+ case "ERROR":
322
+ return this.parseError();
323
+ case "FUNCTION":
324
+ return this.parseFunctionCall();
325
+ case "IDENTIFIER":
326
+ return this.parseIdentifier();
327
+ case "INFINITY":
328
+ const infinityToken = this.tokens.consume();
329
+ return createInfinityNode(infinityToken.position);
330
+ case "AT":
331
+ return this.parseCurrentRowReference();
332
+ case "HASH":
333
+ return this.parseTableSelector();
334
+ case "DOLLAR":
335
+ return this.parseAbsoluteReference();
336
+ case "LPAREN":
337
+ return this.parseParenthesizedExpression();
338
+ case "LBRACE":
339
+ return this.parseArrayLiteral();
340
+ case "LBRACKET":
341
+ if (this.tokens.peekAhead(1)?.type === "AT") {
342
+ return this.parseCurrentRowReference();
343
+ } else if (this.tokens.peekAhead(1)?.type === "IDENTIFIER" || this.tokens.peekAhead(1)?.type === "FUNCTION" || this.tokens.peekAhead(1)?.type === "NUMBER" || this.tokens.peekAhead(1)?.type === "HASH") {
344
+ const lookahead = this.lookAheadForWorkbookReference();
345
+ if (lookahead.isWorkbookReference) {
346
+ return this.parseWorkbookReference();
347
+ }
348
+ return this.parseBareColumnReference();
349
+ }
350
+ throw new ParseError(`Unexpected bracket: ${token.value}`, token.position);
351
+ default:
352
+ throw new ParseError(`Unexpected token: ${token.value}`, token.position);
353
+ }
354
+ }
355
+ parseAbsoluteReference() {
356
+ const start = this.tokens.peek().position.start;
357
+ let ref = "";
358
+ ref += this.tokens.consume().value;
359
+ if (this.tokens.match("IDENTIFIER")) {
360
+ const identifier = this.tokens.consume().value;
361
+ const match = identifier.match(/^([A-Z]+)(\d+)$/i);
362
+ if (match) {
363
+ ref += identifier;
364
+ } else if (/^[A-Z]+$/i.test(identifier)) {
365
+ ref += identifier;
366
+ if (this.tokens.match("DOLLAR")) {
367
+ ref += this.tokens.consume().value;
368
+ }
369
+ if (this.tokens.match("NUMBER")) {
370
+ ref += this.tokens.consume().value;
371
+ } else if (!this.tokens.match("COLON")) {
372
+ throw new ParseError("Expected row number", this.tokens.peek().position);
373
+ }
374
+ } else {
375
+ throw new ParseError("Invalid cell reference format", this.tokens.peek().position);
376
+ }
377
+ } else if (this.tokens.match("NUMBER")) {
378
+ const number = this.tokens.consume().value;
379
+ ref += number;
380
+ } else {
381
+ throw new ParseError("Expected column letter or row number after $", this.tokens.peek().position);
382
+ }
383
+ if (this.tokens.match("COLON")) {
384
+ this.tokens.consume();
385
+ const endRef = this.parseRangeEnd();
386
+ return this.parseRange(ref, endRef, start, this.tokens.peek().position.start);
387
+ }
388
+ const cellRef = this.parseCellReferenceString(ref);
389
+ if (cellRef) {
390
+ return cellRef;
391
+ }
392
+ throw new ParseError(`Invalid cell reference: ${ref}`, {
393
+ start,
394
+ end: this.tokens.peek().position.start
395
+ });
396
+ }
397
+ parseNumber() {
398
+ const token = this.tokens.peek();
399
+ const start = token.position.start;
400
+ if (this.tokens.peekNext() && this.tokens.peekNext().type === "COLON") {
401
+ const startRow = this.tokens.consume().value;
402
+ this.tokens.consume();
403
+ let endRow = "";
404
+ if (this.tokens.match("DOLLAR")) {
405
+ endRow += this.tokens.consume().value;
406
+ }
407
+ if (this.tokens.match("NUMBER")) {
408
+ endRow += this.tokens.consume().value;
409
+ } else {
410
+ throw new ParseError("Expected row number after :", this.tokens.peek().position);
411
+ }
412
+ return this.parseRange(startRow, endRow, start, this.tokens.peek().position.start);
413
+ }
414
+ this.tokens.consume();
415
+ const value = parseFloat(token.value);
416
+ if (isNaN(value)) {
417
+ throw new ParseError(`Invalid number: ${token.value}`, token.position);
418
+ }
419
+ return createValueNode({
420
+ type: "number",
421
+ value
422
+ }, {
423
+ start: token.position.start,
424
+ end: token.position.end
425
+ });
426
+ }
427
+ parseString() {
428
+ const token = this.tokens.consume();
429
+ return createValueNode({
430
+ type: "string",
431
+ value: token.value
432
+ }, {
433
+ start: token.position.start,
434
+ end: token.position.end
435
+ });
436
+ }
437
+ parseBoolean() {
438
+ const token = this.tokens.consume();
439
+ const value = token.value.toUpperCase() === "TRUE";
440
+ return createValueNode({
441
+ type: "boolean",
442
+ value
443
+ }, {
444
+ start: token.position.start,
445
+ end: token.position.end
446
+ });
447
+ }
448
+ parseError() {
449
+ const token = this.tokens.consume();
450
+ const error = token.value;
451
+ return createErrorNode(error, `Error literal: ${error}`, {
452
+ start: token.position.start,
453
+ end: token.position.end
454
+ });
455
+ }
456
+ parseFunctionCall() {
457
+ const nameToken = this.tokens.consume();
458
+ const functionName = nameToken.value;
459
+ const start = nameToken.position.start;
460
+ if (SPECIAL_FUNCTIONS.has(functionName.toUpperCase()) && !this.tokens.match("LPAREN")) {
461
+ return createFunctionNode(functionName, [], {
462
+ start,
463
+ end: nameToken.position.end
464
+ });
465
+ }
466
+ if (!this.tokens.match("LPAREN")) {
467
+ throw new ParseError(`Expected '(' after function name ${functionName}`, this.tokens.peek().position);
468
+ }
469
+ this.tokens.consume();
470
+ const args = [];
471
+ if (this.tokens.match("RPAREN")) {
472
+ const rparenToken = this.tokens.consume();
473
+ const endPos = rparenToken.position.end;
474
+ const node = createFunctionNode(functionName, args, {
475
+ start,
476
+ end: endPos
477
+ });
478
+ return node;
479
+ }
480
+ while (true) {
481
+ args.push(this.parseExpression());
482
+ if (this.tokens.match("COMMA")) {
483
+ this.tokens.consume();
484
+ } else if (this.tokens.match("RPAREN")) {
485
+ const rparenToken = this.tokens.consume();
486
+ const end = rparenToken.position.end;
487
+ const node = createFunctionNode(functionName, args, {
488
+ start,
489
+ end
490
+ });
491
+ return node;
492
+ } else {
493
+ throw new ParseError(`Expected ',' or ')' in function arguments`, this.tokens.peek().position);
494
+ }
495
+ }
496
+ throw new ParseError("Unexpected end of function argument parsing", this.tokens.peek().position);
497
+ }
498
+ parseIdentifier() {
499
+ const start = this.tokens.peek().position.start;
500
+ const token = this.tokens.consume();
501
+ let value = token.value;
502
+ if (this.tokens.match("COLON")) {
503
+ const colonPos = this.tokens.getPosition();
504
+ const nextToken = this.tokens.peekAhead(1);
505
+ const tokenAfterNext = this.tokens.peekAhead(2);
506
+ if (nextToken?.type === "IDENTIFIER" && tokenAfterNext?.type === "EXCLAMATION") {
507
+ this.tokens.consume();
508
+ const endSheetToken = this.tokens.consume();
509
+ const endSheet = endSheetToken.value;
510
+ this.tokens.consume();
511
+ let startSheet = value;
512
+ if (startSheet.startsWith("'") && startSheet.endsWith("'")) {
513
+ startSheet = startSheet.slice(1, -1).replace(/''/g, "'");
514
+ }
515
+ let endSheetName = endSheet;
516
+ if (endSheetName.startsWith("'") && endSheetName.endsWith("'")) {
517
+ endSheetName = endSheetName.slice(1, -1).replace(/''/g, "'");
518
+ }
519
+ const ref = this.parseCellOrRangeAfterSheets();
520
+ return createThreeDRangeNode(startSheet, endSheetName, ref, {
521
+ start,
522
+ end: this.tokens.peek().position?.end ?? 0
523
+ });
524
+ }
525
+ }
526
+ if (this.tokens.match("EXCLAMATION")) {
527
+ this.tokens.consume();
528
+ let sheetName = value;
529
+ if (sheetName.startsWith("'") && sheetName.endsWith("'")) {
530
+ sheetName = sheetName.slice(1, -1).replace(/''/g, "'");
531
+ }
532
+ const cellRef = this.parseCellOrRangeWithSheet(sheetName, start);
533
+ return cellRef;
534
+ }
535
+ if (this.tokens.match("LBRACKET")) {
536
+ return this.parseTableReference(value, start);
537
+ }
538
+ if (this.tokens.match("DOLLAR") && this.isColumnIdentifier(value)) {
539
+ value += this.tokens.consume().value;
540
+ if (this.tokens.match("NUMBER")) {
541
+ value += this.tokens.consume().value;
542
+ } else {
543
+ throw new ParseError("Expected row number after $", this.tokens.peek().position);
544
+ }
545
+ } else if (this.tokens.match("NUMBER") && this.isColumnIdentifier(value)) {
546
+ value += this.tokens.consume().value;
547
+ }
548
+ if (this.tokens.match("COLON")) {
549
+ this.tokens.consume();
550
+ const endStart = this.tokens.peek().position.start;
551
+ const endRef = this.parseRangeEnd();
552
+ const endPos = this.tokens.peek().position.start;
553
+ return this.parseRange(value, endRef, start, endPos);
554
+ }
555
+ const parsedCellRef = this.parseCellReferenceString(value);
556
+ if (parsedCellRef) {
557
+ return parsedCellRef;
558
+ }
559
+ return createNamedExpressionNode(value, {
560
+ start,
561
+ end: token.position.end
562
+ });
563
+ }
564
+ isColumnIdentifier(str) {
565
+ return /^[A-Z]+$/i.test(str);
566
+ }
567
+ parseRangeEnd() {
568
+ let result = "";
569
+ if (this.tokens.match("INFINITY")) {
570
+ result += this.tokens.consume().value;
571
+ return result;
572
+ }
573
+ if (this.tokens.match("DOLLAR")) {
574
+ result += this.tokens.consume().value;
575
+ }
576
+ if (this.tokens.match("IDENTIFIER")) {
577
+ result += this.tokens.consume().value;
578
+ if (this.tokens.match("DOLLAR")) {
579
+ result += this.tokens.consume().value;
580
+ }
581
+ if (this.tokens.match("NUMBER")) {
582
+ result += this.tokens.consume().value;
583
+ }
584
+ } else if (this.tokens.match("NUMBER")) {
585
+ result += this.tokens.consume().value;
586
+ } else {
587
+ throw new ParseError("Expected cell reference, column, row, or INFINITY after :", this.tokens.peek().position);
588
+ }
589
+ return result;
590
+ }
591
+ parseParenthesizedExpression() {
592
+ const start = this.tokens.peek().position.start;
593
+ this.tokens.consume();
594
+ const expr = this.parseExpression();
595
+ if (!this.tokens.match("RPAREN")) {
596
+ throw new ParseError(`Expected ')'`, this.tokens.peek().position);
597
+ }
598
+ const end = this.tokens.peek().position.end;
599
+ this.tokens.consume();
600
+ if (expr.position) {
601
+ expr.position.start = start;
602
+ expr.position.end = end;
603
+ }
604
+ return expr;
605
+ }
606
+ parseArrayLiteral() {
607
+ const start = this.tokens.peek().position.start;
608
+ this.tokens.consume();
609
+ const rows = [];
610
+ let currentRow = [];
611
+ if (this.tokens.match("RBRACE")) {
612
+ this.tokens.consume();
613
+ return createArrayNode([[createEmptyNode()]], {
614
+ start,
615
+ end: this.tokens.peek().position.start
616
+ });
617
+ }
618
+ while (true) {
619
+ currentRow.push(this.parseExpression());
620
+ if (this.tokens.match("COMMA")) {
621
+ this.tokens.consume();
622
+ } else if (this.tokens.match("SEMICOLON")) {
623
+ this.tokens.consume();
624
+ rows.push(currentRow);
625
+ currentRow = [];
626
+ } else if (this.tokens.match("RBRACE")) {
627
+ this.tokens.consume();
628
+ rows.push(currentRow);
629
+ break;
630
+ } else {
631
+ throw new ParseError(`Expected ',', ';', or '}' in array literal`, this.tokens.peek().position);
632
+ }
633
+ }
634
+ if (rows.length > 0 && rows[0]) {
635
+ const rowLength = rows[0].length;
636
+ for (let i = 1;i < rows.length; i++) {
637
+ const row = rows[i];
638
+ if (row && row.length !== rowLength) {
639
+ throw new ParseError(`Inconsistent row lengths in array literal`, {
640
+ start,
641
+ end: this.tokens.peek().position.start
642
+ });
643
+ }
644
+ }
645
+ }
646
+ return createArrayNode(rows, {
647
+ start,
648
+ end: this.tokens.peek().position.start
649
+ });
650
+ }
651
+ parseCellReferenceString(value) {
652
+ const parsed = parseCellReference(value);
653
+ if (!parsed) {
654
+ return null;
655
+ }
656
+ const colNum = columnToIndex(parsed.col);
657
+ const rowNum = parseInt(parsed.row) - 1;
658
+ if (colNum < 0 || rowNum < 0) {
659
+ return null;
660
+ }
661
+ return createReferenceNode({
662
+ address: {
663
+ colIndex: colNum,
664
+ rowIndex: rowNum
665
+ },
666
+ isAbsolute: {
667
+ col: parsed.colAbsolute,
668
+ row: parsed.rowAbsolute
669
+ },
670
+ sheetName: parsed.sheet
671
+ });
672
+ }
673
+ parseTableReference(tableName, startPos) {
674
+ this.tokens.consume();
675
+ let selector;
676
+ let cols;
677
+ let isCurrentRow = false;
678
+ if (this.tokens.match("LBRACKET")) {
679
+ this.tokens.consume();
680
+ if (this.tokens.match("HASH")) {
681
+ this.tokens.consume();
682
+ if (!this.tokens.match("IDENTIFIER")) {
683
+ throw new ParseError("Expected selector name after #", this.tokens.peek().position);
684
+ }
685
+ const selectorName = this.tokens.consume().value;
686
+ selector = `#${selectorName}`;
687
+ if (!this.tokens.match("RBRACKET")) {
688
+ throw new ParseError("Expected ] after selector", this.tokens.peek().position);
689
+ }
690
+ this.tokens.consume();
691
+ if (this.tokens.match("COMMA")) {
692
+ this.tokens.consume();
693
+ if (!this.tokens.match("LBRACKET")) {
694
+ throw new ParseError("Expected [ after comma", this.tokens.peek().position);
695
+ }
696
+ this.tokens.consume();
697
+ if (!this.tokens.match("IDENTIFIER") && !this.tokens.match("FUNCTION") && !this.tokens.match("NUMBER") && !this.tokens.match("OPERATOR")) {
698
+ throw new ParseError("Expected column name", this.tokens.peek().position);
699
+ }
700
+ const colStart = this.parseColumnName();
701
+ if (this.tokens.match("COLON") && !this.tokens.peekAhead(1)?.type.match(/RBRACKET/)) {
702
+ this.tokens.consume();
703
+ if (!this.tokens.match("IDENTIFIER") && !this.tokens.match("FUNCTION") && !this.tokens.match("NUMBER") && !this.tokens.match("OPERATOR")) {
704
+ throw new ParseError("Expected end column name after :", this.tokens.peek().position);
705
+ }
706
+ const colEnd = this.parseColumnName();
707
+ cols = {
708
+ startCol: colStart,
709
+ endCol: colEnd
710
+ };
711
+ } else {
712
+ cols = {
713
+ startCol: colStart,
714
+ endCol: colStart
715
+ };
716
+ }
717
+ if (!this.tokens.match("RBRACKET")) {
718
+ throw new ParseError("Expected ] after column specification", this.tokens.peek().position);
719
+ }
720
+ this.tokens.consume();
721
+ if (this.tokens.match("COLON")) {
722
+ this.tokens.consume();
723
+ if (!this.tokens.match("LBRACKET")) {
724
+ throw new ParseError("Expected [ after : in column range", this.tokens.peek().position);
725
+ }
726
+ this.tokens.consume();
727
+ if (!this.tokens.match("IDENTIFIER") && !this.tokens.match("FUNCTION") && !this.tokens.match("NUMBER") && !this.tokens.match("OPERATOR")) {
728
+ throw new ParseError("Expected end column name", this.tokens.peek().position);
729
+ }
730
+ const colEnd = this.parseColumnName();
731
+ if (!this.tokens.match("RBRACKET")) {
732
+ throw new ParseError("Expected ] after end column name", this.tokens.peek().position);
733
+ }
734
+ this.tokens.consume();
735
+ cols = {
736
+ startCol: colStart,
737
+ endCol: colEnd
738
+ };
739
+ }
740
+ }
741
+ if (!this.tokens.match("RBRACKET")) {
742
+ throw new ParseError("Expected ] to close table reference", this.tokens.peek().position);
743
+ }
744
+ this.tokens.consume();
745
+ } else if (this.tokens.match("IDENTIFIER") || this.tokens.match("FUNCTION") || this.tokens.match("NUMBER") || this.tokens.match("OPERATOR")) {
746
+ const colStart = this.parseColumnName();
747
+ if (!this.tokens.match("RBRACKET")) {
748
+ throw new ParseError("Expected ] after column name", this.tokens.peek().position);
749
+ }
750
+ this.tokens.consume();
751
+ if (this.tokens.match("COLON")) {
752
+ this.tokens.consume();
753
+ if (!this.tokens.match("LBRACKET")) {
754
+ throw new ParseError("Expected [ before second column name", this.tokens.peek().position);
755
+ }
756
+ this.tokens.consume();
757
+ const colEnd = this.parseColumnName();
758
+ if (!this.tokens.match("RBRACKET")) {
759
+ throw new ParseError("Expected ] after second column name", this.tokens.peek().position);
760
+ }
761
+ this.tokens.consume();
762
+ if (!this.tokens.match("RBRACKET")) {
763
+ throw new ParseError("Expected ] to close table reference", this.tokens.peek().position);
764
+ }
765
+ this.tokens.consume();
766
+ cols = {
767
+ startCol: colStart,
768
+ endCol: colEnd
769
+ };
770
+ } else {
771
+ if (!this.tokens.match("RBRACKET")) {
772
+ throw new ParseError("Expected ] to close table reference", this.tokens.peek().position);
773
+ }
774
+ this.tokens.consume();
775
+ cols = {
776
+ startCol: colStart,
777
+ endCol: colStart
778
+ };
779
+ }
780
+ }
781
+ } else if (this.tokens.match("AT")) {
782
+ this.tokens.consume();
783
+ isCurrentRow = true;
784
+ if (this.tokens.match("LBRACKET")) {
785
+ this.tokens.consume();
786
+ const colStart = this.parseColumnName();
787
+ if (!this.tokens.match("RBRACKET")) {
788
+ throw new ParseError("Expected ] after column name", this.tokens.peek().position);
789
+ }
790
+ this.tokens.consume();
791
+ if (this.tokens.match("COLON")) {
792
+ this.tokens.consume();
793
+ if (!this.tokens.match("LBRACKET")) {
794
+ throw new ParseError("Expected [ before second column name", this.tokens.peek().position);
795
+ }
796
+ this.tokens.consume();
797
+ const colEnd = this.parseColumnName();
798
+ if (!this.tokens.match("RBRACKET")) {
799
+ throw new ParseError("Expected ] after second column name", this.tokens.peek().position);
800
+ }
801
+ this.tokens.consume();
802
+ cols = {
803
+ startCol: colStart,
804
+ endCol: colEnd
805
+ };
806
+ } else {
807
+ cols = {
808
+ startCol: colStart,
809
+ endCol: colStart
810
+ };
811
+ }
812
+ if (!this.tokens.match("RBRACKET")) {
813
+ throw new ParseError("Expected ] to close table reference", this.tokens.peek().position);
814
+ }
815
+ this.tokens.consume();
816
+ } else {
817
+ const colStart = this.parseColumnName();
818
+ if (this.tokens.match("COLON")) {
819
+ this.tokens.consume();
820
+ const colEnd = this.parseColumnName();
821
+ cols = {
822
+ startCol: colStart,
823
+ endCol: colEnd
824
+ };
825
+ } else {
826
+ cols = {
827
+ startCol: colStart,
828
+ endCol: colStart
829
+ };
830
+ }
831
+ if (!this.tokens.match("RBRACKET")) {
832
+ throw new ParseError("Expected ] after column reference", this.tokens.peek().position);
833
+ }
834
+ this.tokens.consume();
835
+ }
836
+ } else if (this.tokens.match("IDENTIFIER") || this.tokens.match("FUNCTION") || this.tokens.match("NUMBER") || this.tokens.match("OPERATOR")) {
837
+ const colStart = this.parseColumnName();
838
+ if (this.tokens.match("COLON")) {
839
+ this.tokens.consume();
840
+ const colEnd = this.parseColumnName();
841
+ cols = {
842
+ startCol: colStart,
843
+ endCol: colEnd
844
+ };
845
+ } else {
846
+ cols = {
847
+ startCol: colStart,
848
+ endCol: colStart
849
+ };
850
+ }
851
+ if (!this.tokens.match("RBRACKET")) {
852
+ throw new ParseError("Expected ] after column name", this.tokens.peek().position);
853
+ }
854
+ this.tokens.consume();
855
+ } else if (this.tokens.match("HASH")) {
856
+ this.tokens.consume();
857
+ if (!this.tokens.match("IDENTIFIER")) {
858
+ throw new ParseError("Expected selector name after #", this.tokens.peek().position);
859
+ }
860
+ const selectorName = this.tokens.consume().value;
861
+ selector = `#${selectorName}`;
862
+ if (!this.tokens.match("RBRACKET")) {
863
+ throw new ParseError("Expected ] after selector", this.tokens.peek().position);
864
+ }
865
+ this.tokens.consume();
866
+ } else {
867
+ throw new ParseError("Expected column name or selector in table reference", this.tokens.peek().position);
868
+ }
869
+ return createStructuredReferenceNode({
870
+ tableName,
871
+ cols,
872
+ selector,
873
+ isCurrentRow,
874
+ position: {
875
+ start: startPos,
876
+ end: this.tokens.peek().position?.end ?? 0
877
+ }
878
+ });
879
+ }
880
+ parseTableReferenceWithSheet(tableName, sheetName, startPos) {
881
+ this.tokens.consume();
882
+ let selector;
883
+ let cols;
884
+ let isCurrentRow = false;
885
+ if (this.tokens.match("LBRACKET")) {
886
+ this.tokens.consume();
887
+ if (this.tokens.match("HASH")) {
888
+ this.tokens.consume();
889
+ if (!this.tokens.match("IDENTIFIER")) {
890
+ throw new ParseError("Expected selector name after #", this.tokens.peek().position);
891
+ }
892
+ const selectorName = this.tokens.consume().value;
893
+ selector = `#${selectorName}`;
894
+ if (!this.tokens.match("RBRACKET")) {
895
+ throw new ParseError("Expected ] after selector", this.tokens.peek().position);
896
+ }
897
+ this.tokens.consume();
898
+ if (this.tokens.match("COMMA")) {
899
+ this.tokens.consume();
900
+ if (!this.tokens.match("LBRACKET")) {
901
+ throw new ParseError("Expected [ after comma", this.tokens.peek().position);
902
+ }
903
+ this.tokens.consume();
904
+ if (!this.tokens.match("IDENTIFIER") && !this.tokens.match("FUNCTION") && !this.tokens.match("NUMBER") && !this.tokens.match("OPERATOR")) {
905
+ throw new ParseError("Expected column name", this.tokens.peek().position);
906
+ }
907
+ const colStart = this.parseColumnName();
908
+ if (this.tokens.match("COLON") && !this.tokens.peekAhead(1)?.type.match(/RBRACKET/)) {
909
+ this.tokens.consume();
910
+ if (!this.tokens.match("IDENTIFIER") && !this.tokens.match("FUNCTION") && !this.tokens.match("NUMBER") && !this.tokens.match("OPERATOR")) {
911
+ throw new ParseError("Expected end column name after :", this.tokens.peek().position);
912
+ }
913
+ const colEnd = this.parseColumnName();
914
+ cols = {
915
+ startCol: colStart,
916
+ endCol: colEnd
917
+ };
918
+ } else {
919
+ cols = {
920
+ startCol: colStart,
921
+ endCol: colStart
922
+ };
923
+ }
924
+ if (!this.tokens.match("RBRACKET")) {
925
+ throw new ParseError("Expected ] after column specification", this.tokens.peek().position);
926
+ }
927
+ this.tokens.consume();
928
+ if (this.tokens.match("COLON")) {
929
+ this.tokens.consume();
930
+ if (!this.tokens.match("LBRACKET")) {
931
+ throw new ParseError("Expected [ after : in column range", this.tokens.peek().position);
932
+ }
933
+ this.tokens.consume();
934
+ if (!this.tokens.match("IDENTIFIER") && !this.tokens.match("FUNCTION") && !this.tokens.match("NUMBER") && !this.tokens.match("OPERATOR")) {
935
+ throw new ParseError("Expected end column name", this.tokens.peek().position);
936
+ }
937
+ const colEnd = this.parseColumnName();
938
+ if (!this.tokens.match("RBRACKET")) {
939
+ throw new ParseError("Expected ] after end column name", this.tokens.peek().position);
940
+ }
941
+ this.tokens.consume();
942
+ cols = {
943
+ startCol: colStart,
944
+ endCol: colEnd
945
+ };
946
+ }
947
+ }
948
+ if (!this.tokens.match("RBRACKET")) {
949
+ throw new ParseError("Expected ] to close table reference", this.tokens.peek().position);
950
+ }
951
+ this.tokens.consume();
952
+ } else if (this.tokens.match("IDENTIFIER") || this.tokens.match("FUNCTION") || this.tokens.match("NUMBER") || this.tokens.match("OPERATOR")) {
953
+ const colStart = this.parseColumnName();
954
+ if (!this.tokens.match("RBRACKET")) {
955
+ throw new ParseError("Expected ] after column name", this.tokens.peek().position);
956
+ }
957
+ this.tokens.consume();
958
+ if (this.tokens.match("COLON")) {
959
+ this.tokens.consume();
960
+ if (!this.tokens.match("LBRACKET")) {
961
+ throw new ParseError("Expected [ before second column name", this.tokens.peek().position);
962
+ }
963
+ this.tokens.consume();
964
+ const colEnd = this.parseColumnName();
965
+ if (!this.tokens.match("RBRACKET")) {
966
+ throw new ParseError("Expected ] after second column name", this.tokens.peek().position);
967
+ }
968
+ this.tokens.consume();
969
+ if (!this.tokens.match("RBRACKET")) {
970
+ throw new ParseError("Expected ] to close table reference", this.tokens.peek().position);
971
+ }
972
+ this.tokens.consume();
973
+ cols = {
974
+ startCol: colStart,
975
+ endCol: colEnd
976
+ };
977
+ } else {
978
+ if (!this.tokens.match("RBRACKET")) {
979
+ throw new ParseError("Expected ] to close table reference", this.tokens.peek().position);
980
+ }
981
+ this.tokens.consume();
982
+ cols = {
983
+ startCol: colStart,
984
+ endCol: colStart
985
+ };
986
+ }
987
+ }
988
+ } else if (this.tokens.match("AT")) {
989
+ this.tokens.consume();
990
+ isCurrentRow = true;
991
+ if (this.tokens.match("LBRACKET")) {
992
+ this.tokens.consume();
993
+ const colStart = this.parseColumnName();
994
+ if (!this.tokens.match("RBRACKET")) {
995
+ throw new ParseError("Expected ] after column name", this.tokens.peek().position);
996
+ }
997
+ this.tokens.consume();
998
+ if (this.tokens.match("COLON")) {
999
+ this.tokens.consume();
1000
+ if (!this.tokens.match("LBRACKET")) {
1001
+ throw new ParseError("Expected [ before second column name", this.tokens.peek().position);
1002
+ }
1003
+ this.tokens.consume();
1004
+ const colEnd = this.parseColumnName();
1005
+ if (!this.tokens.match("RBRACKET")) {
1006
+ throw new ParseError("Expected ] after second column name", this.tokens.peek().position);
1007
+ }
1008
+ this.tokens.consume();
1009
+ cols = {
1010
+ startCol: colStart,
1011
+ endCol: colEnd
1012
+ };
1013
+ } else {
1014
+ cols = {
1015
+ startCol: colStart,
1016
+ endCol: colStart
1017
+ };
1018
+ }
1019
+ if (!this.tokens.match("RBRACKET")) {
1020
+ throw new ParseError("Expected ] to close table reference", this.tokens.peek().position);
1021
+ }
1022
+ this.tokens.consume();
1023
+ } else {
1024
+ const colStart = this.parseColumnName();
1025
+ if (this.tokens.match("COLON")) {
1026
+ this.tokens.consume();
1027
+ const colEnd = this.parseColumnName();
1028
+ cols = {
1029
+ startCol: colStart,
1030
+ endCol: colEnd
1031
+ };
1032
+ } else {
1033
+ cols = {
1034
+ startCol: colStart,
1035
+ endCol: colStart
1036
+ };
1037
+ }
1038
+ if (!this.tokens.match("RBRACKET")) {
1039
+ throw new ParseError("Expected ] after column reference", this.tokens.peek().position);
1040
+ }
1041
+ this.tokens.consume();
1042
+ }
1043
+ } else if (this.tokens.match("IDENTIFIER") || this.tokens.match("FUNCTION") || this.tokens.match("NUMBER") || this.tokens.match("OPERATOR")) {
1044
+ const colStart = this.parseColumnName();
1045
+ if (this.tokens.match("COLON")) {
1046
+ this.tokens.consume();
1047
+ const colEnd = this.parseColumnName();
1048
+ cols = {
1049
+ startCol: colStart,
1050
+ endCol: colEnd
1051
+ };
1052
+ } else {
1053
+ cols = {
1054
+ startCol: colStart,
1055
+ endCol: colStart
1056
+ };
1057
+ }
1058
+ if (!this.tokens.match("RBRACKET")) {
1059
+ throw new ParseError("Expected ] after column name", this.tokens.peek().position);
1060
+ }
1061
+ this.tokens.consume();
1062
+ } else if (this.tokens.match("HASH")) {
1063
+ this.tokens.consume();
1064
+ if (!this.tokens.match("IDENTIFIER")) {
1065
+ throw new ParseError("Expected selector name after #", this.tokens.peek().position);
1066
+ }
1067
+ const selectorName = this.tokens.consume().value;
1068
+ selector = `#${selectorName}`;
1069
+ if (!this.tokens.match("RBRACKET")) {
1070
+ throw new ParseError("Expected ] after selector", this.tokens.peek().position);
1071
+ }
1072
+ this.tokens.consume();
1073
+ } else {
1074
+ throw new ParseError("Expected column name or selector in table reference", this.tokens.peek().position);
1075
+ }
1076
+ return createStructuredReferenceNode({
1077
+ tableName,
1078
+ sheetName,
1079
+ cols,
1080
+ selector,
1081
+ isCurrentRow,
1082
+ position: {
1083
+ start: startPos,
1084
+ end: this.tokens.peek().position?.end ?? 0
1085
+ }
1086
+ });
1087
+ }
1088
+ parseCellOrRangeAfterSheets() {
1089
+ const start = this.tokens.peek().position?.start ?? 0;
1090
+ if (this.tokens.match("IDENTIFIER")) {
1091
+ const firstIdent = this.tokens.consume().value;
1092
+ const cellRef = this.parseCellReferenceString(firstIdent);
1093
+ if (cellRef) {
1094
+ if (this.tokens.match("COLON")) {
1095
+ this.tokens.consume();
1096
+ const endRef = this.parseRangeEnd();
1097
+ const endPos = this.tokens.peek().position?.end ?? 0;
1098
+ const parsed = this.parseRange(firstIdent, endRef, start, endPos);
1099
+ if (parsed.type === "range") {
1100
+ parsed.sheetName = undefined;
1101
+ }
1102
+ return parsed;
1103
+ }
1104
+ if (cellRef.type === "reference") {
1105
+ cellRef.sheetName = undefined;
1106
+ }
1107
+ return cellRef;
1108
+ }
1109
+ }
1110
+ if (this.tokens.match("DOLLAR")) {
1111
+ const dollarStart = this.tokens.getPosition();
1112
+ this.tokens.consume();
1113
+ let ref = "$";
1114
+ if (this.tokens.match("IDENTIFIER")) {
1115
+ const col = this.tokens.consume().value;
1116
+ if (this.isColumnIdentifier(col)) {
1117
+ ref += col;
1118
+ }
1119
+ }
1120
+ if (this.tokens.match("DOLLAR")) {
1121
+ ref += this.tokens.consume().value;
1122
+ }
1123
+ if (this.tokens.match("NUMBER")) {
1124
+ ref += this.tokens.consume().value;
1125
+ }
1126
+ if (this.tokens.match("COLON")) {
1127
+ this.tokens.consume();
1128
+ const endRef = this.parseRangeEnd();
1129
+ const endPos = this.tokens.peek().position?.end ?? 0;
1130
+ const parsed = this.parseRange(ref, endRef, start, endPos);
1131
+ if (parsed.type === "range") {
1132
+ parsed.sheetName = undefined;
1133
+ }
1134
+ return parsed;
1135
+ }
1136
+ const cellRef = this.parseCellReferenceString(ref);
1137
+ if (!cellRef) {
1138
+ throw new ParseError(`Invalid cell reference: ${ref}`, this.tokens.peek().position);
1139
+ }
1140
+ if (cellRef.type === "reference") {
1141
+ cellRef.sheetName = undefined;
1142
+ }
1143
+ return cellRef;
1144
+ }
1145
+ throw new ParseError("Expected cell or range reference after sheet range", this.tokens.peek().position);
1146
+ }
1147
+ parseCurrentRowReference() {
1148
+ const start = this.tokens.getPosition();
1149
+ if (this.tokens.match("LBRACKET")) {
1150
+ this.tokens.consume();
1151
+ if (!this.tokens.match("AT")) {
1152
+ throw new ParseError("Expected @ after [", this.tokens.peek().position);
1153
+ }
1154
+ this.tokens.consume();
1155
+ let columnName2;
1156
+ if (this.tokens.match("LBRACKET")) {
1157
+ this.tokens.consume();
1158
+ const colStart = this.parseColumnName();
1159
+ if (!this.tokens.match("RBRACKET")) {
1160
+ throw new ParseError("Expected ] to close column name", this.tokens.peek().position);
1161
+ }
1162
+ this.tokens.consume();
1163
+ if (this.tokens.match("COLON")) {
1164
+ this.tokens.consume();
1165
+ if (!this.tokens.match("LBRACKET")) {
1166
+ throw new ParseError("Expected [ before second column name", this.tokens.peek().position);
1167
+ }
1168
+ this.tokens.consume();
1169
+ const colEnd = this.parseColumnName();
1170
+ if (!this.tokens.match("RBRACKET")) {
1171
+ throw new ParseError("Expected ] after second column name", this.tokens.peek().position);
1172
+ }
1173
+ this.tokens.consume();
1174
+ if (!this.tokens.match("RBRACKET")) {
1175
+ throw new ParseError("Expected ] to close column range", this.tokens.peek().position);
1176
+ }
1177
+ this.tokens.consume();
1178
+ return createStructuredReferenceNode({
1179
+ tableName: undefined,
1180
+ cols: {
1181
+ startCol: colStart,
1182
+ endCol: colEnd
1183
+ },
1184
+ isCurrentRow: true,
1185
+ position: {
1186
+ start: this.tokens.getTokens()[start]?.position?.start ?? 0,
1187
+ end: this.tokens.peek().position?.end ?? 0
1188
+ }
1189
+ });
1190
+ } else {
1191
+ if (!this.tokens.match("RBRACKET")) {
1192
+ throw new ParseError("Expected ] after column reference", this.tokens.peek().position);
1193
+ }
1194
+ this.tokens.consume();
1195
+ return createStructuredReferenceNode({
1196
+ tableName: undefined,
1197
+ cols: {
1198
+ startCol: colStart,
1199
+ endCol: colStart
1200
+ },
1201
+ isCurrentRow: true,
1202
+ position: {
1203
+ start: this.tokens.getTokens()[start]?.position?.start ?? 0,
1204
+ end: this.tokens.peek().position?.end ?? 0
1205
+ }
1206
+ });
1207
+ }
1208
+ } else {
1209
+ columnName2 = this.parseColumnName();
1210
+ }
1211
+ if (!this.tokens.match("RBRACKET")) {
1212
+ throw new ParseError("Expected ] after column reference", this.tokens.peek().position);
1213
+ }
1214
+ this.tokens.consume();
1215
+ return createStructuredReferenceNode({
1216
+ tableName: undefined,
1217
+ cols: {
1218
+ startCol: columnName2,
1219
+ endCol: columnName2
1220
+ },
1221
+ isCurrentRow: true,
1222
+ position: {
1223
+ start: this.tokens.getTokens()[start]?.position?.start ?? 0,
1224
+ end: this.tokens.peek().position?.end ?? 0
1225
+ }
1226
+ });
1227
+ }
1228
+ this.tokens.consume();
1229
+ const columnName = this.parseColumnName();
1230
+ return createStructuredReferenceNode({
1231
+ tableName: undefined,
1232
+ cols: {
1233
+ startCol: columnName,
1234
+ endCol: columnName
1235
+ },
1236
+ isCurrentRow: true,
1237
+ position: {
1238
+ start: this.tokens.getTokens()[start]?.position?.start ?? 0,
1239
+ end: this.tokens.peek().position?.end ?? 0
1240
+ }
1241
+ });
1242
+ }
1243
+ parseTableSelector() {
1244
+ const hashToken = this.tokens.consume();
1245
+ if (!this.tokens.match("IDENTIFIER")) {
1246
+ throw new ParseError("Expected selector name after #", this.tokens.peek().position);
1247
+ }
1248
+ const selectorName = this.tokens.consume().value;
1249
+ const selector = `#${selectorName}`;
1250
+ if (!["#All", "#Data", "#Headers"].includes(selector.toUpperCase())) {
1251
+ throw new ParseError(`Invalid table selector: ${selector}`, hashToken.position);
1252
+ }
1253
+ throw new ParseError("Table selector must be part of a table reference", hashToken.position);
1254
+ }
1255
+ parseRangeWithWorkbook(startRef, endRef, workbookName, startPos, endPos) {
1256
+ const rangeNode = this.parseRange(startRef, endRef, startPos, endPos);
1257
+ rangeNode.workbookName = workbookName;
1258
+ return rangeNode;
1259
+ }
1260
+ parseTableReferenceWithWorkbookAndSheet(tableName, workbookName, sheetName, startPos) {
1261
+ const tableRef = this.parseTableReferenceWithSheet(tableName, sheetName, startPos);
1262
+ if (tableRef.type === "structured-reference") {
1263
+ tableRef.workbookName = workbookName;
1264
+ }
1265
+ return tableRef;
1266
+ }
1267
+ parseRange(startRef, endRef, startPos, endPos) {
1268
+ let fullRange = `${startRef}:${endRef}`;
1269
+ let sheetName;
1270
+ const sheetMatch = startRef.match(/^(?:([A-Za-z_][A-Za-z0-9_]*)|'([^']+)')!/);
1271
+ if (sheetMatch) {
1272
+ sheetName = sheetMatch[1] || sheetMatch[2];
1273
+ const infiniteTest = parseInfiniteRange(fullRange);
1274
+ const openEndedTest = parseOpenEndedRange(fullRange);
1275
+ if (infiniteTest || openEndedTest) {} else {
1276
+ const endSheetMatch = endRef.match(/^(?:([A-Za-z_][A-Za-z0-9_]*)|'([^']+)')!/);
1277
+ if (!endSheetMatch && sheetName) {
1278
+ const quotedSheetName = sheetName.includes(" ") ? `'${sheetName}'` : sheetName;
1279
+ endRef = `${quotedSheetName}!${endRef}`;
1280
+ fullRange = `${startRef}:${endRef}`;
1281
+ }
1282
+ }
1283
+ }
1284
+ const infiniteParsed = parseInfiniteRange(fullRange);
1285
+ if (infiniteParsed) {
1286
+ sheetName = sheetName ?? infiniteParsed.sheet;
1287
+ if (infiniteParsed.type === "column") {
1288
+ const startCol2 = columnToIndex(infiniteParsed.start);
1289
+ const endCol2 = columnToIndex(infiniteParsed.end);
1290
+ if (startCol2 < 0 || endCol2 < 0) {
1291
+ throw new ParseError(`Invalid column range: ${startRef}:${endRef}`, {
1292
+ start: startPos,
1293
+ end: endPos
1294
+ });
1295
+ }
1296
+ const range2 = {
1297
+ start: {
1298
+ col: Math.min(startCol2, endCol2),
1299
+ row: 0
1300
+ },
1301
+ end: {
1302
+ col: {
1303
+ type: "number",
1304
+ value: Math.max(startCol2, endCol2)
1305
+ },
1306
+ row: {
1307
+ type: "infinity",
1308
+ sign: "positive"
1309
+ }
1310
+ }
1311
+ };
1312
+ return createRangeNode({
1313
+ sheetName,
1314
+ range: range2,
1315
+ isAbsolute: {
1316
+ start: {
1317
+ col: infiniteParsed.startAbsolute,
1318
+ row: false
1319
+ },
1320
+ end: {
1321
+ col: infiniteParsed.endAbsolute,
1322
+ row: false
1323
+ }
1324
+ },
1325
+ position: {
1326
+ start: startPos,
1327
+ end: endPos
1328
+ }
1329
+ });
1330
+ } else {
1331
+ const startRow2 = parseInt(infiniteParsed.start) - 1;
1332
+ const endRow2 = parseInt(infiniteParsed.end) - 1;
1333
+ if (startRow2 < 0 || endRow2 < 0) {
1334
+ throw new ParseError(`Invalid row range: ${startRef}:${endRef}`, {
1335
+ start: startPos,
1336
+ end: endPos
1337
+ });
1338
+ }
1339
+ const range2 = {
1340
+ start: {
1341
+ col: 0,
1342
+ row: Math.min(startRow2, endRow2)
1343
+ },
1344
+ end: {
1345
+ col: {
1346
+ type: "infinity",
1347
+ sign: "positive"
1348
+ },
1349
+ row: {
1350
+ type: "number",
1351
+ value: Math.max(startRow2, endRow2)
1352
+ }
1353
+ }
1354
+ };
1355
+ return createRangeNode({
1356
+ sheetName,
1357
+ range: range2,
1358
+ isAbsolute: {
1359
+ start: {
1360
+ col: false,
1361
+ row: infiniteParsed.startAbsolute
1362
+ },
1363
+ end: {
1364
+ col: false,
1365
+ row: infiniteParsed.endAbsolute
1366
+ }
1367
+ },
1368
+ position: {
1369
+ start: startPos,
1370
+ end: endPos
1371
+ }
1372
+ });
1373
+ }
1374
+ }
1375
+ const openEndedParsed = parseOpenEndedRange(fullRange);
1376
+ if (openEndedParsed) {
1377
+ sheetName = sheetName ?? openEndedParsed.sheet;
1378
+ const startCol2 = columnToIndex(openEndedParsed.startCol);
1379
+ const startRow2 = parseInt(openEndedParsed.startRow) - 1;
1380
+ if (startCol2 < 0 || startRow2 < 0) {
1381
+ throw new ParseError(`Invalid range reference: ${startRef}:${endRef}`, {
1382
+ start: startPos,
1383
+ end: endPos
1384
+ });
1385
+ }
1386
+ if (openEndedParsed.type === "infinity") {
1387
+ const range2 = {
1388
+ start: {
1389
+ col: startCol2,
1390
+ row: startRow2
1391
+ },
1392
+ end: {
1393
+ col: {
1394
+ type: "infinity",
1395
+ sign: "positive"
1396
+ },
1397
+ row: {
1398
+ type: "infinity",
1399
+ sign: "positive"
1400
+ }
1401
+ }
1402
+ };
1403
+ return createRangeNode({
1404
+ sheetName,
1405
+ range: range2,
1406
+ isAbsolute: {
1407
+ start: {
1408
+ col: openEndedParsed.startColAbsolute,
1409
+ row: openEndedParsed.startRowAbsolute
1410
+ },
1411
+ end: {
1412
+ col: false,
1413
+ row: false
1414
+ }
1415
+ },
1416
+ position: {
1417
+ start: startPos,
1418
+ end: endPos
1419
+ }
1420
+ });
1421
+ } else if (openEndedParsed.type === "column-bounded") {
1422
+ const endCol2 = columnToIndex(openEndedParsed.endCol);
1423
+ if (endCol2 < 0) {
1424
+ throw new ParseError(`Invalid column range: ${startRef}:${endRef}`, {
1425
+ start: startPos,
1426
+ end: endPos
1427
+ });
1428
+ }
1429
+ const range2 = {
1430
+ start: {
1431
+ col: Math.min(startCol2, endCol2),
1432
+ row: startRow2
1433
+ },
1434
+ end: {
1435
+ col: {
1436
+ type: "number",
1437
+ value: Math.max(startCol2, endCol2)
1438
+ },
1439
+ row: {
1440
+ type: "infinity",
1441
+ sign: "positive"
1442
+ }
1443
+ }
1444
+ };
1445
+ return createRangeNode({
1446
+ sheetName,
1447
+ range: range2,
1448
+ isAbsolute: {
1449
+ start: {
1450
+ col: openEndedParsed.startColAbsolute,
1451
+ row: openEndedParsed.startRowAbsolute
1452
+ },
1453
+ end: {
1454
+ col: openEndedParsed.endColAbsolute,
1455
+ row: false
1456
+ }
1457
+ },
1458
+ position: {
1459
+ start: startPos,
1460
+ end: endPos
1461
+ }
1462
+ });
1463
+ } else if (openEndedParsed.type === "row-bounded") {
1464
+ const endRow2 = parseInt(openEndedParsed.endRow) - 1;
1465
+ if (endRow2 < 0) {
1466
+ throw new ParseError(`Invalid row range: ${startRef}:${endRef}`, {
1467
+ start: startPos,
1468
+ end: endPos
1469
+ });
1470
+ }
1471
+ const range2 = {
1472
+ start: {
1473
+ col: startCol2,
1474
+ row: Math.min(startRow2, endRow2)
1475
+ },
1476
+ end: {
1477
+ col: {
1478
+ type: "infinity",
1479
+ sign: "positive"
1480
+ },
1481
+ row: {
1482
+ type: "number",
1483
+ value: Math.max(startRow2, endRow2)
1484
+ }
1485
+ }
1486
+ };
1487
+ return createRangeNode({
1488
+ sheetName,
1489
+ range: range2,
1490
+ isAbsolute: {
1491
+ start: {
1492
+ col: openEndedParsed.startColAbsolute,
1493
+ row: openEndedParsed.startRowAbsolute
1494
+ },
1495
+ end: {
1496
+ col: false,
1497
+ row: openEndedParsed.endRowAbsolute
1498
+ }
1499
+ },
1500
+ position: {
1501
+ start: startPos,
1502
+ end: endPos
1503
+ }
1504
+ });
1505
+ }
1506
+ }
1507
+ const startParsed = parseCellReference(startRef);
1508
+ const endParsed = parseCellReference(endRef);
1509
+ if (!startParsed || !endParsed) {
1510
+ throw new ParseError(`Invalid range reference: ${startRef}:${endRef}`, {
1511
+ start: startPos,
1512
+ end: endPos
1513
+ });
1514
+ }
1515
+ const startSheet = startParsed.sheet;
1516
+ const endSheet = endParsed.sheet;
1517
+ if (startSheet !== endSheet) {
1518
+ throw new ParseError(`Range references must be on the same sheet`, {
1519
+ start: startPos,
1520
+ end: endPos
1521
+ });
1522
+ }
1523
+ sheetName = sheetName ?? startSheet;
1524
+ const startCol = columnToIndex(startParsed.col);
1525
+ const startRow = parseInt(startParsed.row) - 1;
1526
+ const endCol = columnToIndex(endParsed.col);
1527
+ const endRow = parseInt(endParsed.row) - 1;
1528
+ if (startCol < 0 || startRow < 0 || endCol < 0 || endRow < 0) {
1529
+ throw new ParseError(`Invalid range reference: ${startRef}:${endRef}`, {
1530
+ start: startPos,
1531
+ end: endPos
1532
+ });
1533
+ }
1534
+ const range = {
1535
+ start: {
1536
+ col: Math.min(startCol, endCol),
1537
+ row: Math.min(startRow, endRow)
1538
+ },
1539
+ end: {
1540
+ col: {
1541
+ type: "number",
1542
+ value: Math.max(startCol, endCol)
1543
+ },
1544
+ row: {
1545
+ type: "number",
1546
+ value: Math.max(startRow, endRow)
1547
+ }
1548
+ }
1549
+ };
1550
+ return createRangeNode({
1551
+ sheetName,
1552
+ range,
1553
+ isAbsolute: {
1554
+ start: {
1555
+ col: startParsed.colAbsolute,
1556
+ row: startParsed.rowAbsolute
1557
+ },
1558
+ end: {
1559
+ col: endParsed.colAbsolute,
1560
+ row: endParsed.rowAbsolute
1561
+ }
1562
+ },
1563
+ position: {
1564
+ start: startPos,
1565
+ end: endPos
1566
+ }
1567
+ });
1568
+ }
1569
+ parseCellOrRangeWithWorkbookAndSheet(workbookName, sheetName, startPos) {
1570
+ let ref = sheetName.includes(" ") ? `'${sheetName}'!` : sheetName + "!";
1571
+ if (this.tokens.match("DOLLAR")) {
1572
+ ref += this.tokens.consume().value;
1573
+ }
1574
+ if (this.tokens.match("IDENTIFIER")) {
1575
+ const identifier2 = this.tokens.consume();
1576
+ ref += identifier2.value;
1577
+ if (this.tokens.match("LBRACKET")) {
1578
+ return this.parseTableReferenceWithWorkbookAndSheet(identifier2.value, workbookName, sheetName, startPos);
1579
+ }
1580
+ if (this.tokens.match("COLON")) {
1581
+ this.tokens.consume();
1582
+ const endRef = this.parseRangeEnd();
1583
+ return this.parseRangeWithWorkbook(ref, endRef, workbookName, startPos, this.tokens.peek().position.start);
1584
+ }
1585
+ if (this.tokens.match("DOLLAR")) {
1586
+ ref += this.tokens.consume().value;
1587
+ }
1588
+ if (this.tokens.match("NUMBER")) {
1589
+ ref += this.tokens.consume().value;
1590
+ }
1591
+ } else if (this.tokens.match("NUMBER")) {
1592
+ const number = this.tokens.consume();
1593
+ ref += number.value;
1594
+ if (this.tokens.match("COLON")) {
1595
+ this.tokens.consume();
1596
+ const endRef = this.parseRangeEnd();
1597
+ return this.parseRangeWithWorkbook(ref, endRef, workbookName, startPos, this.tokens.peek().position.start);
1598
+ }
1599
+ } else {
1600
+ throw new ParseError(`Expected cell reference after [${workbookName}]${sheetName}!`, this.tokens.peek().position);
1601
+ }
1602
+ if (this.tokens.match("COLON")) {
1603
+ this.tokens.consume();
1604
+ const endRef = this.parseRangeEnd();
1605
+ return this.parseRangeWithWorkbook(ref, endRef, workbookName, startPos, this.tokens.peek().position.start);
1606
+ }
1607
+ const cellRef = this.parseCellReferenceString(ref);
1608
+ if (cellRef) {
1609
+ cellRef.workbookName = workbookName;
1610
+ return cellRef;
1611
+ }
1612
+ const sheetPrefix = sheetName.includes(" ") ? `'${sheetName}'!` : `${sheetName}!`;
1613
+ const identifier = ref.substring(sheetPrefix.length);
1614
+ if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(identifier)) {
1615
+ return createNamedExpressionNode(identifier, {
1616
+ start: startPos,
1617
+ end: this.tokens.peek().position.start
1618
+ }, sheetName, workbookName);
1619
+ }
1620
+ throw new ParseError(`Invalid cell reference: ${ref}`, {
1621
+ start: startPos,
1622
+ end: this.tokens.peek().position.start
1623
+ });
1624
+ }
1625
+ parseCellOrRangeWithSheet(sheetName, startPos) {
1626
+ let ref = sheetName.includes(" ") ? `'${sheetName}'!` : sheetName + "!";
1627
+ if (this.tokens.match("DOLLAR")) {
1628
+ ref += this.tokens.consume().value;
1629
+ }
1630
+ if (this.tokens.match("IDENTIFIER")) {
1631
+ const identifier = this.tokens.consume();
1632
+ ref += identifier.value;
1633
+ if (this.tokens.match("LBRACKET")) {
1634
+ return this.parseTableReferenceWithSheet(identifier.value, sheetName, startPos);
1635
+ }
1636
+ if (this.tokens.match("COLON")) {
1637
+ this.tokens.consume();
1638
+ const endRef = this.parseRangeEnd();
1639
+ return this.parseRange(ref, endRef, startPos, this.tokens.peek().position.start);
1640
+ }
1641
+ if (this.tokens.match("DOLLAR")) {
1642
+ ref += this.tokens.consume().value;
1643
+ }
1644
+ if (this.tokens.match("NUMBER")) {
1645
+ ref += this.tokens.consume().value;
1646
+ }
1647
+ } else if (this.tokens.match("NUMBER")) {
1648
+ const number = this.tokens.consume();
1649
+ ref += number.value;
1650
+ if (this.tokens.match("COLON")) {
1651
+ this.tokens.consume();
1652
+ const endRef = this.parseRangeEnd();
1653
+ return this.parseRange(ref, endRef, startPos, this.tokens.peek().position.start);
1654
+ }
1655
+ } else {
1656
+ throw new ParseError(`Expected cell reference after ${sheetName}!`, this.tokens.peek().position);
1657
+ }
1658
+ if (this.tokens.match("COLON")) {
1659
+ this.tokens.consume();
1660
+ const endRef = this.parseRangeEnd();
1661
+ return this.parseRange(ref, endRef, startPos, this.tokens.peek().position.start);
1662
+ }
1663
+ const cellRef = this.parseCellReferenceString(ref);
1664
+ if (cellRef) {
1665
+ return cellRef;
1666
+ }
1667
+ if (this.tokens.isAtEnd() || !this.tokens.match("IDENTIFIER")) {
1668
+ const sheetPrefix = sheetName.includes(" ") ? `'${sheetName}'!` : `${sheetName}!`;
1669
+ const identifier = ref.substring(sheetPrefix.length);
1670
+ if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(identifier)) {
1671
+ return createNamedExpressionNode(identifier, {
1672
+ start: startPos,
1673
+ end: this.tokens.peek().position.start
1674
+ }, sheetName);
1675
+ }
1676
+ }
1677
+ throw new ParseError(`Invalid cell reference: ${ref}`, {
1678
+ start: startPos,
1679
+ end: this.tokens.peek().position.start
1680
+ });
1681
+ }
1682
+ }
1683
+ function parseFormula(formula) {
1684
+ return Parser.parse(formula);
1685
+ }
1686
+ export {
1687
+ parseFormula,
1688
+ Parser,
1689
+ ParseError
1690
+ };
1691
+
1692
+ //# debugId=A96B29CE76343DE364756E2164756E21