@opencode/codemode 0.0.0-dev-19530 → 2.0.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/dist/data.d.ts +5 -6
- package/dist/data.js +44 -47
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/interpreter/errors.d.ts +3 -5
- package/dist/interpreter/errors.js +22 -51
- package/dist/interpreter/execute.js +3 -5
- package/dist/interpreter/globals.js +47 -69
- package/dist/interpreter/host.d.ts +41 -0
- package/dist/interpreter/host.js +44 -0
- package/dist/interpreter/methods.d.ts +4 -0
- package/dist/interpreter/methods.js +837 -0
- package/dist/interpreter/model.d.ts +36 -13
- package/dist/interpreter/model.js +45 -15
- package/dist/interpreter/objects.d.ts +13 -106
- package/dist/interpreter/objects.js +65 -192
- package/dist/interpreter/promises.d.ts +13 -12
- package/dist/interpreter/promises.js +54 -59
- package/dist/interpreter/references.d.ts +0 -1
- package/dist/interpreter/references.js +33 -20
- package/dist/interpreter/runner.d.ts +11 -15
- package/dist/interpreter/runner.js +21 -21
- package/dist/interpreter/runtime.d.ts +3 -3
- package/dist/interpreter/runtime.js +327 -165
- package/dist/interpreter/scope.js +6 -6
- package/dist/stdlib/array.d.ts +2 -4
- package/dist/stdlib/array.js +32 -424
- package/dist/stdlib/collections.d.ts +7 -3
- package/dist/stdlib/collections.js +119 -291
- package/dist/stdlib/console.d.ts +2 -3
- package/dist/stdlib/console.js +30 -35
- package/dist/stdlib/date.d.ts +7 -1
- package/dist/stdlib/date.js +188 -93
- package/dist/stdlib/json.d.ts +2 -2
- package/dist/stdlib/json.js +27 -27
- package/dist/stdlib/math.d.ts +2 -2
- package/dist/stdlib/math.js +76 -96
- package/dist/stdlib/number.d.ts +4 -3
- package/dist/stdlib/number.js +60 -95
- package/dist/stdlib/object.d.ts +4 -4
- package/dist/stdlib/object.js +54 -128
- package/dist/stdlib/regexp.d.ts +8 -6
- package/dist/stdlib/regexp.js +68 -76
- package/dist/stdlib/string.d.ts +2 -2
- package/dist/stdlib/string.js +50 -213
- package/dist/stdlib/url.d.ts +13 -5
- package/dist/stdlib/url.js +102 -202
- package/dist/stdlib/value.d.ts +9 -5
- package/dist/stdlib/value.js +38 -16
- package/dist/stdlib/web.d.ts +4 -4
- package/dist/stdlib/web.js +10 -12
- package/dist/tool-runtime.d.ts +1 -2
- package/dist/tool-runtime.js +2 -2
- package/dist/values.d.ts +37 -0
- package/dist/values.js +56 -0
- package/package.json +1 -1
- package/dist/interpreter/generators.d.ts +0 -4
- package/dist/interpreter/generators.js +0 -25
- package/dist/interpreter/intrinsics.d.ts +0 -13
- package/dist/interpreter/intrinsics.js +0 -82
- package/dist/interpreter/native.d.ts +0 -19
- package/dist/interpreter/native.js +0 -40
|
@@ -1,73 +1,132 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
|
-
import {
|
|
2
|
+
import { HostFunction, requiresNew } from "../interpreter/host.js";
|
|
3
3
|
import { InterpreterRuntimeError } from "../interpreter/model.js";
|
|
4
|
-
import {
|
|
4
|
+
import { getOwn, ProgramArray, ProgramObject, set } from "../interpreter/objects.js";
|
|
5
5
|
import { describeValue, isRuntimeReference } from "../interpreter/references.js";
|
|
6
|
-
import { applyCollectionCallback,
|
|
6
|
+
import { applyCollectionCallback, preserveConsumerError, toPrimitive } from "../interpreter/runner.js";
|
|
7
|
+
import { Values } from "../values.js";
|
|
8
|
+
import { coerceToString } from "./value.js";
|
|
9
|
+
export const arrayMethods = new Set([
|
|
10
|
+
"map",
|
|
11
|
+
"filter",
|
|
12
|
+
"find",
|
|
13
|
+
"findIndex",
|
|
14
|
+
"findLast",
|
|
15
|
+
"findLastIndex",
|
|
16
|
+
"some",
|
|
17
|
+
"every",
|
|
18
|
+
"includes",
|
|
19
|
+
"join",
|
|
20
|
+
"reduce",
|
|
21
|
+
"reduceRight",
|
|
22
|
+
"flatMap",
|
|
23
|
+
"forEach",
|
|
24
|
+
"sort",
|
|
25
|
+
"toSorted",
|
|
26
|
+
"slice",
|
|
27
|
+
"concat",
|
|
28
|
+
"indexOf",
|
|
29
|
+
"lastIndexOf",
|
|
30
|
+
"at",
|
|
31
|
+
"flat",
|
|
32
|
+
"reverse",
|
|
33
|
+
"toReversed",
|
|
34
|
+
"with",
|
|
35
|
+
"push",
|
|
36
|
+
"pop",
|
|
37
|
+
"shift",
|
|
38
|
+
"unshift",
|
|
39
|
+
"splice",
|
|
40
|
+
"toSpliced",
|
|
41
|
+
"fill",
|
|
42
|
+
"copyWithin",
|
|
43
|
+
"keys",
|
|
44
|
+
"values",
|
|
45
|
+
"entries",
|
|
46
|
+
]);
|
|
47
|
+
export const mapMethods = new Set(["get", "set", "has", "delete", "clear", "forEach", "keys", "values", "entries"]);
|
|
48
|
+
export const setMethods = new Set([
|
|
49
|
+
"add",
|
|
50
|
+
"has",
|
|
51
|
+
"delete",
|
|
52
|
+
"clear",
|
|
53
|
+
"forEach",
|
|
54
|
+
"keys",
|
|
55
|
+
"values",
|
|
56
|
+
"entries",
|
|
57
|
+
"union",
|
|
58
|
+
"intersection",
|
|
59
|
+
"difference",
|
|
60
|
+
"symmetricDifference",
|
|
61
|
+
"isSubsetOf",
|
|
62
|
+
"isSupersetOf",
|
|
63
|
+
"isDisjointFrom",
|
|
64
|
+
]);
|
|
7
65
|
const coerceGroupByPropertyKey = (runner, value, node) => {
|
|
8
|
-
if (value instanceof
|
|
66
|
+
if (value instanceof Values.Promise)
|
|
9
67
|
return Effect.succeed("[object Promise]");
|
|
10
|
-
if (!
|
|
68
|
+
if (!Values.isValue(value) && isRuntimeReference(value)) {
|
|
11
69
|
throw new InterpreterRuntimeError(`Object.groupBy callback must return a data value, received ${describeValue(value)}.`, node, "InvalidDataValue");
|
|
12
70
|
}
|
|
13
|
-
return
|
|
71
|
+
return Effect.map(toPrimitive(runner, value, "string", node), coerceToString);
|
|
14
72
|
};
|
|
15
73
|
/** `Map.groupBy` and `Object.groupBy`: the same iteration, keyed into a Map or a data object. */
|
|
16
|
-
export const groupBy = (runner, namespace) =>
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
74
|
+
export const groupBy = (runner, namespace) => new HostFunction({
|
|
75
|
+
name: `${namespace}.groupBy`,
|
|
76
|
+
call: (args, node) => {
|
|
77
|
+
const source = args[0];
|
|
78
|
+
if (source === null || source === undefined) {
|
|
79
|
+
throw new InterpreterRuntimeError(`${namespace}.groupBy expects an iterable collection.`, node).as("TypeError");
|
|
80
|
+
}
|
|
81
|
+
const apply = applyCollectionCallback(runner, args[1], `${namespace}.groupBy`, node);
|
|
82
|
+
return Effect.gen(function* () {
|
|
83
|
+
const cursor = yield* runner.syncIterator(source, node);
|
|
84
|
+
if (cursor === undefined) {
|
|
85
|
+
throw new InterpreterRuntimeError(`${namespace}.groupBy expects an iterable collection.`, node).as("TypeError");
|
|
86
|
+
}
|
|
87
|
+
if (namespace === "Map") {
|
|
88
|
+
const result = new Values.Map();
|
|
89
|
+
let index = 0;
|
|
90
|
+
while (true) {
|
|
91
|
+
const step = yield* cursor.next;
|
|
92
|
+
if (step.done)
|
|
93
|
+
return result;
|
|
94
|
+
const item = step.value;
|
|
95
|
+
const key = yield* preserveConsumerError(cursor, apply([item, index]));
|
|
96
|
+
const group = result.map.get(key);
|
|
97
|
+
if (group === undefined)
|
|
98
|
+
result.map.set(key, new ProgramArray([item]));
|
|
99
|
+
else
|
|
100
|
+
group.items.push(item);
|
|
101
|
+
index += 1;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
const result = new ProgramObject();
|
|
30
105
|
let index = 0;
|
|
31
106
|
while (true) {
|
|
32
107
|
const step = yield* cursor.next;
|
|
33
108
|
if (step.done)
|
|
34
109
|
return result;
|
|
35
110
|
const item = step.value;
|
|
36
|
-
const key = yield* preserveConsumerError(cursor, apply([item, index]));
|
|
37
|
-
const group = result
|
|
111
|
+
const key = yield* preserveConsumerError(cursor, Effect.flatMap(apply([item, index]), (value) => coerceGroupByPropertyKey(runner, value, node)));
|
|
112
|
+
const group = getOwn(result, key);
|
|
38
113
|
if (group === undefined)
|
|
39
|
-
|
|
114
|
+
set(result, key, new ProgramArray([item]));
|
|
40
115
|
else
|
|
41
116
|
group.items.push(item);
|
|
42
117
|
index += 1;
|
|
43
118
|
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const result = new ProgramObject(null);
|
|
47
|
-
let index = 0;
|
|
48
|
-
while (true) {
|
|
49
|
-
const step = yield* cursor.next;
|
|
50
|
-
if (step.done)
|
|
51
|
-
return result;
|
|
52
|
-
const item = step.value;
|
|
53
|
-
const key = yield* preserveConsumerError(cursor, Effect.flatMap(apply([item, index]), (value) => coerceGroupByPropertyKey(runner, value, node)));
|
|
54
|
-
const group = getOwn(result, key);
|
|
55
|
-
if (group === undefined)
|
|
56
|
-
define(result, key, new ProgramArray(protos.Array, [item]));
|
|
57
|
-
else
|
|
58
|
-
group.items.push(item);
|
|
59
|
-
index += 1;
|
|
60
|
-
}
|
|
61
|
-
});
|
|
119
|
+
});
|
|
120
|
+
},
|
|
62
121
|
});
|
|
63
|
-
const constructMap = (runner, init,
|
|
64
|
-
const target = new
|
|
122
|
+
const constructMap = (runner, init, node) => {
|
|
123
|
+
const target = new Values.Map();
|
|
65
124
|
if (init === undefined || init === null)
|
|
66
125
|
return Effect.succeed(target);
|
|
67
126
|
return Effect.gen(function* () {
|
|
68
127
|
const cursor = yield* runner.syncIterator(init, node);
|
|
69
128
|
if (cursor === undefined) {
|
|
70
|
-
throw new InterpreterRuntimeError("new Map(...) expects an iterable of [key, value] pairs or no argument.", node);
|
|
129
|
+
throw new InterpreterRuntimeError("new Map(...) expects an iterable of [key, value] pairs or no argument.", node).as("TypeError");
|
|
71
130
|
}
|
|
72
131
|
while (true) {
|
|
73
132
|
const step = yield* cursor.next;
|
|
@@ -75,21 +134,21 @@ const constructMap = (runner, init, proto, node) => {
|
|
|
75
134
|
return target;
|
|
76
135
|
yield* preserveConsumerError(cursor, Effect.sync(() => {
|
|
77
136
|
if (!(step.value instanceof ProgramObject)) {
|
|
78
|
-
throw new InterpreterRuntimeError("new Map(...) expects [key, value] pairs as entry objects.", node);
|
|
137
|
+
throw new InterpreterRuntimeError("new Map(...) expects [key, value] pairs as entry objects.", node).as("TypeError");
|
|
79
138
|
}
|
|
80
139
|
target.map.set(getOwn(step.value, 0), getOwn(step.value, 1));
|
|
81
140
|
}));
|
|
82
141
|
}
|
|
83
142
|
});
|
|
84
143
|
};
|
|
85
|
-
const constructSet = (runner, init,
|
|
86
|
-
const target = new
|
|
144
|
+
const constructSet = (runner, init, node) => {
|
|
145
|
+
const target = new Values.Set();
|
|
87
146
|
if (init === undefined || init === null)
|
|
88
147
|
return Effect.succeed(target);
|
|
89
148
|
return Effect.gen(function* () {
|
|
90
149
|
const cursor = yield* runner.syncIterator(init, node);
|
|
91
150
|
if (cursor === undefined) {
|
|
92
|
-
throw new InterpreterRuntimeError("new Set(...) expects a synchronous iterable or no argument.", node);
|
|
151
|
+
throw new InterpreterRuntimeError("new Set(...) expects a synchronous iterable or no argument.", node).as("TypeError");
|
|
93
152
|
}
|
|
94
153
|
while (true) {
|
|
95
154
|
const step = yield* cursor.next;
|
|
@@ -99,247 +158,16 @@ const constructSet = (runner, init, proto, node) => {
|
|
|
99
158
|
}
|
|
100
159
|
});
|
|
101
160
|
};
|
|
102
|
-
export const mapGlobal = (runner) => {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
methods(protos, proto, [
|
|
115
|
-
["get", 1, (thisValue, args, node) => self(thisValue, "get", node).map.get(args[0])],
|
|
116
|
-
["has", 1, (thisValue, args, node) => self(thisValue, "has", node).map.has(args[0])],
|
|
117
|
-
[
|
|
118
|
-
"set",
|
|
119
|
-
2,
|
|
120
|
-
(thisValue, args, node) => {
|
|
121
|
-
const target = self(thisValue, "set", node);
|
|
122
|
-
target.map.set(args[0], args[1]);
|
|
123
|
-
return target;
|
|
124
|
-
},
|
|
125
|
-
],
|
|
126
|
-
["delete", 1, (thisValue, args, node) => self(thisValue, "delete", node).map.delete(args[0])],
|
|
127
|
-
[
|
|
128
|
-
"clear",
|
|
129
|
-
0,
|
|
130
|
-
(thisValue, _, node) => {
|
|
131
|
-
self(thisValue, "clear", node).map.clear();
|
|
132
|
-
return undefined;
|
|
133
|
-
},
|
|
134
|
-
],
|
|
135
|
-
["keys", 0, (thisValue, _, node) => wrap(Array.from(self(thisValue, "keys", node).map.keys()))],
|
|
136
|
-
["values", 0, (thisValue, _, node) => wrap(Array.from(self(thisValue, "values", node).map.values()))],
|
|
137
|
-
[
|
|
138
|
-
"entries",
|
|
139
|
-
0,
|
|
140
|
-
(thisValue, _, node) => wrap(Array.from(self(thisValue, "entries", node).map.entries(), ([key, item]) => wrap([key, item]))),
|
|
141
|
-
],
|
|
142
|
-
[
|
|
143
|
-
"forEach",
|
|
144
|
-
1,
|
|
145
|
-
(thisValue, args, node) => {
|
|
146
|
-
const target = self(thisValue, "forEach", node);
|
|
147
|
-
const apply = applyCollectionCallback(runner, args[0], "Map.forEach", node);
|
|
148
|
-
return Effect.gen(function* () {
|
|
149
|
-
for (const [key, item] of Array.from(target.map.entries()))
|
|
150
|
-
yield* apply([item, key, target]);
|
|
151
|
-
return undefined;
|
|
152
|
-
});
|
|
153
|
-
},
|
|
154
|
-
],
|
|
155
|
-
]);
|
|
156
|
-
return map;
|
|
157
|
-
};
|
|
158
|
-
const loadSetRecord = (runner, source, name, node) => {
|
|
159
|
-
if (source instanceof ProgramSet) {
|
|
160
|
-
return Effect.succeed({
|
|
161
|
-
size: source.set.size,
|
|
162
|
-
has: (item) => Effect.succeed(source.set.has(item)),
|
|
163
|
-
keys: () => Effect.succeed(source.set.values()),
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
if (source instanceof ProgramMap) {
|
|
167
|
-
return Effect.succeed({
|
|
168
|
-
size: source.map.size,
|
|
169
|
-
has: (item) => Effect.succeed(source.map.has(item)),
|
|
170
|
-
keys: () => Effect.succeed(source.map.keys()),
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
if (!(source instanceof ProgramObject)) {
|
|
174
|
-
throw new InterpreterRuntimeError(`Set.${name} expects a Set-like object.`, node);
|
|
175
|
-
}
|
|
176
|
-
return Effect.gen(function* () {
|
|
177
|
-
const size = yield* toPrimitiveNumber(runner, get(source, "size"), node);
|
|
178
|
-
if (Number.isNaN(size)) {
|
|
179
|
-
throw new InterpreterRuntimeError(`Set.${name} received a Set-like object with an invalid size.`, node);
|
|
180
|
-
}
|
|
181
|
-
const has = get(source, "has");
|
|
182
|
-
const keys = get(source, "keys");
|
|
183
|
-
if (!isSupportedCallback(has) || !isSupportedCallback(keys)) {
|
|
184
|
-
throw new InterpreterRuntimeError(`Set.${name} expects callable 'has' and 'keys' methods.`, node);
|
|
185
|
-
}
|
|
186
|
-
return {
|
|
187
|
-
size: Math.max(Math.trunc(size), 0),
|
|
188
|
-
has: (item) => Effect.map(runner.invokeCallable(has, source, [item], node), Boolean),
|
|
189
|
-
keys: () => Effect.flatMap(runner.invokeCallable(keys, source, [], node), (result) => {
|
|
190
|
-
if (result instanceof ProgramArray)
|
|
191
|
-
return Effect.succeed(result.items);
|
|
192
|
-
throw new InterpreterRuntimeError(`Set.${name} expected 'keys' to return an iterator.`, node);
|
|
193
|
-
}),
|
|
194
|
-
};
|
|
195
|
-
});
|
|
196
|
-
};
|
|
197
|
-
const setOperation = (runner, target, name, source, node) => Effect.gen(function* () {
|
|
198
|
-
const other = yield* loadSetRecord(runner, source, name, node);
|
|
199
|
-
const copy = () => {
|
|
200
|
-
const result = new ProgramSet(runner.prototypes.Set);
|
|
201
|
-
for (const item of target.set.values())
|
|
202
|
-
result.set.add(item);
|
|
203
|
-
return result;
|
|
204
|
-
};
|
|
205
|
-
if (name === "union") {
|
|
206
|
-
const result = copy();
|
|
207
|
-
for (const item of yield* other.keys())
|
|
208
|
-
result.set.add(item);
|
|
209
|
-
return result;
|
|
210
|
-
}
|
|
211
|
-
if (name === "intersection") {
|
|
212
|
-
const result = new ProgramSet(runner.prototypes.Set);
|
|
213
|
-
if (target.set.size <= other.size) {
|
|
214
|
-
for (const item of target.set.values()) {
|
|
215
|
-
if (yield* other.has(item))
|
|
216
|
-
result.set.add(item);
|
|
217
|
-
}
|
|
218
|
-
return result;
|
|
219
|
-
}
|
|
220
|
-
for (const item of yield* other.keys()) {
|
|
221
|
-
if (target.set.has(item))
|
|
222
|
-
result.set.add(item);
|
|
223
|
-
}
|
|
224
|
-
return result;
|
|
225
|
-
}
|
|
226
|
-
if (name === "difference") {
|
|
227
|
-
const result = copy();
|
|
228
|
-
if (target.set.size <= other.size) {
|
|
229
|
-
for (const item of result.set.values()) {
|
|
230
|
-
if (yield* other.has(item))
|
|
231
|
-
result.set.delete(item);
|
|
232
|
-
}
|
|
233
|
-
return result;
|
|
234
|
-
}
|
|
235
|
-
for (const item of yield* other.keys())
|
|
236
|
-
result.set.delete(item);
|
|
237
|
-
return result;
|
|
238
|
-
}
|
|
239
|
-
if (name === "symmetricDifference") {
|
|
240
|
-
const result = copy();
|
|
241
|
-
for (const item of yield* other.keys()) {
|
|
242
|
-
if (target.set.has(item))
|
|
243
|
-
result.set.delete(item);
|
|
244
|
-
else
|
|
245
|
-
result.set.add(item);
|
|
246
|
-
}
|
|
247
|
-
return result;
|
|
248
|
-
}
|
|
249
|
-
if (name === "isSubsetOf") {
|
|
250
|
-
if (target.set.size > other.size)
|
|
251
|
-
return false;
|
|
252
|
-
for (const item of target.set.values()) {
|
|
253
|
-
if (!(yield* other.has(item)))
|
|
254
|
-
return false;
|
|
255
|
-
}
|
|
256
|
-
return true;
|
|
257
|
-
}
|
|
258
|
-
if (name === "isSupersetOf") {
|
|
259
|
-
if (target.set.size < other.size)
|
|
260
|
-
return false;
|
|
261
|
-
for (const item of yield* other.keys()) {
|
|
262
|
-
if (!target.set.has(item))
|
|
263
|
-
return false;
|
|
264
|
-
}
|
|
265
|
-
return true;
|
|
266
|
-
}
|
|
267
|
-
if (target.set.size <= other.size) {
|
|
268
|
-
for (const item of target.set.values()) {
|
|
269
|
-
if (yield* other.has(item))
|
|
270
|
-
return false;
|
|
271
|
-
}
|
|
272
|
-
return true;
|
|
273
|
-
}
|
|
274
|
-
for (const item of yield* other.keys()) {
|
|
275
|
-
if (target.set.has(item))
|
|
276
|
-
return false;
|
|
277
|
-
}
|
|
278
|
-
return true;
|
|
161
|
+
export const mapGlobal = (runner) => new HostFunction({
|
|
162
|
+
name: "Map",
|
|
163
|
+
call: requiresNew("Map"),
|
|
164
|
+
construct: (args, node) => constructMap(runner, args[0], node),
|
|
165
|
+
instanceOf: (value) => value instanceof Values.Map,
|
|
166
|
+
members: { groupBy: groupBy(runner, "Map") },
|
|
167
|
+
});
|
|
168
|
+
export const setGlobal = (runner) => new HostFunction({
|
|
169
|
+
name: "Set",
|
|
170
|
+
call: requiresNew("Set"),
|
|
171
|
+
construct: (args, node) => constructSet(runner, args[0], node),
|
|
172
|
+
instanceOf: (value) => value instanceof Values.Set,
|
|
279
173
|
});
|
|
280
|
-
export const setGlobal = (runner) => {
|
|
281
|
-
const protos = runner.prototypes;
|
|
282
|
-
const proto = protos.Set;
|
|
283
|
-
const set = constructor(protos, proto, {
|
|
284
|
-
name: "Set",
|
|
285
|
-
call: requiresNew("Set"),
|
|
286
|
-
construct: (args, newTarget, node) => constructSet(runner, args[0], prototypeFrom(newTarget, proto), node),
|
|
287
|
-
});
|
|
288
|
-
const self = (thisValue, name, node) => receiver(ProgramSet, thisValue, `Set.prototype.${name}`, node);
|
|
289
|
-
const wrap = (items) => new ProgramArray(protos.Array, items);
|
|
290
|
-
const operation = (name) => [
|
|
291
|
-
name,
|
|
292
|
-
1,
|
|
293
|
-
(thisValue, args, node) => setOperation(runner, self(thisValue, name, node), name, args[0], node),
|
|
294
|
-
];
|
|
295
|
-
defineAccessor(proto, "size", (thisValue) => receiver(ProgramSet, thisValue, "Set.prototype.size").set.size);
|
|
296
|
-
methods(protos, proto, [
|
|
297
|
-
["has", 1, (thisValue, args, node) => self(thisValue, "has", node).set.has(args[0])],
|
|
298
|
-
[
|
|
299
|
-
"add",
|
|
300
|
-
1,
|
|
301
|
-
(thisValue, args, node) => {
|
|
302
|
-
const target = self(thisValue, "add", node);
|
|
303
|
-
target.set.add(args[0]);
|
|
304
|
-
return target;
|
|
305
|
-
},
|
|
306
|
-
],
|
|
307
|
-
["delete", 1, (thisValue, args, node) => self(thisValue, "delete", node).set.delete(args[0])],
|
|
308
|
-
[
|
|
309
|
-
"clear",
|
|
310
|
-
0,
|
|
311
|
-
(thisValue, _, node) => {
|
|
312
|
-
self(thisValue, "clear", node).set.clear();
|
|
313
|
-
return undefined;
|
|
314
|
-
},
|
|
315
|
-
],
|
|
316
|
-
["keys", 0, (thisValue, _, node) => wrap(Array.from(self(thisValue, "keys", node).set.values()))],
|
|
317
|
-
["values", 0, (thisValue, _, node) => wrap(Array.from(self(thisValue, "values", node).set.values()))],
|
|
318
|
-
[
|
|
319
|
-
"entries",
|
|
320
|
-
0,
|
|
321
|
-
(thisValue, _, node) => wrap(Array.from(self(thisValue, "entries", node).set.values(), (item) => wrap([item, item]))),
|
|
322
|
-
],
|
|
323
|
-
[
|
|
324
|
-
"forEach",
|
|
325
|
-
1,
|
|
326
|
-
(thisValue, args, node) => {
|
|
327
|
-
const target = self(thisValue, "forEach", node);
|
|
328
|
-
const apply = applyCollectionCallback(runner, args[0], "Set.forEach", node);
|
|
329
|
-
return Effect.gen(function* () {
|
|
330
|
-
for (const item of Array.from(target.set.values()))
|
|
331
|
-
yield* apply([item, item, target]);
|
|
332
|
-
return undefined;
|
|
333
|
-
});
|
|
334
|
-
},
|
|
335
|
-
],
|
|
336
|
-
operation("union"),
|
|
337
|
-
operation("intersection"),
|
|
338
|
-
operation("difference"),
|
|
339
|
-
operation("symmetricDifference"),
|
|
340
|
-
operation("isSubsetOf"),
|
|
341
|
-
operation("isSupersetOf"),
|
|
342
|
-
operation("isDisjointFrom"),
|
|
343
|
-
]);
|
|
344
|
-
return set;
|
|
345
|
-
};
|
package/dist/stdlib/console.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { Runner } from "../interpreter/runner.js";
|
|
1
|
+
import { HostNamespace } from "../interpreter/host.js";
|
|
3
2
|
/** Captured console: every method appends one formatted line to `logs`. */
|
|
4
|
-
export declare const consoleGlobal:
|
|
3
|
+
export declare const consoleGlobal: (logs: Array<string>) => HostNamespace;
|
package/dist/stdlib/console.js
CHANGED
|
@@ -1,29 +1,24 @@
|
|
|
1
1
|
import { toData, toProgram } from "../data.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { HostNamespace, sync } from "../interpreter/host.js";
|
|
3
|
+
import { get, ownEntries, ProgramArray, ProgramObject } from "../interpreter/objects.js";
|
|
4
4
|
import { containsOpaqueReference, containsRuntimeReference, isRuntimeReference } from "../interpreter/references.js";
|
|
5
|
+
import { Values } from "../values.js";
|
|
5
6
|
import { coerceToString } from "./value.js";
|
|
6
7
|
const consoleMethods = ["log", "info", "debug", "warn", "error", "dir", "table"];
|
|
7
8
|
/** Captured console: every method appends one formatted line to `logs`. */
|
|
8
|
-
export const consoleGlobal = (
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
logs.push(formatConsoleMessage(protos, name, args));
|
|
16
|
-
return undefined;
|
|
17
|
-
},
|
|
18
|
-
]));
|
|
19
|
-
return console;
|
|
20
|
-
};
|
|
9
|
+
export const consoleGlobal = (logs) => new HostNamespace("console", Object.fromEntries(consoleMethods.map((name) => [
|
|
10
|
+
name,
|
|
11
|
+
sync(`console.${name}`, (args) => {
|
|
12
|
+
logs.push(formatConsoleMessage(name, args));
|
|
13
|
+
return undefined;
|
|
14
|
+
}),
|
|
15
|
+
])));
|
|
21
16
|
const MAX_CONSOLE_DEPTH = 32;
|
|
22
|
-
const formatConsoleMessage = (
|
|
17
|
+
const formatConsoleMessage = (name, args) => {
|
|
23
18
|
if (name === "dir")
|
|
24
19
|
return args.length === 0 ? "undefined" : formatConsoleArgument(args[0]);
|
|
25
20
|
if (name === "table")
|
|
26
|
-
return formatConsoleTable(
|
|
21
|
+
return formatConsoleTable(args[0], args[1]);
|
|
27
22
|
const prefix = name === "warn" ? "[warn] " : name === "error" ? "[error] " : name === "debug" ? "[debug] " : "";
|
|
28
23
|
return `${prefix}${args.map((arg) => formatConsoleArgument(arg)).join(" ")}`;
|
|
29
24
|
};
|
|
@@ -43,34 +38,34 @@ const formatConsoleValue = (value, seen, depth) => {
|
|
|
43
38
|
return String(value);
|
|
44
39
|
if (typeof value !== "object")
|
|
45
40
|
return String(value);
|
|
46
|
-
if (value instanceof
|
|
41
|
+
if (value instanceof Values.Promise)
|
|
47
42
|
return "[Promise (await it to get its value)]";
|
|
48
|
-
if (value instanceof
|
|
43
|
+
if (value instanceof Values.Date)
|
|
49
44
|
return coerceToString(value);
|
|
50
|
-
if (value instanceof
|
|
45
|
+
if (value instanceof Values.RegExp)
|
|
51
46
|
return coerceToString(value);
|
|
52
|
-
if (value instanceof
|
|
47
|
+
if (value instanceof Values.URL)
|
|
53
48
|
return coerceToString(value);
|
|
54
|
-
if (value instanceof
|
|
49
|
+
if (value instanceof Values.URLSearchParams)
|
|
55
50
|
return coerceToString(value);
|
|
56
51
|
if (depth > MAX_CONSOLE_DEPTH)
|
|
57
52
|
return "...";
|
|
58
53
|
if (seen.has(value))
|
|
59
54
|
return "[Circular]";
|
|
60
|
-
if (value instanceof
|
|
55
|
+
if (value instanceof Values.Map) {
|
|
61
56
|
seen.add(value);
|
|
62
57
|
try {
|
|
63
|
-
const
|
|
64
|
-
return `Map(${value.map.size})
|
|
58
|
+
const entries = Array.from(value.map.entries(), ([key, item]) => new ProgramArray([key, item]));
|
|
59
|
+
return `Map(${value.map.size}) ${formatConsoleValue(new ProgramArray(entries), seen, depth + 1)}`;
|
|
65
60
|
}
|
|
66
61
|
finally {
|
|
67
62
|
seen.delete(value);
|
|
68
63
|
}
|
|
69
64
|
}
|
|
70
|
-
if (value instanceof
|
|
65
|
+
if (value instanceof Values.Set) {
|
|
71
66
|
seen.add(value);
|
|
72
67
|
try {
|
|
73
|
-
return `Set(${value.set.size})
|
|
68
|
+
return `Set(${value.set.size}) ${formatConsoleValue(new ProgramArray([...value.set.values()]), seen, depth + 1)}`;
|
|
74
69
|
}
|
|
75
70
|
finally {
|
|
76
71
|
seen.delete(value);
|
|
@@ -80,11 +75,12 @@ const formatConsoleValue = (value, seen, depth) => {
|
|
|
80
75
|
return "[opaque reference]";
|
|
81
76
|
seen.add(value);
|
|
82
77
|
try {
|
|
83
|
-
if (value instanceof ProgramArray)
|
|
84
|
-
return `[${
|
|
78
|
+
if (value instanceof ProgramArray) {
|
|
79
|
+
return `[${value.items.map((item) => formatConsoleValue(item, seen, depth + 1)).join(",")}]`;
|
|
80
|
+
}
|
|
85
81
|
if (!(value instanceof ProgramObject))
|
|
86
82
|
return "[object Object]";
|
|
87
|
-
return `{${
|
|
83
|
+
return `{${ownEntries(value)
|
|
88
84
|
.map(([key, item]) => `${JSON.stringify(key)}:${formatConsoleValue(item, seen, depth + 1)}`)
|
|
89
85
|
.join(",")}}`;
|
|
90
86
|
}
|
|
@@ -92,13 +88,12 @@ const formatConsoleValue = (value, seen, depth) => {
|
|
|
92
88
|
seen.delete(value);
|
|
93
89
|
}
|
|
94
90
|
};
|
|
95
|
-
const
|
|
96
|
-
const formatConsoleTable = (protos, value, columnsArgument) => {
|
|
91
|
+
const formatConsoleTable = (value, columnsArgument) => {
|
|
97
92
|
if (value === undefined)
|
|
98
93
|
return "undefined";
|
|
99
94
|
if (containsOpaqueReference(value))
|
|
100
95
|
return "[opaque reference]";
|
|
101
|
-
const data = toProgram(
|
|
96
|
+
const data = toProgram(value, "console.table argument");
|
|
102
97
|
const columns = consoleTableColumns(columnsArgument);
|
|
103
98
|
const rows = consoleTableRows(data, columns);
|
|
104
99
|
const keys = columns ?? Array.from(new Set(rows.flatMap((row) => Object.keys(row.values))));
|
|
@@ -121,7 +116,7 @@ const consoleTableRows = (data, columns) => {
|
|
|
121
116
|
return data.items.map((item, index) => ({ index: String(index), values: consoleTableValues(item, columns) }));
|
|
122
117
|
}
|
|
123
118
|
if (data instanceof ProgramObject) {
|
|
124
|
-
return
|
|
119
|
+
return ownEntries(data).map(([index, item]) => ({ index, values: consoleTableValues(item, columns) }));
|
|
125
120
|
}
|
|
126
121
|
return [{ index: "0", values: { Value: data } }];
|
|
127
122
|
};
|
|
@@ -129,7 +124,7 @@ const consoleTableValues = (value, columns) => {
|
|
|
129
124
|
if (value instanceof ProgramObject && !(value instanceof ProgramArray)) {
|
|
130
125
|
if (columns !== undefined)
|
|
131
126
|
return Object.fromEntries(columns.map((column) => [column, get(value, column)]));
|
|
132
|
-
return Object.fromEntries(
|
|
127
|
+
return Object.fromEntries(ownEntries(value));
|
|
133
128
|
}
|
|
134
129
|
return { Value: value };
|
|
135
130
|
};
|
package/dist/stdlib/date.d.ts
CHANGED
|
@@ -1,2 +1,8 @@
|
|
|
1
|
+
import { HostFunction } from "../interpreter/host.js";
|
|
2
|
+
import { type AstNode } from "../interpreter/model.js";
|
|
1
3
|
import { type Runner } from "../interpreter/runner.js";
|
|
2
|
-
|
|
4
|
+
import { Values } from "../values.js";
|
|
5
|
+
export declare const dateMethods: Set<string>;
|
|
6
|
+
export declare const dateGlobal: <R>(runner: Runner<R>) => HostFunction<R>;
|
|
7
|
+
export declare const dateSetterArgumentCount: (name: string) => number | undefined;
|
|
8
|
+
export declare const invokeDateMethod: (value: Values.Date, name: string, args: Array<number>, node: AstNode, initialTime?: number) => unknown;
|