@bilig/formula 0.1.82 → 0.1.84

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 (167) hide show
  1. package/dist/addressing.d.ts +6 -6
  2. package/dist/addressing.js +16 -16
  3. package/dist/addressing.js.map +1 -1
  4. package/dist/ast.d.ts +18 -18
  5. package/dist/binder-wasm-rules.d.ts +2 -2
  6. package/dist/binder-wasm-rules.js +677 -724
  7. package/dist/binder-wasm-rules.js.map +1 -1
  8. package/dist/binder.d.ts +2 -2
  9. package/dist/binder.js +133 -137
  10. package/dist/binder.js.map +1 -1
  11. package/dist/builtin-capabilities.d.ts +4 -4
  12. package/dist/builtin-capabilities.js +777 -816
  13. package/dist/builtin-capabilities.js.map +1 -1
  14. package/dist/builtins/complex.d.ts +3 -3
  15. package/dist/builtins/complex.js +20 -48
  16. package/dist/builtins/complex.js.map +1 -1
  17. package/dist/builtins/convert.d.ts +1 -1
  18. package/dist/builtins/convert.js +180 -181
  19. package/dist/builtins/convert.js.map +1 -1
  20. package/dist/builtins/datetime.d.ts +1 -1
  21. package/dist/builtins/datetime.js +60 -72
  22. package/dist/builtins/datetime.js.map +1 -1
  23. package/dist/builtins/distribution-builtins.d.ts +2 -2
  24. package/dist/builtins/distribution-builtins.js +62 -112
  25. package/dist/builtins/distribution-builtins.js.map +1 -1
  26. package/dist/builtins/distributions.js +17 -54
  27. package/dist/builtins/distributions.js.map +1 -1
  28. package/dist/builtins/financial-builtins.d.ts +2 -2
  29. package/dist/builtins/financial-builtins.js +9 -42
  30. package/dist/builtins/financial-builtins.js.map +1 -1
  31. package/dist/builtins/financial.js +4 -18
  32. package/dist/builtins/financial.js.map +1 -1
  33. package/dist/builtins/fixed-income-builtins.d.ts +2 -2
  34. package/dist/builtins/fixed-income-builtins.js +18 -60
  35. package/dist/builtins/fixed-income-builtins.js.map +1 -1
  36. package/dist/builtins/fixed-income.js +25 -96
  37. package/dist/builtins/fixed-income.js.map +1 -1
  38. package/dist/builtins/formatting.js +9 -9
  39. package/dist/builtins/formatting.js.map +1 -1
  40. package/dist/builtins/logical.d.ts +1 -1
  41. package/dist/builtins/logical.js +5 -5
  42. package/dist/builtins/logical.js.map +1 -1
  43. package/dist/builtins/lookup-array-shape-builtins.d.ts +3 -3
  44. package/dist/builtins/lookup-array-shape-builtins.js +8 -15
  45. package/dist/builtins/lookup-array-shape-builtins.js.map +1 -1
  46. package/dist/builtins/lookup-criteria-builtins.d.ts +2 -2
  47. package/dist/builtins/lookup-criteria-builtins.js +1 -1
  48. package/dist/builtins/lookup-criteria-builtins.js.map +1 -1
  49. package/dist/builtins/lookup-database-builtins.d.ts +2 -2
  50. package/dist/builtins/lookup-database-builtins.js +20 -24
  51. package/dist/builtins/lookup-database-builtins.js.map +1 -1
  52. package/dist/builtins/lookup-financial-builtins.d.ts +3 -3
  53. package/dist/builtins/lookup-financial-builtins.js +14 -30
  54. package/dist/builtins/lookup-financial-builtins.js.map +1 -1
  55. package/dist/builtins/lookup-hypothesis-builtins.d.ts +2 -2
  56. package/dist/builtins/lookup-hypothesis-builtins.js +23 -58
  57. package/dist/builtins/lookup-hypothesis-builtins.js.map +1 -1
  58. package/dist/builtins/lookup-matrix-builtins.d.ts +3 -3
  59. package/dist/builtins/lookup-matrix-builtins.js +5 -3
  60. package/dist/builtins/lookup-matrix-builtins.js.map +1 -1
  61. package/dist/builtins/lookup-order-statistics-builtins.d.ts +3 -3
  62. package/dist/builtins/lookup-order-statistics-builtins.js +18 -30
  63. package/dist/builtins/lookup-order-statistics-builtins.js.map +1 -1
  64. package/dist/builtins/lookup-reference-builtins.d.ts +2 -2
  65. package/dist/builtins/lookup-reference-builtins.js +10 -26
  66. package/dist/builtins/lookup-reference-builtins.js.map +1 -1
  67. package/dist/builtins/lookup-regression-builtins.d.ts +2 -2
  68. package/dist/builtins/lookup-regression-builtins.js +52 -69
  69. package/dist/builtins/lookup-regression-builtins.js.map +1 -1
  70. package/dist/builtins/lookup-sort-filter-builtins.d.ts +3 -3
  71. package/dist/builtins/lookup-sort-filter-builtins.js +5 -13
  72. package/dist/builtins/lookup-sort-filter-builtins.js.map +1 -1
  73. package/dist/builtins/lookup.d.ts +5 -5
  74. package/dist/builtins/lookup.js +61 -73
  75. package/dist/builtins/lookup.js.map +1 -1
  76. package/dist/builtins/math-builtins.d.ts +2 -2
  77. package/dist/builtins/math-builtins.js +11 -17
  78. package/dist/builtins/math-builtins.js.map +1 -1
  79. package/dist/builtins/numeric.d.ts +2 -2
  80. package/dist/builtins/numeric.js +2 -2
  81. package/dist/builtins/numeric.js.map +1 -1
  82. package/dist/builtins/placeholder.d.ts +1 -1
  83. package/dist/builtins/placeholder.js +505 -505
  84. package/dist/builtins/placeholder.js.map +1 -1
  85. package/dist/builtins/radix.d.ts +2 -2
  86. package/dist/builtins/radix.js +33 -39
  87. package/dist/builtins/radix.js.map +1 -1
  88. package/dist/builtins/statistical-builtins.d.ts +2 -2
  89. package/dist/builtins/statistical-builtins.js +29 -56
  90. package/dist/builtins/statistical-builtins.js.map +1 -1
  91. package/dist/builtins/statistics.d.ts +1 -1
  92. package/dist/builtins/statistics.js +3 -7
  93. package/dist/builtins/statistics.js.map +1 -1
  94. package/dist/builtins/text-core-builtins.d.ts +2 -2
  95. package/dist/builtins/text-core-builtins.js +110 -110
  96. package/dist/builtins/text-core-builtins.js.map +1 -1
  97. package/dist/builtins/text-format-builtins.d.ts +2 -2
  98. package/dist/builtins/text-format-builtins.js +109 -141
  99. package/dist/builtins/text-format-builtins.js.map +1 -1
  100. package/dist/builtins/text-search-builtins.d.ts +2 -2
  101. package/dist/builtins/text-search-builtins.js +37 -44
  102. package/dist/builtins/text-search-builtins.js.map +1 -1
  103. package/dist/builtins/text.d.ts +2 -2
  104. package/dist/builtins/text.js +19 -29
  105. package/dist/builtins/text.js.map +1 -1
  106. package/dist/builtins.d.ts +3 -3
  107. package/dist/builtins.js +55 -75
  108. package/dist/builtins.js.map +1 -1
  109. package/dist/compatibility.js +425 -430
  110. package/dist/compatibility.js.map +1 -1
  111. package/dist/compiler.d.ts +7 -7
  112. package/dist/compiler.js +212 -228
  113. package/dist/compiler.js.map +1 -1
  114. package/dist/external-function-adapter.d.ts +6 -6
  115. package/dist/external-function-adapter.js +3 -3
  116. package/dist/external-function-adapter.js.map +1 -1
  117. package/dist/formula-template-key.js +25 -26
  118. package/dist/formula-template-key.js.map +1 -1
  119. package/dist/generated/formula-inventory.js +3567 -3567
  120. package/dist/generated/formula-inventory.js.map +1 -1
  121. package/dist/group-pivot-evaluator.d.ts +2 -2
  122. package/dist/group-pivot-evaluator.js +27 -32
  123. package/dist/group-pivot-evaluator.js.map +1 -1
  124. package/dist/index.d.ts +20 -20
  125. package/dist/index.js +20 -20
  126. package/dist/index.js.map +1 -1
  127. package/dist/js-evaluator-array-special-calls.d.ts +3 -3
  128. package/dist/js-evaluator-array-special-calls.js +25 -34
  129. package/dist/js-evaluator-array-special-calls.js.map +1 -1
  130. package/dist/js-evaluator-context-special-calls.d.ts +2 -2
  131. package/dist/js-evaluator-context-special-calls.js +23 -27
  132. package/dist/js-evaluator-context-special-calls.js.map +1 -1
  133. package/dist/js-evaluator-reference-context.d.ts +2 -2
  134. package/dist/js-evaluator-reference-context.js +22 -24
  135. package/dist/js-evaluator-reference-context.js.map +1 -1
  136. package/dist/js-evaluator-workbook-special-calls.d.ts +2 -2
  137. package/dist/js-evaluator-workbook-special-calls.js +18 -24
  138. package/dist/js-evaluator-workbook-special-calls.js.map +1 -1
  139. package/dist/js-evaluator.d.ts +40 -40
  140. package/dist/js-evaluator.js +135 -147
  141. package/dist/js-evaluator.js.map +1 -1
  142. package/dist/js-plan-lowering.d.ts +2 -2
  143. package/dist/js-plan-lowering.js +103 -108
  144. package/dist/js-plan-lowering.js.map +1 -1
  145. package/dist/lexer.d.ts +1 -1
  146. package/dist/lexer.js +34 -43
  147. package/dist/lexer.js.map +1 -1
  148. package/dist/optimizer.d.ts +1 -1
  149. package/dist/optimizer.js +99 -108
  150. package/dist/optimizer.js.map +1 -1
  151. package/dist/parser.d.ts +1 -1
  152. package/dist/parser.js +129 -136
  153. package/dist/parser.js.map +1 -1
  154. package/dist/program-arena.js.map +1 -1
  155. package/dist/runtime-inventory.d.ts +2 -2
  156. package/dist/runtime-inventory.js +14 -20
  157. package/dist/runtime-inventory.js.map +1 -1
  158. package/dist/runtime-values.d.ts +4 -4
  159. package/dist/runtime-values.js +2 -2
  160. package/dist/runtime-values.js.map +1 -1
  161. package/dist/special-call-rewrites.d.ts +1 -1
  162. package/dist/special-call-rewrites.js +14 -18
  163. package/dist/special-call-rewrites.js.map +1 -1
  164. package/dist/translation.d.ts +7 -7
  165. package/dist/translation.js +323 -366
  166. package/dist/translation.js.map +1 -1
  167. package/package.json +2 -2
