@trebco/treb 31.9.1 → 32.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/treb-spreadsheet.mjs +8 -8
- package/i18n/languages/treb-i18n-da.mjs +1 -0
- package/i18n/languages/treb-i18n-de.mjs +1 -0
- package/i18n/languages/treb-i18n-es.mjs +1 -0
- package/i18n/languages/treb-i18n-fr.mjs +1 -0
- package/i18n/languages/treb-i18n-it.mjs +1 -0
- package/i18n/languages/treb-i18n-nl.mjs +1 -0
- package/i18n/languages/treb-i18n-no.mjs +1 -0
- package/i18n/languages/treb-i18n-pl.mjs +1 -0
- package/i18n/languages/treb-i18n-pt.mjs +1 -0
- package/i18n/languages/treb-i18n-sv.mjs +1 -0
- package/package.json +1 -1
- package/treb-base-types/src/union.ts +6 -0
- package/treb-base-types/src/value-type.ts +13 -0
- package/treb-calculator/src/calculator.ts +18 -1
- package/treb-calculator/src/descriptors.ts +42 -3
- package/treb-calculator/src/expression-calculator.ts +182 -6
- package/treb-calculator/src/functions/base-functions.ts +48 -0
- package/treb-calculator/src/functions/lambda-functions.ts +96 -0
- package/treb-data-model/src/data_model.ts +28 -13
- package/treb-data-model/src/named.ts +7 -0
- package/treb-data-model/src/sheet.ts +17 -0
- package/treb-embed/src/embedded-spreadsheet.ts +12 -3
- package/treb-embed/style/theme-defaults.scss +0 -22
- package/treb-grid/src/types/grid.ts +4 -3
- package/treb-parser/src/parser-types.ts +21 -0
- package/treb-parser/src/parser.ts +126 -218
- package/dist/treb-export-worker.mjs +0 -2
- package/dist/treb.d.ts +0 -2235
|
@@ -351,6 +351,54 @@ export const BaseFunctionLibrary: FunctionMap = {
|
|
|
351
351
|
fn: () => { return { type: ValueType.number, value: Math.random() }},
|
|
352
352
|
},
|
|
353
353
|
|
|
354
|
+
RandArray: {
|
|
355
|
+
volatile: true,
|
|
356
|
+
arguments: [
|
|
357
|
+
{name: 'rows'},
|
|
358
|
+
{name: 'columns'},
|
|
359
|
+
{name: 'min'},
|
|
360
|
+
{name: 'max'},
|
|
361
|
+
{name: 'integer'},
|
|
362
|
+
],
|
|
363
|
+
description: 'Returns an array of uniformly-distributed random numbers',
|
|
364
|
+
fn: (rows = 1, columns = 1, min = 0, max = 1, integer = false) => {
|
|
365
|
+
const value: UnionValue[][] = [];
|
|
366
|
+
|
|
367
|
+
if (integer) {
|
|
368
|
+
const range = max - min + 1;
|
|
369
|
+
for (let i = 0; i < rows; i++) {
|
|
370
|
+
const row: UnionValue[] = [];
|
|
371
|
+
for (let j = 0; j < columns; j++) {
|
|
372
|
+
row.push({
|
|
373
|
+
type: ValueType.number,
|
|
374
|
+
value: Math.floor(Math.random() * range + min),
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
value.push(row);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
else {
|
|
381
|
+
const range = max - min;
|
|
382
|
+
|
|
383
|
+
for (let i = 0; i < rows; i++) {
|
|
384
|
+
const row: UnionValue[] = [];
|
|
385
|
+
for (let j = 0; j < columns; j++) {
|
|
386
|
+
row.push({
|
|
387
|
+
type: ValueType.number,
|
|
388
|
+
value: Math.random() * range + min,
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
value.push(row);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
return {
|
|
396
|
+
type: ValueType.array,
|
|
397
|
+
value,
|
|
398
|
+
}
|
|
399
|
+
},
|
|
400
|
+
},
|
|
401
|
+
|
|
354
402
|
RandBetween: {
|
|
355
403
|
arguments: [{name: 'min'}, {name: 'max'}],
|
|
356
404
|
volatile: true,
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
|
|
2
|
+
import type { FunctionMap } from '../descriptors';
|
|
3
|
+
import type { UnionValue} from 'treb-base-types';
|
|
4
|
+
import { ValueType } from 'treb-base-types';
|
|
5
|
+
import type { ExpressionUnit } from 'treb-parser';
|
|
6
|
+
|
|
7
|
+
export const LambdaFunctionLibrary: FunctionMap = {
|
|
8
|
+
|
|
9
|
+
Lambda: {
|
|
10
|
+
|
|
11
|
+
// FIXME: we could use the create_binding_context callback
|
|
12
|
+
// here to validate the original parameters, might be useful
|
|
13
|
+
|
|
14
|
+
description: 'Creates a function',
|
|
15
|
+
arguments: [
|
|
16
|
+
{ name: 'Argument', repeat: true, boxed: true, passthrough: true },
|
|
17
|
+
{ name: 'Function', boxed: true, passthrough: true },
|
|
18
|
+
],
|
|
19
|
+
|
|
20
|
+
fn: (...args: ExpressionUnit[]) => {
|
|
21
|
+
return {
|
|
22
|
+
type: ValueType.function,
|
|
23
|
+
|
|
24
|
+
// FIXME: lock down this type
|
|
25
|
+
|
|
26
|
+
value: {
|
|
27
|
+
|
|
28
|
+
// we should probably clone these
|
|
29
|
+
|
|
30
|
+
bindings: args.slice(0, args.length - 1),
|
|
31
|
+
func: args[args.length - 1],
|
|
32
|
+
|
|
33
|
+
alt: 'LAMBDA', // metadata
|
|
34
|
+
type: 'function', // metadata
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
Let: {
|
|
43
|
+
|
|
44
|
+
// this function has weird semantics we don't normally see --
|
|
45
|
+
// the first two arguments repeat, and the last one is constant.
|
|
46
|
+
// our tooltips aren't prepared for this.
|
|
47
|
+
|
|
48
|
+
// also it creates temporary names, we'll need to create some sort
|
|
49
|
+
// of temporary binding context. complicated!
|
|
50
|
+
|
|
51
|
+
description: 'Binds values to names for a calculation',
|
|
52
|
+
arguments: [
|
|
53
|
+
{ name: 'Name', repeat: true },
|
|
54
|
+
{ name: 'Value', repeat: true },
|
|
55
|
+
{ name: 'Calculation', boxed: true },
|
|
56
|
+
],
|
|
57
|
+
|
|
58
|
+
create_binding_context: ({args, descriptors}) => {
|
|
59
|
+
|
|
60
|
+
if (args.length % 2 !== 1) {
|
|
61
|
+
return undefined; // error
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const context: Record<string, ExpressionUnit> = {};
|
|
65
|
+
|
|
66
|
+
for (let i = 0; i < args.length - 1; i += 2) {
|
|
67
|
+
const name = args[i];
|
|
68
|
+
const value = args[i+1];
|
|
69
|
+
|
|
70
|
+
if (name.type === 'identifier') {
|
|
71
|
+
context[name.name] = value;
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
return undefined; // error
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
context,
|
|
81
|
+
args: args.slice(-1),
|
|
82
|
+
argument_descriptors: descriptors.slice(-1),
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
fn: (arg?: UnionValue) => {
|
|
87
|
+
return arg ? arg : { type: ValueType.undefined };
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
|
|
@@ -111,13 +111,17 @@ export class DataModel {
|
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
/**
|
|
114
|
-
*
|
|
114
|
+
* @param force_locale - always parse assuming a locale like en-us (comma
|
|
115
|
+
* argument separators). the current thinking is that this is required for
|
|
116
|
+
* XLSX import, although that might be incorrect.
|
|
115
117
|
*/
|
|
116
|
-
public UnserializeNames(names: SerializedNamed[], active_sheet?: Sheet) {
|
|
118
|
+
public UnserializeNames(names: SerializedNamed[], active_sheet?: Sheet, force_locale = false) {
|
|
117
119
|
|
|
118
120
|
this.parser.Save();
|
|
119
|
-
|
|
120
|
-
|
|
121
|
+
if (force_locale) {
|
|
122
|
+
this.parser.SetLocaleSettings(DecimalMarkType.Period, ArgumentSeparatorType.Comma);
|
|
123
|
+
}
|
|
124
|
+
|
|
121
125
|
//const sorted = names.map(named => {
|
|
122
126
|
for (const named of names) {
|
|
123
127
|
|
|
@@ -197,6 +201,7 @@ export class DataModel {
|
|
|
197
201
|
const named: SerializedNamed = {
|
|
198
202
|
name: entry.name,
|
|
199
203
|
expression: '',
|
|
204
|
+
type: entry.type,
|
|
200
205
|
};
|
|
201
206
|
|
|
202
207
|
if (entry.scope) {
|
|
@@ -239,6 +244,11 @@ export class DataModel {
|
|
|
239
244
|
return true;
|
|
240
245
|
});
|
|
241
246
|
|
|
247
|
+
// this is using the current locale settings, but unserialize
|
|
248
|
+
// assumes we are unserializing in US-style locale. I think we
|
|
249
|
+
// do that because excel always uses that? not sure, but we need
|
|
250
|
+
// to be consistent.
|
|
251
|
+
|
|
242
252
|
named.expression = this.parser.Render(entry.expression, { missing: '' });
|
|
243
253
|
|
|
244
254
|
}
|
|
@@ -601,9 +611,9 @@ export class DataModel {
|
|
|
601
611
|
* be inlined (assuming it's only called in one place), but we are breaking
|
|
602
612
|
* it out so we can develop/test/manage it.
|
|
603
613
|
*/
|
|
604
|
-
public TranslateFunction(value: string): string {
|
|
614
|
+
public TranslateFunction(value: string, options?: { r1c1?: boolean }): string {
|
|
605
615
|
if (this.language_map) {
|
|
606
|
-
return this.TranslateInternal(value, this.language_map, this.language_model?.boolean_true, this.language_model?.boolean_false);
|
|
616
|
+
return this.TranslateInternal(value, this.language_map, this.language_model?.boolean_true, this.language_model?.boolean_false, options);
|
|
607
617
|
}
|
|
608
618
|
return value;
|
|
609
619
|
}
|
|
@@ -612,14 +622,14 @@ export class DataModel {
|
|
|
612
622
|
* translate from local language -> common (english).
|
|
613
623
|
* @see TranslateFunction
|
|
614
624
|
*/
|
|
615
|
-
public UntranslateFunction(value: string): string {
|
|
625
|
+
public UntranslateFunction(value: string, options?: { r1c1?: boolean }): string {
|
|
616
626
|
if (this.reverse_language_map) {
|
|
617
|
-
return this.TranslateInternal(value, this.reverse_language_map, 'TRUE', 'FALSE');
|
|
627
|
+
return this.TranslateInternal(value, this.reverse_language_map, 'TRUE', 'FALSE', options);
|
|
618
628
|
}
|
|
619
629
|
return value;
|
|
620
630
|
}
|
|
621
631
|
|
|
622
|
-
public UntranslateData(value: CellValue|CellValue[]|CellValue[][]): CellValue|CellValue[]|CellValue[][] {
|
|
632
|
+
public UntranslateData(value: CellValue|CellValue[]|CellValue[][], options?: { r1c1?: boolean }): CellValue|CellValue[]|CellValue[][] {
|
|
623
633
|
|
|
624
634
|
if (Array.isArray(value)) {
|
|
625
635
|
|
|
@@ -628,7 +638,7 @@ export class DataModel {
|
|
|
628
638
|
if (Is2DArray(value)) {
|
|
629
639
|
return value.map(row => row.map(entry => {
|
|
630
640
|
if (entry && typeof entry === 'string' && entry[0] === '=') {
|
|
631
|
-
return this.UntranslateFunction(entry);
|
|
641
|
+
return this.UntranslateFunction(entry, options);
|
|
632
642
|
}
|
|
633
643
|
return entry;
|
|
634
644
|
}));
|
|
@@ -636,7 +646,7 @@ export class DataModel {
|
|
|
636
646
|
else {
|
|
637
647
|
return value.map(entry => {
|
|
638
648
|
if (entry && typeof entry === 'string' && entry[0] === '=') {
|
|
639
|
-
return this.UntranslateFunction(entry);
|
|
649
|
+
return this.UntranslateFunction(entry, options);
|
|
640
650
|
}
|
|
641
651
|
return entry;
|
|
642
652
|
});
|
|
@@ -646,7 +656,7 @@ export class DataModel {
|
|
|
646
656
|
else if (value && typeof value === 'string' && value[0] === '=') {
|
|
647
657
|
|
|
648
658
|
// single value
|
|
649
|
-
value = this.UntranslateFunction(value);
|
|
659
|
+
value = this.UntranslateFunction(value, options);
|
|
650
660
|
|
|
651
661
|
}
|
|
652
662
|
|
|
@@ -663,7 +673,10 @@ export class DataModel {
|
|
|
663
673
|
* FIXME: it's about time we started using proper maps, we dropped
|
|
664
674
|
* support for IE11 some time ago.
|
|
665
675
|
*/
|
|
666
|
-
private TranslateInternal(value: string, map: Record<string, string>, boolean_true?: string, boolean_false?: string): string {
|
|
676
|
+
private TranslateInternal(value: string, map: Record<string, string>, boolean_true?: string, boolean_false?: string, options?: { r1c1?: boolean }): string {
|
|
677
|
+
|
|
678
|
+
this.parser.Save();
|
|
679
|
+
this.parser.flags.r1c1 = options?.r1c1;
|
|
667
680
|
|
|
668
681
|
const parse_result = this.parser.Parse(value);
|
|
669
682
|
|
|
@@ -694,10 +707,12 @@ export class DataModel {
|
|
|
694
707
|
if (modified) {
|
|
695
708
|
return '=' + this.parser.Render(parse_result.expression, {
|
|
696
709
|
missing: '', boolean_true, boolean_false,
|
|
710
|
+
r1c1: options?.r1c1,
|
|
697
711
|
});
|
|
698
712
|
}
|
|
699
713
|
}
|
|
700
714
|
|
|
715
|
+
this.parser.Restore();
|
|
701
716
|
return value;
|
|
702
717
|
|
|
703
718
|
}
|
|
@@ -33,6 +33,7 @@ interface NamedRange {
|
|
|
33
33
|
area: Area;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
/** @internal */
|
|
36
37
|
export type Named = (NamedExpression | NamedRange) & {
|
|
37
38
|
name: string; // canonical name
|
|
38
39
|
scope?: number; // scope to sheet by ID
|
|
@@ -57,6 +58,12 @@ export interface SerializedNamed {
|
|
|
57
58
|
/** scope is a sheet name (not ID) */
|
|
58
59
|
scope?: string;
|
|
59
60
|
|
|
61
|
+
/**
|
|
62
|
+
* adding type. this is optional, it's not used by tooling. it's
|
|
63
|
+
* just for informational purpopses for clients.
|
|
64
|
+
*/
|
|
65
|
+
type?: 'range'|'expression';
|
|
66
|
+
|
|
60
67
|
}
|
|
61
68
|
|
|
62
69
|
/**
|
|
@@ -1631,6 +1631,23 @@ export class Sheet {
|
|
|
1631
1631
|
cell.rendered_type = ValueType.dimensioned_quantity; // who cares about rendered_type? (...)
|
|
1632
1632
|
|
|
1633
1633
|
}
|
|
1634
|
+
else if (type === ValueType.function) {
|
|
1635
|
+
|
|
1636
|
+
/*
|
|
1637
|
+
// FIXME: lock down this type (function)
|
|
1638
|
+
|
|
1639
|
+
if ((cell.calculated as any)?.alt) {
|
|
1640
|
+
cell.formatted = (cell.calculated as any).alt.toString();
|
|
1641
|
+
cell.rendered_type = ValueType.string;
|
|
1642
|
+
}
|
|
1643
|
+
else
|
|
1644
|
+
*/
|
|
1645
|
+
|
|
1646
|
+
{
|
|
1647
|
+
cell.formatted = '𝑓()'; // FIXME
|
|
1648
|
+
cell.rendered_type = ValueType.string;
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1634
1651
|
else {
|
|
1635
1652
|
|
|
1636
1653
|
// why is this being treated as a number? (...)
|
|
@@ -49,9 +49,9 @@ import type {
|
|
|
49
49
|
CondifionalFormatExpressionOptions,
|
|
50
50
|
ConditionalFormatCellMatchOptions,
|
|
51
51
|
ConditionalFormatCellMatch,
|
|
52
|
-
|
|
53
52
|
LanguageModel,
|
|
54
53
|
TranslatedFunctionDescriptor,
|
|
54
|
+
SerializedNamed,
|
|
55
55
|
|
|
56
56
|
} from 'treb-data-model';
|
|
57
57
|
|
|
@@ -4172,7 +4172,7 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
|
|
|
4172
4172
|
*
|
|
4173
4173
|
* @public
|
|
4174
4174
|
*/
|
|
4175
|
-
public Resolve(reference: string): ICellAddress | IArea | undefined {
|
|
4175
|
+
public Resolve(reference: string, options?: { r1c1?: boolean }): ICellAddress | IArea | undefined {
|
|
4176
4176
|
|
|
4177
4177
|
// API v1 OK
|
|
4178
4178
|
|
|
@@ -4183,7 +4183,7 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
|
|
|
4183
4183
|
// FIXME: we're using the sheet EnsureAddress method, but that should
|
|
4184
4184
|
// move either in here or into some sort of helper class
|
|
4185
4185
|
|
|
4186
|
-
const result = this.model.ResolveAddress(reference, this.grid.active_sheet);
|
|
4186
|
+
const result = this.model.ResolveAddress(reference, this.grid.active_sheet, options);
|
|
4187
4187
|
|
|
4188
4188
|
if (IsCellAddress(result)) {
|
|
4189
4189
|
return result.sheet_id ? result : undefined;
|
|
@@ -4418,6 +4418,10 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
|
|
|
4418
4418
|
|
|
4419
4419
|
}
|
|
4420
4420
|
|
|
4421
|
+
public ListNames(): SerializedNamed[] {
|
|
4422
|
+
return this.model.SerializeNames();
|
|
4423
|
+
}
|
|
4424
|
+
|
|
4421
4425
|
/**
|
|
4422
4426
|
* Create a named range or named expression. A named range refers to an
|
|
4423
4427
|
* address or range. A named expression can be any value or formula. To set
|
|
@@ -6445,7 +6449,10 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
|
|
|
6445
6449
|
model.named.Reset();
|
|
6446
6450
|
|
|
6447
6451
|
if (data.named) {
|
|
6452
|
+
|
|
6453
|
+
// use locale setting for parsing
|
|
6448
6454
|
this.model.UnserializeNames(data.named, this.grid.active_sheet);
|
|
6455
|
+
|
|
6449
6456
|
}
|
|
6450
6457
|
else {
|
|
6451
6458
|
|
|
@@ -6482,6 +6489,8 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
|
|
|
6482
6489
|
if (data.named_expressions) {
|
|
6483
6490
|
for (const pair of data.named_expressions) {
|
|
6484
6491
|
|
|
6492
|
+
// use locale setting for parsing
|
|
6493
|
+
|
|
6485
6494
|
this.model.UnserializeNames([{
|
|
6486
6495
|
name: pair.name,
|
|
6487
6496
|
expression: pair.expression,
|
|
@@ -33,24 +33,6 @@
|
|
|
33
33
|
$primary-selection-color: #4caaf1;
|
|
34
34
|
$primary-selection-color-unfocused: #acc0cf;
|
|
35
35
|
|
|
36
|
-
/*
|
|
37
|
-
$alternate-selection-color-1: rgb(251, 177, 60);
|
|
38
|
-
$alternate-selection-color-2: rgb(64, 192, 64);
|
|
39
|
-
$alternate-selection-color-3: rgb(182, 109, 13);
|
|
40
|
-
$alternate-selection-color-4: rgb(33, 118, 174);
|
|
41
|
-
$alternate-selection-color-5: rgb(254, 104, 71);
|
|
42
|
-
|
|
43
|
-
/ * *
|
|
44
|
-
* slightly darkening colors for text highlighting
|
|
45
|
-
* algo: convert to HSL; if L > .5, regenerate with L = .5; back to RGB (why?)
|
|
46
|
-
* /
|
|
47
|
-
$text-reference-color-1: rgb(250, 155, 5);
|
|
48
|
-
$text-reference-color-2: rgb(58, 173, 58);
|
|
49
|
-
$text-reference-color-3: rgb(182, 109, 13);
|
|
50
|
-
$text-reference-color-4: rgb(33, 118, 174);
|
|
51
|
-
$text-reference-color-5: rgb(254, 47, 1);
|
|
52
|
-
*/
|
|
53
|
-
|
|
54
36
|
.treb-main.treb-main {
|
|
55
37
|
|
|
56
38
|
--alternate-selection-color-1: rgb(251, 177, 60);
|
|
@@ -324,25 +306,21 @@ $text-reference-color-5: rgb(254, 47, 1);
|
|
|
324
306
|
|
|
325
307
|
/* span:nth-of-type(2n) { */
|
|
326
308
|
span.highlight-2 {
|
|
327
|
-
// color: $text-reference-color-2;
|
|
328
309
|
color: var(--text-reference-color-2);
|
|
329
310
|
}
|
|
330
311
|
|
|
331
312
|
/* span:nth-of-type(3n) { */
|
|
332
313
|
span.highlight-3 {
|
|
333
|
-
// color: $text-reference-color-3;
|
|
334
314
|
color: var(--text-reference-color-3);
|
|
335
315
|
}
|
|
336
316
|
|
|
337
317
|
/* span:nth-of-type(4n) { */
|
|
338
318
|
span.highlight-4 {
|
|
339
|
-
// color: $text-reference-color-4;
|
|
340
319
|
color: var(--text-reference-color-4);
|
|
341
320
|
}
|
|
342
321
|
|
|
343
322
|
/* span:nth-of-type(5n) { */
|
|
344
323
|
span.highlight-5 {
|
|
345
|
-
// color: $text-reference-color-5;
|
|
346
324
|
color: var(--text-reference-color-5);
|
|
347
325
|
}
|
|
348
326
|
|
|
@@ -1284,7 +1284,7 @@ export class Grid extends GridBase {
|
|
|
1284
1284
|
this.model.named.Reset();
|
|
1285
1285
|
|
|
1286
1286
|
if (import_data.named) {
|
|
1287
|
-
this.model.UnserializeNames(import_data.named, this.active_sheet);
|
|
1287
|
+
this.model.UnserializeNames(import_data.named, this.active_sheet, true);
|
|
1288
1288
|
}
|
|
1289
1289
|
|
|
1290
1290
|
// FIXME: do we need to rebuild autocomplete here (A: yes)
|
|
@@ -2350,11 +2350,12 @@ export class Grid extends GridBase {
|
|
|
2350
2350
|
|
|
2351
2351
|
|
|
2352
2352
|
// this is public so we need to (un)translate.
|
|
2353
|
-
|
|
2353
|
+
// console.info("PRE", {r1c1}, data);
|
|
2354
|
+
data = this.model.UntranslateData(data, { r1c1 });
|
|
2355
|
+
// console.info("POST", data, "\n");
|
|
2354
2356
|
|
|
2355
2357
|
// single value, easiest
|
|
2356
2358
|
if (!Array.isArray(data)) {
|
|
2357
|
-
|
|
2358
2359
|
if (recycle || array) {
|
|
2359
2360
|
this.ExecCommand({ key: CommandKey.SetRange, area: range, value: data, array, r1c1 });
|
|
2360
2361
|
}
|
|
@@ -167,6 +167,17 @@ export interface UnitCall extends BaseUnit {
|
|
|
167
167
|
|
|
168
168
|
}
|
|
169
169
|
|
|
170
|
+
/**
|
|
171
|
+
* new call type: implicit. we might merge these.
|
|
172
|
+
*/
|
|
173
|
+
export interface UnitImplicitCall extends BaseUnit {
|
|
174
|
+
type: 'implicit-call';
|
|
175
|
+
position: number;
|
|
176
|
+
args: ExpressionUnit[];
|
|
177
|
+
call: ExpressionUnit;
|
|
178
|
+
|
|
179
|
+
}
|
|
180
|
+
|
|
170
181
|
/**
|
|
171
182
|
* this isn't an output type (unless parsing fails), but it's useful
|
|
172
183
|
* to be able to pass these around with the same semantics.
|
|
@@ -177,6 +188,14 @@ export interface UnitOperator extends BaseUnit {
|
|
|
177
188
|
operator: string;
|
|
178
189
|
}
|
|
179
190
|
|
|
191
|
+
/**
|
|
192
|
+
* also not an output type
|
|
193
|
+
*/
|
|
194
|
+
export interface UnitGroupSeparator extends BaseUnit {
|
|
195
|
+
type: 'group-separator';
|
|
196
|
+
position: number;
|
|
197
|
+
}
|
|
198
|
+
|
|
180
199
|
/**
|
|
181
200
|
* expression unit representing a binary operation. operations may be
|
|
182
201
|
* re-ordered based on precendence.
|
|
@@ -259,9 +278,11 @@ export type BaseExpressionUnit =
|
|
|
259
278
|
| UnitArray
|
|
260
279
|
| UnitIdentifier
|
|
261
280
|
| UnitCall
|
|
281
|
+
| UnitImplicitCall
|
|
262
282
|
| UnitMissing
|
|
263
283
|
| UnitGroup
|
|
264
284
|
| UnitOperator
|
|
285
|
+
| UnitGroupSeparator
|
|
265
286
|
| UnitBinary
|
|
266
287
|
| UnitUnary
|
|
267
288
|
| UnitAddress
|