@opencode/codemode 2.0.1 → 2.0.2
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 +6 -5
- package/dist/data.js +44 -46
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/interpreter/errors.d.ts +3 -4
- package/dist/interpreter/errors.js +40 -17
- package/dist/interpreter/execute.js +5 -3
- package/dist/interpreter/generators.d.ts +4 -0
- package/dist/interpreter/generators.js +25 -0
- package/dist/interpreter/globals.js +67 -46
- package/dist/interpreter/intrinsics.d.ts +8 -5
- package/dist/interpreter/intrinsics.js +59 -18
- package/dist/interpreter/model.d.ts +2 -32
- package/dist/interpreter/model.js +4 -38
- package/dist/interpreter/native.d.ts +19 -0
- package/dist/interpreter/native.js +40 -0
- package/dist/interpreter/objects.d.ts +105 -12
- package/dist/interpreter/objects.js +190 -66
- package/dist/interpreter/promises.d.ts +12 -13
- package/dist/interpreter/promises.js +52 -46
- package/dist/interpreter/references.d.ts +1 -0
- package/dist/interpreter/references.js +20 -33
- package/dist/interpreter/runner.d.ts +15 -13
- package/dist/interpreter/runner.js +19 -19
- package/dist/interpreter/runtime.d.ts +3 -3
- package/dist/interpreter/runtime.js +150 -314
- package/dist/stdlib/array.d.ts +4 -2
- package/dist/stdlib/array.js +423 -31
- package/dist/stdlib/collections.d.ts +3 -7
- package/dist/stdlib/collections.js +286 -114
- package/dist/stdlib/console.d.ts +3 -2
- package/dist/stdlib/console.js +35 -30
- package/dist/stdlib/date.d.ts +1 -7
- package/dist/stdlib/date.js +93 -188
- package/dist/stdlib/json.d.ts +2 -2
- package/dist/stdlib/json.js +24 -24
- package/dist/stdlib/math.d.ts +2 -2
- package/dist/stdlib/math.js +96 -76
- package/dist/stdlib/number.d.ts +3 -4
- package/dist/stdlib/number.js +94 -59
- package/dist/stdlib/object.d.ts +4 -4
- package/dist/stdlib/object.js +123 -49
- package/dist/stdlib/regexp.d.ts +6 -8
- package/dist/stdlib/regexp.js +71 -63
- package/dist/stdlib/string.d.ts +2 -2
- package/dist/stdlib/string.js +213 -50
- package/dist/stdlib/url.d.ts +5 -13
- package/dist/stdlib/url.js +196 -96
- package/dist/stdlib/value.d.ts +5 -4
- package/dist/stdlib/value.js +16 -16
- package/dist/stdlib/web.d.ts +4 -4
- package/dist/stdlib/web.js +8 -7
- package/dist/tool-runtime.d.ts +2 -1
- package/dist/tool-runtime.js +2 -2
- package/package.json +1 -1
- package/dist/interpreter/host.d.ts +0 -41
- package/dist/interpreter/host.js +0 -44
- package/dist/interpreter/methods.d.ts +0 -4
- package/dist/interpreter/methods.js +0 -837
- package/dist/values.d.ts +0 -37
- package/dist/values.js +0 -56
|
@@ -1,126 +1,67 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
|
-
import {
|
|
2
|
+
import { constructor, fn, methods, prototypeFrom, receiver, requiresNew } from "../interpreter/native.js";
|
|
3
3
|
import { InterpreterRuntimeError } from "../interpreter/model.js";
|
|
4
|
-
import { getOwn, ProgramArray, ProgramObject,
|
|
4
|
+
import { define, defineAccessor, get, getOwn, hidden, isWrapper, ProgramArray, ProgramMap, ProgramObject, ProgramPromise, ProgramSet, } from "../interpreter/objects.js";
|
|
5
5
|
import { describeValue, isRuntimeReference } from "../interpreter/references.js";
|
|
6
|
-
import { applyCollectionCallback, preserveConsumerError,
|
|
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
|
-
]);
|
|
6
|
+
import { applyCollectionCallback, isSupportedCallback, preserveConsumerError, toPrimitiveNumber, toPrimitiveString, } from "../interpreter/runner.js";
|
|
65
7
|
const coerceGroupByPropertyKey = (runner, value, node) => {
|
|
66
|
-
if (value instanceof
|
|
8
|
+
if (value instanceof ProgramPromise)
|
|
67
9
|
return Effect.succeed("[object Promise]");
|
|
68
|
-
if (!
|
|
10
|
+
if (!isWrapper(value) && isRuntimeReference(value)) {
|
|
69
11
|
throw new InterpreterRuntimeError(`Object.groupBy callback must return a data value, received ${describeValue(value)}.`, node, "InvalidDataValue");
|
|
70
12
|
}
|
|
71
|
-
return
|
|
13
|
+
return toPrimitiveString(runner, value, node);
|
|
72
14
|
};
|
|
73
15
|
/** `Map.groupBy` and `Object.groupBy`: the same iteration, keyed into a Map or a data object. */
|
|
74
|
-
export const groupBy = (runner, namespace) =>
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
16
|
+
export const groupBy = (runner, namespace) => fn(runner.prototypes, "groupBy", 2, (_, args, node) => {
|
|
17
|
+
const protos = runner.prototypes;
|
|
18
|
+
const source = args[0];
|
|
19
|
+
if (source === null || source === undefined) {
|
|
20
|
+
throw new InterpreterRuntimeError(`${namespace}.groupBy expects an iterable collection.`, node);
|
|
21
|
+
}
|
|
22
|
+
const apply = applyCollectionCallback(runner, args[1], `${namespace}.groupBy`, node);
|
|
23
|
+
return Effect.gen(function* () {
|
|
24
|
+
const cursor = yield* runner.syncIterator(source, node);
|
|
25
|
+
if (cursor === undefined) {
|
|
79
26
|
throw new InterpreterRuntimeError(`${namespace}.groupBy expects an iterable collection.`, node);
|
|
80
27
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
const cursor = yield* runner.syncIterator(source, node);
|
|
84
|
-
if (cursor === undefined) {
|
|
85
|
-
throw new InterpreterRuntimeError(`${namespace}.groupBy expects an iterable collection.`, node);
|
|
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();
|
|
28
|
+
if (namespace === "Map") {
|
|
29
|
+
const result = new ProgramMap(protos.Map);
|
|
105
30
|
let index = 0;
|
|
106
31
|
while (true) {
|
|
107
32
|
const step = yield* cursor.next;
|
|
108
33
|
if (step.done)
|
|
109
34
|
return result;
|
|
110
35
|
const item = step.value;
|
|
111
|
-
const key = yield* preserveConsumerError(cursor,
|
|
112
|
-
const group =
|
|
36
|
+
const key = yield* preserveConsumerError(cursor, apply([item, index]));
|
|
37
|
+
const group = result.map.get(key);
|
|
113
38
|
if (group === undefined)
|
|
114
|
-
set(
|
|
39
|
+
result.map.set(key, new ProgramArray(protos.Array, [item]));
|
|
115
40
|
else
|
|
116
41
|
group.items.push(item);
|
|
117
42
|
index += 1;
|
|
118
43
|
}
|
|
119
|
-
}
|
|
120
|
-
|
|
44
|
+
}
|
|
45
|
+
// Object.groupBy returns a null-prototype object, so group names never collide with inherited methods.
|
|
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
|
+
});
|
|
121
62
|
});
|
|
122
|
-
const constructMap = (runner, init, node) => {
|
|
123
|
-
const target = new
|
|
63
|
+
const constructMap = (runner, init, proto, node) => {
|
|
64
|
+
const target = new ProgramMap(proto);
|
|
124
65
|
if (init === undefined || init === null)
|
|
125
66
|
return Effect.succeed(target);
|
|
126
67
|
return Effect.gen(function* () {
|
|
@@ -141,8 +82,8 @@ const constructMap = (runner, init, node) => {
|
|
|
141
82
|
}
|
|
142
83
|
});
|
|
143
84
|
};
|
|
144
|
-
const constructSet = (runner, init, node) => {
|
|
145
|
-
const target = new
|
|
85
|
+
const constructSet = (runner, init, proto, node) => {
|
|
86
|
+
const target = new ProgramSet(proto);
|
|
146
87
|
if (init === undefined || init === null)
|
|
147
88
|
return Effect.succeed(target);
|
|
148
89
|
return Effect.gen(function* () {
|
|
@@ -158,16 +99,247 @@ const constructSet = (runner, init, node) => {
|
|
|
158
99
|
}
|
|
159
100
|
});
|
|
160
101
|
};
|
|
161
|
-
export const mapGlobal = (runner) =>
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
102
|
+
export const mapGlobal = (runner) => {
|
|
103
|
+
const protos = runner.prototypes;
|
|
104
|
+
const proto = protos.Map;
|
|
105
|
+
const map = constructor(protos, proto, {
|
|
106
|
+
name: "Map",
|
|
107
|
+
call: requiresNew("Map"),
|
|
108
|
+
construct: (args, newTarget, node) => constructMap(runner, args[0], prototypeFrom(newTarget, proto), node),
|
|
109
|
+
});
|
|
110
|
+
define(map, "groupBy", groupBy(runner, "Map"), hidden);
|
|
111
|
+
const self = (thisValue, name, node) => receiver(ProgramMap, thisValue, `Map.prototype.${name}`, node);
|
|
112
|
+
const wrap = (items) => new ProgramArray(protos.Array, items);
|
|
113
|
+
defineAccessor(proto, "size", (thisValue) => receiver(ProgramMap, thisValue, "Map.prototype.size").map.size);
|
|
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;
|
|
173
279
|
});
|
|
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,3 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ProgramObject } from "../interpreter/objects.js";
|
|
2
|
+
import type { Runner } from "../interpreter/runner.js";
|
|
2
3
|
/** Captured console: every method appends one formatted line to `logs`. */
|
|
3
|
-
export declare const consoleGlobal: (logs: Array<string>) =>
|
|
4
|
+
export declare const consoleGlobal: <R>(runner: Runner<R>, logs: Array<string>) => ProgramObject;
|
package/dist/stdlib/console.js
CHANGED
|
@@ -1,24 +1,29 @@
|
|
|
1
1
|
import { toData, toProgram } from "../data.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { methods } from "../interpreter/native.js";
|
|
3
|
+
import { entries, get, ProgramArray, ProgramDate, ProgramMap, ProgramObject, ProgramPromise, ProgramRegExp, ProgramSet, ProgramURL, ProgramURLSearchParams, } from "../interpreter/objects.js";
|
|
4
4
|
import { containsOpaqueReference, containsRuntimeReference, isRuntimeReference } from "../interpreter/references.js";
|
|
5
|
-
import { Values } from "../values.js";
|
|
6
5
|
import { coerceToString } from "./value.js";
|
|
7
6
|
const consoleMethods = ["log", "info", "debug", "warn", "error", "dir", "table"];
|
|
8
7
|
/** Captured console: every method appends one formatted line to `logs`. */
|
|
9
|
-
export const consoleGlobal = (
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
export const consoleGlobal = (runner, logs) => {
|
|
9
|
+
const protos = runner.prototypes;
|
|
10
|
+
const console = new ProgramObject(protos.Object);
|
|
11
|
+
methods(protos, console, consoleMethods.map((name) => [
|
|
12
|
+
name,
|
|
13
|
+
0,
|
|
14
|
+
(_, args) => {
|
|
15
|
+
logs.push(formatConsoleMessage(protos, name, args));
|
|
16
|
+
return undefined;
|
|
17
|
+
},
|
|
18
|
+
]));
|
|
19
|
+
return console;
|
|
20
|
+
};
|
|
16
21
|
const MAX_CONSOLE_DEPTH = 32;
|
|
17
|
-
const formatConsoleMessage = (name, args) => {
|
|
22
|
+
const formatConsoleMessage = (protos, name, args) => {
|
|
18
23
|
if (name === "dir")
|
|
19
24
|
return args.length === 0 ? "undefined" : formatConsoleArgument(args[0]);
|
|
20
25
|
if (name === "table")
|
|
21
|
-
return formatConsoleTable(args[0], args[1]);
|
|
26
|
+
return formatConsoleTable(protos, args[0], args[1]);
|
|
22
27
|
const prefix = name === "warn" ? "[warn] " : name === "error" ? "[error] " : name === "debug" ? "[debug] " : "";
|
|
23
28
|
return `${prefix}${args.map((arg) => formatConsoleArgument(arg)).join(" ")}`;
|
|
24
29
|
};
|
|
@@ -38,34 +43,34 @@ const formatConsoleValue = (value, seen, depth) => {
|
|
|
38
43
|
return String(value);
|
|
39
44
|
if (typeof value !== "object")
|
|
40
45
|
return String(value);
|
|
41
|
-
if (value instanceof
|
|
46
|
+
if (value instanceof ProgramPromise)
|
|
42
47
|
return "[Promise (await it to get its value)]";
|
|
43
|
-
if (value instanceof
|
|
48
|
+
if (value instanceof ProgramDate)
|
|
44
49
|
return coerceToString(value);
|
|
45
|
-
if (value instanceof
|
|
50
|
+
if (value instanceof ProgramRegExp)
|
|
46
51
|
return coerceToString(value);
|
|
47
|
-
if (value instanceof
|
|
52
|
+
if (value instanceof ProgramURL)
|
|
48
53
|
return coerceToString(value);
|
|
49
|
-
if (value instanceof
|
|
54
|
+
if (value instanceof ProgramURLSearchParams)
|
|
50
55
|
return coerceToString(value);
|
|
51
56
|
if (depth > MAX_CONSOLE_DEPTH)
|
|
52
57
|
return "...";
|
|
53
58
|
if (seen.has(value))
|
|
54
59
|
return "[Circular]";
|
|
55
|
-
if (value instanceof
|
|
60
|
+
if (value instanceof ProgramMap) {
|
|
56
61
|
seen.add(value);
|
|
57
62
|
try {
|
|
58
|
-
const
|
|
59
|
-
return `Map(${value.map.size}) ${
|
|
63
|
+
const items = Array.from(value.map.entries(), ([key, item]) => `[${formatItems([key, item], seen, depth + 1)}]`);
|
|
64
|
+
return `Map(${value.map.size}) [${items.join(",")}]`;
|
|
60
65
|
}
|
|
61
66
|
finally {
|
|
62
67
|
seen.delete(value);
|
|
63
68
|
}
|
|
64
69
|
}
|
|
65
|
-
if (value instanceof
|
|
70
|
+
if (value instanceof ProgramSet) {
|
|
66
71
|
seen.add(value);
|
|
67
72
|
try {
|
|
68
|
-
return `Set(${value.set.size}) ${
|
|
73
|
+
return `Set(${value.set.size}) [${formatItems([...value.set.values()], seen, depth + 1)}]`;
|
|
69
74
|
}
|
|
70
75
|
finally {
|
|
71
76
|
seen.delete(value);
|
|
@@ -75,12 +80,11 @@ const formatConsoleValue = (value, seen, depth) => {
|
|
|
75
80
|
return "[opaque reference]";
|
|
76
81
|
seen.add(value);
|
|
77
82
|
try {
|
|
78
|
-
if (value instanceof ProgramArray)
|
|
79
|
-
return `[${value.items
|
|
80
|
-
}
|
|
83
|
+
if (value instanceof ProgramArray)
|
|
84
|
+
return `[${formatItems(value.items, seen, depth + 1)}]`;
|
|
81
85
|
if (!(value instanceof ProgramObject))
|
|
82
86
|
return "[object Object]";
|
|
83
|
-
return `{${
|
|
87
|
+
return `{${entries(value)
|
|
84
88
|
.map(([key, item]) => `${JSON.stringify(key)}:${formatConsoleValue(item, seen, depth + 1)}`)
|
|
85
89
|
.join(",")}}`;
|
|
86
90
|
}
|
|
@@ -88,12 +92,13 @@ const formatConsoleValue = (value, seen, depth) => {
|
|
|
88
92
|
seen.delete(value);
|
|
89
93
|
}
|
|
90
94
|
};
|
|
91
|
-
const
|
|
95
|
+
const formatItems = (items, seen, depth) => items.map((item) => formatConsoleValue(item, seen, depth)).join(",");
|
|
96
|
+
const formatConsoleTable = (protos, value, columnsArgument) => {
|
|
92
97
|
if (value === undefined)
|
|
93
98
|
return "undefined";
|
|
94
99
|
if (containsOpaqueReference(value))
|
|
95
100
|
return "[opaque reference]";
|
|
96
|
-
const data = toProgram(value, "console.table argument");
|
|
101
|
+
const data = toProgram(protos, value, "console.table argument");
|
|
97
102
|
const columns = consoleTableColumns(columnsArgument);
|
|
98
103
|
const rows = consoleTableRows(data, columns);
|
|
99
104
|
const keys = columns ?? Array.from(new Set(rows.flatMap((row) => Object.keys(row.values))));
|
|
@@ -116,7 +121,7 @@ const consoleTableRows = (data, columns) => {
|
|
|
116
121
|
return data.items.map((item, index) => ({ index: String(index), values: consoleTableValues(item, columns) }));
|
|
117
122
|
}
|
|
118
123
|
if (data instanceof ProgramObject) {
|
|
119
|
-
return
|
|
124
|
+
return entries(data).map(([index, item]) => ({ index, values: consoleTableValues(item, columns) }));
|
|
120
125
|
}
|
|
121
126
|
return [{ index: "0", values: { Value: data } }];
|
|
122
127
|
};
|
|
@@ -124,7 +129,7 @@ const consoleTableValues = (value, columns) => {
|
|
|
124
129
|
if (value instanceof ProgramObject && !(value instanceof ProgramArray)) {
|
|
125
130
|
if (columns !== undefined)
|
|
126
131
|
return Object.fromEntries(columns.map((column) => [column, get(value, column)]));
|
|
127
|
-
return Object.fromEntries(
|
|
132
|
+
return Object.fromEntries(entries(value));
|
|
128
133
|
}
|
|
129
134
|
return { Value: value };
|
|
130
135
|
};
|
package/dist/stdlib/date.d.ts
CHANGED
|
@@ -1,8 +1,2 @@
|
|
|
1
|
-
import { HostFunction } from "../interpreter/host.js";
|
|
2
|
-
import { type AstNode } from "../interpreter/model.js";
|
|
3
1
|
import { type Runner } from "../interpreter/runner.js";
|
|
4
|
-
|
|
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;
|
|
2
|
+
export declare const dateGlobal: <R>(runner: Runner<R>) => import("../interpreter/objects.js").NativeFunction<R>;
|