@bilig/formula 0.1.83 → 0.1.85

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 (165) 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/group-pivot-evaluator.d.ts +2 -2
  120. package/dist/group-pivot-evaluator.js +27 -32
  121. package/dist/group-pivot-evaluator.js.map +1 -1
  122. package/dist/index.d.ts +20 -20
  123. package/dist/index.js +20 -20
  124. package/dist/index.js.map +1 -1
  125. package/dist/js-evaluator-array-special-calls.d.ts +3 -3
  126. package/dist/js-evaluator-array-special-calls.js +25 -34
  127. package/dist/js-evaluator-array-special-calls.js.map +1 -1
  128. package/dist/js-evaluator-context-special-calls.d.ts +2 -2
  129. package/dist/js-evaluator-context-special-calls.js +23 -27
  130. package/dist/js-evaluator-context-special-calls.js.map +1 -1
  131. package/dist/js-evaluator-reference-context.d.ts +2 -2
  132. package/dist/js-evaluator-reference-context.js +22 -24
  133. package/dist/js-evaluator-reference-context.js.map +1 -1
  134. package/dist/js-evaluator-workbook-special-calls.d.ts +2 -2
  135. package/dist/js-evaluator-workbook-special-calls.js +18 -24
  136. package/dist/js-evaluator-workbook-special-calls.js.map +1 -1
  137. package/dist/js-evaluator.d.ts +40 -40
  138. package/dist/js-evaluator.js +135 -147
  139. package/dist/js-evaluator.js.map +1 -1
  140. package/dist/js-plan-lowering.d.ts +2 -2
  141. package/dist/js-plan-lowering.js +103 -108
  142. package/dist/js-plan-lowering.js.map +1 -1
  143. package/dist/lexer.d.ts +1 -1
  144. package/dist/lexer.js +34 -43
  145. package/dist/lexer.js.map +1 -1
  146. package/dist/optimizer.d.ts +1 -1
  147. package/dist/optimizer.js +99 -108
  148. package/dist/optimizer.js.map +1 -1
  149. package/dist/parser.d.ts +1 -1
  150. package/dist/parser.js +129 -136
  151. package/dist/parser.js.map +1 -1
  152. package/dist/program-arena.js.map +1 -1
  153. package/dist/runtime-inventory.d.ts +2 -2
  154. package/dist/runtime-inventory.js +14 -20
  155. package/dist/runtime-inventory.js.map +1 -1
  156. package/dist/runtime-values.d.ts +4 -4
  157. package/dist/runtime-values.js +2 -2
  158. package/dist/runtime-values.js.map +1 -1
  159. package/dist/special-call-rewrites.d.ts +1 -1
  160. package/dist/special-call-rewrites.js +14 -18
  161. package/dist/special-call-rewrites.js.map +1 -1
  162. package/dist/translation.d.ts +7 -7
  163. package/dist/translation.js +323 -366
  164. package/dist/translation.js.map +1 -1
  165. package/package.json +2 -2
@@ -1,14 +1,14 @@
1
- import { ErrorCode, ValueTag, formatErrorCode } from "@bilig/protocol";
2
- import { parseRangeAddress } from "./addressing.js";
3
- import { getBuiltin } from "./builtins.js";
4
- import { getLookupBuiltin, } from "./builtins/lookup.js";
5
- import { evaluateArraySpecialCall } from "./js-evaluator-array-special-calls.js";
6
- import { evaluateContextSpecialCall } from "./js-evaluator-context-special-calls.js";
7
- import { absoluteAddress, cellTypeCode, currentCellReference, referenceColumnNumber, referenceRowNumber, referenceSheetName, referenceTopLeftAddress, sheetIndexByName, sheetNames, } from "./js-evaluator-reference-context.js";
8
- import { evaluateWorkbookSpecialCall } from "./js-evaluator-workbook-special-calls.js";
9
- import { lowerToPlan } from "./js-plan-lowering.js";
10
- import { isArrayValue, scalarFromEvaluationResult, } from "./runtime-values.js";
11
- export { lowerToPlan } from "./js-plan-lowering.js";
1
+ import { ErrorCode, ValueTag, formatErrorCode } from '@bilig/protocol';
2
+ import { parseRangeAddress } from './addressing.js';
3
+ import { getBuiltin } from './builtins.js';
4
+ import { getLookupBuiltin } from './builtins/lookup.js';
5
+ import { evaluateArraySpecialCall } from './js-evaluator-array-special-calls.js';
6
+ import { evaluateContextSpecialCall } from './js-evaluator-context-special-calls.js';
7
+ import { absoluteAddress, cellTypeCode, currentCellReference, referenceColumnNumber, referenceRowNumber, referenceSheetName, referenceTopLeftAddress, sheetIndexByName, sheetNames, } from './js-evaluator-reference-context.js';
8
+ import { evaluateWorkbookSpecialCall } from './js-evaluator-workbook-special-calls.js';
9
+ import { lowerToPlan } from './js-plan-lowering.js';
10
+ import { isArrayValue, scalarFromEvaluationResult } from './runtime-values.js';
11
+ export { lowerToPlan } from './js-plan-lowering.js';
12
12
  function emptyValue() {
13
13
  return { tag: ValueTag.Empty };
14
14
  }