package/dist/compiler.js CHANGED
@@ -1,43 +1,43 @@
1
- import { BuiltinId, FormulaMode, Opcode } from "@bilig/protocol";
2
- import { columnToIndex, formatRangeAddress, parseCellAddress, parseRangeAddress, } from "./addressing.js";
3
- import { getNativeGroupedArrayKind } from "./binder-wasm-rules.js";
4
- import { bindFormula, encodeBuiltin } from "./binder.js";
5
- import { lowerToPlan } from "./js-evaluator.js";
6
- import { optimizeFormula } from "./optimizer.js";
7
- import { parseFormula } from "./parser.js";
8
- import { rewriteSpecialCall } from "./special-call-rewrites.js";
1
+ import { BuiltinId, FormulaMode, Opcode } from '@bilig/protocol';
2
+ import { columnToIndex, formatRangeAddress, parseCellAddress, parseRangeAddress } from './addressing.js';
3
+ import { getNativeGroupedArrayKind } from './binder-wasm-rules.js';
4
+ import { bindFormula, encodeBuiltin } from './binder.js';
5
+ import { lowerToPlan } from './js-evaluator.js';
6
+ import { optimizeFormula } from './optimizer.js';
7
+ import { parseFormula } from './parser.js';
8
+ import { rewriteSpecialCall } from './special-call-rewrites.js';
9
9
  function encodeInstruction(opcode, operand = 0) {
10
10
  return (opcode << 24) | (operand & 0x00ff_ffff);
11
11
  }
12
12
  const SIMPLE_CELL_REF_RE = /^\$?[A-Z]+\$?[1-9][0-9]*$/;
13
13
  const SIMPLE_NUMBER_RE = /^[+-]?(?:\d+(?:\.\d+)?|\.\d+)(?:[eE][+-]?\d+)?$/;
