@calcit/procs 0.5.0-a9 → 0.5.0
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/lib/calcit-data.js +37 -18
- package/lib/calcit.procs.js +73 -73
- package/lib/custom-formatter.js +11 -11
- package/lib/js-cirru.js +20 -20
- package/lib/js-list.js +190 -117
- package/lib/js-map.js +194 -130
- package/lib/js-record.js +7 -7
- package/lib/js-set.js +5 -5
- package/lib/js-tuple.js +4 -4
- package/package.json +5 -5
- package/ts-src/calcit-data.ts +37 -18
- package/ts-src/calcit.procs.ts +95 -95
- package/ts-src/custom-formatter.ts +10 -10
- package/ts-src/js-cirru.ts +22 -22
- package/ts-src/js-list.ts +195 -121
- package/ts-src/js-map.ts +216 -135
- package/ts-src/js-primes.ts +5 -3
- package/ts-src/js-record.ts +6 -6
- package/ts-src/js-set.ts +18 -5
- package/ts-src/js-tuple.ts +4 -4
package/lib/custom-formatter.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import "./js-primes";
|
|
2
2
|
import { CalcitRef, CalcitSymbol, CalcitKeyword } from "./calcit-data";
|
|
3
|
-
import
|
|
3
|
+
import "@calcit/ternary-tree";
|
|
4
4
|
import { CalcitRecord } from "./js-record";
|
|
5
|
-
import { CalcitMap } from "./js-map";
|
|
6
|
-
import { CalcitList } from "./js-list";
|
|
5
|
+
import { CalcitMap, CalcitSliceMap } from "./js-map";
|
|
6
|
+
import { CalcitList, CalcitSliceList } from "./js-list";
|
|
7
7
|
import { CalcitSet } from "./js-set";
|
|
8
8
|
import { CalcitTuple } from "./js-tuple";
|
|
9
9
|
let embedObject = (x) => {
|
|
@@ -28,7 +28,7 @@ export let load_console_formatter_$x_ = () => {
|
|
|
28
28
|
if (obj instanceof CalcitSymbol) {
|
|
29
29
|
return ["div", { style: "color: hsl(340, 80%, 60%)" }, obj.toString()];
|
|
30
30
|
}
|
|
31
|
-
if (obj instanceof CalcitList) {
|
|
31
|
+
if (obj instanceof CalcitList || obj instanceof CalcitSliceList) {
|
|
32
32
|
return [
|
|
33
33
|
"div",
|
|
34
34
|
{ style: "color: hsl(280, 80%, 60%, 0.4)" },
|
|
@@ -36,7 +36,7 @@ export let load_console_formatter_$x_ = () => {
|
|
|
36
36
|
["span", { style: "font-size: 80%; vertical-align: 0.7em; color: hsl(280, 80%, 60%, 0.8)" }, `${obj.len()}`],
|
|
37
37
|
];
|
|
38
38
|
}
|
|
39
|
-
if (obj instanceof CalcitMap) {
|
|
39
|
+
if (obj instanceof CalcitMap || obj instanceof CalcitSliceMap) {
|
|
40
40
|
return ["div", { style: "color: hsl(280, 80%, 60%, 0.4)" }, obj.toString(true)];
|
|
41
41
|
}
|
|
42
42
|
if (obj instanceof CalcitSet) {
|
|
@@ -65,10 +65,10 @@ export let load_console_formatter_$x_ = () => {
|
|
|
65
65
|
return null;
|
|
66
66
|
},
|
|
67
67
|
hasBody: (obj) => {
|
|
68
|
-
if (obj instanceof CalcitList) {
|
|
68
|
+
if (obj instanceof CalcitList || obj instanceof CalcitSliceList) {
|
|
69
69
|
return obj.len() > 0;
|
|
70
70
|
}
|
|
71
|
-
if (obj instanceof CalcitMap) {
|
|
71
|
+
if (obj instanceof CalcitMap || obj instanceof CalcitSliceMap) {
|
|
72
72
|
return obj.len() > 0;
|
|
73
73
|
}
|
|
74
74
|
if (obj instanceof CalcitSet) {
|
|
@@ -77,7 +77,7 @@ export let load_console_formatter_$x_ = () => {
|
|
|
77
77
|
return false;
|
|
78
78
|
},
|
|
79
79
|
body: (obj, config) => {
|
|
80
|
-
if (obj instanceof CalcitList) {
|
|
80
|
+
if (obj instanceof CalcitList || obj instanceof CalcitSliceList) {
|
|
81
81
|
return ["div", { style: "color: hsl(280, 80%, 60%)" }].concat(obj.toArray().map((x, idx) => {
|
|
82
82
|
return [
|
|
83
83
|
"div",
|
|
@@ -102,10 +102,10 @@ export let load_console_formatter_$x_ = () => {
|
|
|
102
102
|
ret.push(["div", { style: "margin-left: 8px; display: inline-block;" }, embedObject(obj.snd)]);
|
|
103
103
|
return ret;
|
|
104
104
|
}
|
|
105
|
-
if (obj instanceof CalcitMap) {
|
|
105
|
+
if (obj instanceof CalcitMap || obj instanceof CalcitSliceMap) {
|
|
106
106
|
let ret = ["div", { style: "color: hsl(280, 80%, 60%)" }];
|
|
107
|
-
obj.
|
|
108
|
-
for (let [k, v] of
|
|
107
|
+
let pairs = obj.pairs();
|
|
108
|
+
for (let [k, v] of pairs) {
|
|
109
109
|
ret.push([
|
|
110
110
|
"div",
|
|
111
111
|
{ style: "margin-left: 8px; display: flex;" },
|
package/lib/js-cirru.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import "@calcit/ternary-tree";
|
|
2
2
|
import { writeCirruCode } from "@cirru/writer.ts";
|
|
3
3
|
import "./js-primes";
|
|
4
|
-
import { CalcitList } from "./js-list";
|
|
4
|
+
import { CalcitList, CalcitSliceList } from "./js-list";
|
|
5
5
|
import { CalcitRecord } from "./js-record";
|
|
6
|
-
import { CalcitMap } from "./js-map";
|
|
6
|
+
import { CalcitMap, CalcitSliceMap } from "./js-map";
|
|
7
7
|
import { CalcitSet } from "./js-set";
|
|
8
8
|
import { CalcitKeyword, CalcitSymbol, CalcitRecur, CalcitRef, kwd } from "./calcit-data";
|
|
9
9
|
import { CalcitTuple } from "./js-tuple";
|
|
@@ -39,11 +39,11 @@ export let to_cirru_edn = (x) => {
|
|
|
39
39
|
if (x instanceof CalcitSymbol) {
|
|
40
40
|
return x.toString();
|
|
41
41
|
}
|
|
42
|
-
if (x instanceof CalcitList) {
|
|
42
|
+
if (x instanceof CalcitList || x instanceof CalcitSliceList) {
|
|
43
43
|
// TODO can be faster
|
|
44
44
|
return ["[]"].concat(x.toArray().map(to_cirru_edn));
|
|
45
45
|
}
|
|
46
|
-
if (x instanceof CalcitMap) {
|
|
46
|
+
if (x instanceof CalcitMap || x instanceof CalcitSliceMap) {
|
|
47
47
|
let buffer = ["{}"];
|
|
48
48
|
for (let [k, v] of x.pairs()) {
|
|
49
49
|
buffer.push([to_cirru_edn(k), to_cirru_edn(v)]);
|
|
@@ -101,7 +101,7 @@ export let extract_cirru_edn = (x) => {
|
|
|
101
101
|
if (x === "false") {
|
|
102
102
|
return false;
|
|
103
103
|
}
|
|
104
|
-
if (x
|
|
104
|
+
if (x === "") {
|
|
105
105
|
throw new Error("cannot be empty");
|
|
106
106
|
}
|
|
107
107
|
if (x[0] === "|" || x[0] === '"') {
|
|
@@ -127,17 +127,17 @@ export let extract_cirru_edn = (x) => {
|
|
|
127
127
|
if (x[0] === "{}") {
|
|
128
128
|
let result = [];
|
|
129
129
|
x.forEach((pair, idx) => {
|
|
130
|
-
if (idx
|
|
130
|
+
if (idx === 0) {
|
|
131
131
|
return; // skip first `{}` symbol
|
|
132
132
|
}
|
|
133
|
-
if (pair instanceof Array && pair.length
|
|
134
|
-
result.push(
|
|
133
|
+
if (pair instanceof Array && pair.length === 2) {
|
|
134
|
+
result.push(extract_cirru_edn(pair[0]), extract_cirru_edn(pair[1]));
|
|
135
135
|
}
|
|
136
136
|
else {
|
|
137
137
|
throw new Error("Expected pairs for map");
|
|
138
138
|
}
|
|
139
139
|
});
|
|
140
|
-
return new
|
|
140
|
+
return new CalcitSliceMap(result);
|
|
141
141
|
}
|
|
142
142
|
if (x[0] === "%{}") {
|
|
143
143
|
let name = x[1];
|
|
@@ -150,7 +150,7 @@ export let extract_cirru_edn = (x) => {
|
|
|
150
150
|
if (idx <= 1) {
|
|
151
151
|
return; // skip %{} name
|
|
152
152
|
}
|
|
153
|
-
if (pair instanceof Array && pair.length
|
|
153
|
+
if (pair instanceof Array && pair.length === 2) {
|
|
154
154
|
if (typeof pair[0] === "string") {
|
|
155
155
|
entries.push([extractFieldKwd(pair[0]), extract_cirru_edn(pair[1])]);
|
|
156
156
|
}
|
|
@@ -174,7 +174,7 @@ export let extract_cirru_edn = (x) => {
|
|
|
174
174
|
return new CalcitRecord(extractFieldKwd(name), fields, values);
|
|
175
175
|
}
|
|
176
176
|
if (x[0] === "[]") {
|
|
177
|
-
return new
|
|
177
|
+
return new CalcitSliceList(x.slice(1).map(extract_cirru_edn));
|
|
178
178
|
}
|
|
179
179
|
if (x[0] === "#{}") {
|
|
180
180
|
return new CalcitSet(x.slice(1).map(extract_cirru_edn));
|
|
@@ -205,10 +205,10 @@ export let format_cirru_edn = (data, useInline = true) => {
|
|
|
205
205
|
if (typeof data === "string") {
|
|
206
206
|
return "\ndo " + to_cirru_edn(data) + "\n";
|
|
207
207
|
}
|
|
208
|
-
if (typeof data
|
|
208
|
+
if (typeof data === "boolean") {
|
|
209
209
|
return "\ndo " + to_cirru_edn(data) + "\n";
|
|
210
210
|
}
|
|
211
|
-
if (typeof data
|
|
211
|
+
if (typeof data === "string") {
|
|
212
212
|
return "\ndo " + to_cirru_edn(data) + "\n";
|
|
213
213
|
}
|
|
214
214
|
if (data instanceof CalcitSymbol) {
|
|
@@ -239,7 +239,7 @@ export let to_calcit_data = (x, noKeyword = false) => {
|
|
|
239
239
|
x.forEach((v) => {
|
|
240
240
|
result.push(to_calcit_data(v, noKeyword));
|
|
241
241
|
});
|
|
242
|
-
return new
|
|
242
|
+
return new CalcitSliceList(result);
|
|
243
243
|
}
|
|
244
244
|
if (x instanceof Set) {
|
|
245
245
|
let result = [];
|
|
@@ -248,9 +248,9 @@ export let to_calcit_data = (x, noKeyword = false) => {
|
|
|
248
248
|
});
|
|
249
249
|
return new CalcitSet(result);
|
|
250
250
|
}
|
|
251
|
-
if (x instanceof CalcitList)
|
|
251
|
+
if (x instanceof CalcitList || x instanceof CalcitSliceList)
|
|
252
252
|
return x;
|
|
253
|
-
if (x instanceof CalcitMap)
|
|
253
|
+
if (x instanceof CalcitMap || x instanceof CalcitSliceMap)
|
|
254
254
|
return x;
|
|
255
255
|
if (x instanceof CalcitSet)
|
|
256
256
|
return x;
|
|
@@ -270,9 +270,9 @@ export let to_calcit_data = (x, noKeyword = false) => {
|
|
|
270
270
|
if (x === Object(x)) {
|
|
271
271
|
let result = [];
|
|
272
272
|
Object.keys(x).forEach((k) => {
|
|
273
|
-
result.push(
|
|
273
|
+
result.push(to_calcit_data(k, noKeyword), to_calcit_data(x[k], noKeyword));
|
|
274
274
|
});
|
|
275
|
-
return new
|
|
275
|
+
return new CalcitSliceMap(result);
|
|
276
276
|
}
|
|
277
277
|
console.error(x);
|
|
278
278
|
throw new Error("Unexpected data for converting");
|
|
@@ -281,7 +281,7 @@ let toWriterNode = (xs) => {
|
|
|
281
281
|
if (typeof xs === "string") {
|
|
282
282
|
return xs;
|
|
283
283
|
}
|
|
284
|
-
if (xs instanceof CalcitList) {
|
|
284
|
+
if (xs instanceof CalcitList || xs instanceof CalcitSliceList) {
|
|
285
285
|
return xs.toArray().map(toWriterNode);
|
|
286
286
|
}
|
|
287
287
|
else {
|
package/lib/js-list.js
CHANGED
|
@@ -1,92 +1,153 @@
|
|
|
1
1
|
import * as ternaryTree from "@calcit/ternary-tree";
|
|
2
2
|
import "./js-primes";
|
|
3
|
-
import { initTernaryTreeList, listLen, listGet, assocList, listToItems, dissocList, assocBefore, assocAfter, } from "@calcit/ternary-tree";
|
|
4
|
-
import { CalcitMap } from "./js-map";
|
|
3
|
+
import { initTernaryTreeList, initTernaryTreeListFromRange, listLen, listGet, assocList, listToItems, dissocList, assocBefore, assocAfter, } from "@calcit/ternary-tree";
|
|
4
|
+
import { CalcitMap, CalcitSliceMap } from "./js-map";
|
|
5
5
|
import { CalcitSet } from "./js-set";
|
|
6
6
|
import { CalcitTuple } from "./js-tuple";
|
|
7
|
-
import "./calcit.procs";
|
|
8
7
|
import { isNestedCalcitData, tipNestedCalcitData, toString } from "./calcit-data";
|
|
8
|
+
// two list implementations, should offer same interface
|
|
9
9
|
export class CalcitList {
|
|
10
10
|
constructor(value) {
|
|
11
|
-
if (value == null) {
|
|
12
|
-
value = []; // dirty, better handled from outside
|
|
13
|
-
}
|
|
14
11
|
this.cachedHash = null;
|
|
15
|
-
if (
|
|
16
|
-
this.
|
|
17
|
-
this.arrayValue = value;
|
|
18
|
-
this.arrayStart = 0;
|
|
19
|
-
this.arrayEnd = value.length;
|
|
20
|
-
this.value = null;
|
|
12
|
+
if (value == null) {
|
|
13
|
+
this.value = initTernaryTreeList([]);
|
|
21
14
|
}
|
|
22
15
|
else {
|
|
23
|
-
this.arrayMode = false;
|
|
24
16
|
this.value = value;
|
|
25
|
-
this.arrayValue = [];
|
|
26
|
-
this.arrayStart = null;
|
|
27
|
-
this.arrayEnd = null;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
turnListMode() {
|
|
31
|
-
if (this.arrayMode) {
|
|
32
|
-
this.value = initTernaryTreeList(this.arrayValue.slice(this.arrayStart, this.arrayEnd));
|
|
33
|
-
this.arrayValue = null;
|
|
34
|
-
this.arrayStart = null;
|
|
35
|
-
this.arrayEnd = null;
|
|
36
|
-
this.arrayMode = false;
|
|
37
17
|
}
|
|
38
18
|
}
|
|
39
19
|
len() {
|
|
40
|
-
|
|
41
|
-
return this.arrayEnd - this.arrayStart;
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
return listLen(this.value);
|
|
45
|
-
}
|
|
20
|
+
return listLen(this.value);
|
|
46
21
|
}
|
|
47
22
|
get(idx) {
|
|
48
|
-
|
|
49
|
-
return this.arrayValue[this.arrayStart + idx];
|
|
50
|
-
}
|
|
51
|
-
else {
|
|
52
|
-
return listGet(this.value, idx);
|
|
53
|
-
}
|
|
23
|
+
return listGet(this.value, idx);
|
|
54
24
|
}
|
|
55
25
|
assoc(idx, v) {
|
|
56
|
-
this.turnListMode();
|
|
57
26
|
return new CalcitList(assocList(this.value, idx, v));
|
|
58
27
|
}
|
|
59
28
|
assocBefore(idx, v) {
|
|
60
|
-
this.turnListMode();
|
|
61
29
|
return new CalcitList(assocBefore(this.value, idx, v));
|
|
62
30
|
}
|
|
63
31
|
assocAfter(idx, v) {
|
|
64
|
-
this.turnListMode();
|
|
65
32
|
return new CalcitList(assocAfter(this.value, idx, v));
|
|
66
33
|
}
|
|
67
34
|
dissoc(idx) {
|
|
68
|
-
this.turnListMode();
|
|
69
35
|
return new CalcitList(dissocList(this.value, idx));
|
|
70
36
|
}
|
|
71
37
|
slice(from, to) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
38
|
+
return new CalcitList(ternaryTree.slice(this.value, from, to));
|
|
39
|
+
}
|
|
40
|
+
toString(shorter = false) {
|
|
41
|
+
let result = "";
|
|
42
|
+
for (let item of this.items()) {
|
|
43
|
+
if (shorter && isNestedCalcitData(item)) {
|
|
44
|
+
result = `${result} ${tipNestedCalcitData(item)}`;
|
|
78
45
|
}
|
|
79
|
-
|
|
80
|
-
|
|
46
|
+
else {
|
|
47
|
+
result = `${result} ${toString(item, true)}`;
|
|
81
48
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
49
|
+
}
|
|
50
|
+
return `([]${result})`;
|
|
51
|
+
}
|
|
52
|
+
isEmpty() {
|
|
53
|
+
return this.len() === 0;
|
|
54
|
+
}
|
|
55
|
+
/** usage: `for of` */
|
|
56
|
+
items() {
|
|
57
|
+
return listToItems(this.value);
|
|
58
|
+
}
|
|
59
|
+
append(v) {
|
|
60
|
+
return new CalcitList(ternaryTree.append(this.value, v));
|
|
61
|
+
}
|
|
62
|
+
prepend(v) {
|
|
63
|
+
return new CalcitList(ternaryTree.prepend(this.value, v));
|
|
64
|
+
}
|
|
65
|
+
first() {
|
|
66
|
+
return ternaryTree.first(this.value);
|
|
67
|
+
}
|
|
68
|
+
rest() {
|
|
69
|
+
return new CalcitList(ternaryTree.rest(this.value));
|
|
70
|
+
}
|
|
71
|
+
concat(ys) {
|
|
72
|
+
if (ys instanceof CalcitSliceList) {
|
|
73
|
+
return new CalcitList(ternaryTree.concat(this.value, ys.turnListMode().value));
|
|
74
|
+
}
|
|
75
|
+
else if (ys instanceof CalcitList) {
|
|
76
|
+
return new CalcitList(ternaryTree.concat(this.value, ys.value));
|
|
86
77
|
}
|
|
87
78
|
else {
|
|
88
|
-
|
|
79
|
+
throw new Error(`Unknown data to concat: ${ys}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
map(f) {
|
|
83
|
+
return new CalcitList(ternaryTree.listMapValues(this.value, f));
|
|
84
|
+
}
|
|
85
|
+
toArray() {
|
|
86
|
+
return [...ternaryTree.listToItems(this.value)];
|
|
87
|
+
}
|
|
88
|
+
reverse() {
|
|
89
|
+
return new CalcitList(ternaryTree.reverse(this.value));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// represent append-only immutable list in Array slices
|
|
93
|
+
export class CalcitSliceList {
|
|
94
|
+
constructor(value) {
|
|
95
|
+
if (value == null) {
|
|
96
|
+
value = []; // dirty, better handled from outside
|
|
89
97
|
}
|
|
98
|
+
this.cachedHash = null;
|
|
99
|
+
this.value = value;
|
|
100
|
+
this.start = 0;
|
|
101
|
+
this.end = value.length;
|
|
102
|
+
}
|
|
103
|
+
turnListMode() {
|
|
104
|
+
return new CalcitList(initTernaryTreeListFromRange(this.value, this.start, this.end));
|
|
105
|
+
}
|
|
106
|
+
len() {
|
|
107
|
+
return this.end - this.start;
|
|
108
|
+
}
|
|
109
|
+
get(idx) {
|
|
110
|
+
return this.value[this.start + idx];
|
|
111
|
+
}
|
|
112
|
+
assoc(idx, v) {
|
|
113
|
+
return this.turnListMode().assoc(idx, v);
|
|
114
|
+
}
|
|
115
|
+
assocBefore(idx, v) {
|
|
116
|
+
return this.turnListMode().assocBefore(idx, v);
|
|
117
|
+
}
|
|
118
|
+
assocAfter(idx, v) {
|
|
119
|
+
if (idx === this.len() - 1) {
|
|
120
|
+
return this.append(v);
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
return this.turnListMode().assocAfter(idx, v);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
dissoc(idx) {
|
|
127
|
+
if (idx === 0) {
|
|
128
|
+
return this.rest();
|
|
129
|
+
}
|
|
130
|
+
else if (idx === this.len() - 1) {
|
|
131
|
+
return this.slice(0, idx);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
return this.turnListMode().dissoc(idx);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
slice(from, to) {
|
|
138
|
+
if (from < 0) {
|
|
139
|
+
throw new Error(`from index too small: ${from}`);
|
|
140
|
+
}
|
|
141
|
+
if (to > this.len()) {
|
|
142
|
+
throw new Error(`end index too large: ${to}`);
|
|
143
|
+
}
|
|
144
|
+
if (to < from) {
|
|
145
|
+
throw new Error("end index too small");
|
|
146
|
+
}
|
|
147
|
+
let result = new CalcitSliceList(this.value);
|
|
148
|
+
result.start = this.start + from;
|
|
149
|
+
result.end = this.start + to;
|
|
150
|
+
return result;
|
|
90
151
|
}
|
|
91
152
|
toString(shorter = false) {
|
|
92
153
|
let result = "";
|
|
@@ -105,59 +166,40 @@ export class CalcitList {
|
|
|
105
166
|
}
|
|
106
167
|
/** usage: `for of` */
|
|
107
168
|
items() {
|
|
108
|
-
|
|
109
|
-
return sliceGenerator(this.arrayValue, this.arrayStart, this.arrayEnd);
|
|
110
|
-
}
|
|
111
|
-
else {
|
|
112
|
-
return listToItems(this.value);
|
|
113
|
-
}
|
|
169
|
+
return sliceGenerator(this.value, this.start, this.end);
|
|
114
170
|
}
|
|
115
171
|
append(v) {
|
|
116
|
-
if (this.
|
|
172
|
+
if (this.end === this.value.length && this.start < 32) {
|
|
117
173
|
// dirty trick to reuse list memory, data storage actually appended at existing array
|
|
118
|
-
this.
|
|
119
|
-
let newList = new
|
|
120
|
-
newList.
|
|
121
|
-
newList.
|
|
174
|
+
this.value.push(v);
|
|
175
|
+
let newList = new CalcitSliceList(this.value);
|
|
176
|
+
newList.start = this.start;
|
|
177
|
+
newList.end = this.end + 1;
|
|
122
178
|
return newList;
|
|
123
179
|
}
|
|
124
180
|
else {
|
|
125
|
-
this.turnListMode();
|
|
126
|
-
return new CalcitList(ternaryTree.append(this.value, v));
|
|
181
|
+
return this.turnListMode().append(v);
|
|
127
182
|
}
|
|
128
183
|
}
|
|
129
184
|
prepend(v) {
|
|
130
|
-
this.turnListMode();
|
|
131
|
-
return new CalcitList(ternaryTree.prepend(this.value, v));
|
|
185
|
+
return this.turnListMode().prepend(v);
|
|
132
186
|
}
|
|
133
187
|
first() {
|
|
134
|
-
if (this.
|
|
135
|
-
|
|
136
|
-
return this.arrayValue[this.arrayStart];
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
return null;
|
|
140
|
-
}
|
|
188
|
+
if (this.value.length > this.start) {
|
|
189
|
+
return this.value[this.start];
|
|
141
190
|
}
|
|
142
191
|
else {
|
|
143
|
-
return
|
|
192
|
+
return null;
|
|
144
193
|
}
|
|
145
194
|
}
|
|
146
195
|
rest() {
|
|
147
|
-
|
|
148
|
-
return this.slice(1, this.arrayEnd - this.arrayStart);
|
|
149
|
-
}
|
|
150
|
-
else {
|
|
151
|
-
return new CalcitList(ternaryTree.rest(this.value));
|
|
152
|
-
}
|
|
196
|
+
return this.slice(1, this.end - this.start);
|
|
153
197
|
}
|
|
198
|
+
// TODO
|
|
154
199
|
concat(ys) {
|
|
155
|
-
if (
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
if (this.arrayMode && ys.arrayMode) {
|
|
159
|
-
let size = this.arrayEnd - this.arrayStart;
|
|
160
|
-
let otherSize = ys.arrayEnd - ys.arrayStart;
|
|
200
|
+
if (ys instanceof CalcitSliceList) {
|
|
201
|
+
let size = this.end - this.start;
|
|
202
|
+
let otherSize = ys.end - ys.start;
|
|
161
203
|
let combined = new Array(size + otherSize);
|
|
162
204
|
for (let i = 0; i < size; i++) {
|
|
163
205
|
combined[i] = this.get(i);
|
|
@@ -165,38 +207,39 @@ export class CalcitList {
|
|
|
165
207
|
for (let i = 0; i < otherSize; i++) {
|
|
166
208
|
combined[i + size] = ys.get(i);
|
|
167
209
|
}
|
|
168
|
-
return new
|
|
210
|
+
return new CalcitSliceList(combined);
|
|
211
|
+
}
|
|
212
|
+
else if (ys instanceof CalcitList) {
|
|
213
|
+
return this.turnListMode().concat(ys);
|
|
169
214
|
}
|
|
170
215
|
else {
|
|
171
|
-
|
|
172
|
-
ys.turnListMode();
|
|
173
|
-
return new CalcitList(ternaryTree.concat(this.value, ys.value));
|
|
216
|
+
throw new Error("Expected list");
|
|
174
217
|
}
|
|
175
218
|
}
|
|
176
219
|
map(f) {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
else {
|
|
181
|
-
return new CalcitList(ternaryTree.listMapValues(this.value, f));
|
|
220
|
+
let ys = [];
|
|
221
|
+
for (let x in sliceGenerator(this.value, this.start, this.end)) {
|
|
222
|
+
ys.push(f(x));
|
|
182
223
|
}
|
|
224
|
+
return new CalcitSliceList(ys);
|
|
183
225
|
}
|
|
184
226
|
toArray() {
|
|
185
|
-
|
|
186
|
-
return this.arrayValue.slice(this.arrayStart, this.arrayEnd);
|
|
187
|
-
}
|
|
188
|
-
else {
|
|
189
|
-
return [...ternaryTree.listToItems(this.value)];
|
|
190
|
-
}
|
|
227
|
+
return this.value.slice(this.start, this.end);
|
|
191
228
|
}
|
|
192
229
|
reverse() {
|
|
193
|
-
this.turnListMode();
|
|
194
|
-
return new CalcitList(ternaryTree.reverse(this.value));
|
|
230
|
+
return this.turnListMode().reverse();
|
|
195
231
|
}
|
|
196
232
|
}
|
|
197
233
|
function* sliceGenerator(xs, start, end) {
|
|
198
|
-
|
|
199
|
-
|
|
234
|
+
if (xs == null) {
|
|
235
|
+
if (end <= start) {
|
|
236
|
+
throw new Error("invalid list to slice");
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
for (let idx = start; idx < end; idx++) {
|
|
241
|
+
yield xs[idx];
|
|
242
|
+
}
|
|
200
243
|
}
|
|
201
244
|
}
|
|
202
245
|
export let foldl = function (xs, acc, f) {
|
|
@@ -204,10 +247,9 @@ export let foldl = function (xs, acc, f) {
|
|
|
204
247
|
throw new Error("foldl takes 3 arguments");
|
|
205
248
|
}
|
|
206
249
|
if (f == null) {
|
|
207
|
-
debugger;
|
|
208
250
|
throw new Error("Expected function for folding");
|
|
209
251
|
}
|
|
210
|
-
if (xs instanceof CalcitList) {
|
|
252
|
+
if (xs instanceof CalcitSliceList || xs instanceof CalcitList) {
|
|
211
253
|
var result = acc;
|
|
212
254
|
for (let idx = 0; idx < xs.len(); idx++) {
|
|
213
255
|
let item = xs.get(idx);
|
|
@@ -222,10 +264,20 @@ export let foldl = function (xs, acc, f) {
|
|
|
222
264
|
});
|
|
223
265
|
return result;
|
|
224
266
|
}
|
|
267
|
+
if (xs instanceof CalcitSliceMap) {
|
|
268
|
+
let result = acc;
|
|
269
|
+
// low-level code for performance
|
|
270
|
+
let size = xs.chunk.length >> 1;
|
|
271
|
+
for (let i = 0; i < size; i++) {
|
|
272
|
+
let pos = i << 1;
|
|
273
|
+
result = f(result, new CalcitSliceList([xs.chunk[pos], xs.chunk[pos + 1]]));
|
|
274
|
+
}
|
|
275
|
+
return result;
|
|
276
|
+
}
|
|
225
277
|
if (xs instanceof CalcitMap) {
|
|
226
278
|
let result = acc;
|
|
227
|
-
xs.pairs().forEach((
|
|
228
|
-
result = f(result, new
|
|
279
|
+
xs.pairs().forEach((pair) => {
|
|
280
|
+
result = f(result, new CalcitSliceList(pair));
|
|
229
281
|
});
|
|
230
282
|
return result;
|
|
231
283
|
}
|
|
@@ -236,10 +288,9 @@ export let foldl_shortcut = function (xs, acc, v0, f) {
|
|
|
236
288
|
throw new Error("foldl-shortcut takes 4 arguments");
|
|
237
289
|
}
|
|
238
290
|
if (f == null) {
|
|
239
|
-
debugger;
|
|
240
291
|
throw new Error("Expected function for folding");
|
|
241
292
|
}
|
|
242
|
-
if (xs instanceof CalcitList) {
|
|
293
|
+
if (xs instanceof CalcitList || xs instanceof CalcitSliceList) {
|
|
243
294
|
var state = acc;
|
|
244
295
|
for (let idx = 0; idx < xs.len(); idx++) {
|
|
245
296
|
let item = xs.get(idx);
|
|
@@ -280,10 +331,33 @@ export let foldl_shortcut = function (xs, acc, v0, f) {
|
|
|
280
331
|
}
|
|
281
332
|
return v0;
|
|
282
333
|
}
|
|
334
|
+
if (xs instanceof CalcitSliceMap) {
|
|
335
|
+
let state = acc;
|
|
336
|
+
// low-level code for performance
|
|
337
|
+
let size = xs.chunk.length >> 1;
|
|
338
|
+
for (let i = 0; i < size; i++) {
|
|
339
|
+
let pos = i << 1;
|
|
340
|
+
let pair = f(state, new CalcitSliceList([xs.chunk[pos], xs.chunk[pos + 1]]));
|
|
341
|
+
if (pair instanceof CalcitTuple) {
|
|
342
|
+
if (typeof pair.fst === "boolean") {
|
|
343
|
+
if (pair.fst) {
|
|
344
|
+
return pair.snd;
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
state = pair.snd;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
else {
|
|
352
|
+
throw new Error("Expected return value in `:: bool acc` structure");
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
return v0;
|
|
356
|
+
}
|
|
283
357
|
if (xs instanceof CalcitMap) {
|
|
284
358
|
let state = acc;
|
|
285
359
|
for (let item of xs.pairs()) {
|
|
286
|
-
let pair = f(state, new
|
|
360
|
+
let pair = f(state, new CalcitSliceList(item));
|
|
287
361
|
if (pair instanceof CalcitTuple) {
|
|
288
362
|
if (typeof pair.fst === "boolean") {
|
|
289
363
|
if (pair.fst) {
|
|
@@ -307,10 +381,9 @@ export let foldr_shortcut = function (xs, acc, v0, f) {
|
|
|
307
381
|
throw new Error("foldr-shortcut takes 4 arguments");
|
|
308
382
|
}
|
|
309
383
|
if (f == null) {
|
|
310
|
-
debugger;
|
|
311
384
|
throw new Error("Expected function for folding");
|
|
312
385
|
}
|
|
313
|
-
if (xs instanceof CalcitList) {
|
|
386
|
+
if (xs instanceof CalcitList || xs instanceof CalcitSliceList) {
|
|
314
387
|
var state = acc;
|
|
315
388
|
// iterate from right
|
|
316
389
|
for (let idx = xs.len() - 1; idx >= 0; idx--) {
|