@bilig/formula 0.1.83 → 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.
- package/dist/addressing.d.ts +6 -6
- package/dist/addressing.js +16 -16
- package/dist/addressing.js.map +1 -1
- package/dist/ast.d.ts +18 -18
- package/dist/binder-wasm-rules.d.ts +2 -2
- package/dist/binder-wasm-rules.js +677 -724
- package/dist/binder-wasm-rules.js.map +1 -1
- package/dist/binder.d.ts +2 -2
- package/dist/binder.js +133 -137
- package/dist/binder.js.map +1 -1
- package/dist/builtin-capabilities.d.ts +4 -4
- package/dist/builtin-capabilities.js +777 -816
- package/dist/builtin-capabilities.js.map +1 -1
- package/dist/builtins/complex.d.ts +3 -3
- package/dist/builtins/complex.js +20 -48
- package/dist/builtins/complex.js.map +1 -1
- package/dist/builtins/convert.d.ts +1 -1
- package/dist/builtins/convert.js +180 -181
- package/dist/builtins/convert.js.map +1 -1
- package/dist/builtins/datetime.d.ts +1 -1
- package/dist/builtins/datetime.js +60 -72
- package/dist/builtins/datetime.js.map +1 -1
- package/dist/builtins/distribution-builtins.d.ts +2 -2
- package/dist/builtins/distribution-builtins.js +62 -112
- package/dist/builtins/distribution-builtins.js.map +1 -1
- package/dist/builtins/distributions.js +17 -54
- package/dist/builtins/distributions.js.map +1 -1
- package/dist/builtins/financial-builtins.d.ts +2 -2
- package/dist/builtins/financial-builtins.js +9 -42
- package/dist/builtins/financial-builtins.js.map +1 -1
- package/dist/builtins/financial.js +4 -18
- package/dist/builtins/financial.js.map +1 -1
- package/dist/builtins/fixed-income-builtins.d.ts +2 -2
- package/dist/builtins/fixed-income-builtins.js +18 -60
- package/dist/builtins/fixed-income-builtins.js.map +1 -1
- package/dist/builtins/fixed-income.js +25 -96
- package/dist/builtins/fixed-income.js.map +1 -1
- package/dist/builtins/formatting.js +9 -9
- package/dist/builtins/formatting.js.map +1 -1
- package/dist/builtins/logical.d.ts +1 -1
- package/dist/builtins/logical.js +5 -5
- package/dist/builtins/logical.js.map +1 -1
- package/dist/builtins/lookup-array-shape-builtins.d.ts +3 -3
- package/dist/builtins/lookup-array-shape-builtins.js +8 -15
- package/dist/builtins/lookup-array-shape-builtins.js.map +1 -1
- package/dist/builtins/lookup-criteria-builtins.d.ts +2 -2
- package/dist/builtins/lookup-criteria-builtins.js +1 -1
- package/dist/builtins/lookup-criteria-builtins.js.map +1 -1
- package/dist/builtins/lookup-database-builtins.d.ts +2 -2
- package/dist/builtins/lookup-database-builtins.js +20 -24
- package/dist/builtins/lookup-database-builtins.js.map +1 -1
- package/dist/builtins/lookup-financial-builtins.d.ts +3 -3
- package/dist/builtins/lookup-financial-builtins.js +14 -30
- package/dist/builtins/lookup-financial-builtins.js.map +1 -1
- package/dist/builtins/lookup-hypothesis-builtins.d.ts +2 -2
- package/dist/builtins/lookup-hypothesis-builtins.js +23 -58
- package/dist/builtins/lookup-hypothesis-builtins.js.map +1 -1
- package/dist/builtins/lookup-matrix-builtins.d.ts +3 -3
- package/dist/builtins/lookup-matrix-builtins.js +5 -3
- package/dist/builtins/lookup-matrix-builtins.js.map +1 -1
- package/dist/builtins/lookup-order-statistics-builtins.d.ts +3 -3
- package/dist/builtins/lookup-order-statistics-builtins.js +18 -30
- package/dist/builtins/lookup-order-statistics-builtins.js.map +1 -1
- package/dist/builtins/lookup-reference-builtins.d.ts +2 -2
- package/dist/builtins/lookup-reference-builtins.js +10 -26
- package/dist/builtins/lookup-reference-builtins.js.map +1 -1
- package/dist/builtins/lookup-regression-builtins.d.ts +2 -2
- package/dist/builtins/lookup-regression-builtins.js +52 -69
- package/dist/builtins/lookup-regression-builtins.js.map +1 -1
- package/dist/builtins/lookup-sort-filter-builtins.d.ts +3 -3
- package/dist/builtins/lookup-sort-filter-builtins.js +5 -13
- package/dist/builtins/lookup-sort-filter-builtins.js.map +1 -1
- package/dist/builtins/lookup.d.ts +5 -5
- package/dist/builtins/lookup.js +61 -73
- package/dist/builtins/lookup.js.map +1 -1
- package/dist/builtins/math-builtins.d.ts +2 -2
- package/dist/builtins/math-builtins.js +11 -17
- package/dist/builtins/math-builtins.js.map +1 -1
- package/dist/builtins/numeric.d.ts +2 -2
- package/dist/builtins/numeric.js +2 -2
- package/dist/builtins/numeric.js.map +1 -1
- package/dist/builtins/placeholder.d.ts +1 -1
- package/dist/builtins/placeholder.js +505 -505
- package/dist/builtins/placeholder.js.map +1 -1
- package/dist/builtins/radix.d.ts +2 -2
- package/dist/builtins/radix.js +33 -39
- package/dist/builtins/radix.js.map +1 -1
- package/dist/builtins/statistical-builtins.d.ts +2 -2
- package/dist/builtins/statistical-builtins.js +29 -56
- package/dist/builtins/statistical-builtins.js.map +1 -1
- package/dist/builtins/statistics.d.ts +1 -1
- package/dist/builtins/statistics.js +3 -7
- package/dist/builtins/statistics.js.map +1 -1
- package/dist/builtins/text-core-builtins.d.ts +2 -2
- package/dist/builtins/text-core-builtins.js +110 -110
- package/dist/builtins/text-core-builtins.js.map +1 -1
- package/dist/builtins/text-format-builtins.d.ts +2 -2
- package/dist/builtins/text-format-builtins.js +109 -141
- package/dist/builtins/text-format-builtins.js.map +1 -1
- package/dist/builtins/text-search-builtins.d.ts +2 -2
- package/dist/builtins/text-search-builtins.js +37 -44
- package/dist/builtins/text-search-builtins.js.map +1 -1
- package/dist/builtins/text.d.ts +2 -2
- package/dist/builtins/text.js +19 -29
- package/dist/builtins/text.js.map +1 -1
- package/dist/builtins.d.ts +3 -3
- package/dist/builtins.js +55 -75
- package/dist/builtins.js.map +1 -1
- package/dist/compatibility.js +425 -430
- package/dist/compatibility.js.map +1 -1
- package/dist/compiler.d.ts +7 -7
- package/dist/compiler.js +212 -228
- package/dist/compiler.js.map +1 -1
- package/dist/external-function-adapter.d.ts +6 -6
- package/dist/external-function-adapter.js +3 -3
- package/dist/external-function-adapter.js.map +1 -1
- package/dist/formula-template-key.js +25 -26
- package/dist/formula-template-key.js.map +1 -1
- package/dist/generated/formula-inventory.js +3567 -3567
- package/dist/generated/formula-inventory.js.map +1 -1
- package/dist/group-pivot-evaluator.d.ts +2 -2
- package/dist/group-pivot-evaluator.js +27 -32
- package/dist/group-pivot-evaluator.js.map +1 -1
- package/dist/index.d.ts +20 -20
- package/dist/index.js +20 -20
- package/dist/index.js.map +1 -1
- package/dist/js-evaluator-array-special-calls.d.ts +3 -3
- package/dist/js-evaluator-array-special-calls.js +25 -34
- package/dist/js-evaluator-array-special-calls.js.map +1 -1
- package/dist/js-evaluator-context-special-calls.d.ts +2 -2
- package/dist/js-evaluator-context-special-calls.js +23 -27
- package/dist/js-evaluator-context-special-calls.js.map +1 -1
- package/dist/js-evaluator-reference-context.d.ts +2 -2
- package/dist/js-evaluator-reference-context.js +22 -24
- package/dist/js-evaluator-reference-context.js.map +1 -1
- package/dist/js-evaluator-workbook-special-calls.d.ts +2 -2
- package/dist/js-evaluator-workbook-special-calls.js +18 -24
- package/dist/js-evaluator-workbook-special-calls.js.map +1 -1
- package/dist/js-evaluator.d.ts +40 -40
- package/dist/js-evaluator.js +135 -147
- package/dist/js-evaluator.js.map +1 -1
- package/dist/js-plan-lowering.d.ts +2 -2
- package/dist/js-plan-lowering.js +103 -108
- package/dist/js-plan-lowering.js.map +1 -1
- package/dist/lexer.d.ts +1 -1
- package/dist/lexer.js +34 -43
- package/dist/lexer.js.map +1 -1
- package/dist/optimizer.d.ts +1 -1
- package/dist/optimizer.js +99 -108
- package/dist/optimizer.js.map +1 -1
- package/dist/parser.d.ts +1 -1
- package/dist/parser.js +129 -136
- package/dist/parser.js.map +1 -1
- package/dist/program-arena.js.map +1 -1
- package/dist/runtime-inventory.d.ts +2 -2
- package/dist/runtime-inventory.js +14 -20
- package/dist/runtime-inventory.js.map +1 -1
- package/dist/runtime-values.d.ts +4 -4
- package/dist/runtime-values.js +2 -2
- package/dist/runtime-values.js.map +1 -1
- package/dist/special-call-rewrites.d.ts +1 -1
- package/dist/special-call-rewrites.js +14 -18
- package/dist/special-call-rewrites.js.map +1 -1
- package/dist/translation.d.ts +7 -7
- package/dist/translation.js +323 -366
- package/dist/translation.js.map +1 -1
- package/package.json +2 -2
package/dist/translation.js
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
import { ErrorCode, FormulaMode } from
|
|
2
|
-
import { formatRangeAddress, parseCellAddress, parseRangeAddress } from
|
|
3
|
-
import { compileFormulaAst, } from
|
|
4
|
-
import { parseFormula } from
|
|
1
|
+
import { ErrorCode, FormulaMode } from '@bilig/protocol';
|
|
2
|
+
import { formatRangeAddress, parseCellAddress, parseRangeAddress } from './addressing.js';
|
|
3
|
+
import { compileFormulaAst, } from './compiler.js';
|
|
4
|
+
import { parseFormula } from './parser.js';
|
|
5
5
|
const CELL_REF_RE = /^(\$?)([A-Z]+)(\$?)([1-9][0-9]*)$/;
|
|
6
6
|
const COLUMN_REF_RE = /^(\$?)([A-Z]+)$/;
|
|
7
7
|
const ROW_REF_RE = /^(\$?)([1-9][0-9]*)$/;
|
|
8
8
|
const BINARY_PRECEDENCE = {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
9
|
+
'=': 1,
|
|
10
|
+
'<>': 1,
|
|
11
|
+
'>': 1,
|
|
12
|
+
'>=': 1,
|
|
13
|
+
'<': 1,
|
|
14
|
+
'<=': 1,
|
|
15
|
+
'&': 2,
|
|
16
|
+
'+': 3,
|
|
17
|
+
'-': 3,
|
|
18
|
+
'*': 4,
|
|
19
|
+
'/': 4,
|
|
20
|
+
'^': 5,
|
|
21
21
|
};
|
|
22
22
|
function assertNever(value) {
|
|
23
23
|
throw new Error(`Unexpected value: ${String(value)}`);
|
|
24
24
|
}
|
|
25
25
|
const ERROR_LITERAL_TEXT = {
|
|
26
|
-
[ErrorCode.Ref]:
|
|
27
|
-
[ErrorCode.Name]:
|
|
28
|
-
[ErrorCode.Div0]:
|
|
29
|
-
[ErrorCode.NA]:
|
|
30
|
-
[ErrorCode.Value]:
|
|
31
|
-
[ErrorCode.Cycle]:
|
|
32
|
-
[ErrorCode.Spill]:
|
|
33
|
-
[ErrorCode.Blocked]:
|
|
26
|
+
[ErrorCode.Ref]: '#REF!',
|
|
27
|
+
[ErrorCode.Name]: '#NAME?',
|
|
28
|
+
[ErrorCode.Div0]: '#DIV/0!',
|
|
29
|
+
[ErrorCode.NA]: '#N/A',
|
|
30
|
+
[ErrorCode.Value]: '#VALUE!',
|
|
31
|
+
[ErrorCode.Cycle]: '#CYCLE!',
|
|
32
|
+
[ErrorCode.Spill]: '#SPILL!',
|
|
33
|
+
[ErrorCode.Blocked]: '#BLOCKED!',
|
|
34
34
|
};
|
|
35
35
|
export function translateFormulaReferences(source, rowDelta, colDelta) {
|
|
36
36
|
const ast = parseFormula(source);
|
|
@@ -47,8 +47,7 @@ export function canTranslateCompiledFormulaWithoutAst(compiled) {
|
|
|
47
47
|
compiled.symbolicNames.length === 0 &&
|
|
48
48
|
compiled.symbolicTables.length === 0 &&
|
|
49
49
|
compiled.symbolicSpills.length === 0 &&
|
|
50
|
-
!compiled.jsPlan.some((instruction) => instruction.opcode ===
|
|
51
|
-
instruction.opcode === "lookup-approximate-match"));
|
|
50
|
+
!compiled.jsPlan.some((instruction) => instruction.opcode === 'lookup-exact-match' || instruction.opcode === 'lookup-approximate-match'));
|
|
52
51
|
}
|
|
53
52
|
export function translateCompiledFormulaWithoutAst(compiled, rowDelta, colDelta, sourceOverride) {
|
|
54
53
|
const translatedParsedDeps = compiled.parsedDeps?.map((dependency) => translateParsedDependencyReference(dependency, rowDelta, colDelta));
|
|
@@ -74,17 +73,13 @@ export function translateCompiledFormulaWithoutAst(compiled, rowDelta, colDelta,
|
|
|
74
73
|
: compiled.jsPlan.map((instruction) => translateJsPlanInstructionWithoutAst(instruction, translatedCellMap, translatedRangeMap, rowDelta, colDelta)),
|
|
75
74
|
...(translatedParsedDeps ? { parsedDeps: translatedParsedDeps } : {}),
|
|
76
75
|
...(translatedParsedSymbolicRefs ? { parsedSymbolicRefs: translatedParsedSymbolicRefs } : {}),
|
|
77
|
-
...(translatedParsedSymbolicRanges
|
|
78
|
-
? { parsedSymbolicRanges: translatedParsedSymbolicRanges }
|
|
79
|
-
: {}),
|
|
76
|
+
...(translatedParsedSymbolicRanges ? { parsedSymbolicRanges: translatedParsedSymbolicRanges } : {}),
|
|
80
77
|
},
|
|
81
78
|
};
|
|
82
79
|
}
|
|
83
80
|
export function translateCompiledFormula(compiled, rowDelta, colDelta, sourceOverride) {
|
|
84
81
|
const translatedAst = translateNode(compiled.ast, rowDelta, colDelta);
|
|
85
|
-
const translatedOptimizedAst = compiled.optimizedAst === compiled.ast
|
|
86
|
-
? translatedAst
|
|
87
|
-
: translateNode(compiled.optimizedAst, rowDelta, colDelta);
|
|
82
|
+
const translatedOptimizedAst = compiled.optimizedAst === compiled.ast ? translatedAst : translateNode(compiled.optimizedAst, rowDelta, colDelta);
|
|
88
83
|
const translatedParsedDeps = compiled.parsedDeps?.map((dependency) => translateParsedDependencyReference(dependency, rowDelta, colDelta));
|
|
89
84
|
const translatedParsedSymbolicRefs = compiled.parsedSymbolicRefs?.map((reference) => translateParsedCellReference(reference, rowDelta, colDelta));
|
|
90
85
|
const translatedParsedSymbolicRanges = compiled.parsedSymbolicRanges?.map((range) => translateParsedRangeReference(range, rowDelta, colDelta));
|
|
@@ -106,9 +101,7 @@ export function translateCompiledFormula(compiled, rowDelta, colDelta, sourceOve
|
|
|
106
101
|
jsPlan: compiled.jsPlan.map((instruction) => translateJsPlanInstruction(instruction, rowDelta, colDelta)),
|
|
107
102
|
...(translatedParsedDeps ? { parsedDeps: translatedParsedDeps } : {}),
|
|
108
103
|
...(translatedParsedSymbolicRefs ? { parsedSymbolicRefs: translatedParsedSymbolicRefs } : {}),
|
|
109
|
-
...(translatedParsedSymbolicRanges
|
|
110
|
-
? { parsedSymbolicRanges: translatedParsedSymbolicRanges }
|
|
111
|
-
: {}),
|
|
104
|
+
...(translatedParsedSymbolicRanges ? { parsedSymbolicRanges: translatedParsedSymbolicRanges } : {}),
|
|
112
105
|
},
|
|
113
106
|
};
|
|
114
107
|
}
|
|
@@ -118,11 +111,7 @@ export function rewriteFormulaForStructuralTransform(source, ownerSheetName, tar
|
|
|
118
111
|
}
|
|
119
112
|
export function rewriteCompiledFormulaForStructuralTransform(compiled, ownerSheetName, targetSheetName, transform) {
|
|
120
113
|
const currentAst = compiled.astMatchesSource === false ? parseFormula(compiled.source) : compiled.ast;
|
|
121
|
-
const currentOptimizedAst = compiled.astMatchesSource === false
|
|
122
|
-
? currentAst
|
|
123
|
-
: compiled.optimizedAst === compiled.ast
|
|
124
|
-
? currentAst
|
|
125
|
-
: compiled.optimizedAst;
|
|
114
|
+
const currentOptimizedAst = compiled.astMatchesSource === false ? currentAst : compiled.optimizedAst === compiled.ast ? currentAst : compiled.optimizedAst;
|
|
126
115
|
const rewrittenAst = rewriteNodeForStructuralTransform(currentAst, ownerSheetName, targetSheetName, transform);
|
|
127
116
|
const rewrittenOptimizedAst = currentOptimizedAst === currentAst
|
|
128
117
|
? rewrittenAst
|
|
@@ -180,8 +169,8 @@ export function rewriteAddressForStructuralTransform(address, transform) {
|
|
|
180
169
|
if (!parsed) {
|
|
181
170
|
throw new Error(`Invalid cell reference '${address}'`);
|
|
182
171
|
}
|
|
183
|
-
const nextRow = transform.axis ===
|
|
184
|
-
const nextCol = transform.axis ===
|
|
172
|
+
const nextRow = transform.axis === 'row' ? mapPointIndex(parsed.row, transform) : parsed.row;
|
|
173
|
+
const nextCol = transform.axis === 'column' ? mapPointIndex(parsed.col, transform) : parsed.col;
|
|
185
174
|
if (nextRow === undefined || nextCol === undefined) {
|
|
186
175
|
return undefined;
|
|
187
176
|
}
|
|
@@ -193,10 +182,10 @@ export function rewriteRangeForStructuralTransform(startAddress, endAddress, tra
|
|
|
193
182
|
if (!start || !end) {
|
|
194
183
|
throw new Error(`Invalid range reference '${startAddress}:${endAddress}'`);
|
|
195
184
|
}
|
|
196
|
-
const nextRows = transform.axis ===
|
|
185
|
+
const nextRows = transform.axis === 'row'
|
|
197
186
|
? mapInterval(Math.min(start.row, end.row), Math.max(start.row, end.row), transform)
|
|
198
187
|
: { start: Math.min(start.row, end.row), end: Math.max(start.row, end.row) };
|
|
199
|
-
const nextCols = transform.axis ===
|
|
188
|
+
const nextCols = transform.axis === 'column'
|
|
200
189
|
? mapInterval(Math.min(start.col, end.col), Math.max(start.col, end.col), transform)
|
|
201
190
|
: { start: Math.min(start.col, end.col), end: Math.max(start.col, end.col) };
|
|
202
191
|
if (!nextRows || !nextCols) {
|
|
@@ -209,64 +198,64 @@ export function rewriteRangeForStructuralTransform(startAddress, endAddress, tra
|
|
|
209
198
|
}
|
|
210
199
|
function translateNode(node, rowDelta, colDelta) {
|
|
211
200
|
switch (node.kind) {
|
|
212
|
-
case
|
|
213
|
-
case
|
|
214
|
-
case
|
|
215
|
-
case
|
|
216
|
-
case
|
|
217
|
-
case
|
|
201
|
+
case 'NumberLiteral':
|
|
202
|
+
case 'BooleanLiteral':
|
|
203
|
+
case 'StringLiteral':
|
|
204
|
+
case 'ErrorLiteral':
|
|
205
|
+
case 'NameRef':
|
|
206
|
+
case 'StructuredRef':
|
|
218
207
|
return node;
|
|
219
|
-
case
|
|
208
|
+
case 'CellRef':
|
|
220
209
|
return {
|
|
221
210
|
...node,
|
|
222
211
|
ref: translateCellReference(node.ref, rowDelta, colDelta),
|
|
223
212
|
};
|
|
224
|
-
case
|
|
213
|
+
case 'SpillRef':
|
|
225
214
|
return {
|
|
226
215
|
...node,
|
|
227
216
|
ref: translateCellReference(node.ref, rowDelta, colDelta),
|
|
228
217
|
};
|
|
229
|
-
case
|
|
218
|
+
case 'ColumnRef':
|
|
230
219
|
return {
|
|
231
220
|
...node,
|
|
232
221
|
ref: translateColumnReference(node.ref, colDelta),
|
|
233
222
|
};
|
|
234
|
-
case
|
|
223
|
+
case 'RowRef':
|
|
235
224
|
return {
|
|
236
225
|
...node,
|
|
237
226
|
ref: translateRowReference(node.ref, rowDelta),
|
|
238
227
|
};
|
|
239
|
-
case
|
|
228
|
+
case 'RangeRef':
|
|
240
229
|
return {
|
|
241
230
|
...node,
|
|
242
|
-
start: node.refKind ===
|
|
231
|
+
start: node.refKind === 'cells'
|
|
243
232
|
? translateCellReference(node.start, rowDelta, colDelta)
|
|
244
|
-
: node.refKind ===
|
|
233
|
+
: node.refKind === 'cols'
|
|
245
234
|
? translateColumnReference(node.start, colDelta)
|
|
246
235
|
: translateRowReference(node.start, rowDelta),
|
|
247
|
-
end: node.refKind ===
|
|
236
|
+
end: node.refKind === 'cells'
|
|
248
237
|
? translateCellReference(node.end, rowDelta, colDelta)
|
|
249
|
-
: node.refKind ===
|
|
238
|
+
: node.refKind === 'cols'
|
|
250
239
|
? translateColumnReference(node.end, colDelta)
|
|
251
240
|
: translateRowReference(node.end, rowDelta),
|
|
252
241
|
};
|
|
253
|
-
case
|
|
242
|
+
case 'UnaryExpr':
|
|
254
243
|
return {
|
|
255
244
|
...node,
|
|
256
245
|
argument: translateNode(node.argument, rowDelta, colDelta),
|
|
257
246
|
};
|
|
258
|
-
case
|
|
247
|
+
case 'BinaryExpr':
|
|
259
248
|
return {
|
|
260
249
|
...node,
|
|
261
250
|
left: translateNode(node.left, rowDelta, colDelta),
|
|
262
251
|
right: translateNode(node.right, rowDelta, colDelta),
|
|
263
252
|
};
|
|
264
|
-
case
|
|
253
|
+
case 'CallExpr':
|
|
265
254
|
return {
|
|
266
255
|
...node,
|
|
267
256
|
args: node.args.map((arg) => translateNode(arg, rowDelta, colDelta)),
|
|
268
257
|
};
|
|
269
|
-
case
|
|
258
|
+
case 'InvokeExpr':
|
|
270
259
|
return {
|
|
271
260
|
...node,
|
|
272
261
|
callee: translateNode(node.callee, rowDelta, colDelta),
|
|
@@ -276,82 +265,80 @@ function translateNode(node, rowDelta, colDelta) {
|
|
|
276
265
|
}
|
|
277
266
|
function buildRelativeFormulaTemplateKeyInternal(node, ownerRow, ownerCol) {
|
|
278
267
|
switch (node.kind) {
|
|
279
|
-
case
|
|
268
|
+
case 'NumberLiteral':
|
|
280
269
|
return `n:${node.value}`;
|
|
281
|
-
case
|
|
282
|
-
return node.value ?
|
|
283
|
-
case
|
|
270
|
+
case 'BooleanLiteral':
|
|
271
|
+
return node.value ? 'b:1' : 'b:0';
|
|
272
|
+
case 'StringLiteral':
|
|
284
273
|
return `s:${JSON.stringify(node.value)}`;
|
|
285
|
-
case
|
|
274
|
+
case 'ErrorLiteral':
|
|
286
275
|
return `e:${node.code}`;
|
|
287
|
-
case
|
|
276
|
+
case 'NameRef':
|
|
288
277
|
return `name:${node.name}`;
|
|
289
|
-
case
|
|
278
|
+
case 'StructuredRef':
|
|
290
279
|
return `table:${node.tableName}[${node.columnName}]`;
|
|
291
|
-
case
|
|
280
|
+
case 'CellRef':
|
|
292
281
|
return `cell:${templateSheetKey(node.sheetName)}:${buildRelativeCellReferenceKey(node.ref, ownerRow, ownerCol)}`;
|
|
293
|
-
case
|
|
282
|
+
case 'SpillRef':
|
|
294
283
|
return `spill:${templateSheetKey(node.sheetName)}:${buildRelativeCellReferenceKey(node.ref, ownerRow, ownerCol)}`;
|
|
295
|
-
case
|
|
296
|
-
return `col:${templateSheetKey(node.sheetName)}:${buildRelativeAxisReferenceKey(node.ref, ownerCol,
|
|
297
|
-
case
|
|
298
|
-
return `row:${templateSheetKey(node.sheetName)}:${buildRelativeAxisReferenceKey(node.ref, ownerRow,
|
|
299
|
-
case
|
|
284
|
+
case 'ColumnRef':
|
|
285
|
+
return `col:${templateSheetKey(node.sheetName)}:${buildRelativeAxisReferenceKey(node.ref, ownerCol, 'column')}`;
|
|
286
|
+
case 'RowRef':
|
|
287
|
+
return `row:${templateSheetKey(node.sheetName)}:${buildRelativeAxisReferenceKey(node.ref, ownerRow, 'row')}`;
|
|
288
|
+
case 'RangeRef':
|
|
300
289
|
return `range:${node.refKind}:${templateSheetKey(node.sheetName)}:${buildRelativeRangeReferenceKey(node, ownerRow, ownerCol)}`;
|
|
301
|
-
case
|
|
290
|
+
case 'UnaryExpr':
|
|
302
291
|
return `unary:${node.operator}:${buildRelativeFormulaTemplateKeyInternal(node.argument, ownerRow, ownerCol)}`;
|
|
303
|
-
case
|
|
292
|
+
case 'BinaryExpr':
|
|
304
293
|
return `binary:${node.operator}:${buildRelativeFormulaTemplateKeyInternal(node.left, ownerRow, ownerCol)}:${buildRelativeFormulaTemplateKeyInternal(node.right, ownerRow, ownerCol)}`;
|
|
305
|
-
case
|
|
306
|
-
return `call:${node.callee}:${node.args.map((arg) => buildRelativeFormulaTemplateKeyInternal(arg, ownerRow, ownerCol)).join(
|
|
307
|
-
case
|
|
308
|
-
return `invoke:${buildRelativeFormulaTemplateKeyInternal(node.callee, ownerRow, ownerCol)}:${node.args.map((arg) => buildRelativeFormulaTemplateKeyInternal(arg, ownerRow, ownerCol)).join(
|
|
294
|
+
case 'CallExpr':
|
|
295
|
+
return `call:${node.callee}:${node.args.map((arg) => buildRelativeFormulaTemplateKeyInternal(arg, ownerRow, ownerCol)).join('|')}`;
|
|
296
|
+
case 'InvokeExpr':
|
|
297
|
+
return `invoke:${buildRelativeFormulaTemplateKeyInternal(node.callee, ownerRow, ownerCol)}:${node.args.map((arg) => buildRelativeFormulaTemplateKeyInternal(arg, ownerRow, ownerCol)).join('|')}`;
|
|
309
298
|
}
|
|
310
299
|
}
|
|
311
300
|
function rewriteNodeForStructuralTransform(node, ownerSheetName, targetSheetName, transform) {
|
|
312
301
|
switch (node.kind) {
|
|
313
|
-
case
|
|
314
|
-
case
|
|
315
|
-
case
|
|
316
|
-
case
|
|
317
|
-
case
|
|
318
|
-
case
|
|
302
|
+
case 'NumberLiteral':
|
|
303
|
+
case 'BooleanLiteral':
|
|
304
|
+
case 'StringLiteral':
|
|
305
|
+
case 'ErrorLiteral':
|
|
306
|
+
case 'NameRef':
|
|
307
|
+
case 'StructuredRef':
|
|
319
308
|
return node;
|
|
320
|
-
case
|
|
309
|
+
case 'CellRef':
|
|
321
310
|
return rewriteCellLikeNode(node, ownerSheetName, targetSheetName, transform);
|
|
322
|
-
case
|
|
311
|
+
case 'SpillRef':
|
|
323
312
|
return rewriteCellLikeNode(node, ownerSheetName, targetSheetName, transform);
|
|
324
|
-
case
|
|
325
|
-
if (!targetsSheet(node.sheetName, ownerSheetName, targetSheetName) ||
|
|
326
|
-
transform.axis !== "column") {
|
|
313
|
+
case 'ColumnRef':
|
|
314
|
+
if (!targetsSheet(node.sheetName, ownerSheetName, targetSheetName) || transform.axis !== 'column') {
|
|
327
315
|
return node;
|
|
328
316
|
}
|
|
329
317
|
return rewriteAxisNode(node, transform);
|
|
330
|
-
case
|
|
331
|
-
if (!targetsSheet(node.sheetName, ownerSheetName, targetSheetName) ||
|
|
332
|
-
transform.axis !== "row") {
|
|
318
|
+
case 'RowRef':
|
|
319
|
+
if (!targetsSheet(node.sheetName, ownerSheetName, targetSheetName) || transform.axis !== 'row') {
|
|
333
320
|
return node;
|
|
334
321
|
}
|
|
335
322
|
return rewriteAxisNode(node, transform);
|
|
336
|
-
case
|
|
323
|
+
case 'RangeRef':
|
|
337
324
|
return rewriteRangeNode(node, ownerSheetName, targetSheetName, transform);
|
|
338
|
-
case
|
|
325
|
+
case 'UnaryExpr':
|
|
339
326
|
return {
|
|
340
327
|
...node,
|
|
341
328
|
argument: rewriteNodeForStructuralTransform(node.argument, ownerSheetName, targetSheetName, transform),
|
|
342
329
|
};
|
|
343
|
-
case
|
|
330
|
+
case 'BinaryExpr':
|
|
344
331
|
return {
|
|
345
332
|
...node,
|
|
346
333
|
left: rewriteNodeForStructuralTransform(node.left, ownerSheetName, targetSheetName, transform),
|
|
347
334
|
right: rewriteNodeForStructuralTransform(node.right, ownerSheetName, targetSheetName, transform),
|
|
348
335
|
};
|
|
349
|
-
case
|
|
336
|
+
case 'CallExpr':
|
|
350
337
|
return {
|
|
351
338
|
...node,
|
|
352
339
|
args: node.args.map((arg) => rewriteNodeForStructuralTransform(arg, ownerSheetName, targetSheetName, transform)),
|
|
353
340
|
};
|
|
354
|
-
case
|
|
341
|
+
case 'InvokeExpr':
|
|
355
342
|
return {
|
|
356
343
|
...node,
|
|
357
344
|
callee: rewriteNodeForStructuralTransform(node.callee, ownerSheetName, targetSheetName, transform),
|
|
@@ -360,7 +347,7 @@ function rewriteNodeForStructuralTransform(node, ownerSheetName, targetSheetName
|
|
|
360
347
|
}
|
|
361
348
|
}
|
|
362
349
|
function templateSheetKey(sheetName) {
|
|
363
|
-
return sheetName === undefined ?
|
|
350
|
+
return sheetName === undefined ? '.' : JSON.stringify(sheetName);
|
|
364
351
|
}
|
|
365
352
|
function buildRelativeCellReferenceKey(ref, ownerRow, ownerCol) {
|
|
366
353
|
const parsed = parseCellReferenceParts(ref);
|
|
@@ -380,12 +367,12 @@ function buildRelativeAxisReferenceKey(ref, ownerIndex, kind) {
|
|
|
380
367
|
}
|
|
381
368
|
function buildRelativeRangeReferenceKey(node, ownerRow, ownerCol) {
|
|
382
369
|
switch (node.refKind) {
|
|
383
|
-
case
|
|
370
|
+
case 'cells':
|
|
384
371
|
return `${buildRelativeCellReferenceKey(node.start, ownerRow, ownerCol)}:${buildRelativeCellReferenceKey(node.end, ownerRow, ownerCol)}`;
|
|
385
|
-
case
|
|
386
|
-
return `${buildRelativeAxisReferenceKey(node.start, ownerRow,
|
|
387
|
-
case
|
|
388
|
-
return `${buildRelativeAxisReferenceKey(node.start, ownerCol,
|
|
372
|
+
case 'rows':
|
|
373
|
+
return `${buildRelativeAxisReferenceKey(node.start, ownerRow, 'row')}:${buildRelativeAxisReferenceKey(node.end, ownerRow, 'row')}`;
|
|
374
|
+
case 'cols':
|
|
375
|
+
return `${buildRelativeAxisReferenceKey(node.start, ownerCol, 'column')}:${buildRelativeAxisReferenceKey(node.end, ownerCol, 'column')}`;
|
|
389
376
|
}
|
|
390
377
|
}
|
|
391
378
|
function nodeStructuralShapeEqual(left, right) {
|
|
@@ -393,43 +380,39 @@ function nodeStructuralShapeEqual(left, right) {
|
|
|
393
380
|
return false;
|
|
394
381
|
}
|
|
395
382
|
switch (left.kind) {
|
|
396
|
-
case
|
|
397
|
-
return right.kind ===
|
|
398
|
-
case
|
|
399
|
-
return right.kind ===
|
|
400
|
-
case
|
|
401
|
-
return right.kind ===
|
|
402
|
-
case
|
|
403
|
-
return right.kind ===
|
|
404
|
-
case
|
|
405
|
-
return right.kind ===
|
|
406
|
-
case
|
|
407
|
-
return
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
case
|
|
411
|
-
case
|
|
412
|
-
case "ColumnRef":
|
|
413
|
-
case "RowRef":
|
|
383
|
+
case 'NumberLiteral':
|
|
384
|
+
return right.kind === 'NumberLiteral' && left.value === right.value;
|
|
385
|
+
case 'BooleanLiteral':
|
|
386
|
+
return right.kind === 'BooleanLiteral' && left.value === right.value;
|
|
387
|
+
case 'StringLiteral':
|
|
388
|
+
return right.kind === 'StringLiteral' && left.value === right.value;
|
|
389
|
+
case 'ErrorLiteral':
|
|
390
|
+
return right.kind === 'ErrorLiteral' && left.code === right.code;
|
|
391
|
+
case 'NameRef':
|
|
392
|
+
return right.kind === 'NameRef' && left.name === right.name;
|
|
393
|
+
case 'StructuredRef':
|
|
394
|
+
return right.kind === 'StructuredRef' && left.tableName === right.tableName && left.columnName === right.columnName;
|
|
395
|
+
case 'CellRef':
|
|
396
|
+
case 'SpillRef':
|
|
397
|
+
case 'ColumnRef':
|
|
398
|
+
case 'RowRef':
|
|
414
399
|
return true;
|
|
415
|
-
case
|
|
416
|
-
return right.kind ===
|
|
417
|
-
case
|
|
418
|
-
return
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
case "BinaryExpr":
|
|
422
|
-
return (right.kind === "BinaryExpr" &&
|
|
400
|
+
case 'RangeRef':
|
|
401
|
+
return right.kind === 'RangeRef' && left.refKind === right.refKind;
|
|
402
|
+
case 'UnaryExpr':
|
|
403
|
+
return right.kind === 'UnaryExpr' && left.operator === right.operator && nodeStructuralShapeEqual(left.argument, right.argument);
|
|
404
|
+
case 'BinaryExpr':
|
|
405
|
+
return (right.kind === 'BinaryExpr' &&
|
|
423
406
|
left.operator === right.operator &&
|
|
424
407
|
nodeStructuralShapeEqual(left.left, right.left) &&
|
|
425
408
|
nodeStructuralShapeEqual(left.right, right.right));
|
|
426
|
-
case
|
|
427
|
-
return (right.kind ===
|
|
409
|
+
case 'CallExpr':
|
|
410
|
+
return (right.kind === 'CallExpr' &&
|
|
428
411
|
left.callee === right.callee &&
|
|
429
412
|
left.args.length === right.args.length &&
|
|
430
413
|
left.args.every((arg, index) => nodeStructuralShapeEqual(arg, right.args[index])));
|
|
431
|
-
case
|
|
432
|
-
return (right.kind ===
|
|
414
|
+
case 'InvokeExpr':
|
|
415
|
+
return (right.kind === 'InvokeExpr' &&
|
|
433
416
|
left.args.length === right.args.length &&
|
|
434
417
|
nodeStructuralShapeEqual(left.callee, right.callee) &&
|
|
435
418
|
left.args.every((arg, index) => nodeStructuralShapeEqual(arg, right.args[index])));
|
|
@@ -437,39 +420,39 @@ function nodeStructuralShapeEqual(left, right) {
|
|
|
437
420
|
}
|
|
438
421
|
function renameNodeSheetReferences(node, oldSheetName, newSheetName) {
|
|
439
422
|
switch (node.kind) {
|
|
440
|
-
case
|
|
441
|
-
case
|
|
442
|
-
case
|
|
443
|
-
case
|
|
444
|
-
case
|
|
445
|
-
case
|
|
423
|
+
case 'NumberLiteral':
|
|
424
|
+
case 'BooleanLiteral':
|
|
425
|
+
case 'StringLiteral':
|
|
426
|
+
case 'ErrorLiteral':
|
|
427
|
+
case 'NameRef':
|
|
428
|
+
case 'StructuredRef':
|
|
446
429
|
return node;
|
|
447
|
-
case
|
|
448
|
-
case
|
|
449
|
-
case
|
|
450
|
-
case
|
|
451
|
-
case
|
|
430
|
+
case 'CellRef':
|
|
431
|
+
case 'SpillRef':
|
|
432
|
+
case 'RowRef':
|
|
433
|
+
case 'ColumnRef':
|
|
434
|
+
case 'RangeRef':
|
|
452
435
|
return {
|
|
453
436
|
...node,
|
|
454
437
|
...(node.sheetName === oldSheetName ? { sheetName: newSheetName } : {}),
|
|
455
438
|
};
|
|
456
|
-
case
|
|
439
|
+
case 'UnaryExpr':
|
|
457
440
|
return {
|
|
458
441
|
...node,
|
|
459
442
|
argument: renameNodeSheetReferences(node.argument, oldSheetName, newSheetName),
|
|
460
443
|
};
|
|
461
|
-
case
|
|
444
|
+
case 'BinaryExpr':
|
|
462
445
|
return {
|
|
463
446
|
...node,
|
|
464
447
|
left: renameNodeSheetReferences(node.left, oldSheetName, newSheetName),
|
|
465
448
|
right: renameNodeSheetReferences(node.right, oldSheetName, newSheetName),
|
|
466
449
|
};
|
|
467
|
-
case
|
|
450
|
+
case 'CallExpr':
|
|
468
451
|
return {
|
|
469
452
|
...node,
|
|
470
453
|
args: node.args.map((arg) => renameNodeSheetReferences(arg, oldSheetName, newSheetName)),
|
|
471
454
|
};
|
|
472
|
-
case
|
|
455
|
+
case 'InvokeExpr':
|
|
473
456
|
return {
|
|
474
457
|
...node,
|
|
475
458
|
callee: renameNodeSheetReferences(node.callee, oldSheetName, newSheetName),
|
|
@@ -483,12 +466,12 @@ function rewriteCellLikeNode(node, ownerSheetName, targetSheetName, transform) {
|
|
|
483
466
|
}
|
|
484
467
|
const parsed = parseCellReferenceParts(node.ref);
|
|
485
468
|
if (!parsed) {
|
|
486
|
-
return { kind:
|
|
469
|
+
return { kind: 'ErrorLiteral', code: ErrorCode.Ref };
|
|
487
470
|
}
|
|
488
|
-
const nextRow = transform.axis ===
|
|
489
|
-
const nextCol = transform.axis ===
|
|
471
|
+
const nextRow = transform.axis === 'row' ? mapPointIndex(parsed.row, transform) : parsed.row;
|
|
472
|
+
const nextCol = transform.axis === 'column' ? mapPointIndex(parsed.col, transform) : parsed.col;
|
|
490
473
|
if (nextRow === undefined || nextCol === undefined) {
|
|
491
|
-
return { kind:
|
|
474
|
+
return { kind: 'ErrorLiteral', code: ErrorCode.Ref };
|
|
492
475
|
}
|
|
493
476
|
return {
|
|
494
477
|
...node,
|
|
@@ -496,41 +479,40 @@ function rewriteCellLikeNode(node, ownerSheetName, targetSheetName, transform) {
|
|
|
496
479
|
};
|
|
497
480
|
}
|
|
498
481
|
function rewriteAxisNode(node, transform) {
|
|
499
|
-
const parsed = parseAxisReferenceParts(node.ref, node.kind ===
|
|
482
|
+
const parsed = parseAxisReferenceParts(node.ref, node.kind === 'RowRef' ? 'row' : 'column');
|
|
500
483
|
if (!parsed) {
|
|
501
|
-
return { kind:
|
|
484
|
+
return { kind: 'ErrorLiteral', code: ErrorCode.Ref };
|
|
502
485
|
}
|
|
503
486
|
const nextIndex = mapPointIndex(parsed.index, transform);
|
|
504
487
|
if (nextIndex === undefined) {
|
|
505
|
-
return { kind:
|
|
488
|
+
return { kind: 'ErrorLiteral', code: ErrorCode.Ref };
|
|
506
489
|
}
|
|
507
490
|
return {
|
|
508
491
|
...node,
|
|
509
|
-
ref: formatAxisReference(parsed.absolute, nextIndex, node.kind ===
|
|
492
|
+
ref: formatAxisReference(parsed.absolute, nextIndex, node.kind === 'RowRef' ? 'row' : 'column'),
|
|
510
493
|
};
|
|
511
494
|
}
|
|
512
495
|
function rewriteRangeNode(node, ownerSheetName, targetSheetName, transform) {
|
|
513
496
|
if (!targetsSheet(node.sheetName, ownerSheetName, targetSheetName)) {
|
|
514
497
|
return node;
|
|
515
498
|
}
|
|
516
|
-
if ((node.refKind ===
|
|
517
|
-
(node.refKind === "cols" && transform.axis === "row")) {
|
|
499
|
+
if ((node.refKind === 'rows' && transform.axis === 'column') || (node.refKind === 'cols' && transform.axis === 'row')) {
|
|
518
500
|
return node;
|
|
519
501
|
}
|
|
520
|
-
if (node.refKind ===
|
|
502
|
+
if (node.refKind === 'cells') {
|
|
521
503
|
const start = parseCellReferenceParts(node.start);
|
|
522
504
|
const end = parseCellReferenceParts(node.end);
|
|
523
505
|
if (!start || !end) {
|
|
524
|
-
return { kind:
|
|
506
|
+
return { kind: 'ErrorLiteral', code: ErrorCode.Ref };
|
|
525
507
|
}
|
|
526
|
-
const nextRows = transform.axis ===
|
|
508
|
+
const nextRows = transform.axis === 'row'
|
|
527
509
|
? mapInterval(Math.min(start.row, end.row), Math.max(start.row, end.row), transform)
|
|
528
510
|
: { start: Math.min(start.row, end.row), end: Math.max(start.row, end.row) };
|
|
529
|
-
const nextCols = transform.axis ===
|
|
511
|
+
const nextCols = transform.axis === 'column'
|
|
530
512
|
? mapInterval(Math.min(start.col, end.col), Math.max(start.col, end.col), transform)
|
|
531
513
|
: { start: Math.min(start.col, end.col), end: Math.max(start.col, end.col) };
|
|
532
514
|
if (!nextRows || !nextCols) {
|
|
533
|
-
return { kind:
|
|
515
|
+
return { kind: 'ErrorLiteral', code: ErrorCode.Ref };
|
|
534
516
|
}
|
|
535
517
|
return {
|
|
536
518
|
...node,
|
|
@@ -538,19 +520,19 @@ function rewriteRangeNode(node, ownerSheetName, targetSheetName, transform) {
|
|
|
538
520
|
end: formatCellReference(end, nextRows.end, nextCols.end),
|
|
539
521
|
};
|
|
540
522
|
}
|
|
541
|
-
const start = parseAxisReferenceParts(node.start, node.refKind ===
|
|
542
|
-
const end = parseAxisReferenceParts(node.end, node.refKind ===
|
|
523
|
+
const start = parseAxisReferenceParts(node.start, node.refKind === 'rows' ? 'row' : 'column');
|
|
524
|
+
const end = parseAxisReferenceParts(node.end, node.refKind === 'rows' ? 'row' : 'column');
|
|
543
525
|
if (!start || !end) {
|
|
544
|
-
return { kind:
|
|
526
|
+
return { kind: 'ErrorLiteral', code: ErrorCode.Ref };
|
|
545
527
|
}
|
|
546
528
|
const nextInterval = mapInterval(Math.min(start.index, end.index), Math.max(start.index, end.index), transform);
|
|
547
529
|
if (!nextInterval) {
|
|
548
|
-
return { kind:
|
|
530
|
+
return { kind: 'ErrorLiteral', code: ErrorCode.Ref };
|
|
549
531
|
}
|
|
550
532
|
return {
|
|
551
533
|
...node,
|
|
552
|
-
start: formatAxisReference(start.absolute, nextInterval.start, node.refKind ===
|
|
553
|
-
end: formatAxisReference(end.absolute, nextInterval.end, node.refKind ===
|
|
534
|
+
start: formatAxisReference(start.absolute, nextInterval.start, node.refKind === 'rows' ? 'row' : 'column'),
|
|
535
|
+
end: formatAxisReference(end.absolute, nextInterval.end, node.refKind === 'rows' ? 'row' : 'column'),
|
|
554
536
|
};
|
|
555
537
|
}
|
|
556
538
|
function rewriteParsedCellReference(reference, ownerSheetName, targetSheetName, transform) {
|
|
@@ -580,14 +562,14 @@ function rewriteParsedRangeReference(reference, ownerSheetName, targetSheetName,
|
|
|
580
562
|
if (!nextRange) {
|
|
581
563
|
return reference;
|
|
582
564
|
}
|
|
583
|
-
const bounds = nextRange.kind ===
|
|
565
|
+
const bounds = nextRange.kind === 'cells'
|
|
584
566
|
? {
|
|
585
567
|
startRow: nextRange.start.row,
|
|
586
568
|
endRow: nextRange.end.row,
|
|
587
569
|
startCol: nextRange.start.col,
|
|
588
570
|
endCol: nextRange.end.col,
|
|
589
571
|
}
|
|
590
|
-
: nextRange.kind ===
|
|
572
|
+
: nextRange.kind === 'rows'
|
|
591
573
|
? {
|
|
592
574
|
startRow: nextRange.start.row,
|
|
593
575
|
endRow: nextRange.end.row,
|
|
@@ -610,15 +592,12 @@ function rewriteParsedRangeReference(reference, ownerSheetName, targetSheetName,
|
|
|
610
592
|
};
|
|
611
593
|
}
|
|
612
594
|
function rewriteParsedDependencyReference(reference, ownerSheetName, targetSheetName, transform) {
|
|
613
|
-
return reference.kind ===
|
|
595
|
+
return reference.kind === 'cell'
|
|
614
596
|
? rewriteParsedCellReference(reference, ownerSheetName, targetSheetName, transform)
|
|
615
597
|
: rewriteParsedRangeReference(reference, ownerSheetName, targetSheetName, transform);
|
|
616
598
|
}
|
|
617
599
|
function translateParsedCellReference(reference, rowDelta, colDelta) {
|
|
618
|
-
const parts = reference.rowAbsolute !== undefined &&
|
|
619
|
-
reference.colAbsolute !== undefined &&
|
|
620
|
-
reference.row !== undefined &&
|
|
621
|
-
reference.col !== undefined
|
|
600
|
+
const parts = reference.rowAbsolute !== undefined && reference.colAbsolute !== undefined && reference.row !== undefined && reference.col !== undefined
|
|
622
601
|
? {
|
|
623
602
|
row: reference.row,
|
|
624
603
|
col: reference.col,
|
|
@@ -648,14 +627,14 @@ function translateParsedCellReference(reference, rowDelta, colDelta) {
|
|
|
648
627
|
}
|
|
649
628
|
function translateParsedRangeReference(reference, rowDelta, colDelta) {
|
|
650
629
|
const nextRange = translateParsedRangeReferenceInfo(reference, rowDelta, colDelta);
|
|
651
|
-
const bounds = nextRange.refKind ===
|
|
630
|
+
const bounds = nextRange.refKind === 'cells'
|
|
652
631
|
? {
|
|
653
632
|
startRow: nextRange.startRow,
|
|
654
633
|
endRow: nextRange.endRow,
|
|
655
634
|
startCol: nextRange.startCol,
|
|
656
635
|
endCol: nextRange.endCol,
|
|
657
636
|
}
|
|
658
|
-
: nextRange.refKind ===
|
|
637
|
+
: nextRange.refKind === 'rows'
|
|
659
638
|
? {
|
|
660
639
|
startRow: nextRange.startRow,
|
|
661
640
|
endRow: nextRange.endRow,
|
|
@@ -679,17 +658,15 @@ function translateParsedRangeReference(reference, rowDelta, colDelta) {
|
|
|
679
658
|
};
|
|
680
659
|
}
|
|
681
660
|
function translateParsedDependencyReference(reference, rowDelta, colDelta) {
|
|
682
|
-
return reference.kind ===
|
|
661
|
+
return reference.kind === 'cell'
|
|
683
662
|
? translateParsedCellReference(reference, rowDelta, colDelta)
|
|
684
663
|
: translateParsedRangeReference(reference, rowDelta, colDelta);
|
|
685
664
|
}
|
|
686
665
|
function translateQualifiedCellReference(raw, rowDelta, colDelta) {
|
|
687
|
-
const explicitlyQualified = raw.includes(
|
|
666
|
+
const explicitlyQualified = raw.includes('!');
|
|
688
667
|
const parsed = parseCellAddress(raw);
|
|
689
668
|
const nextAddress = translateCellReference(parsed.text, rowDelta, colDelta);
|
|
690
|
-
return explicitlyQualified
|
|
691
|
-
? formatQualifiedCellReference(parsed.sheetName, nextAddress)
|
|
692
|
-
: nextAddress;
|
|
669
|
+
return explicitlyQualified ? formatQualifiedCellReference(parsed.sheetName, nextAddress) : nextAddress;
|
|
693
670
|
}
|
|
694
671
|
function formatParsedCellReference(reference) {
|
|
695
672
|
const localAddress = formatParsedLocalCellReference(reference);
|
|
@@ -698,10 +675,7 @@ function formatParsedCellReference(reference) {
|
|
|
698
675
|
: localAddress;
|
|
699
676
|
}
|
|
700
677
|
function formatParsedLocalCellReference(reference) {
|
|
701
|
-
const parts = reference.row !== undefined &&
|
|
702
|
-
reference.col !== undefined &&
|
|
703
|
-
reference.rowAbsolute !== undefined &&
|
|
704
|
-
reference.colAbsolute !== undefined
|
|
678
|
+
const parts = reference.row !== undefined && reference.col !== undefined && reference.rowAbsolute !== undefined && reference.colAbsolute !== undefined
|
|
705
679
|
? {
|
|
706
680
|
row: reference.row,
|
|
707
681
|
col: reference.col,
|
|
@@ -718,14 +692,14 @@ function formatParsedRangeReference(reference) {
|
|
|
718
692
|
return formatQualifiedRangeReference(reference.explicitSheet ? reference.sheetName : undefined, reference.startAddress, reference.endAddress);
|
|
719
693
|
}
|
|
720
694
|
function stripSheetQualifier(reference) {
|
|
721
|
-
const bang = reference.lastIndexOf(
|
|
695
|
+
const bang = reference.lastIndexOf('!');
|
|
722
696
|
return bang === -1 ? reference : reference.slice(bang + 1);
|
|
723
697
|
}
|
|
724
698
|
function translatedCellInstructionKey(sheetName, address) {
|
|
725
|
-
return `${sheetName ??
|
|
699
|
+
return `${sheetName ?? ''}\t${address}`;
|
|
726
700
|
}
|
|
727
701
|
function translatedRangeInstructionKey(sheetName, refKind, start, end) {
|
|
728
|
-
return `${sheetName ??
|
|
702
|
+
return `${sheetName ?? ''}\t${refKind}\t${start}\t${end}`;
|
|
729
703
|
}
|
|
730
704
|
function buildTranslatedCellReferenceMap(original, translated) {
|
|
731
705
|
const output = new Map();
|
|
@@ -758,18 +732,16 @@ function buildTranslatedRangeReferenceMap(original, translated) {
|
|
|
758
732
|
return output;
|
|
759
733
|
}
|
|
760
734
|
function formatParsedDependencyReference(reference) {
|
|
761
|
-
return reference.kind ===
|
|
762
|
-
? formatParsedCellReference(reference)
|
|
763
|
-
: formatParsedRangeReference(reference);
|
|
735
|
+
return reference.kind === 'cell' ? formatParsedCellReference(reference) : formatParsedRangeReference(reference);
|
|
764
736
|
}
|
|
765
737
|
function translateQualifiedDependencyReference(raw, rowDelta, colDelta) {
|
|
766
|
-
if (!raw.includes(
|
|
738
|
+
if (!raw.includes(':')) {
|
|
767
739
|
return translateQualifiedCellReference(raw, rowDelta, colDelta);
|
|
768
740
|
}
|
|
769
741
|
return translateQualifiedRangeReference(raw, rowDelta, colDelta);
|
|
770
742
|
}
|
|
771
743
|
function translateQualifiedRangeReference(raw, rowDelta, colDelta) {
|
|
772
|
-
const explicitlyQualified = raw.includes(
|
|
744
|
+
const explicitlyQualified = raw.includes('!');
|
|
773
745
|
const parsed = parseRangeAddress(raw);
|
|
774
746
|
const nextRange = translateRangeAddress(parsed, rowDelta, colDelta);
|
|
775
747
|
if (explicitlyQualified) {
|
|
@@ -779,17 +751,17 @@ function translateQualifiedRangeReference(raw, rowDelta, colDelta) {
|
|
|
779
751
|
}
|
|
780
752
|
function translateRangeAddress(range, rowDelta, colDelta) {
|
|
781
753
|
switch (range.kind) {
|
|
782
|
-
case
|
|
754
|
+
case 'cells': {
|
|
783
755
|
const startAddress = translateCellReference(range.start.text, rowDelta, colDelta);
|
|
784
756
|
const endAddress = translateCellReference(range.end.text, rowDelta, colDelta);
|
|
785
757
|
return parseRangeAddress(formatQualifiedRangeReference(range.sheetName, startAddress, endAddress));
|
|
786
758
|
}
|
|
787
|
-
case
|
|
759
|
+
case 'rows': {
|
|
788
760
|
const start = translateRowReference(range.start.text, rowDelta);
|
|
789
761
|
const end = translateRowReference(range.end.text, rowDelta);
|
|
790
762
|
return parseRangeAddress(formatQualifiedRangeReference(range.sheetName, start, end));
|
|
791
763
|
}
|
|
792
|
-
case
|
|
764
|
+
case 'cols': {
|
|
793
765
|
const start = translateColumnReference(range.start.text, colDelta);
|
|
794
766
|
const end = translateColumnReference(range.end.text, colDelta);
|
|
795
767
|
return parseRangeAddress(formatQualifiedRangeReference(range.sheetName, start, end));
|
|
@@ -797,7 +769,7 @@ function translateRangeAddress(range, rowDelta, colDelta) {
|
|
|
797
769
|
}
|
|
798
770
|
}
|
|
799
771
|
function translateParsedRangeReferenceInfo(reference, rowDelta, colDelta) {
|
|
800
|
-
if (reference.refKind ===
|
|
772
|
+
if (reference.refKind === 'cells') {
|
|
801
773
|
const startRow = (reference.startRowAbsolute ?? false) ? reference.startRow : reference.startRow + rowDelta;
|
|
802
774
|
const endRow = (reference.endRowAbsolute ?? false) ? reference.endRow : reference.endRow + rowDelta;
|
|
803
775
|
const startCol = (reference.startColAbsolute ?? false) ? reference.startCol : reference.startCol + colDelta;
|
|
@@ -824,13 +796,13 @@ function translateParsedRangeReferenceInfo(reference, rowDelta, colDelta) {
|
|
|
824
796
|
endCol,
|
|
825
797
|
};
|
|
826
798
|
}
|
|
827
|
-
if (reference.refKind ===
|
|
799
|
+
if (reference.refKind === 'rows') {
|
|
828
800
|
const startRow = (reference.startRowAbsolute ?? false) ? reference.startRow : reference.startRow + rowDelta;
|
|
829
801
|
const endRow = (reference.endRowAbsolute ?? false) ? reference.endRow : reference.endRow + rowDelta;
|
|
830
802
|
return {
|
|
831
803
|
...reference,
|
|
832
|
-
startAddress: formatAxisReference(reference.startRowAbsolute ?? false, startRow,
|
|
833
|
-
endAddress: formatAxisReference(reference.endRowAbsolute ?? false, endRow,
|
|
804
|
+
startAddress: formatAxisReference(reference.startRowAbsolute ?? false, startRow, 'row'),
|
|
805
|
+
endAddress: formatAxisReference(reference.endRowAbsolute ?? false, endRow, 'row'),
|
|
834
806
|
startRow,
|
|
835
807
|
endRow,
|
|
836
808
|
startCol: 0,
|
|
@@ -841,8 +813,8 @@ function translateParsedRangeReferenceInfo(reference, rowDelta, colDelta) {
|
|
|
841
813
|
const endCol = (reference.endColAbsolute ?? false) ? reference.endCol : reference.endCol + colDelta;
|
|
842
814
|
return {
|
|
843
815
|
...reference,
|
|
844
|
-
startAddress: formatAxisReference(reference.startColAbsolute ?? false, startCol,
|
|
845
|
-
endAddress: formatAxisReference(reference.endColAbsolute ?? false, endCol,
|
|
816
|
+
startAddress: formatAxisReference(reference.startColAbsolute ?? false, startCol, 'column'),
|
|
817
|
+
endAddress: formatAxisReference(reference.endColAbsolute ?? false, endCol, 'column'),
|
|
846
818
|
startRow: 0,
|
|
847
819
|
endRow: 0,
|
|
848
820
|
startCol,
|
|
@@ -850,7 +822,7 @@ function translateParsedRangeReferenceInfo(reference, rowDelta, colDelta) {
|
|
|
850
822
|
};
|
|
851
823
|
}
|
|
852
824
|
function rewriteQualifiedCellReference(raw, ownerSheetName, targetSheetName, transform) {
|
|
853
|
-
const explicitlyQualified = raw.includes(
|
|
825
|
+
const explicitlyQualified = raw.includes('!');
|
|
854
826
|
const parsed = parseCellAddress(raw, ownerSheetName);
|
|
855
827
|
if (parsed.sheetName !== targetSheetName) {
|
|
856
828
|
return raw;
|
|
@@ -859,18 +831,16 @@ function rewriteQualifiedCellReference(raw, ownerSheetName, targetSheetName, tra
|
|
|
859
831
|
if (!nextAddress) {
|
|
860
832
|
return raw;
|
|
861
833
|
}
|
|
862
|
-
return explicitlyQualified
|
|
863
|
-
? formatQualifiedCellReference(parsed.sheetName, nextAddress)
|
|
864
|
-
: nextAddress;
|
|
834
|
+
return explicitlyQualified ? formatQualifiedCellReference(parsed.sheetName, nextAddress) : nextAddress;
|
|
865
835
|
}
|
|
866
836
|
function rewriteQualifiedDependencyReference(raw, ownerSheetName, targetSheetName, transform) {
|
|
867
|
-
if (!raw.includes(
|
|
837
|
+
if (!raw.includes(':')) {
|
|
868
838
|
return rewriteQualifiedCellReference(raw, ownerSheetName, targetSheetName, transform);
|
|
869
839
|
}
|
|
870
840
|
return rewriteQualifiedRangeReference(raw, ownerSheetName, targetSheetName, transform);
|
|
871
841
|
}
|
|
872
842
|
function rewriteQualifiedRangeReference(raw, ownerSheetName, targetSheetName, transform) {
|
|
873
|
-
const explicitlyQualified = raw.includes(
|
|
843
|
+
const explicitlyQualified = raw.includes('!');
|
|
874
844
|
const parsed = parseRangeAddress(raw, ownerSheetName);
|
|
875
845
|
const sheetName = parsed.sheetName ?? ownerSheetName;
|
|
876
846
|
if (sheetName !== targetSheetName) {
|
|
@@ -887,60 +857,56 @@ function rewriteQualifiedRangeReference(raw, ownerSheetName, targetSheetName, tr
|
|
|
887
857
|
}
|
|
888
858
|
function rewriteRangeAddressForStructuralTransform(range, transform) {
|
|
889
859
|
switch (range.kind) {
|
|
890
|
-
case
|
|
860
|
+
case 'cells': {
|
|
891
861
|
const nextRange = rewriteRangeForStructuralTransform(range.start.text, range.end.text, transform);
|
|
892
862
|
if (!nextRange) {
|
|
893
863
|
return undefined;
|
|
894
864
|
}
|
|
895
865
|
return parseRangeAddress(formatQualifiedRangeReference(range.sheetName, nextRange.startAddress, nextRange.endAddress));
|
|
896
866
|
}
|
|
897
|
-
case
|
|
898
|
-
if (transform.axis !==
|
|
867
|
+
case 'rows':
|
|
868
|
+
if (transform.axis !== 'row') {
|
|
899
869
|
return range;
|
|
900
870
|
}
|
|
901
871
|
return rewriteAxisRangeAddress(range, transform);
|
|
902
|
-
case
|
|
903
|
-
if (transform.axis !==
|
|
872
|
+
case 'cols':
|
|
873
|
+
if (transform.axis !== 'column') {
|
|
904
874
|
return range;
|
|
905
875
|
}
|
|
906
876
|
return rewriteAxisRangeAddress(range, transform);
|
|
907
877
|
}
|
|
908
878
|
}
|
|
909
879
|
function rewriteAxisRangeAddress(range, transform) {
|
|
910
|
-
const startIndex = range.kind ===
|
|
911
|
-
const endIndex = range.kind ===
|
|
880
|
+
const startIndex = range.kind === 'rows' ? range.start.row : range.start.col;
|
|
881
|
+
const endIndex = range.kind === 'rows' ? range.end.row : range.end.col;
|
|
912
882
|
const nextInterval = mapInterval(startIndex, endIndex, transform);
|
|
913
883
|
if (!nextInterval) {
|
|
914
884
|
return undefined;
|
|
915
885
|
}
|
|
916
|
-
const prefix = range.sheetName ? `${quoteSheetNameIfNeeded(range.sheetName)}!` :
|
|
917
|
-
const startText = range.kind ===
|
|
918
|
-
|
|
919
|
-
: formatAxisReference(false, nextInterval.start, "column");
|
|
920
|
-
const endText = range.kind === "rows"
|
|
921
|
-
? formatAxisReference(false, nextInterval.end, "row")
|
|
922
|
-
: formatAxisReference(false, nextInterval.end, "column");
|
|
886
|
+
const prefix = range.sheetName ? `${quoteSheetNameIfNeeded(range.sheetName)}!` : '';
|
|
887
|
+
const startText = range.kind === 'rows' ? formatAxisReference(false, nextInterval.start, 'row') : formatAxisReference(false, nextInterval.start, 'column');
|
|
888
|
+
const endText = range.kind === 'rows' ? formatAxisReference(false, nextInterval.end, 'row') : formatAxisReference(false, nextInterval.end, 'column');
|
|
923
889
|
return parseRangeAddress(`${prefix}${startText}:${endText}`);
|
|
924
890
|
}
|
|
925
891
|
function rewriteJsPlanInstruction(instruction, ownerSheetName, targetSheetName, transform) {
|
|
926
892
|
switch (instruction.opcode) {
|
|
927
|
-
case
|
|
893
|
+
case 'push-cell':
|
|
928
894
|
return {
|
|
929
895
|
...instruction,
|
|
930
896
|
address: rewriteReferenceOperandAddress(instruction.sheetName, instruction.address, ownerSheetName, targetSheetName, transform),
|
|
931
897
|
};
|
|
932
|
-
case
|
|
898
|
+
case 'push-range': {
|
|
933
899
|
const nextRange = rewritePlanRangeInstruction(instruction.sheetName, instruction.start, instruction.end, instruction.refKind, ownerSheetName, targetSheetName, transform);
|
|
934
900
|
return nextRange ? { ...instruction, ...nextRange } : instruction;
|
|
935
901
|
}
|
|
936
|
-
case
|
|
937
|
-
case
|
|
902
|
+
case 'lookup-exact-match':
|
|
903
|
+
case 'lookup-approximate-match': {
|
|
938
904
|
const nextRange = rewritePlanRangeInstruction(instruction.sheetName, instruction.start, instruction.end, instruction.refKind, ownerSheetName, targetSheetName, transform);
|
|
939
905
|
if (!nextRange) {
|
|
940
906
|
return instruction;
|
|
941
907
|
}
|
|
942
908
|
const parsed = parseRangeAddress(formatQualifiedRangeReference(instruction.sheetName, nextRange.start, nextRange.end));
|
|
943
|
-
if (parsed.kind !==
|
|
909
|
+
if (parsed.kind !== 'cells') {
|
|
944
910
|
return instruction;
|
|
945
911
|
}
|
|
946
912
|
return {
|
|
@@ -952,53 +918,51 @@ function rewriteJsPlanInstruction(instruction, ownerSheetName, targetSheetName,
|
|
|
952
918
|
endCol: parsed.end.col,
|
|
953
919
|
};
|
|
954
920
|
}
|
|
955
|
-
case
|
|
921
|
+
case 'call':
|
|
956
922
|
return instruction.argRefs
|
|
957
923
|
? {
|
|
958
924
|
...instruction,
|
|
959
|
-
argRefs: instruction.argRefs.map((argRef) => argRef
|
|
960
|
-
? rewriteReferenceOperand(argRef, ownerSheetName, targetSheetName, transform)
|
|
961
|
-
: argRef),
|
|
925
|
+
argRefs: instruction.argRefs.map((argRef) => argRef ? rewriteReferenceOperand(argRef, ownerSheetName, targetSheetName, transform) : argRef),
|
|
962
926
|
}
|
|
963
927
|
: instruction;
|
|
964
|
-
case
|
|
928
|
+
case 'push-lambda':
|
|
965
929
|
return {
|
|
966
930
|
...instruction,
|
|
967
931
|
body: instruction.body.map((step) => rewriteJsPlanInstruction(step, ownerSheetName, targetSheetName, transform)),
|
|
968
932
|
};
|
|
969
|
-
case
|
|
970
|
-
case
|
|
971
|
-
case
|
|
972
|
-
case
|
|
973
|
-
case
|
|
974
|
-
case
|
|
975
|
-
case
|
|
976
|
-
case
|
|
977
|
-
case
|
|
978
|
-
case
|
|
979
|
-
case
|
|
980
|
-
case
|
|
981
|
-
case
|
|
982
|
-
case
|
|
933
|
+
case 'push-number':
|
|
934
|
+
case 'push-boolean':
|
|
935
|
+
case 'push-string':
|
|
936
|
+
case 'push-error':
|
|
937
|
+
case 'push-name':
|
|
938
|
+
case 'unary':
|
|
939
|
+
case 'binary':
|
|
940
|
+
case 'invoke':
|
|
941
|
+
case 'begin-scope':
|
|
942
|
+
case 'bind-name':
|
|
943
|
+
case 'end-scope':
|
|
944
|
+
case 'jump-if-false':
|
|
945
|
+
case 'jump':
|
|
946
|
+
case 'return':
|
|
983
947
|
return instruction;
|
|
984
948
|
}
|
|
985
949
|
}
|
|
986
950
|
function translateJsPlanInstruction(instruction, rowDelta, colDelta) {
|
|
987
951
|
switch (instruction.opcode) {
|
|
988
|
-
case
|
|
952
|
+
case 'push-cell':
|
|
989
953
|
return {
|
|
990
954
|
...instruction,
|
|
991
955
|
address: translateCellReference(instruction.address, rowDelta, colDelta),
|
|
992
956
|
};
|
|
993
|
-
case
|
|
957
|
+
case 'push-range': {
|
|
994
958
|
const nextRange = translatePlanRangeInstruction(instruction.sheetName, instruction.start, instruction.end, rowDelta, colDelta);
|
|
995
959
|
return { ...instruction, ...nextRange };
|
|
996
960
|
}
|
|
997
|
-
case
|
|
998
|
-
case
|
|
961
|
+
case 'lookup-exact-match':
|
|
962
|
+
case 'lookup-approximate-match': {
|
|
999
963
|
const nextRange = translatePlanRangeInstruction(instruction.sheetName, instruction.start, instruction.end, rowDelta, colDelta);
|
|
1000
964
|
const parsed = parseRangeAddress(formatQualifiedRangeReference(instruction.sheetName, nextRange.start, nextRange.end));
|
|
1001
|
-
if (parsed.kind !==
|
|
965
|
+
if (parsed.kind !== 'cells') {
|
|
1002
966
|
return instruction;
|
|
1003
967
|
}
|
|
1004
968
|
return {
|
|
@@ -1010,38 +974,38 @@ function translateJsPlanInstruction(instruction, rowDelta, colDelta) {
|
|
|
1010
974
|
endCol: parsed.end.col,
|
|
1011
975
|
};
|
|
1012
976
|
}
|
|
1013
|
-
case
|
|
977
|
+
case 'call':
|
|
1014
978
|
return instruction.argRefs
|
|
1015
979
|
? {
|
|
1016
980
|
...instruction,
|
|
1017
|
-
argRefs: instruction.argRefs.map((argRef) => argRef ? translateReferenceOperand(argRef, rowDelta, colDelta) : argRef),
|
|
981
|
+
argRefs: instruction.argRefs.map((argRef) => (argRef ? translateReferenceOperand(argRef, rowDelta, colDelta) : argRef)),
|
|
1018
982
|
}
|
|
1019
983
|
: instruction;
|
|
1020
|
-
case
|
|
984
|
+
case 'push-lambda':
|
|
1021
985
|
return {
|
|
1022
986
|
...instruction,
|
|
1023
987
|
body: instruction.body.map((step) => translateJsPlanInstruction(step, rowDelta, colDelta)),
|
|
1024
988
|
};
|
|
1025
|
-
case
|
|
1026
|
-
case
|
|
1027
|
-
case
|
|
1028
|
-
case
|
|
1029
|
-
case
|
|
1030
|
-
case
|
|
1031
|
-
case
|
|
1032
|
-
case
|
|
1033
|
-
case
|
|
1034
|
-
case
|
|
1035
|
-
case
|
|
1036
|
-
case
|
|
1037
|
-
case
|
|
1038
|
-
case
|
|
989
|
+
case 'push-number':
|
|
990
|
+
case 'push-boolean':
|
|
991
|
+
case 'push-string':
|
|
992
|
+
case 'push-error':
|
|
993
|
+
case 'push-name':
|
|
994
|
+
case 'unary':
|
|
995
|
+
case 'binary':
|
|
996
|
+
case 'invoke':
|
|
997
|
+
case 'begin-scope':
|
|
998
|
+
case 'bind-name':
|
|
999
|
+
case 'end-scope':
|
|
1000
|
+
case 'jump-if-false':
|
|
1001
|
+
case 'jump':
|
|
1002
|
+
case 'return':
|
|
1039
1003
|
return instruction;
|
|
1040
1004
|
}
|
|
1041
1005
|
}
|
|
1042
1006
|
function translateJsPlanInstructionWithoutAst(instruction, translatedCellMap, translatedRangeMap, rowDelta, colDelta) {
|
|
1043
1007
|
switch (instruction.opcode) {
|
|
1044
|
-
case
|
|
1008
|
+
case 'push-cell': {
|
|
1045
1009
|
const translated = translatedCellMap.get(translatedCellInstructionKey(instruction.sheetName, instruction.address));
|
|
1046
1010
|
return translated
|
|
1047
1011
|
? {
|
|
@@ -1050,7 +1014,7 @@ function translateJsPlanInstructionWithoutAst(instruction, translatedCellMap, tr
|
|
|
1050
1014
|
}
|
|
1051
1015
|
: translateJsPlanInstruction(instruction, rowDelta, colDelta);
|
|
1052
1016
|
}
|
|
1053
|
-
case
|
|
1017
|
+
case 'push-range': {
|
|
1054
1018
|
const translated = translatedRangeMap.get(translatedRangeInstructionKey(instruction.sheetName, instruction.refKind, instruction.start, instruction.end));
|
|
1055
1019
|
return translated
|
|
1056
1020
|
? {
|
|
@@ -1060,10 +1024,10 @@ function translateJsPlanInstructionWithoutAst(instruction, translatedCellMap, tr
|
|
|
1060
1024
|
}
|
|
1061
1025
|
: translateJsPlanInstruction(instruction, rowDelta, colDelta);
|
|
1062
1026
|
}
|
|
1063
|
-
case
|
|
1064
|
-
case
|
|
1027
|
+
case 'lookup-exact-match':
|
|
1028
|
+
case 'lookup-approximate-match': {
|
|
1065
1029
|
const translated = translatedRangeMap.get(translatedRangeInstructionKey(instruction.sheetName, instruction.refKind, instruction.start, instruction.end));
|
|
1066
|
-
if (!translated || translated.refKind !==
|
|
1030
|
+
if (!translated || translated.refKind !== 'cells') {
|
|
1067
1031
|
return translateJsPlanInstruction(instruction, rowDelta, colDelta);
|
|
1068
1032
|
}
|
|
1069
1033
|
return {
|
|
@@ -1076,68 +1040,66 @@ function translateJsPlanInstructionWithoutAst(instruction, translatedCellMap, tr
|
|
|
1076
1040
|
endCol: translated.endCol,
|
|
1077
1041
|
};
|
|
1078
1042
|
}
|
|
1079
|
-
case
|
|
1043
|
+
case 'call':
|
|
1080
1044
|
return instruction.argRefs
|
|
1081
1045
|
? {
|
|
1082
1046
|
...instruction,
|
|
1083
|
-
argRefs: instruction.argRefs.map((argRef) => argRef
|
|
1084
|
-
? translateReferenceOperandWithoutAst(argRef, translatedCellMap, translatedRangeMap, rowDelta, colDelta)
|
|
1085
|
-
: argRef),
|
|
1047
|
+
argRefs: instruction.argRefs.map((argRef) => argRef ? translateReferenceOperandWithoutAst(argRef, translatedCellMap, translatedRangeMap, rowDelta, colDelta) : argRef),
|
|
1086
1048
|
}
|
|
1087
1049
|
: instruction;
|
|
1088
|
-
case
|
|
1050
|
+
case 'push-lambda':
|
|
1089
1051
|
return {
|
|
1090
1052
|
...instruction,
|
|
1091
1053
|
body: instruction.body.map((step) => translateJsPlanInstructionWithoutAst(step, translatedCellMap, translatedRangeMap, rowDelta, colDelta)),
|
|
1092
1054
|
};
|
|
1093
|
-
case
|
|
1094
|
-
case
|
|
1095
|
-
case
|
|
1096
|
-
case
|
|
1097
|
-
case
|
|
1098
|
-
case
|
|
1099
|
-
case
|
|
1100
|
-
case
|
|
1101
|
-
case
|
|
1102
|
-
case
|
|
1103
|
-
case
|
|
1104
|
-
case
|
|
1105
|
-
case
|
|
1106
|
-
case
|
|
1055
|
+
case 'push-number':
|
|
1056
|
+
case 'push-boolean':
|
|
1057
|
+
case 'push-string':
|
|
1058
|
+
case 'push-error':
|
|
1059
|
+
case 'push-name':
|
|
1060
|
+
case 'unary':
|
|
1061
|
+
case 'binary':
|
|
1062
|
+
case 'invoke':
|
|
1063
|
+
case 'begin-scope':
|
|
1064
|
+
case 'bind-name':
|
|
1065
|
+
case 'end-scope':
|
|
1066
|
+
case 'jump-if-false':
|
|
1067
|
+
case 'jump':
|
|
1068
|
+
case 'return':
|
|
1107
1069
|
return instruction;
|
|
1108
1070
|
}
|
|
1109
1071
|
}
|
|
1110
1072
|
function rewriteReferenceOperand(operand, ownerSheetName, targetSheetName, transform) {
|
|
1111
1073
|
switch (operand.kind) {
|
|
1112
|
-
case
|
|
1074
|
+
case 'cell':
|
|
1113
1075
|
return operand.address
|
|
1114
1076
|
? {
|
|
1115
1077
|
...operand,
|
|
1116
1078
|
address: rewriteReferenceOperandAddress(operand.sheetName, operand.address, ownerSheetName, targetSheetName, transform),
|
|
1117
1079
|
}
|
|
1118
1080
|
: operand;
|
|
1119
|
-
case
|
|
1081
|
+
case 'range': {
|
|
1120
1082
|
if (!operand.start || !operand.end || !operand.refKind) {
|
|
1121
1083
|
return operand;
|
|
1122
1084
|
}
|
|
1123
1085
|
const nextRange = rewritePlanRangeInstruction(operand.sheetName, operand.start, operand.end, operand.refKind, ownerSheetName, targetSheetName, transform);
|
|
1124
1086
|
return nextRange ? { ...operand, ...nextRange } : operand;
|
|
1125
1087
|
}
|
|
1126
|
-
case
|
|
1127
|
-
case
|
|
1088
|
+
case 'row':
|
|
1089
|
+
case 'col':
|
|
1128
1090
|
return operand;
|
|
1129
1091
|
}
|
|
1130
1092
|
}
|
|
1131
1093
|
function translateReferenceOperand(operand, rowDelta, colDelta) {
|
|
1132
1094
|
switch (operand.kind) {
|
|
1133
|
-
case
|
|
1095
|
+
case 'cell':
|
|
1134
1096
|
return operand.address
|
|
1135
1097
|
? {
|
|
1136
1098
|
...operand,
|
|
1137
1099
|
address: translateCellReference(operand.address, rowDelta, colDelta),
|
|
1138
1100
|
}
|
|
1139
1101
|
: operand;
|
|
1140
|
-
case
|
|
1102
|
+
case 'range':
|
|
1141
1103
|
if (!operand.start || !operand.end || !operand.refKind) {
|
|
1142
1104
|
return operand;
|
|
1143
1105
|
}
|
|
@@ -1145,14 +1107,14 @@ function translateReferenceOperand(operand, rowDelta, colDelta) {
|
|
|
1145
1107
|
...operand,
|
|
1146
1108
|
...translatePlanRangeInstruction(operand.sheetName, operand.start, operand.end, rowDelta, colDelta),
|
|
1147
1109
|
};
|
|
1148
|
-
case
|
|
1110
|
+
case 'row':
|
|
1149
1111
|
return operand.address
|
|
1150
1112
|
? {
|
|
1151
1113
|
...operand,
|
|
1152
1114
|
address: translateRowReference(operand.address, rowDelta),
|
|
1153
1115
|
}
|
|
1154
1116
|
: operand;
|
|
1155
|
-
case
|
|
1117
|
+
case 'col':
|
|
1156
1118
|
return operand.address
|
|
1157
1119
|
? {
|
|
1158
1120
|
...operand,
|
|
@@ -1163,7 +1125,7 @@ function translateReferenceOperand(operand, rowDelta, colDelta) {
|
|
|
1163
1125
|
}
|
|
1164
1126
|
function translateReferenceOperandWithoutAst(operand, translatedCellMap, translatedRangeMap, rowDelta, colDelta) {
|
|
1165
1127
|
switch (operand.kind) {
|
|
1166
|
-
case
|
|
1128
|
+
case 'cell': {
|
|
1167
1129
|
if (!operand.address) {
|
|
1168
1130
|
return operand;
|
|
1169
1131
|
}
|
|
@@ -1175,7 +1137,7 @@ function translateReferenceOperandWithoutAst(operand, translatedCellMap, transla
|
|
|
1175
1137
|
}
|
|
1176
1138
|
: translateReferenceOperand(operand, rowDelta, colDelta);
|
|
1177
1139
|
}
|
|
1178
|
-
case
|
|
1140
|
+
case 'range': {
|
|
1179
1141
|
if (!operand.start || !operand.end || !operand.refKind) {
|
|
1180
1142
|
return operand;
|
|
1181
1143
|
}
|
|
@@ -1189,8 +1151,8 @@ function translateReferenceOperandWithoutAst(operand, translatedCellMap, transla
|
|
|
1189
1151
|
}
|
|
1190
1152
|
: translateReferenceOperand(operand, rowDelta, colDelta);
|
|
1191
1153
|
}
|
|
1192
|
-
case
|
|
1193
|
-
case
|
|
1154
|
+
case 'row':
|
|
1155
|
+
case 'col':
|
|
1194
1156
|
return translateReferenceOperand(operand, rowDelta, colDelta);
|
|
1195
1157
|
}
|
|
1196
1158
|
}
|
|
@@ -1204,7 +1166,7 @@ function rewritePlanRangeInstruction(explicitSheetName, start, end, refKind, own
|
|
|
1204
1166
|
if ((explicitSheetName ?? ownerSheetName) !== targetSheetName) {
|
|
1205
1167
|
return undefined;
|
|
1206
1168
|
}
|
|
1207
|
-
if (refKind ===
|
|
1169
|
+
if (refKind === 'cells') {
|
|
1208
1170
|
const nextRange = rewriteRangeForStructuralTransform(start, end, transform);
|
|
1209
1171
|
return nextRange
|
|
1210
1172
|
? {
|
|
@@ -1213,8 +1175,7 @@ function rewritePlanRangeInstruction(explicitSheetName, start, end, refKind, own
|
|
|
1213
1175
|
}
|
|
1214
1176
|
: undefined;
|
|
1215
1177
|
}
|
|
1216
|
-
if ((refKind ===
|
|
1217
|
-
(refKind === "cols" && transform.axis !== "column")) {
|
|
1178
|
+
if ((refKind === 'rows' && transform.axis !== 'row') || (refKind === 'cols' && transform.axis !== 'column')) {
|
|
1218
1179
|
return undefined;
|
|
1219
1180
|
}
|
|
1220
1181
|
const parsed = parseRangeAddress(formatQualifiedRangeReference(explicitSheetName, start, end));
|
|
@@ -1242,7 +1203,7 @@ function formatQualifiedCellReference(sheetName, address) {
|
|
|
1242
1203
|
return `${quoteSheetNameIfNeeded(sheetName)}!${parsed.text}`;
|
|
1243
1204
|
}
|
|
1244
1205
|
function formatQualifiedRangeReference(sheetName, start, end) {
|
|
1245
|
-
const prefix = sheetName ? `${quoteSheetNameIfNeeded(sheetName)}!` :
|
|
1206
|
+
const prefix = sheetName ? `${quoteSheetNameIfNeeded(sheetName)}!` : '';
|
|
1246
1207
|
return `${prefix}${start}:${end}`;
|
|
1247
1208
|
}
|
|
1248
1209
|
function translateCellReference(ref, rowDelta, colDelta) {
|
|
@@ -1258,7 +1219,7 @@ function translateCellReference(ref, rowDelta, colDelta) {
|
|
|
1258
1219
|
return formatCellReference(parsed, nextRow, nextCol);
|
|
1259
1220
|
}
|
|
1260
1221
|
function translateColumnReference(ref, colDelta) {
|
|
1261
|
-
const parsed = parseAxisReferenceParts(ref,
|
|
1222
|
+
const parsed = parseAxisReferenceParts(ref, 'column');
|
|
1262
1223
|
if (!parsed) {
|
|
1263
1224
|
throw new Error(`Invalid column reference '${ref}'`);
|
|
1264
1225
|
}
|
|
@@ -1266,10 +1227,10 @@ function translateColumnReference(ref, colDelta) {
|
|
|
1266
1227
|
if (nextCol < 0) {
|
|
1267
1228
|
throw new Error(`Translated reference moved outside worksheet bounds: ${ref}`);
|
|
1268
1229
|
}
|
|
1269
|
-
return formatAxisReference(parsed.absolute, nextCol,
|
|
1230
|
+
return formatAxisReference(parsed.absolute, nextCol, 'column');
|
|
1270
1231
|
}
|
|
1271
1232
|
function translateRowReference(ref, rowDelta) {
|
|
1272
|
-
const parsed = parseAxisReferenceParts(ref,
|
|
1233
|
+
const parsed = parseAxisReferenceParts(ref, 'row');
|
|
1273
1234
|
if (!parsed) {
|
|
1274
1235
|
throw new Error(`Invalid row reference '${ref}'`);
|
|
1275
1236
|
}
|
|
@@ -1277,59 +1238,58 @@ function translateRowReference(ref, rowDelta) {
|
|
|
1277
1238
|
if (nextRow < 0) {
|
|
1278
1239
|
throw new Error(`Translated reference moved outside worksheet bounds: ${ref}`);
|
|
1279
1240
|
}
|
|
1280
|
-
return formatAxisReference(parsed.absolute, nextRow,
|
|
1241
|
+
return formatAxisReference(parsed.absolute, nextRow, 'row');
|
|
1281
1242
|
}
|
|
1282
1243
|
export function serializeFormula(node, parentPrecedence = 0, parentAssociativity = null) {
|
|
1283
1244
|
switch (node.kind) {
|
|
1284
|
-
case
|
|
1245
|
+
case 'NumberLiteral':
|
|
1285
1246
|
return String(node.value);
|
|
1286
|
-
case
|
|
1287
|
-
return node.value ?
|
|
1288
|
-
case
|
|
1247
|
+
case 'BooleanLiteral':
|
|
1248
|
+
return node.value ? 'TRUE' : 'FALSE';
|
|
1249
|
+
case 'StringLiteral':
|
|
1289
1250
|
return `"${node.value.replaceAll('"', '""')}"`;
|
|
1290
|
-
case
|
|
1291
|
-
return ERROR_LITERAL_TEXT[node.code] ??
|
|
1292
|
-
case
|
|
1251
|
+
case 'ErrorLiteral':
|
|
1252
|
+
return ERROR_LITERAL_TEXT[node.code] ?? '#ERROR!';
|
|
1253
|
+
case 'NameRef':
|
|
1293
1254
|
return node.name;
|
|
1294
|
-
case
|
|
1255
|
+
case 'StructuredRef':
|
|
1295
1256
|
return `${node.tableName}[${node.columnName}]`;
|
|
1296
|
-
case
|
|
1257
|
+
case 'CellRef':
|
|
1297
1258
|
return `${formatSheetPrefix(node.sheetName)}${node.ref}`;
|
|
1298
|
-
case
|
|
1259
|
+
case 'SpillRef':
|
|
1299
1260
|
return `${formatSheetPrefix(node.sheetName)}${node.ref}#`;
|
|
1300
|
-
case
|
|
1261
|
+
case 'ColumnRef':
|
|
1301
1262
|
return `${formatSheetPrefix(node.sheetName)}${node.ref}`;
|
|
1302
|
-
case
|
|
1263
|
+
case 'RowRef':
|
|
1303
1264
|
return `${formatSheetPrefix(node.sheetName)}${node.ref}`;
|
|
1304
|
-
case
|
|
1265
|
+
case 'RangeRef':
|
|
1305
1266
|
return `${formatSheetPrefix(node.sheetName)}${node.start}:${node.end}`;
|
|
1306
|
-
case
|
|
1267
|
+
case 'UnaryExpr':
|
|
1307
1268
|
return `${node.operator}${serializeFormula(node.argument, 6)}`;
|
|
1308
|
-
case
|
|
1309
|
-
return `${node.callee}(${node.args.map((arg) => serializeFormula(arg)).join(
|
|
1310
|
-
case
|
|
1311
|
-
const callee = node.callee.kind ===
|
|
1269
|
+
case 'CallExpr':
|
|
1270
|
+
return `${node.callee}(${node.args.map((arg) => serializeFormula(arg)).join(',')})`;
|
|
1271
|
+
case 'InvokeExpr': {
|
|
1272
|
+
const callee = node.callee.kind === 'CallExpr' || node.callee.kind === 'InvokeExpr'
|
|
1312
1273
|
? serializeFormula(node.callee)
|
|
1313
1274
|
: `(${serializeFormula(node.callee)})`;
|
|
1314
|
-
return `${callee}(${node.args.map((arg) => serializeFormula(arg)).join(
|
|
1275
|
+
return `${callee}(${node.args.map((arg) => serializeFormula(arg)).join(',')})`;
|
|
1315
1276
|
}
|
|
1316
|
-
case
|
|
1277
|
+
case 'BinaryExpr': {
|
|
1317
1278
|
const precedence = BINARY_PRECEDENCE[node.operator];
|
|
1318
|
-
const isRightAssociative = node.operator ===
|
|
1319
|
-
const left = serializeFormula(node.left, precedence,
|
|
1320
|
-
const right = serializeFormula(node.right, precedence,
|
|
1279
|
+
const isRightAssociative = node.operator === '^';
|
|
1280
|
+
const left = serializeFormula(node.left, precedence, 'left');
|
|
1281
|
+
const right = serializeFormula(node.right, precedence, 'right');
|
|
1321
1282
|
const output = `${left}${node.operator}${right}`;
|
|
1322
1283
|
const needsParens = precedence < parentPrecedence ||
|
|
1323
1284
|
(precedence === parentPrecedence &&
|
|
1324
|
-
((parentAssociativity ===
|
|
1325
|
-
(parentAssociativity === "right" && !isRightAssociative)));
|
|
1285
|
+
((parentAssociativity === 'left' && isRightAssociative) || (parentAssociativity === 'right' && !isRightAssociative)));
|
|
1326
1286
|
return needsParens ? `(${output})` : output;
|
|
1327
1287
|
}
|
|
1328
1288
|
}
|
|
1329
1289
|
}
|
|
1330
1290
|
function formatSheetPrefix(sheetName) {
|
|
1331
1291
|
if (!sheetName) {
|
|
1332
|
-
return
|
|
1292
|
+
return '';
|
|
1333
1293
|
}
|
|
1334
1294
|
return `${quoteSheetNameIfNeeded(sheetName)}!`;
|
|
1335
1295
|
}
|
|
@@ -1345,7 +1305,7 @@ function columnToIndex(column) {
|
|
|
1345
1305
|
}
|
|
1346
1306
|
function indexToColumn(index) {
|
|
1347
1307
|
let current = index + 1;
|
|
1348
|
-
let output =
|
|
1308
|
+
let output = '';
|
|
1349
1309
|
while (current > 0) {
|
|
1350
1310
|
const remainder = (current - 1) % 26;
|
|
1351
1311
|
output = String.fromCharCode(65 + remainder) + output;
|
|
@@ -1363,39 +1323,39 @@ function parseCellReferenceParts(ref) {
|
|
|
1363
1323
|
}
|
|
1364
1324
|
const [, colAbsolute, columnText, rowAbsolute, rowText] = match;
|
|
1365
1325
|
return {
|
|
1366
|
-
colAbsolute: colAbsolute ===
|
|
1367
|
-
rowAbsolute: rowAbsolute ===
|
|
1326
|
+
colAbsolute: colAbsolute === '$',
|
|
1327
|
+
rowAbsolute: rowAbsolute === '$',
|
|
1368
1328
|
col: columnToIndex(columnText),
|
|
1369
1329
|
row: Number.parseInt(rowText, 10) - 1,
|
|
1370
1330
|
};
|
|
1371
1331
|
}
|
|
1372
1332
|
function formatCellReference(parts, row, col) {
|
|
1373
|
-
return `${parts.colAbsolute ?
|
|
1333
|
+
return `${parts.colAbsolute ? '$' : ''}${indexToColumn(col)}${parts.rowAbsolute ? '$' : ''}${row + 1}`;
|
|
1374
1334
|
}
|
|
1375
1335
|
function parseAxisReferenceParts(ref, kind) {
|
|
1376
|
-
const match = (kind ===
|
|
1336
|
+
const match = (kind === 'row' ? ROW_REF_RE : COLUMN_REF_RE).exec(ref.toUpperCase());
|
|
1377
1337
|
if (!match) {
|
|
1378
1338
|
return undefined;
|
|
1379
1339
|
}
|
|
1380
|
-
return kind ===
|
|
1340
|
+
return kind === 'row'
|
|
1381
1341
|
? {
|
|
1382
|
-
absolute: match[1] ===
|
|
1342
|
+
absolute: match[1] === '$',
|
|
1383
1343
|
index: Number.parseInt(match[2], 10) - 1,
|
|
1384
1344
|
}
|
|
1385
1345
|
: {
|
|
1386
|
-
absolute: match[1] ===
|
|
1346
|
+
absolute: match[1] === '$',
|
|
1387
1347
|
index: columnToIndex(match[2]),
|
|
1388
1348
|
};
|
|
1389
1349
|
}
|
|
1390
1350
|
function formatAxisReference(absolute, index, kind) {
|
|
1391
|
-
const prefix = absolute ?
|
|
1392
|
-
return kind ===
|
|
1351
|
+
const prefix = absolute ? '$' : '';
|
|
1352
|
+
return kind === 'row' ? `${prefix}${index + 1}` : `${prefix}${indexToColumn(index)}`;
|
|
1393
1353
|
}
|
|
1394
1354
|
function mapPointIndex(index, transform) {
|
|
1395
1355
|
switch (transform.kind) {
|
|
1396
|
-
case
|
|
1356
|
+
case 'insert':
|
|
1397
1357
|
return index >= transform.start ? index + transform.count : index;
|
|
1398
|
-
case
|
|
1358
|
+
case 'delete':
|
|
1399
1359
|
if (index < transform.start) {
|
|
1400
1360
|
return index;
|
|
1401
1361
|
}
|
|
@@ -1403,15 +1363,14 @@ function mapPointIndex(index, transform) {
|
|
|
1403
1363
|
return index - transform.count;
|
|
1404
1364
|
}
|
|
1405
1365
|
return undefined;
|
|
1406
|
-
case
|
|
1366
|
+
case 'move':
|
|
1407
1367
|
if (transform.target < transform.start) {
|
|
1408
1368
|
if (index >= transform.target && index < transform.start) {
|
|
1409
1369
|
return index + transform.count;
|
|
1410
1370
|
}
|
|
1411
1371
|
}
|
|
1412
1372
|
else if (transform.target > transform.start) {
|
|
1413
|
-
if (index >= transform.start + transform.count &&
|
|
1414
|
-
index < transform.target + transform.count) {
|
|
1373
|
+
if (index >= transform.start + transform.count && index < transform.target + transform.count) {
|
|
1415
1374
|
return index - transform.count;
|
|
1416
1375
|
}
|
|
1417
1376
|
}
|
|
@@ -1425,7 +1384,7 @@ function mapPointIndex(index, transform) {
|
|
|
1425
1384
|
}
|
|
1426
1385
|
function mapInterval(start, end, transform) {
|
|
1427
1386
|
switch (transform.kind) {
|
|
1428
|
-
case
|
|
1387
|
+
case 'insert': {
|
|
1429
1388
|
if (transform.start <= start) {
|
|
1430
1389
|
return { start: start + transform.count, end: end + transform.count };
|
|
1431
1390
|
}
|
|
@@ -1434,7 +1393,7 @@ function mapInterval(start, end, transform) {
|
|
|
1434
1393
|
}
|
|
1435
1394
|
return { start, end };
|
|
1436
1395
|
}
|
|
1437
|
-
case
|
|
1396
|
+
case 'delete': {
|
|
1438
1397
|
const deleteEnd = transform.start + transform.count - 1;
|
|
1439
1398
|
if (deleteEnd < start) {
|
|
1440
1399
|
return { start: start - transform.count, end: end - transform.count };
|
|
@@ -1449,11 +1408,9 @@ function mapInterval(start, end, transform) {
|
|
|
1449
1408
|
}
|
|
1450
1409
|
const nextStart = mapPointIndex(survivingStart, transform);
|
|
1451
1410
|
const nextEnd = mapPointIndex(survivingEnd, transform);
|
|
1452
|
-
return nextStart === undefined || nextEnd === undefined
|
|
1453
|
-
? undefined
|
|
1454
|
-
: { start: nextStart, end: nextEnd };
|
|
1411
|
+
return nextStart === undefined || nextEnd === undefined ? undefined : { start: nextStart, end: nextEnd };
|
|
1455
1412
|
}
|
|
1456
|
-
case
|
|
1413
|
+
case 'move': {
|
|
1457
1414
|
const segments = transform.target < transform.start
|
|
1458
1415
|
? [
|
|
1459
1416
|
{ start: 0, end: transform.target - 1, delta: 0 },
|