14
14
  const SIMPLE_BINARY_RE = /^\s*(\$?[A-Z]+\$?[1-9][0-9]*|[+-]?(?:\d+(?:\.\d+)?|\.\d+)(?:[eE][+-]?\d+)?)\s*([+*])\s*(\$?[A-Z]+\$?[1-9][0-9]*|[+-]?(?:\d+(?:\.\d+)?|\.\d+)(?:[eE][+-]?\d+)?)\s*$/;
15
- const VOLATILE_BUILTINS = new Set(["TODAY", "NOW", "RAND", "RANDBETWEEN", "RANDARRAY"]);
15
+ const VOLATILE_BUILTINS = new Set(['TODAY', 'NOW', 'RAND', 'RANDBETWEEN', 'RANDARRAY']);
16
16
  function producesSpillResult(node) {
17
17
  switch (node.kind) {
18
- case "NumberLiteral":
19
- case "BooleanLiteral":
20
- case "StringLiteral":
21
- case "ErrorLiteral":
22
- case "NameRef":
23
- case "StructuredRef":
24
- case "CellRef":
25
- case "SpillRef":
26
- case "RowRef":
27
- case "ColumnRef":
28
- case "InvokeExpr":
18
+ case 'NumberLiteral':
19
+ case 'BooleanLiteral':
20
+ case 'StringLiteral':
21
+ case 'ErrorLiteral':
22
+ case 'NameRef':
23
+ case 'StructuredRef':
24
+ case 'CellRef':
25
+ case 'SpillRef':
26
+ case 'RowRef':
27
+ case 'ColumnRef':
28
+ case 'InvokeExpr':
29
29
  return false;
30
- case "RangeRef":
30
+ case 'RangeRef':
31
31
  return true;
32
- case "UnaryExpr":
32
+ case 'UnaryExpr':
33
33
  return producesSpillResult(node.argument);
34
- case "BinaryExpr":
34
+ case 'BinaryExpr':
35
35
  return producesSpillResult(node.left) || producesSpillResult(node.right);
36
- case "CallExpr":
37
- if (node.callee.toUpperCase() === "CHOOSE") {
36
+ case 'CallExpr':
37
+ if (node.callee.toUpperCase() === 'CHOOSE') {
38
38
  return node.args.slice(1).some((arg) => producesSpillResult(arg));
39
39
  }
40
- if (node.callee.toUpperCase() === "TREND" || node.callee.toUpperCase() === "GROWTH") {
40
+ if (node.callee.toUpperCase() === 'TREND' || node.callee.toUpperCase() === 'GROWTH') {
41
41
  const shapeArg = node.args[2] ?? node.args[1] ?? node.args[0];
42
42
  if (shapeArg === undefined) {
43
43
  return false;
@@ -45,58 +45,58 @@ function producesSpillResult(node) {
45
45
  return producesSpillResult(shapeArg);
46
46
  }
47
47
  return [
48
- "SEQUENCE",
49
- "EXPAND",
50
- "LINEST",
51
- "LOGEST",
52
- "OFFSET",
53
- "TAKE",
54
- "DROP",
55
- "CHOOSECOLS",
56
- "CHOOSEROWS",
57
- "SORT",
58
- "SORTBY",
59
- "TOCOL",
60
- "TOROW",
61
- "WRAPROWS",
62
- "WRAPCOLS",
63
- "FILTER",
64
- "UNIQUE",
65
- "FREQUENCY",
66
- "MODE.MULT",
67
- "TEXTSPLIT",
68
- "TRIMRANGE",
69
- "GROUPBY",
70
- "PIVOTBY",
71
- "MAKEARRAY",
72
- "MAP",
73
- "SCAN",
74
- "BYROW",
75
- "BYCOL",
76
- "RANDARRAY",
77
- "MUNIT",
78
- "MINVERSE",
79
- "MMULT",
48
+ 'SEQUENCE',
49
+ 'EXPAND',
50
+ 'LINEST',
51
+ 'LOGEST',
52
+ 'OFFSET',
53
+ 'TAKE',
54
+ 'DROP',
55
+ 'CHOOSECOLS',
56
+ 'CHOOSEROWS',
57
+ 'SORT',
58
+ 'SORTBY',
59
+ 'TOCOL',
60
+ 'TOROW',
61
+ 'WRAPROWS',
62
+ 'WRAPCOLS',
63
+ 'FILTER',
64
+ 'UNIQUE',
65
+ 'FREQUENCY',
66
+ 'MODE.MULT',
67
+ 'TEXTSPLIT',
68
+ 'TRIMRANGE',
69
+ 'GROUPBY',
70
+ 'PIVOTBY',
71
+ 'MAKEARRAY',
72
+ 'MAP',
73
+ 'SCAN',
74
+ 'BYROW',
75
+ 'BYCOL',
76
+ 'RANDARRAY',
77
+ 'MUNIT',
78
+ 'MINVERSE',
79
+ 'MMULT',
80
80
  ].includes(node.callee.toUpperCase());
81
81
  }
82
82
  }
83
83
  function analyzeVolatileMetadata(node) {
84
84
  switch (node.kind) {
85
- case "NumberLiteral":
86
- case "BooleanLiteral":
87
- case "StringLiteral":
88
- case "ErrorLiteral":
89
- case "NameRef":
90
- case "StructuredRef":
91
- case "CellRef":
92
- case "SpillRef":
93
- case "RowRef":
94
- case "ColumnRef":
95
- case "RangeRef":
85
+ case 'NumberLiteral':
86
+ case 'BooleanLiteral':
87
+ case 'StringLiteral':
88
+ case 'ErrorLiteral':
89
+ case 'NameRef':
90
+ case 'StructuredRef':
91
+ case 'CellRef':
92
+ case 'SpillRef':
93
+ case 'RowRef':
94
+ case 'ColumnRef':
95
+ case 'RangeRef':
96
96
  return { volatile: false, randCallCount: 0 };
97
- case "UnaryExpr":
97
+ case 'UnaryExpr':
98
98
  return analyzeVolatileMetadata(node.argument);
99
- case "BinaryExpr": {
99
+ case 'BinaryExpr': {
100
100
  const left = analyzeVolatileMetadata(node.left);
101
101
  const right = analyzeVolatileMetadata(node.right);
102
102
  return {
@@ -104,14 +104,14 @@ function analyzeVolatileMetadata(node) {
104
104
  randCallCount: left.randCallCount + right.randCallCount,
105
105
  };
106
106
  }
107
- case "CallExpr": {
107
+ case 'CallExpr': {
108
108
  const rewritten = rewriteSpecialCall(node);
109
109
  if (rewritten) {
110
110
  return analyzeVolatileMetadata(rewritten);
111
111
  }
112
112
  const callee = node.callee.toUpperCase();
113
113
  let volatile = VOLATILE_BUILTINS.has(callee);
114
- let randCallCount = callee === "RAND" ? 1 : 0;
114
+ let randCallCount = callee === 'RAND' ? 1 : 0;
115
115
  node.args.forEach((arg) => {
116
116
  const child = analyzeVolatileMetadata(arg);
117
117
  volatile = volatile || child.volatile;
@@ -119,7 +119,7 @@ function analyzeVolatileMetadata(node) {
119
119
  });
120
120
  return { volatile, randCallCount };
121
121
  }
122
- case "InvokeExpr": {
122
+ case 'InvokeExpr': {
123
123
  const callee = analyzeVolatileMetadata(node.callee);
124
124
  const args = node.args.map(analyzeVolatileMetadata);
125
125
  return {
@@ -145,19 +145,19 @@ function emitRangeRef(node, state) {
145
145
  state.program.push(encodeInstruction(Opcode.PushRange, index));
146
146
  }
147
147
  function isCellRangeNode(node) {
148
- if (node.kind !== "RangeRef") {
148
+ if (node.kind !== 'RangeRef') {
149
149
  return false;
150
150
  }
151
151
  try {
152
- const sheetPrefix = node.sheetName ? `${node.sheetName}!` : "";
153
- return parseRangeAddress(`${sheetPrefix}${node.start}:${node.end}`).kind === "cells";
152
+ const sheetPrefix = node.sheetName ? `${node.sheetName}!` : '';
153
+ return parseRangeAddress(`${sheetPrefix}${node.start}:${node.end}`).kind === 'cells';
154
154
  }
155
155
  catch {
156
156
  return false;
157
157
  }
158
158
  }
159
159
  function emitArgument(node, state) {
160
- if (node.kind === "RangeRef") {
160
+ if (node.kind === 'RangeRef') {
161
161
  emitRangeRef(node, state);
162
162
  return 1;
163
163
  }
@@ -165,44 +165,39 @@ function emitArgument(node, state) {
165
165
  return 1;
166
166
  }
167
167
  const AXIS_AGGREGATE_CODES = new Map([
168
- ["SUM", 1],
169
- ["AVERAGE", 2],
170
- ["AVG", 2],
171
- ["MIN", 3],
172
- ["MAX", 4],
173
- ["COUNT", 5],
174
- ["COUNTA", 6],
168
+ ['SUM', 1],
169
+ ['AVERAGE', 2],
170
+ ['AVG', 2],
171
+ ['MIN', 3],
172
+ ['MAX', 4],
173
+ ['COUNT', 5],
174
+ ['COUNTA', 6],
175
175
  ]);
176
176
  function getNativeAxisAggregateCode(node) {
177
- if (node.kind !== "CallExpr" ||
178
- node.callee.toUpperCase() !== "LAMBDA" ||
179
- node.args.length !== 2) {
177
+ if (node.kind !== 'CallExpr' || node.callee.toUpperCase() !== 'LAMBDA' || node.args.length !== 2) {
180
178
  return null;
181
179
  }
182
180
  const [param, body] = node.args;
183
- if (param?.kind !== "NameRef" || body?.kind !== "CallExpr" || body.args.length !== 1) {
181
+ if (param?.kind !== 'NameRef' || body?.kind !== 'CallExpr' || body.args.length !== 1) {
184
182
  return null;
185
183
  }
186
184
  const aggregateCode = AXIS_AGGREGATE_CODES.get(body.callee.toUpperCase());
187
185
  if (aggregateCode === undefined) {
188
186
  return null;
189
187
  }
190
- return body.args[0]?.kind === "NameRef" &&
191
- body.args[0].name.trim().toUpperCase() === param.name.trim().toUpperCase()
188
+ return body.args[0]?.kind === 'NameRef' && body.args[0].name.trim().toUpperCase() === param.name.trim().toUpperCase()
192
189
  ? aggregateCode
193
190
  : null;
194
191
  }
195
192
  function getNativeRunningFoldCode(node) {
196
- if (node.kind !== "CallExpr" ||
197
- node.callee.toUpperCase() !== "LAMBDA" ||
198
- node.args.length !== 3) {
193
+ if (node.kind !== 'CallExpr' || node.callee.toUpperCase() !== 'LAMBDA' || node.args.length !== 3) {
199
194
  return null;
200
195
  }
201
196
  const [acc, value, body] = node.args;
202
- if (acc?.kind !== "NameRef" || value?.kind !== "NameRef" || body?.kind !== "BinaryExpr") {
197
+ if (acc?.kind !== 'NameRef' || value?.kind !== 'NameRef' || body?.kind !== 'BinaryExpr') {
203
198
  return null;
204
199
  }
205
- const foldCode = body.operator === "+" ? 1 : body.operator === "*" ? 2 : null;
200
+ const foldCode = body.operator === '+' ? 1 : body.operator === '*' ? 2 : null;
206
201
  if (foldCode === null) {
207
202
  return null;
208
203
  }
@@ -210,47 +205,44 @@ function getNativeRunningFoldCode(node) {
210
205
  const right = body.right;
211
206
  const accName = acc.name.trim().toUpperCase();
212
207
  const valueName = value.name.trim().toUpperCase();
213
- return left.kind === "NameRef" &&
214
- right.kind === "NameRef" &&
215
- ((left.name.trim().toUpperCase() === accName &&
216
- right.name.trim().toUpperCase() === valueName) ||
208
+ return left.kind === 'NameRef' &&
209
+ right.kind === 'NameRef' &&
210
+ ((left.name.trim().toUpperCase() === accName && right.name.trim().toUpperCase() === valueName) ||
217
211
  (left.name.trim().toUpperCase() === valueName && right.name.trim().toUpperCase() === accName))
218
212
  ? foldCode
219
213
  : null;
220
214
  }
221
215
  function isNativeMakearraySumLambda(node) {
222
- if (node.kind !== "CallExpr" ||
223
- node.callee.toUpperCase() !== "LAMBDA" ||
224
- node.args.length !== 3) {
216
+ if (node.kind !== 'CallExpr' || node.callee.toUpperCase() !== 'LAMBDA' || node.args.length !== 3) {
225
217
  return false;
226
218
  }
227
219
  const [rowParam, colParam, body] = node.args;
228
- if (rowParam?.kind !== "NameRef" || colParam?.kind !== "NameRef" || body?.kind !== "BinaryExpr") {
220
+ if (rowParam?.kind !== 'NameRef' || colParam?.kind !== 'NameRef' || body?.kind !== 'BinaryExpr') {
229
221
  return false;
230
222
  }
231
- if (body.operator !== "+") {
223
+ if (body.operator !== '+') {
232
224
  return false;
233
225
  }
234
226
  const left = body.left;
235
227
  const right = body.right;
236
228
  const rowName = rowParam.name.trim().toUpperCase();
237
229
  const colName = colParam.name.trim().toUpperCase();
238
- return (left.kind === "NameRef" &&
239
- right.kind === "NameRef" &&
230
+ return (left.kind === 'NameRef' &&
231
+ right.kind === 'NameRef' &&
240
232
  ((left.name.trim().toUpperCase() === rowName && right.name.trim().toUpperCase() === colName) ||
241
233
  (left.name.trim().toUpperCase() === colName && right.name.trim().toUpperCase() === rowName)));
242
234
  }
243
235
  function emitNode(node, state) {
244
236
  switch (node.kind) {
245
- case "NumberLiteral": {
237
+ case 'NumberLiteral': {
246
238
  const index = state.constants.push(node.value) - 1;
247
239
  state.program.push(encodeInstruction(Opcode.PushNumber, index));
248
240
  return;
249
241
  }
250
- case "BooleanLiteral":
242
+ case 'BooleanLiteral':
251
243
  state.program.push(encodeInstruction(Opcode.PushBoolean, node.value ? 1 : 0));
252
244
  return;
253
- case "StringLiteral":
245
+ case 'StringLiteral':
254
246
  {
255
247
  let index = state.strings.indexOf(node.value);
256
248
  if (index === -1)
@@ -258,48 +250,48 @@ function emitNode(node, state) {
258
250
  state.program.push(encodeInstruction(Opcode.PushString, index));
259
251
  }
260
252
  return;
261
- case "ErrorLiteral":
253
+ case 'ErrorLiteral':
262
254
  state.program.push(encodeInstruction(Opcode.PushError, node.code));
263
255
  return;
264
- case "NameRef":
265
- case "StructuredRef":
266
- case "SpillRef":
267
- throw new Error("Defined names are not supported on the wasm fast path");
268
- case "CellRef": {
256
+ case 'NameRef':
257
+ case 'StructuredRef':
258
+ case 'SpillRef':
259
+ throw new Error('Defined names are not supported on the wasm fast path');
260
+ case 'CellRef': {
269
261
  emitCellRef(node.ref, node.sheetName, state);
270
262
  return;
271
263
  }
272
- case "RangeRef":
264
+ case 'RangeRef':
273
265
  emitRangeRef(node, state);
274
266
  return;
275
- case "RowRef":
276
- case "ColumnRef":
277
- throw new Error("Row and column references must appear inside a range");
278
- case "UnaryExpr":
267
+ case 'RowRef':
268
+ case 'ColumnRef':
269
+ throw new Error('Row and column references must appear inside a range');
270
+ case 'UnaryExpr':
279
271
  emitNode(node.argument, state);
280
- if (node.operator === "-") {
272
+ if (node.operator === '-') {
281
273
  state.program.push(encodeInstruction(Opcode.Neg));
282
274
  }
283
275
  return;
284
- case "BinaryExpr":
276
+ case 'BinaryExpr':
285
277
  emitNode(node.left, state);
286
278
  emitNode(node.right, state);
287
279
  state.program.push(encodeInstruction({
288
- "+": Opcode.Add,
289
- "-": Opcode.Sub,
290
- "*": Opcode.Mul,
291
- "/": Opcode.Div,
292
- "^": Opcode.Pow,
293
- "&": Opcode.Concat,
294
- "=": Opcode.Eq,
295
- "<>": Opcode.Neq,
296
- ">": Opcode.Gt,
297
- ">=": Opcode.Gte,
298
- "<": Opcode.Lt,
299
- "<=": Opcode.Lte,
280
+ '+': Opcode.Add,
281
+ '-': Opcode.Sub,
282
+ '*': Opcode.Mul,
283
+ '/': Opcode.Div,
284
+ '^': Opcode.Pow,
285
+ '&': Opcode.Concat,
286
+ '=': Opcode.Eq,
287
+ '<>': Opcode.Neq,
288
+ '>': Opcode.Gt,
289
+ '>=': Opcode.Gte,
290
+ '<': Opcode.Lt,
291
+ '<=': Opcode.Lte,
300
292
  }[node.operator]));
301
293
  return;
302
- case "CallExpr":
294
+ case 'CallExpr':
303
295
  {
304
296
  const rewritten = rewriteSpecialCall(node);
305
297
  if (rewritten) {
@@ -308,22 +300,22 @@ function emitNode(node, state) {
308
300
  }
309
301
  const callee = node.callee.toUpperCase();
310
302
  const nativeGroupedArrayKind = getNativeGroupedArrayKind(node);
311
- if (nativeGroupedArrayKind === "groupby-sum-canonical") {
303
+ if (nativeGroupedArrayKind === 'groupby-sum-canonical') {
312
304
  emitArgument(node.args[0], state);
313
305
  emitArgument(node.args[1], state);
314
306
  state.program.push(encodeInstruction(Opcode.CallBuiltin, (BuiltinId.GroupbySumCanonical << 8) | 2));
315
307
  return;
316
308
  }
317
- if (nativeGroupedArrayKind === "pivotby-sum-canonical") {
309
+ if (nativeGroupedArrayKind === 'pivotby-sum-canonical') {
318
310
  emitArgument(node.args[0], state);
319
311
  emitArgument(node.args[1], state);
320
312
  emitArgument(node.args[2], state);
321
313
  state.program.push(encodeInstruction(Opcode.CallBuiltin, (BuiltinId.PivotbySumCanonical << 8) | 3));
322
314
  return;
323
315
  }
324
- if (callee === "IF") {
316
+ if (callee === 'IF') {
325
317
  if (node.args.length !== 3) {
326
- throw new Error("IF requires exactly three arguments on the wasm fast path");
318
+ throw new Error('IF requires exactly three arguments on the wasm fast path');
327
319
  }
328
320
  emitNode(node.args[0], state);
329
321
  const jumpIfFalseIndex = state.program.push(encodeInstruction(Opcode.JumpIfFalse, 0)) - 1;
@@ -336,27 +328,24 @@ function emitNode(node, state) {
336
328
  state.program[jumpIndex] = encodeInstruction(Opcode.Jump, end);
337
329
  return;
338
330
  }
339
- if ((callee === "BYROW" || callee === "BYCOL") && node.args.length === 2) {
331
+ if ((callee === 'BYROW' || callee === 'BYCOL') && node.args.length === 2) {
340
332
  const lambda = node.args[1];
341
333
  const aggregateCode = getNativeAxisAggregateCode(lambda);
342
334
  if (aggregateCode !== null) {
343
335
  const aggregateIndex = state.constants.push(aggregateCode) - 1;
344
336
  state.program.push(encodeInstruction(Opcode.PushNumber, aggregateIndex));
345
337
  emitArgument(node.args[0], state);
346
- state.program.push(encodeInstruction(Opcode.CallBuiltin, ((callee === "BYROW" ? BuiltinId.ByrowAggregate : BuiltinId.BycolAggregate) << 8) |
347
- 2));
338
+ state.program.push(encodeInstruction(Opcode.CallBuiltin, ((callee === 'BYROW' ? BuiltinId.ByrowAggregate : BuiltinId.BycolAggregate) << 8) | 2));
348
339
  return;
349
340
  }
350
341
  }
351
- if (callee === "MAKEARRAY" &&
352
- node.args.length === 3 &&
353
- isNativeMakearraySumLambda(node.args[2])) {
342
+ if (callee === 'MAKEARRAY' && node.args.length === 3 && isNativeMakearraySumLambda(node.args[2])) {
354
343
  emitArgument(node.args[0], state);
355
344
  emitArgument(node.args[1], state);
356
345
  state.program.push(encodeInstruction(Opcode.CallBuiltin, (BuiltinId.MakearraySum << 8) | 2));
357
346
  return;
358
347
  }
359
- if (callee === "REDUCE" || callee === "SCAN") {
348
+ if (callee === 'REDUCE' || callee === 'SCAN') {
360
349
  const sourceArg = node.args.length === 3 ? node.args[1] : node.args[0];
361
350
  const lambdaArg = node.args.length === 3 ? node.args[2] : node.args[1];
362
351
  const initialArg = node.args.length === 3 ? node.args[0] : undefined;
@@ -370,7 +359,7 @@ function emitNode(node, state) {
370
359
  argc += emitArgument(initialArg, state);
371
360
  }
372
361
  argc += emitArgument(sourceArg, state);
373
- state.program.push(encodeInstruction(Opcode.CallBuiltin, ((callee === "REDUCE"
362
+ state.program.push(encodeInstruction(Opcode.CallBuiltin, ((callee === 'REDUCE'
374
363
  ? foldCode === 1
375
364
  ? BuiltinId.ReduceSum
376
365
  : BuiltinId.ReduceProduct
@@ -383,10 +372,7 @@ function emitNode(node, state) {
383
372
  }
384
373
  }
385
374
  const rangeArg = node.args[0];
386
- if (callee === "PHONETIC" &&
387
- node.args.length === 1 &&
388
- rangeArg &&
389
- isCellRangeNode(rangeArg)) {
375
+ if (callee === 'PHONETIC' && node.args.length === 1 && rangeArg && isCellRangeNode(rangeArg)) {
390
376
  emitCellRef(rangeArg.start, rangeArg.sheetName, state);
391
377
  state.program.push(encodeInstruction(Opcode.CallBuiltin, (BuiltinId.Phonetic << 8) | 1));
392
378
  return;
@@ -398,8 +384,8 @@ function emitNode(node, state) {
398
384
  state.program.push(encodeInstruction(Opcode.CallBuiltin, (encodeBuiltin(callee) << 8) | argc));
399
385
  }
400
386
  return;
401
- case "InvokeExpr":
402
- throw new Error("Lambda invocation is not supported on the wasm fast path");
387
+ case 'InvokeExpr':
388
+ throw new Error('Lambda invocation is not supported on the wasm fast path');
403
389
  }
404
390
  }
405
391
  const CELL_REFERENCE_PARTS_RE = /^(\$?)([A-Z]+)(\$?)([1-9][0-9]*)$/i;
@@ -410,41 +396,41 @@ function computeMaxStackDepth(plan) {
410
396
  let max = 0;
411
397
  for (const instruction of plan) {
412
398
  switch (instruction.opcode) {
413
- case "push-number":
414
- case "push-boolean":
415
- case "push-string":
416
- case "push-error":
417
- case "push-name":
418
- case "push-cell":
419
- case "push-range":
420
- case "push-lambda":
399
+ case 'push-number':
400
+ case 'push-boolean':
401
+ case 'push-string':
402
+ case 'push-error':
403
+ case 'push-name':
404
+ case 'push-cell':
405
+ case 'push-range':
406
+ case 'push-lambda':
421
407
  current += 1;
422
408
  break;
423
- case "lookup-exact-match":
424
- case "lookup-approximate-match":
409
+ case 'lookup-exact-match':
410
+ case 'lookup-approximate-match':
425
411
  break;
426
- case "binary":
412
+ case 'binary':
427
413
  current -= 1;
428
414
  break;
429
- case "call":
415
+ case 'call':
430
416
  current -= instruction.argc;
431
417
  current += 1;
432
418
  break;
433
- case "invoke":
419
+ case 'invoke':
434
420
  current -= instruction.argc;
435
421
  current += 1;
436
422
  break;
437
- case "jump-if-false":
423
+ case 'jump-if-false':
438
424
  current -= 1;
439
425
  break;
440
- case "bind-name":
426
+ case 'bind-name':
441
427
  current -= 1;
442
428
  break;
443
- case "unary":
444
- case "begin-scope":
445
- case "end-scope":
446
- case "jump":
447
- case "return":
429
+ case 'unary':
430
+ case 'begin-scope':
431
+ case 'end-scope':
432
+ case 'jump':
433
+ case 'return':
448
434
  break;
449
435
  }
450
436
  max = Math.max(max, current);
@@ -455,20 +441,20 @@ function parseSimpleOperand(source) {
455
441
  const trimmed = source.trim();
456
442
  if (SIMPLE_CELL_REF_RE.test(trimmed)) {
457
443
  return {
458
- kind: "CellRef",
444
+ kind: 'CellRef',
459
445
  ref: trimmed,
460
446
  };
461
447
  }
462
448
  if (SIMPLE_NUMBER_RE.test(trimmed)) {
463
449
  return {
464
- kind: "NumberLiteral",
450
+ kind: 'NumberLiteral',
465
451
  value: Number(trimmed),
466
452
  };
467
453
  }
468
454
  return null;
469
455
  }
470
456
  function stripSheetQualifier(reference) {
471
- const bang = reference.lastIndexOf("!");
457
+ const bang = reference.lastIndexOf('!');
472
458
  return bang === -1 ? reference.trim() : reference.slice(bang + 1).trim();
473
459
  }
474
460
  function parseCellReferenceParts(reference) {
@@ -480,23 +466,23 @@ function parseCellReferenceParts(reference) {
480
466
  return {
481
467
  row: Number.parseInt(rowText, 10) - 1,
482
468
  col: columnToIndex(columnText),
483
- rowAbsolute: rowAbsolute === "$",
484
- colAbsolute: colAbsolute === "$",
469
+ rowAbsolute: rowAbsolute === '$',
470
+ colAbsolute: colAbsolute === '$',
485
471
  };
486
472
  }
487
473
  function parseAxisReferenceParts(reference, kind) {
488
- const match = (kind === "row" ? ROW_REFERENCE_PARTS_RE : COLUMN_REFERENCE_PARTS_RE).exec(stripSheetQualifier(reference));
474
+ const match = (kind === 'row' ? ROW_REFERENCE_PARTS_RE : COLUMN_REFERENCE_PARTS_RE).exec(stripSheetQualifier(reference));
489
475
  if (!match) {
490
476
  return undefined;
491
477
  }
492
- return kind === "row"
478
+ return kind === 'row'
493
479
  ? {
494
480
  index: Number.parseInt(match[2], 10) - 1,
495
- absolute: match[1] === "$",
481
+ absolute: match[1] === '$',
496
482
  }
497
483
  : {
498
484
  index: columnToIndex(match[2]),
499
- absolute: match[1] === "$",
485
+ absolute: match[1] === '$',
500
486
  };
501
487
  }
502
488
  function buildParsedCellReferenceInfo(reference) {
@@ -505,7 +491,7 @@ function buildParsedCellReferenceInfo(reference) {
505
491
  return {
506
492
  address: reference,
507
493
  ...(parsedCell.sheetName !== undefined ? { sheetName: parsedCell.sheetName } : {}),
508
- ...(reference.includes("!") ? { explicitSheet: true } : {}),
494
+ ...(reference.includes('!') ? { explicitSheet: true } : {}),
509
495
  row: parsedCell.row,
510
496
  col: parsedCell.col,
511
497
  ...(parts
@@ -518,14 +504,14 @@ function buildParsedCellReferenceInfo(reference) {
518
504
  }
519
505
  function buildParsedRangeReferenceInfo(reference) {
520
506
  const parsedRange = parseRangeAddress(reference);
521
- const bounds = parsedRange.kind === "cells"
507
+ const bounds = parsedRange.kind === 'cells'
522
508
  ? {
523
509
  startRow: parsedRange.start.row,
524
510
  endRow: parsedRange.end.row,
525
511
  startCol: parsedRange.start.col,
526
512
  endCol: parsedRange.end.col,
527
513
  }
528
- : parsedRange.kind === "rows"
514
+ : parsedRange.kind === 'rows'
529
515
  ? {
530
516
  startRow: parsedRange.start.row,
531
517
  endRow: parsedRange.end.row,
@@ -538,32 +524,32 @@ function buildParsedRangeReferenceInfo(reference) {
538
524
  startCol: parsedRange.start.col,
539
525
  endCol: parsedRange.end.col,
540
526
  };
541
- const separator = reference.indexOf(":");
527
+ const separator = reference.indexOf(':');
542
528
  const rawStart = reference.slice(0, separator).trim();
543
529
  const rawEnd = reference.slice(separator + 1).trim();
544
- const cellStart = parsedRange.kind === "cells" ? parseCellReferenceParts(rawStart) : undefined;
545
- const cellEnd = parsedRange.kind === "cells" ? parseCellReferenceParts(rawEnd) : undefined;
546
- const rowStart = parsedRange.kind === "rows" ? parseAxisReferenceParts(rawStart, "row") : undefined;
547
- const rowEnd = parsedRange.kind === "rows" ? parseAxisReferenceParts(rawEnd, "row") : undefined;
548
- const colStart = parsedRange.kind === "cols" ? parseAxisReferenceParts(rawStart, "column") : undefined;
549
- const colEnd = parsedRange.kind === "cols" ? parseAxisReferenceParts(rawEnd, "column") : undefined;
530
+ const cellStart = parsedRange.kind === 'cells' ? parseCellReferenceParts(rawStart) : undefined;
531
+ const cellEnd = parsedRange.kind === 'cells' ? parseCellReferenceParts(rawEnd) : undefined;
532
+ const rowStart = parsedRange.kind === 'rows' ? parseAxisReferenceParts(rawStart, 'row') : undefined;
533
+ const rowEnd = parsedRange.kind === 'rows' ? parseAxisReferenceParts(rawEnd, 'row') : undefined;
534
+ const colStart = parsedRange.kind === 'cols' ? parseAxisReferenceParts(rawStart, 'column') : undefined;
535
+ const colEnd = parsedRange.kind === 'cols' ? parseAxisReferenceParts(rawEnd, 'column') : undefined;
550
536
  return {
551
537
  address: reference,
552
- kind: "range",
538
+ kind: 'range',
553
539
  refKind: parsedRange.kind,
554
540
  ...(parsedRange.sheetName !== undefined ? { sheetName: parsedRange.sheetName } : {}),
555
- ...(rawStart.includes("!") ? { explicitSheet: true } : {}),
541
+ ...(rawStart.includes('!') ? { explicitSheet: true } : {}),
556
542
  startAddress: parsedRange.start.text,
557
543
  endAddress: parsedRange.end.text,
558
544
  ...bounds,
559
- ...(parsedRange.kind === "cells"
545
+ ...(parsedRange.kind === 'cells'
560
546
  ? {
561
547
  startRowAbsolute: cellStart?.rowAbsolute ?? false,
562
548
  endRowAbsolute: cellEnd?.rowAbsolute ?? false,
563
549
  startColAbsolute: cellStart?.colAbsolute ?? false,
564
550
  endColAbsolute: cellEnd?.colAbsolute ?? false,
565
551
  }
566
- : parsedRange.kind === "rows"
552
+ : parsedRange.kind === 'rows'
567
553
  ? {
568
554
  startRowAbsolute: rowStart?.absolute ?? false,
569
555
  endRowAbsolute: rowEnd?.absolute ?? false,
@@ -575,11 +561,11 @@ function buildParsedRangeReferenceInfo(reference) {
575
561
  };
576
562
  }
577
563
  function parseDependencyReference(reference) {
578
- if (reference.includes(":")) {
564
+ if (reference.includes(':')) {
579
565
  return buildParsedRangeReferenceInfo(reference);
580
566
  }
581
567
  return {
582
- kind: "cell",
568
+ kind: 'cell',
583
569
  ...buildParsedCellReferenceInfo(reference),
584
570
  };
585
571
  }
@@ -600,28 +586,28 @@ function buildSimpleCompiledFormula(source) {
600
586
  const index = refs.push(ref) - 1;
601
587
  parsedRefs.push(buildParsedCellReferenceInfo(ref));
602
588
  deps.push(ref);
603
- parsedDeps.push({ kind: "cell", ...buildParsedCellReferenceInfo(ref) });
589
+ parsedDeps.push({ kind: 'cell', ...buildParsedCellReferenceInfo(ref) });
604
590
  return index;
605
591
  };
606
592
  const emitOperand = (operand, plan) => {
607
- if (operand.kind === "CellRef") {
593
+ if (operand.kind === 'CellRef') {
608
594
  const index = registerCellRef(operand.ref);
609
595
  program.push(encodeInstruction(Opcode.PushCell, index));
610
- plan.push({ opcode: "push-cell", address: operand.ref });
596
+ plan.push({ opcode: 'push-cell', address: operand.ref });
611
597
  return;
612
598
  }
613
- if (operand.kind === "NumberLiteral") {
599
+ if (operand.kind === 'NumberLiteral') {
614
600
  const index = constants.push(operand.value) - 1;
615
601
  program.push(encodeInstruction(Opcode.PushNumber, index));
616
- plan.push({ opcode: "push-number", value: operand.value });
602
+ plan.push({ opcode: 'push-number', value: operand.value });
617
603
  return;
618
604
  }
619
605
  throw new Error(`Unsupported simple operand '${operand.kind}'`);
620
606
  };
621
- if (singleOperand?.kind === "CellRef") {
607
+ if (singleOperand?.kind === 'CellRef') {
622
608
  const jsPlan = [];
623
609
  emitOperand(singleOperand, jsPlan);
624
- jsPlan.push({ opcode: "return" });
610
+ jsPlan.push({ opcode: 'return' });
625
611
  program.push(encodeInstruction(Opcode.Ret));
626
612
  return {
627
613
  id: 0,
@@ -660,15 +646,15 @@ function buildSimpleCompiledFormula(source) {
660
646
  if (!binaryMatch) {
661
647
  return null;
662
648
  }
663
- const left = parseSimpleOperand(binaryMatch[1] ?? "");
649
+ const left = parseSimpleOperand(binaryMatch[1] ?? '');
664
650
  const operatorCandidate = binaryMatch[2];
665
- const operator = operatorCandidate === "+" || operatorCandidate === "*" ? operatorCandidate : undefined;
666
- const right = parseSimpleOperand(binaryMatch[3] ?? "");
651
+ const operator = operatorCandidate === '+' || operatorCandidate === '*' ? operatorCandidate : undefined;
652
+ const right = parseSimpleOperand(binaryMatch[3] ?? '');
667
653
  if (!left || !right || !operator) {
668
654
  return null;
669
655
  }
670
656
  const ast = {
671
- kind: "BinaryExpr",
657
+ kind: 'BinaryExpr',
672
658
  operator,
673
659
  left,
674
660
  right,
@@ -676,9 +662,9 @@ function buildSimpleCompiledFormula(source) {
676
662
  const jsPlan = [];
677
663
  emitOperand(left, jsPlan);
678
664
  emitOperand(right, jsPlan);
679
- jsPlan.push({ opcode: "binary", operator });
680
- jsPlan.push({ opcode: "return" });
681
- program.push(encodeInstruction(operator === "+" ? Opcode.Add : Opcode.Mul));
665
+ jsPlan.push({ opcode: 'binary', operator });
666
+ jsPlan.push({ opcode: 'return' });
667
+ program.push(encodeInstruction(operator === '+' ? Opcode.Add : Opcode.Mul));
682
668
  program.push(encodeInstruction(Opcode.Ret));
683
669
  return {
684
670
  id: 0,
@@ -714,31 +700,29 @@ function buildSimpleCompiledFormula(source) {
714
700
  };
715
701
  }
716
702
  function buildDirectAggregateCandidate(node, symbolicRanges) {
717
- if (node.kind !== "CallExpr" || node.args.length !== 1) {
703
+ if (node.kind !== 'CallExpr' || node.args.length !== 1) {
718
704
  return undefined;
719
705
  }
720
706
  const callee = node.callee.trim().toUpperCase();
721
- const aggregateKind = callee === "SUM"
722
- ? "sum"
723
- : callee === "COUNT"
724
- ? "count"
725
- : callee === "MIN"
726
- ? "min"
727
- : callee === "MAX"
728
- ? "max"
729
- : callee === "AVERAGE" || callee === "AVG"
730
- ? "average"
707
+ const aggregateKind = callee === 'SUM'
708
+ ? 'sum'
709
+ : callee === 'COUNT'
710
+ ? 'count'
711
+ : callee === 'MIN'
712
+ ? 'min'
713
+ : callee === 'MAX'
714
+ ? 'max'
715
+ : callee === 'AVERAGE' || callee === 'AVG'
716
+ ? 'average'
731
717
  : undefined;
732
718
  if (!aggregateKind) {
733
719
  return undefined;
734
720
  }
735
721
  const rangeNode = node.args[0];
736
- if (!rangeNode || rangeNode.kind !== "RangeRef" || rangeNode.refKind !== "cells") {
722
+ if (!rangeNode || rangeNode.kind !== 'RangeRef' || rangeNode.refKind !== 'cells') {
737
723
  return undefined;
738
724
  }
739
- const qualifiedRange = formatRangeAddress(parseRangeAddress(rangeNode.sheetName
740
- ? `${rangeNode.sheetName}!${rangeNode.start}:${rangeNode.end}`
741
- : `${rangeNode.start}:${rangeNode.end}`));
725
+ const qualifiedRange = formatRangeAddress(parseRangeAddress(rangeNode.sheetName ? `${rangeNode.sheetName}!${rangeNode.start}:${rangeNode.end}` : `${rangeNode.start}:${rangeNode.end}`));
742
726
  const symbolicRangeIndex = symbolicRanges.indexOf(qualifiedRange);
743
727
  if (symbolicRangeIndex === -1) {
744
728
  return undefined;