@@ -39,11 +39,11 @@ function toNumber(value) {
39
39
  function toStringValue(value) {
40
40
  switch (value.tag) {
41
41
  case ValueTag.Empty:
42
- return "";
42
+ return '';
43
43
  case ValueTag.Number:
44
44
  return String(value.value);
45
45
  case ValueTag.Boolean:
46
- return value.value ? "TRUE" : "FALSE";
46
+ return value.value ? 'TRUE' : 'FALSE';
47
47
  case ValueTag.String:
48
48
  return value.value;
49
49
  case ValueTag.Error:
@@ -83,36 +83,36 @@ function popScalar(stack) {
83
83
  if (!value) {
84
84
  return error(ErrorCode.Value);
85
85
  }
86
- if (value.kind === "scalar") {
86
+ if (value.kind === 'scalar') {
87
87
  return value.value;
88
88
  }
89
- if (value.kind === "omitted") {
89
+ if (value.kind === 'omitted') {
90
90
  return error(ErrorCode.Value);
91
91
  }
92
- if (value.kind === "lambda") {
92
+ if (value.kind === 'lambda') {
93
93
  return error(ErrorCode.Value);
94
94
  }
95
95
  return value.values[0] ?? emptyValue();
96
96
  }
97
97
  function popArgument(stack) {
98
- return stack.pop() ?? { kind: "scalar", value: error(ErrorCode.Value) };
98
+ return stack.pop() ?? { kind: 'scalar', value: error(ErrorCode.Value) };
99
99
  }
100
100
  function toEvaluationResult(value) {
101
101
  if (!value) {
102
102
  return error(ErrorCode.Value);
103
103
  }
104
- if (value.kind === "scalar") {
104
+ if (value.kind === 'scalar') {
105
105
  return value.value;
106
106
  }
107
- if (value.kind === "omitted") {
107
+ if (value.kind === 'omitted') {
108
108
  return error(ErrorCode.Value);
109
109
  }
110
- if (value.kind === "lambda") {
110
+ if (value.kind === 'lambda') {
111
111
  return error(ErrorCode.Value);
112
112
  }
113
- if (value.kind === "range") {
113
+ if (value.kind === 'range') {
114
114
  return {
115
- kind: "array",
115
+ kind: 'array',
116
116
  rows: value.rows,
117
117
  cols: value.cols,
118
118
  values: value.values,
@@ -121,15 +121,15 @@ function toEvaluationResult(value) {
121
121
  return value;
122
122
  }
123
123
  function cloneStackValue(value) {
124
- if (value.kind === "scalar") {
125
- return { kind: "scalar", value: value.value };
124
+ if (value.kind === 'scalar') {
125
+ return { kind: 'scalar', value: value.value };
126
126
  }
127
- if (value.kind === "omitted") {
128
- return { kind: "omitted" };
127
+ if (value.kind === 'omitted') {
128
+ return { kind: 'omitted' };
129
129
  }
130
- if (value.kind === "range") {
130
+ if (value.kind === 'range') {
131
131
  return {
132
- kind: "range",
132
+ kind: 'range',
133
133
  values: value.values,
134
134
  refKind: value.refKind,
135
135
  rows: value.rows,
@@ -139,39 +139,39 @@ function cloneStackValue(value) {
139
139
  ...(value.end ? { end: value.end } : {}),
140
140
  };
141
141
  }
142
- if (value.kind === "lambda") {
142
+ if (value.kind === 'lambda') {
143
143
  return {
144
- kind: "lambda",
144
+ kind: 'lambda',
145
145
  params: [...value.params],
146
146
  body: value.body,
147
147
  scopes: cloneScopes(value.scopes),
148
148
  };
149
149
  }
150
- return { kind: "array", values: value.values, rows: value.rows, cols: value.cols };
150
+ return { kind: 'array', values: value.values, rows: value.rows, cols: value.cols };
151
151
  }
152
152
  function cloneScopes(scopes) {
153
153
  return scopes.map((scope) => new Map([...scope.entries()].map(([name, value]) => [name, cloneStackValue(value)])));
154
154
  }
155
155
  function toRangeLike(value) {
156
- if (value.kind === "omitted") {
157
- return { kind: "range", values: [error(ErrorCode.Value)], rows: 1, cols: 1, refKind: "cells" };
156
+ if (value.kind === 'omitted') {
157
+ return { kind: 'range', values: [error(ErrorCode.Value)], rows: 1, cols: 1, refKind: 'cells' };
158
158
  }
159
- if (value.kind === "lambda") {
160
- return { kind: "range", values: [error(ErrorCode.Value)], rows: 1, cols: 1, refKind: "cells" };
159
+ if (value.kind === 'lambda') {
160
+ return { kind: 'range', values: [error(ErrorCode.Value)], rows: 1, cols: 1, refKind: 'cells' };
161
161
  }
162
- if (value.kind === "range") {
162
+ if (value.kind === 'range') {
163
163
  return value;
164
164
  }
165
- if (value.kind === "array") {
165
+ if (value.kind === 'array') {
166
166
  return {
167
- kind: "range",
167
+ kind: 'range',
168
168
  values: value.values,
169
169
  rows: value.rows,
170
170
  cols: value.cols,
171
- refKind: "cells",
171
+ refKind: 'cells',
172
172
  };
173
173
  }
174
- return { kind: "range", values: [value.value], rows: 1, cols: 1, refKind: "cells" };
174
+ return { kind: 'range', values: [value.value], rows: 1, cols: 1, refKind: 'cells' };
175
175
  }
176
176
  function scalarBinary(operator, leftValue, rightValue) {
177
177
  if (leftValue.tag === ValueTag.Error) {
@@ -180,29 +180,29 @@ function scalarBinary(operator, leftValue, rightValue) {
180
180
  if (rightValue.tag === ValueTag.Error) {
181
181
  return rightValue;
182
182
  }
183
- if (operator === "&") {
183
+ if (operator === '&') {
184
184
  return {
185
185
  tag: ValueTag.String,
186
186
  value: `${toStringValue(leftValue)}${toStringValue(rightValue)}`,
187
187
  stringId: 0,
188
188
  };
189
189
  }
190
- if (["+", "-", "*", "/", "^"].includes(operator)) {
190
+ if (['+', '-', '*', '/', '^'].includes(operator)) {
191
191
  const left = toNumber(leftValue);
192
192
  const right = toNumber(rightValue);
193
193
  if (left === undefined || right === undefined) {
194
194
  return error(ErrorCode.Value);
195
195
  }
196
- if (operator === "/" && right === 0) {
196
+ if (operator === '/' && right === 0) {
197
197
  return error(ErrorCode.Div0);
198
198
  }
199
- const value = operator === "+"
199
+ const value = operator === '+'
200
200
  ? left + right
201
- : operator === "-"
201
+ : operator === '-'
202
202
  ? left - right
203
- : operator === "*"
203
+ : operator === '*'
204
204
  ? left * right
205
- : operator === "/"
205
+ : operator === '/'
206
206
  ? left / right
207
207
  : left ** right;
208
208
  return { tag: ValueTag.Number, value };
@@ -213,21 +213,21 @@ function scalarBinary(operator, leftValue, rightValue) {
213
213
  }
214
214
  return {
215
215
  tag: ValueTag.Boolean,
216
- value: operator === "="
216
+ value: operator === '='
217
217
  ? comparison === 0
218
- : operator === "<>"
218
+ : operator === '<>'
219
219
  ? comparison !== 0
220
- : operator === ">"
220
+ : operator === '>'
221
221
  ? comparison > 0
222
- : operator === ">="
222
+ : operator === '>='
223
223
  ? comparison >= 0
224
- : operator === "<"
224
+ : operator === '<'
225
225
  ? comparison < 0
226
226
  : comparison <= 0,
227
227
  };
228
228
  }
229
229
  function evaluateBinary(operator, leftValue, rightValue) {
230
- if (leftValue.kind === "scalar" && rightValue.kind === "scalar") {
230
+ if (leftValue.kind === 'scalar' && rightValue.kind === 'scalar') {
231
231
  return scalarBinary(operator, leftValue.value, rightValue.value);
232
232
  }
233
233
  const leftRange = toRangeLike(leftValue);
@@ -257,47 +257,45 @@ function evaluateBinary(operator, leftValue, rightValue) {
257
257
  values.push(scalarBinary(operator, leftRange.values[leftIndex] ?? emptyValue(), rightRange.values[rightIndex] ?? emptyValue()));
258
258
  }
259
259
  }
260
- return rows === 1 && cols === 1
261
- ? (values[0] ?? emptyValue())
262
- : { kind: "array", values, rows, cols };
260
+ return rows === 1 && cols === 1 ? (values[0] ?? emptyValue()) : { kind: 'array', values, rows, cols };
263
261
  }
264
262
  function stackScalar(value) {
265
- return { kind: "scalar", value };
263
+ return { kind: 'scalar', value };
266
264
  }
267
265
  function normalizeScopeName(name) {
268
266
  return name.toUpperCase();
269
267
  }
270
268
  function isSingleCellValue(value) {
271
- if (value.kind === "scalar") {
269
+ if (value.kind === 'scalar') {
272
270
  return value.value;
273
271
  }
274
- if (value.kind === "omitted") {
272
+ if (value.kind === 'omitted') {
275
273
  return undefined;
276
274
  }
277
- if (value.kind === "lambda") {
275
+ if (value.kind === 'lambda') {
278
276
  return undefined;
279
277
  }
280
278
  return value.rows * value.cols === 1 ? (value.values[0] ?? emptyValue()) : undefined;
281
279
  }
282
280
  function toRangeArgument(value) {
283
- if (value.kind === "scalar") {
281
+ if (value.kind === 'scalar') {
284
282
  return value.value;
285
283
  }
286
- if (value.kind === "omitted") {
284
+ if (value.kind === 'omitted') {
287
285
  return error(ErrorCode.Value);
288
286
  }
289
- if (value.kind === "lambda") {
287
+ if (value.kind === 'lambda') {
290
288
  return error(ErrorCode.Value);
291
289
  }
292
290
  return {
293
- kind: "range",
291
+ kind: 'range',
294
292
  values: value.values,
295
- refKind: value.kind === "range" ? value.refKind : "cells",
293
+ refKind: value.kind === 'range' ? value.refKind : 'cells',
296
294
  rows: value.rows,
297
295
  cols: value.cols,
298
- ...(value.kind === "range" && value.sheetName ? { sheetName: value.sheetName } : {}),
299
- ...(value.kind === "range" && value.start ? { start: value.start } : {}),
300
- ...(value.kind === "range" && value.end ? { end: value.end } : {}),
296
+ ...(value.kind === 'range' && value.sheetName ? { sheetName: value.sheetName } : {}),
297
+ ...(value.kind === 'range' && value.start ? { start: value.start } : {}),
298
+ ...(value.kind === 'range' && value.end ? { end: value.end } : {}),
301
299
  };
302
300
  }
303
301
  function toPositiveInteger(value) {
@@ -415,16 +413,16 @@ function coerceOptionalTrimModeArgument(value, fallback) {
415
413
  }
416
414
  }
417
415
  function isCellValueError(value) {
418
- return typeof value === "object" && value !== null && "tag" in value;
416
+ return typeof value === 'object' && value !== null && 'tag' in value;
419
417
  }
420
418
  function makeArrayStack(rows, cols, values) {
421
- return { kind: "array", rows, cols, values };
419
+ return { kind: 'array', rows, cols, values };
422
420
  }
423
421
  function matrixFromStackValue(value) {
424
- if (value.kind === "omitted" || value.kind === "lambda") {
422
+ if (value.kind === 'omitted' || value.kind === 'lambda') {
425
423
  return undefined;
426
424
  }
427
- if (value.kind === "scalar") {
425
+ if (value.kind === 'scalar') {
428
426
  return { rows: 1, cols: 1, values: [value.value] };
429
427
  }
430
428
  return { rows: value.rows, cols: value.cols, values: value.values };
@@ -453,7 +451,7 @@ function vectorIntegerArgument(value) {
453
451
  return values;
454
452
  }
455
453
  function aggregateRangeSubset(functionArg, subset, context, totalSet) {
456
- if (functionArg.kind === "lambda") {
454
+ if (functionArg.kind === 'lambda') {
457
455
  const args = [makeArrayStack(Math.max(subset.length, 1), 1, [...subset])];
458
456
  if (functionArg.params.length >= 2) {
459
457
  args.push(makeArrayStack(Math.max(totalSet?.length ?? 0, 1), 1, [...(totalSet ?? [emptyValue()])]));
@@ -467,10 +465,10 @@ function aggregateRangeSubset(functionArg, subset, context, totalSet) {
467
465
  }
468
466
  const name = scalar.value.trim().toUpperCase();
469
467
  if (subset.length === 0) {
470
- if (name === "SUM" || name === "COUNT" || name === "COUNTA") {
468
+ if (name === 'SUM' || name === 'COUNT' || name === 'COUNTA') {
471
469
  return numberValue(0);
472
470
  }
473
- if (name === "AVERAGE" || name === "AVG") {
471
+ if (name === 'AVERAGE' || name === 'AVG') {
474
472
  return error(ErrorCode.Div0);
475
473
  }
476
474
  return numberValue(0);
@@ -483,20 +481,17 @@ function aggregateRangeSubset(functionArg, subset, context, totalSet) {
483
481
  return isArrayValue(result) ? scalarFromEvaluationResult(result) : result;
484
482
  }
485
483
  function applyLambda(lambdaValue, args, context) {
486
- if (lambdaValue.kind !== "lambda") {
487
- return stackScalar(lambdaValue.kind === "scalar" && lambdaValue.value.tag === ValueTag.Error
488
- ? lambdaValue.value
489
- : error(ErrorCode.Value));
484
+ if (lambdaValue.kind !== 'lambda') {
485
+ return stackScalar(lambdaValue.kind === 'scalar' && lambdaValue.value.tag === ValueTag.Error ? lambdaValue.value : error(ErrorCode.Value));
490
486
  }
491
487
  if (args.length > lambdaValue.params.length) {
492
488
  return stackScalar(error(ErrorCode.Value));
493
489
  }
494
490
  const parameterScope = new Map();
495
491
  lambdaValue.params.forEach((name, index) => {
496
- parameterScope.set(normalizeScopeName(name), index < args.length ? cloneStackValue(args[index]) : { kind: "omitted" });
492
+ parameterScope.set(normalizeScopeName(name), index < args.length ? cloneStackValue(args[index]) : { kind: 'omitted' });
497
493
  });
498
- return (executePlan(lambdaValue.body, context, [...cloneScopes(lambdaValue.scopes), parameterScope]) ??
499
- stackScalar(error(ErrorCode.Value)));
494
+ return executePlan(lambdaValue.body, context, [...cloneScopes(lambdaValue.scopes), parameterScope]) ?? stackScalar(error(ErrorCode.Value));
500
495
  }
501
496
  function evaluateSpecialCall(callee, rawArgs, context, argRefs = []) {
502
497
  switch (callee) {
@@ -565,22 +560,22 @@ function executePlan(plan, context, initialScopes = []) {
565
560
  while (pc < plan.length) {
566
561
  const instruction = plan[pc];
567
562
  switch (instruction.opcode) {
568
- case "push-number":
569
- stack.push({ kind: "scalar", value: { tag: ValueTag.Number, value: instruction.value } });
563
+ case 'push-number':
564
+ stack.push({ kind: 'scalar', value: { tag: ValueTag.Number, value: instruction.value } });
570
565
  break;
571
- case "push-boolean":
572
- stack.push({ kind: "scalar", value: { tag: ValueTag.Boolean, value: instruction.value } });
566
+ case 'push-boolean':
567
+ stack.push({ kind: 'scalar', value: { tag: ValueTag.Boolean, value: instruction.value } });
573
568
  break;
574
- case "push-string":
569
+ case 'push-string':
575
570
  stack.push({
576
- kind: "scalar",
571
+ kind: 'scalar',
577
572
  value: { tag: ValueTag.String, value: instruction.value, stringId: 0 },
578
573
  });
579
574
  break;
580
- case "push-error":
581
- stack.push({ kind: "scalar", value: error(instruction.code) });
575
+ case 'push-error':
576
+ stack.push({ kind: 'scalar', value: error(instruction.code) });
582
577
  break;
583
- case "push-name":
578
+ case 'push-name':
584
579
  {
585
580
  let scopedValue;
586
581
  for (let index = scopes.length - 1; index >= 0; index -= 1) {
@@ -593,27 +588,27 @@ function executePlan(plan, context, initialScopes = []) {
593
588
  stack.push(scopedValue
594
589
  ? cloneStackValue(scopedValue)
595
590
  : {
596
- kind: "scalar",
591
+ kind: 'scalar',
597
592
  value: context.resolveName?.(instruction.name) ?? error(ErrorCode.Name),
598
593
  });
599
594
  }
600
595
  break;
601
- case "push-cell":
596
+ case 'push-cell':
602
597
  stack.push({
603
- kind: "scalar",
598
+ kind: 'scalar',
604
599
  value: context.resolveCell(instruction.sheetName ?? context.sheetName, instruction.address),
605
600
  });
606
601
  break;
607
- case "push-range":
602
+ case 'push-range':
608
603
  {
609
604
  const values = context.resolveRange(instruction.sheetName ?? context.sheetName, instruction.start, instruction.end, instruction.refKind);
610
605
  let rows = values.length;
611
606
  let cols = 1;
612
- if (instruction.refKind === "cells") {
607
+ if (instruction.refKind === 'cells') {
613
608
  try {
614
- const sheetPrefix = instruction.sheetName ? `${instruction.sheetName}!` : "";
609
+ const sheetPrefix = instruction.sheetName ? `${instruction.sheetName}!` : '';
615
610
  const range = parseRangeAddress(`${sheetPrefix}${instruction.start}:${instruction.end}`);
616
- if (range.kind === "cells") {
611
+ if (range.kind === 'cells') {
617
612
  rows = range.end.row - range.start.row + 1;
618
613
  cols = range.end.col - range.start.col + 1;
619
614
  }
@@ -625,7 +620,7 @@ function executePlan(plan, context, initialScopes = []) {
625
620
  }
626
621
  context.noteRangeMaterialization?.(values.length);
627
622
  stack.push({
628
- kind: "range",
623
+ kind: 'range',
629
624
  values,
630
625
  refKind: instruction.refKind,
631
626
  rows,
@@ -636,11 +631,11 @@ function executePlan(plan, context, initialScopes = []) {
636
631
  });
637
632
  }
638
633
  break;
639
- case "lookup-exact-match": {
634
+ case 'lookup-exact-match': {
640
635
  const lookupOperand = popArgument(stack);
641
636
  const lookupValue = isSingleCellValue(lookupOperand);
642
637
  if (!lookupValue) {
643
- stack.push({ kind: "scalar", value: error(ErrorCode.Value) });
638
+ stack.push({ kind: 'scalar', value: error(ErrorCode.Value) });
644
639
  break;
645
640
  }
646
641
  const sheetName = instruction.sheetName ?? context.sheetName;
@@ -658,10 +653,8 @@ function executePlan(plan, context, initialScopes = []) {
658
653
  if (directMatch?.handled) {
659
654
  context.noteExactLookupDirect?.();
660
655
  stack.push({
661
- kind: "scalar",
662
- value: directMatch.position === undefined
663
- ? error(ErrorCode.NA)
664
- : { tag: ValueTag.Number, value: directMatch.position },
656
+ kind: 'scalar',
657
+ value: directMatch.position === undefined ? error(ErrorCode.NA) : { tag: ValueTag.Number, value: directMatch.position },
665
658
  });
666
659
  break;
667
660
  }
@@ -673,7 +666,7 @@ function executePlan(plan, context, initialScopes = []) {
673
666
  rows = instruction.endRow - instruction.startRow + 1;
674
667
  cols = instruction.endCol - instruction.startCol + 1;
675
668
  const rangeArg = {
676
- kind: "range",
669
+ kind: 'range',
677
670
  values,
678
671
  refKind: instruction.refKind,
679
672
  rows,
@@ -682,23 +675,22 @@ function executePlan(plan, context, initialScopes = []) {
682
675
  start: instruction.start,
683
676
  end: instruction.end,
684
677
  };
685
- const lookupBuiltin = context.resolveLookupBuiltin?.(instruction.callee) ??
686
- getLookupBuiltin(instruction.callee);
678
+ const lookupBuiltin = context.resolveLookupBuiltin?.(instruction.callee) ?? getLookupBuiltin(instruction.callee);
687
679
  if (!lookupBuiltin) {
688
- stack.push({ kind: "scalar", value: error(ErrorCode.Name) });
680
+ stack.push({ kind: 'scalar', value: error(ErrorCode.Name) });
689
681
  break;
690
682
  }
691
- const result = instruction.callee === "MATCH"
683
+ const result = instruction.callee === 'MATCH'
692
684
  ? lookupBuiltin(lookupValue, rangeArg, { tag: ValueTag.Number, value: 0 })
693
685
  : lookupBuiltin(lookupValue, rangeArg, { tag: ValueTag.Number, value: 0 }, { tag: ValueTag.Number, value: instruction.searchMode });
694
- stack.push(isArrayValue(result) ? result : { kind: "scalar", value: result });
686
+ stack.push(isArrayValue(result) ? result : { kind: 'scalar', value: result });
695
687
  break;
696
688
  }
697
- case "lookup-approximate-match": {
689
+ case 'lookup-approximate-match': {
698
690
  const lookupOperand = popArgument(stack);
699
691
  const lookupValue = isSingleCellValue(lookupOperand);
700
692
  if (!lookupValue) {
701
- stack.push({ kind: "scalar", value: error(ErrorCode.Value) });
693
+ stack.push({ kind: 'scalar', value: error(ErrorCode.Value) });
702
694
  break;
703
695
  }
704
696
  const sheetName = instruction.sheetName ?? context.sheetName;
@@ -715,10 +707,8 @@ function executePlan(plan, context, initialScopes = []) {
715
707
  });
716
708
  if (directMatch?.handled) {
717
709
  stack.push({
718
- kind: "scalar",
719
- value: directMatch.position === undefined
720
- ? error(ErrorCode.NA)
721
- : { tag: ValueTag.Number, value: directMatch.position },
710
+ kind: 'scalar',
711
+ value: directMatch.position === undefined ? error(ErrorCode.NA) : { tag: ValueTag.Number, value: directMatch.position },
722
712
  });
723
713
  break;
724
714
  }
@@ -727,7 +717,7 @@ function executePlan(plan, context, initialScopes = []) {
727
717
  const rows = instruction.endRow - instruction.startRow + 1;
728
718
  const cols = instruction.endCol - instruction.startCol + 1;
729
719
  const rangeArg = {
730
- kind: "range",
720
+ kind: 'range',
731
721
  values,
732
722
  refKind: instruction.refKind,
733
723
  rows,
@@ -736,61 +726,60 @@ function executePlan(plan, context, initialScopes = []) {
736
726
  start: instruction.start,
737
727
  end: instruction.end,
738
728
  };
739
- const lookupBuiltin = context.resolveLookupBuiltin?.(instruction.callee) ??
740
- getLookupBuiltin(instruction.callee);
729
+ const lookupBuiltin = context.resolveLookupBuiltin?.(instruction.callee) ?? getLookupBuiltin(instruction.callee);
741
730
  if (!lookupBuiltin) {
742
- stack.push({ kind: "scalar", value: error(ErrorCode.Name) });
731
+ stack.push({ kind: 'scalar', value: error(ErrorCode.Name) });
743
732
  break;
744
733
  }
745
734
  const matchModeValue = { tag: ValueTag.Number, value: instruction.matchMode };
746
- const result = instruction.callee === "MATCH"
735
+ const result = instruction.callee === 'MATCH'
747
736
  ? lookupBuiltin(lookupValue, rangeArg, matchModeValue)
748
737
  : lookupBuiltin(lookupValue, rangeArg, matchModeValue);
749
- stack.push(isArrayValue(result) ? result : { kind: "scalar", value: result });
738
+ stack.push(isArrayValue(result) ? result : { kind: 'scalar', value: result });
750
739
  break;
751
740
  }
752
- case "push-lambda":
741
+ case 'push-lambda':
753
742
  stack.push({
754
- kind: "lambda",
743
+ kind: 'lambda',
755
744
  params: [...instruction.params],
756
745
  body: instruction.body,
757
746
  scopes: cloneScopes(scopes),
758
747
  });
759
748
  break;
760
- case "unary": {
749
+ case 'unary': {
761
750
  const value = popScalar(stack);
762
751
  const numeric = toNumber(value);
763
752
  stack.push({
764
- kind: "scalar",
753
+ kind: 'scalar',
765
754
  value: numeric === undefined
766
755
  ? error(ErrorCode.Value)
767
- : { tag: ValueTag.Number, value: instruction.operator === "-" ? -numeric : numeric },
756
+ : { tag: ValueTag.Number, value: instruction.operator === '-' ? -numeric : numeric },
768
757
  });
769
758
  break;
770
759
  }
771
- case "binary": {
760
+ case 'binary': {
772
761
  const right = popArgument(stack);
773
762
  const left = popArgument(stack);
774
763
  const result = evaluateBinary(instruction.operator, left, right);
775
- stack.push(isArrayValue(result) ? result : { kind: "scalar", value: result });
764
+ stack.push(isArrayValue(result) ? result : { kind: 'scalar', value: result });
776
765
  break;
777
766
  }
778
- case "begin-scope":
767
+ case 'begin-scope':
779
768
  scopes.push(new Map());
780
769
  break;
781
- case "bind-name": {
770
+ case 'bind-name': {
782
771
  const scope = scopes[scopes.length - 1];
783
772
  if (!scope) {
784
- stack.push({ kind: "scalar", value: error(ErrorCode.Value) });
773
+ stack.push({ kind: 'scalar', value: error(ErrorCode.Value) });
785
774
  break;
786
775
  }
787
776
  scope.set(normalizeScopeName(instruction.name), cloneStackValue(popArgument(stack)));
788
777
  break;
789
778
  }
790
- case "end-scope":
779
+ case 'end-scope':
791
780
  scopes.pop();
792
781
  break;
793
- case "call": {
782
+ case 'call': {
794
783
  const rawArgs = [];
795
784
  for (let index = 0; index < instruction.argc; index += 1) {
796
785
  rawArgs.unshift(popArgument(stack));
@@ -800,43 +789,42 @@ function executePlan(plan, context, initialScopes = []) {
800
789
  stack.push(specialResult);
801
790
  break;
802
791
  }
803
- const lookupBuiltin = context.resolveLookupBuiltin?.(instruction.callee) ??
804
- getLookupBuiltin(instruction.callee);
792
+ const lookupBuiltin = context.resolveLookupBuiltin?.(instruction.callee) ?? getLookupBuiltin(instruction.callee);
805
793
  if (lookupBuiltin) {
806
794
  const args = [];
807
795
  for (const rawArg of rawArgs) {
808
796
  args.push(toRangeArgument(rawArg));
809
797
  }
810
798
  const result = lookupBuiltin(...args);
811
- stack.push(isArrayValue(result) ? result : { kind: "scalar", value: result });
799
+ stack.push(isArrayValue(result) ? result : { kind: 'scalar', value: result });
812
800
  break;
813
801
  }
814
802
  const builtin = context.resolveBuiltin?.(instruction.callee) ?? getBuiltin(instruction.callee);
815
803
  if (!builtin) {
816
- stack.push({ kind: "scalar", value: error(ErrorCode.Name) });
804
+ stack.push({ kind: 'scalar', value: error(ErrorCode.Name) });
817
805
  break;
818
806
  }
819
807
  const args = [];
820
808
  for (const rawArg of rawArgs) {
821
- if (rawArg.kind === "scalar") {
809
+ if (rawArg.kind === 'scalar') {
822
810
  args.push(rawArg.value);
823
811
  continue;
824
812
  }
825
- if (rawArg.kind === "omitted") {
813
+ if (rawArg.kind === 'omitted') {
826
814
  args.push(error(ErrorCode.Value));
827
815
  continue;
828
816
  }
829
- if (rawArg.kind === "lambda") {
817
+ if (rawArg.kind === 'lambda') {
830
818
  args.push(error(ErrorCode.Value));
831
819
  continue;
832
820
  }
833
821
  args.push(...rawArg.values);
834
822
  }
835
823
  const result = builtin(...args);
836
- stack.push(isArrayValue(result) ? result : { kind: "scalar", value: result });
824
+ stack.push(isArrayValue(result) ? result : { kind: 'scalar', value: result });
837
825
  break;
838
826
  }
839
- case "invoke": {
827
+ case 'invoke': {
840
828
  const args = [];
841
829
  for (let index = 0; index < instruction.argc; index += 1) {
842
830
  args.unshift(popArgument(stack));
@@ -845,7 +833,7 @@ function executePlan(plan, context, initialScopes = []) {
845
833
  stack.push(applyLambda(callee, args, context));
846
834
  break;
847
835
  }
848
- case "jump-if-false": {
836
+ case 'jump-if-false': {
849
837
  const value = popScalar(stack);
850
838
  if (value.tag === ValueTag.Error) {
851
839
  return stackScalar(value);
@@ -856,10 +844,10 @@ function executePlan(plan, context, initialScopes = []) {
856
844
  }
857
845
  break;
858
846
  }
859
- case "jump":
847
+ case 'jump':
860
848
  pc = instruction.target;
861
849
  continue;
862
- case "return":
850
+ case 'return':
863
851
  return stack.pop();
864
852
  }
865
853
  pc += 1;