@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
package/dist/stdlib/date.js
CHANGED
|
@@ -1,24 +1,36 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import { HostFunction, sync } from "../interpreter/host.js";
|
|
3
|
+
import { InterpreterRuntimeError } from "../interpreter/model.js";
|
|
4
|
+
import { toPrimitive } from "../interpreter/runner.js";
|
|
5
|
+
import { Values } from "../values.js";
|
|
6
6
|
import { coerceToNumber, coerceToString } from "./value.js";
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
7
|
+
const dateSetterArguments = new Map([
|
|
8
|
+
["setTime", 1],
|
|
9
|
+
["setMilliseconds", 1],
|
|
10
|
+
["setUTCMilliseconds", 1],
|
|
11
|
+
["setSeconds", 2],
|
|
12
|
+
["setUTCSeconds", 2],
|
|
13
|
+
["setMinutes", 3],
|
|
14
|
+
["setUTCMinutes", 3],
|
|
15
|
+
["setHours", 4],
|
|
16
|
+
["setUTCHours", 4],
|
|
17
|
+
["setDate", 1],
|
|
18
|
+
["setUTCDate", 1],
|
|
19
|
+
["setMonth", 2],
|
|
20
|
+
["setUTCMonth", 2],
|
|
21
|
+
["setFullYear", 3],
|
|
22
|
+
["setUTCFullYear", 3],
|
|
23
|
+
]);
|
|
24
|
+
export const dateMethods = new Set([
|
|
25
|
+
"getTime",
|
|
26
|
+
"valueOf",
|
|
27
|
+
"toISOString",
|
|
28
|
+
"toJSON",
|
|
29
|
+
"toString",
|
|
30
|
+
"toDateString",
|
|
31
|
+
"toTimeString",
|
|
32
|
+
"toUTCString",
|
|
33
|
+
"toGMTString",
|
|
22
34
|
"getFullYear",
|
|
23
35
|
"getMonth",
|
|
24
36
|
"getDate",
|
|
@@ -36,78 +48,161 @@ const getters = [
|
|
|
36
48
|
"getUTCSeconds",
|
|
37
49
|
"getUTCMilliseconds",
|
|
38
50
|
"getTimezoneOffset",
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
(
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
51
|
+
...dateSetterArguments.keys(),
|
|
52
|
+
]);
|
|
53
|
+
const constructDate = (runner, args, node) => {
|
|
54
|
+
if (args.length === 0)
|
|
55
|
+
return Effect.succeed(new Values.Date(Date.now()));
|
|
56
|
+
if (args.length === 1) {
|
|
57
|
+
const arg = args[0];
|
|
58
|
+
if (arg instanceof Values.Date)
|
|
59
|
+
return Effect.succeed(new Values.Date(arg.time));
|
|
60
|
+
return Effect.map(toPrimitive(runner, arg, "number", node), (value) => typeof value === "string"
|
|
61
|
+
? new Values.Date(Date.parse(value))
|
|
62
|
+
: new Values.Date(new Date(coerceToNumber(value)).getTime()));
|
|
63
|
+
}
|
|
64
|
+
const parts = args.map((arg) => coerceToNumber(arg));
|
|
65
|
+
return Effect.succeed(new Values.Date(new Date(...parts).getTime()));
|
|
66
|
+
};
|
|
67
|
+
export const dateGlobal = (runner) => new HostFunction({
|
|
68
|
+
name: "Date",
|
|
69
|
+
// ISO instead of the host's locale string: date strings are deterministic and must not leak the host timezone.
|
|
70
|
+
call: () => Effect.sync(() => new Date().toISOString()),
|
|
71
|
+
construct: (args, node) => constructDate(runner, args, node),
|
|
72
|
+
instanceOf: (value) => value instanceof Values.Date,
|
|
73
|
+
members: {
|
|
74
|
+
now: sync("Date.now", () => Date.now()),
|
|
75
|
+
parse: sync("Date.parse", (args) => Date.parse(coerceToString(args[0]))),
|
|
76
|
+
UTC: sync("Date.UTC", (args) => Date.UTC(...args.map((arg) => coerceToNumber(arg)))),
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
export const dateSetterArgumentCount = (name) => dateSetterArguments.get(name);
|
|
80
|
+
export const invokeDateMethod = (value, name, args, node, initialTime = value.time) => {
|
|
81
|
+
const hosted = new Date(initialTime);
|
|
82
|
+
switch (name) {
|
|
83
|
+
case "getTime":
|
|
84
|
+
case "valueOf":
|
|
85
|
+
return value.time;
|
|
86
|
+
case "toISOString":
|
|
87
|
+
if (!Number.isFinite(value.time))
|
|
88
|
+
throw new InterpreterRuntimeError("Invalid time value.", node).as("RangeError");
|
|
89
|
+
return hosted.toISOString();
|
|
90
|
+
case "toJSON":
|
|
91
|
+
return Number.isFinite(value.time) ? hosted.toISOString() : null;
|
|
92
|
+
case "toString":
|
|
93
|
+
return coerceToString(value);
|
|
94
|
+
case "toDateString":
|
|
95
|
+
return hosted.toDateString();
|
|
96
|
+
case "toTimeString":
|
|
97
|
+
return hosted.toTimeString();
|
|
98
|
+
case "toUTCString":
|
|
99
|
+
case "toGMTString":
|
|
100
|
+
return hosted.toUTCString();
|
|
101
|
+
case "getFullYear":
|
|
102
|
+
return hosted.getFullYear();
|
|
103
|
+
case "getMonth":
|
|
104
|
+
return hosted.getMonth();
|
|
105
|
+
case "getDate":
|
|
106
|
+
return hosted.getDate();
|
|
107
|
+
case "getDay":
|
|
108
|
+
return hosted.getDay();
|
|
109
|
+
case "getHours":
|
|
110
|
+
return hosted.getHours();
|
|
111
|
+
case "getMinutes":
|
|
112
|
+
return hosted.getMinutes();
|
|
113
|
+
case "getSeconds":
|
|
114
|
+
return hosted.getSeconds();
|
|
115
|
+
case "getMilliseconds":
|
|
116
|
+
return hosted.getMilliseconds();
|
|
117
|
+
case "getUTCFullYear":
|
|
118
|
+
return hosted.getUTCFullYear();
|
|
119
|
+
case "getUTCMonth":
|
|
120
|
+
return hosted.getUTCMonth();
|
|
121
|
+
case "getUTCDate":
|
|
122
|
+
return hosted.getUTCDate();
|
|
123
|
+
case "getUTCDay":
|
|
124
|
+
return hosted.getUTCDay();
|
|
125
|
+
case "getUTCHours":
|
|
126
|
+
return hosted.getUTCHours();
|
|
127
|
+
case "getUTCMinutes":
|
|
128
|
+
return hosted.getUTCMinutes();
|
|
129
|
+
case "getUTCSeconds":
|
|
130
|
+
return hosted.getUTCSeconds();
|
|
131
|
+
case "getUTCMilliseconds":
|
|
132
|
+
return hosted.getUTCMilliseconds();
|
|
133
|
+
case "getTimezoneOffset":
|
|
134
|
+
return hosted.getTimezoneOffset();
|
|
135
|
+
case "setTime":
|
|
136
|
+
return updateDate(value, hosted.setTime(args[0]));
|
|
137
|
+
case "setMilliseconds":
|
|
138
|
+
return updateDate(value, hosted.setMilliseconds(args[0]));
|
|
139
|
+
case "setUTCMilliseconds":
|
|
140
|
+
return updateDate(value, hosted.setUTCMilliseconds(args[0]));
|
|
141
|
+
case "setSeconds":
|
|
142
|
+
if (args.length < 2)
|
|
143
|
+
return updateDate(value, hosted.setSeconds(args[0]));
|
|
144
|
+
return updateDate(value, hosted.setSeconds(args[0], args[1]));
|
|
145
|
+
case "setUTCSeconds":
|
|
146
|
+
if (args.length < 2)
|
|
147
|
+
return updateDate(value, hosted.setUTCSeconds(args[0]));
|
|
148
|
+
return updateDate(value, hosted.setUTCSeconds(args[0], args[1]));
|
|
149
|
+
case "setMinutes":
|
|
150
|
+
if (args.length < 2)
|
|
151
|
+
return updateDate(value, hosted.setMinutes(args[0]));
|
|
152
|
+
if (args.length < 3)
|
|
153
|
+
return updateDate(value, hosted.setMinutes(args[0], args[1]));
|
|
154
|
+
return updateDate(value, hosted.setMinutes(args[0], args[1], args[2]));
|
|
155
|
+
case "setUTCMinutes":
|
|
156
|
+
if (args.length < 2)
|
|
157
|
+
return updateDate(value, hosted.setUTCMinutes(args[0]));
|
|
158
|
+
if (args.length < 3)
|
|
159
|
+
return updateDate(value, hosted.setUTCMinutes(args[0], args[1]));
|
|
160
|
+
return updateDate(value, hosted.setUTCMinutes(args[0], args[1], args[2]));
|
|
161
|
+
case "setHours":
|
|
162
|
+
if (args.length < 2)
|
|
163
|
+
return updateDate(value, hosted.setHours(args[0]));
|
|
164
|
+
if (args.length < 3)
|
|
165
|
+
return updateDate(value, hosted.setHours(args[0], args[1]));
|
|
166
|
+
if (args.length < 4)
|
|
167
|
+
return updateDate(value, hosted.setHours(args[0], args[1], args[2]));
|
|
168
|
+
return updateDate(value, hosted.setHours(args[0], args[1], args[2], args[3]));
|
|
169
|
+
case "setUTCHours":
|
|
170
|
+
if (args.length < 2)
|
|
171
|
+
return updateDate(value, hosted.setUTCHours(args[0]));
|
|
172
|
+
if (args.length < 3)
|
|
173
|
+
return updateDate(value, hosted.setUTCHours(args[0], args[1]));
|
|
174
|
+
if (args.length < 4)
|
|
175
|
+
return updateDate(value, hosted.setUTCHours(args[0], args[1], args[2]));
|
|
176
|
+
return updateDate(value, hosted.setUTCHours(args[0], args[1], args[2], args[3]));
|
|
177
|
+
case "setDate":
|
|
178
|
+
return updateDate(value, hosted.setDate(args[0]));
|
|
179
|
+
case "setUTCDate":
|
|
180
|
+
return updateDate(value, hosted.setUTCDate(args[0]));
|
|
181
|
+
case "setMonth":
|
|
182
|
+
if (args.length < 2)
|
|
183
|
+
return updateDate(value, hosted.setMonth(args[0]));
|
|
184
|
+
return updateDate(value, hosted.setMonth(args[0], args[1]));
|
|
185
|
+
case "setUTCMonth":
|
|
186
|
+
if (args.length < 2)
|
|
187
|
+
return updateDate(value, hosted.setUTCMonth(args[0]));
|
|
188
|
+
return updateDate(value, hosted.setUTCMonth(args[0], args[1]));
|
|
189
|
+
case "setFullYear":
|
|
190
|
+
if (args.length < 2)
|
|
191
|
+
return updateDate(value, hosted.setFullYear(args[0]));
|
|
192
|
+
if (args.length < 3)
|
|
193
|
+
return updateDate(value, hosted.setFullYear(args[0], args[1]));
|
|
194
|
+
return updateDate(value, hosted.setFullYear(args[0], args[1], args[2]));
|
|
195
|
+
case "setUTCFullYear":
|
|
196
|
+
if (args.length < 2)
|
|
197
|
+
return updateDate(value, hosted.setUTCFullYear(args[0]));
|
|
198
|
+
if (args.length < 3)
|
|
199
|
+
return updateDate(value, hosted.setUTCFullYear(args[0], args[1]));
|
|
200
|
+
return updateDate(value, hosted.setUTCFullYear(args[0], args[1], args[2]));
|
|
201
|
+
default:
|
|
202
|
+
throw new InterpreterRuntimeError(`Date method '${name}' is not available.`, node);
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
const updateDate = (value, time) => {
|
|
206
|
+
value.time = time;
|
|
207
|
+
return time;
|
|
113
208
|
};
|
package/dist/stdlib/json.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
+
import { HostNamespace } from "../interpreter/host.js";
|
|
1
2
|
import { type Runner } from "../interpreter/runner.js";
|
|
2
|
-
|
|
3
|
-
export declare const jsonGlobal: <R>(runner: Runner<R>) => ProgramObject;
|
|
3
|
+
export declare const jsonGlobal: <R>(runner: Runner<R>) => HostNamespace;
|
package/dist/stdlib/json.js
CHANGED
|
@@ -1,28 +1,25 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
|
-
import {
|
|
2
|
+
import { HostFunction, HostNamespace } from "../interpreter/host.js";
|
|
3
3
|
import { applyCollectionCallback } from "../interpreter/runner.js";
|
|
4
|
-
import { InterpreterRuntimeError
|
|
4
|
+
import { InterpreterRuntimeError } from "../interpreter/model.js";
|
|
5
5
|
import { typeofValue } from "../interpreter/references.js";
|
|
6
6
|
import { fromData, toData, toProgram } from "../data.js";
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
]);
|
|
14
|
-
return json;
|
|
15
|
-
};
|
|
7
|
+
import { get, ownKeys, ProgramArray, ProgramObject, record, remove, set } from "../interpreter/objects.js";
|
|
8
|
+
import { Values } from "../values.js";
|
|
9
|
+
export const jsonGlobal = (runner) => new HostNamespace("JSON", {
|
|
10
|
+
parse: new HostFunction({ name: "JSON.parse", call: (args, node) => parse(runner, args, node) }),
|
|
11
|
+
stringify: new HostFunction({ name: "JSON.stringify", call: (args, node) => stringify(runner, args, node) }),
|
|
12
|
+
});
|
|
16
13
|
const parse = (runner, args, node) => {
|
|
17
14
|
const text = args[0];
|
|
18
15
|
if (typeof text !== "string")
|
|
19
16
|
throw new InterpreterRuntimeError("JSON.parse expects a string.", node);
|
|
20
17
|
const parsed = (() => {
|
|
21
18
|
try {
|
|
22
|
-
return fromData(
|
|
19
|
+
return fromData(JSON.parse(text), "JSON.parse result");
|
|
23
20
|
}
|
|
24
21
|
catch (error) {
|
|
25
|
-
throw
|
|
22
|
+
throw new InterpreterRuntimeError(`JSON.parse received invalid JSON: ${error instanceof Error ? error.message : String(error)}`, node).as("SyntaxError");
|
|
26
23
|
}
|
|
27
24
|
})();
|
|
28
25
|
if (typeofValue(args[1]) !== "function")
|
|
@@ -31,7 +28,7 @@ const parse = (runner, args, node) => {
|
|
|
31
28
|
const visit = (holder, key) => Effect.gen(function* () {
|
|
32
29
|
const value = get(holder, key);
|
|
33
30
|
if (value instanceof ProgramObject) {
|
|
34
|
-
for (const name of
|
|
31
|
+
for (const name of ownKeys(value)) {
|
|
35
32
|
const revived = yield* visit(value, name);
|
|
36
33
|
if (revived === undefined)
|
|
37
34
|
remove(value, name);
|
|
@@ -41,7 +38,7 @@ const parse = (runner, args, node) => {
|
|
|
41
38
|
}
|
|
42
39
|
return yield* apply([key, value]);
|
|
43
40
|
});
|
|
44
|
-
return visit(record(
|
|
41
|
+
return visit(record({ "": parsed }), "");
|
|
45
42
|
};
|
|
46
43
|
const stringify = (runner, args, node) => {
|
|
47
44
|
const space = args[2];
|
|
@@ -56,14 +53,14 @@ const stringify = (runner, args, node) => {
|
|
|
56
53
|
return Effect.succeed(JSON.stringify(toData(args[0], "JSON.stringify value"), properties, indent));
|
|
57
54
|
}
|
|
58
55
|
// Validate up front; the replacer walk below reads the original value.
|
|
59
|
-
toProgram(
|
|
56
|
+
toProgram(args[0], "JSON.stringify value");
|
|
60
57
|
const apply = applyCollectionCallback(runner, replacer, "JSON.stringify", node);
|
|
61
58
|
const stack = new Set();
|
|
62
59
|
const visit = (holder, key) => Effect.gen(function* () {
|
|
63
|
-
const value = yield* apply([key,
|
|
60
|
+
const value = yield* apply([key, toJSONValue(get(holder, key))]);
|
|
64
61
|
if (value === undefined || typeofValue(value) === "function")
|
|
65
62
|
return undefined;
|
|
66
|
-
toProgram(
|
|
63
|
+
toProgram(value, "JSON.stringify replacer result");
|
|
67
64
|
if (typeof value === "number")
|
|
68
65
|
return Number.isFinite(value) ? value : null;
|
|
69
66
|
if (value === null || typeof value === "string" || typeof value === "boolean")
|
|
@@ -71,7 +68,7 @@ const stringify = (runner, args, node) => {
|
|
|
71
68
|
if (!(value instanceof ProgramObject))
|
|
72
69
|
return {};
|
|
73
70
|
if (stack.has(value))
|
|
74
|
-
throw new InterpreterRuntimeError("Converting circular structure to JSON.", node);
|
|
71
|
+
throw new InterpreterRuntimeError("Converting circular structure to JSON.", node).as("TypeError");
|
|
75
72
|
stack.add(value);
|
|
76
73
|
if (value instanceof ProgramArray) {
|
|
77
74
|
const result = [];
|
|
@@ -82,7 +79,9 @@ const stringify = (runner, args, node) => {
|
|
|
82
79
|
return result;
|
|
83
80
|
}
|
|
84
81
|
const result = Object.create(null);
|
|
85
|
-
for (const name of
|
|
82
|
+
for (const name of ownKeys(value)) {
|
|
83
|
+
if (typeof name !== "string")
|
|
84
|
+
continue;
|
|
86
85
|
const item = yield* visit(value, name);
|
|
87
86
|
if (item !== undefined)
|
|
88
87
|
result[name] = item;
|
|
@@ -90,12 +89,13 @@ const stringify = (runner, args, node) => {
|
|
|
90
89
|
stack.delete(value);
|
|
91
90
|
return result;
|
|
92
91
|
});
|
|
93
|
-
return Effect.map(visit(record(
|
|
92
|
+
return Effect.map(visit(record({ "": args[0] }), ""), (value) => JSON.stringify(value, null, indent));
|
|
94
93
|
};
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
94
|
+
const toJSONValue = (value) => {
|
|
95
|
+
if (value instanceof Values.Date) {
|
|
96
|
+
return Number.isFinite(value.time) ? new Date(value.time).toISOString() : null;
|
|
97
|
+
}
|
|
98
|
+
if (value instanceof Values.URL)
|
|
99
|
+
return value.url.href;
|
|
100
|
+
return value;
|
|
101
101
|
};
|
package/dist/stdlib/math.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { HostNamespace } from "../interpreter/host.js";
|
|
2
2
|
import { type Runner } from "../interpreter/runner.js";
|
|
3
3
|
declare global {
|
|
4
4
|
interface Math {
|
|
5
5
|
sumPrecise(values: Iterable<number>): number;
|
|
6
6
|
}
|
|
7
7
|
}
|
|
8
|
-
export declare const mathGlobal: <R>(runner: Runner<R>) =>
|
|
8
|
+
export declare const mathGlobal: <R>(runner: Runner<R>) => HostNamespace;
|
package/dist/stdlib/math.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
|
-
import {
|
|
3
|
-
import { InterpreterRuntimeError } from "../interpreter/model.js";
|
|
4
|
-
import { ProgramObject } from "../interpreter/objects.js";
|
|
2
|
+
import { HostFunction, HostNamespace, sync } from "../interpreter/host.js";
|
|
5
3
|
import { preserveConsumerError } from "../interpreter/runner.js";
|
|
4
|
+
import { InterpreterRuntimeError } from "../interpreter/model.js";
|
|
6
5
|
// Validate only the arguments a method consumes; like JS, extras are ignored
|
|
7
6
|
// (so built-ins work as callbacks receiving (element, index, array)).
|
|
8
7
|
const number = (name, args, index, node) => {
|
|
@@ -13,97 +12,78 @@ const number = (name, args, index, node) => {
|
|
|
13
12
|
throw new InterpreterRuntimeError(`Math.${name} expects number arguments.`, node);
|
|
14
13
|
return arg;
|
|
15
14
|
};
|
|
16
|
-
const unary = (name, op) =>
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
(
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
constants(math, {
|
|
39
|
-
PI: Math.PI,
|
|
40
|
-
E: Math.E,
|
|
41
|
-
LN2: Math.LN2,
|
|
42
|
-
LN10: Math.LN10,
|
|
43
|
-
LOG2E: Math.LOG2E,
|
|
44
|
-
LOG10E: Math.LOG10E,
|
|
45
|
-
SQRT2: Math.SQRT2,
|
|
46
|
-
SQRT1_2: Math.SQRT1_2,
|
|
47
|
-
});
|
|
48
|
-
methods(protos, math, [
|
|
49
|
-
["random", 0, () => Math.random()],
|
|
50
|
-
variadic("max", Math.max),
|
|
51
|
-
variadic("min", Math.min),
|
|
52
|
-
variadic("hypot", Math.hypot),
|
|
53
|
-
unary("abs", Math.abs),
|
|
54
|
-
unary("acos", Math.acos),
|
|
55
|
-
unary("acosh", Math.acosh),
|
|
56
|
-
unary("asin", Math.asin),
|
|
57
|
-
unary("asinh", Math.asinh),
|
|
58
|
-
unary("atan", Math.atan),
|
|
59
|
-
binary("atan2", Math.atan2),
|
|
60
|
-
unary("atanh", Math.atanh),
|
|
61
|
-
unary("floor", Math.floor),
|
|
62
|
-
unary("ceil", Math.ceil),
|
|
63
|
-
unary("round", Math.round),
|
|
64
|
-
unary("trunc", Math.trunc),
|
|
65
|
-
unary("sign", Math.sign),
|
|
66
|
-
unary("sqrt", Math.sqrt),
|
|
67
|
-
unary("cbrt", Math.cbrt),
|
|
68
|
-
binary("pow", Math.pow),
|
|
69
|
-
unary("cos", Math.cos),
|
|
70
|
-
unary("cosh", Math.cosh),
|
|
71
|
-
unary("sin", Math.sin),
|
|
72
|
-
unary("sinh", Math.sinh),
|
|
73
|
-
unary("tan", Math.tan),
|
|
74
|
-
unary("tanh", Math.tanh),
|
|
75
|
-
unary("log", Math.log),
|
|
76
|
-
unary("log2", Math.log2),
|
|
77
|
-
unary("log10", Math.log10),
|
|
78
|
-
unary("log1p", Math.log1p),
|
|
79
|
-
unary("exp", Math.exp),
|
|
80
|
-
unary("expm1", Math.expm1),
|
|
81
|
-
unary("f16round", Math.f16round),
|
|
82
|
-
unary("fround", Math.fround),
|
|
83
|
-
unary("clz32", Math.clz32),
|
|
84
|
-
binary("imul", Math.imul),
|
|
85
|
-
[
|
|
86
|
-
"sumPrecise",
|
|
87
|
-
1,
|
|
88
|
-
(_, args, node) => Effect.gen(function* () {
|
|
89
|
-
const cursor = yield* runner.syncIterator(args[0], node);
|
|
90
|
-
if (cursor === undefined) {
|
|
91
|
-
throw new InterpreterRuntimeError("Math.sumPrecise expects a synchronous iterable.", node);
|
|
92
|
-
}
|
|
93
|
-
const numbers = [];
|
|
94
|
-
while (true) {
|
|
95
|
-
const step = yield* cursor.next;
|
|
96
|
-
if (step.done)
|
|
97
|
-
return Math.sumPrecise(numbers);
|
|
98
|
-
yield* preserveConsumerError(cursor, Effect.sync(() => {
|
|
99
|
-
if (typeof step.value !== "number") {
|
|
100
|
-
throw new InterpreterRuntimeError("Math.sumPrecise expects an iterable of numbers.", node);
|
|
101
|
-
}
|
|
102
|
-
numbers.push(step.value);
|
|
103
|
-
}));
|
|
15
|
+
const unary = (name, op) => sync(`Math.${name}`, (args, node) => op(number(name, args, 0, node)));
|
|
16
|
+
const binary = (name, op) => sync(`Math.${name}`, (args, node) => op(number(name, args, 0, node), number(name, args, 1, node)));
|
|
17
|
+
const variadic = (name, op) => sync(`Math.${name}`, (args, node) => op(...args.map((arg) => {
|
|
18
|
+
if (typeof arg !== "number")
|
|
19
|
+
throw new InterpreterRuntimeError(`Math.${name} expects number arguments.`, node);
|
|
20
|
+
return arg;
|
|
21
|
+
})));
|
|
22
|
+
const sumPrecise = (runner) => new HostFunction({
|
|
23
|
+
name: "Math.sumPrecise",
|
|
24
|
+
call: (args, node) => Effect.gen(function* () {
|
|
25
|
+
const cursor = yield* runner.syncIterator(args[0], node);
|
|
26
|
+
if (cursor === undefined) {
|
|
27
|
+
throw new InterpreterRuntimeError("Math.sumPrecise expects a synchronous iterable.", node).as("TypeError");
|
|
28
|
+
}
|
|
29
|
+
const numbers = [];
|
|
30
|
+
while (true) {
|
|
31
|
+
const step = yield* cursor.next;
|
|
32
|
+
if (step.done)
|
|
33
|
+
return Math.sumPrecise(numbers);
|
|
34
|
+
yield* preserveConsumerError(cursor, Effect.sync(() => {
|
|
35
|
+
if (typeof step.value !== "number") {
|
|
36
|
+
throw new InterpreterRuntimeError("Math.sumPrecise expects an iterable of numbers.", node).as("TypeError");
|
|
104
37
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
};
|
|
38
|
+
numbers.push(step.value);
|
|
39
|
+
}));
|
|
40
|
+
}
|
|
41
|
+
}),
|
|
42
|
+
});
|
|
43
|
+
export const mathGlobal = (runner) => new HostNamespace("Math", {
|
|
44
|
+
PI: Math.PI,
|
|
45
|
+
E: Math.E,
|
|
46
|
+
LN2: Math.LN2,
|
|
47
|
+
LN10: Math.LN10,
|
|
48
|
+
LOG2E: Math.LOG2E,
|
|
49
|
+
LOG10E: Math.LOG10E,
|
|
50
|
+
SQRT2: Math.SQRT2,
|
|
51
|
+
SQRT1_2: Math.SQRT1_2,
|
|
52
|
+
random: sync("Math.random", () => Math.random()),
|
|
53
|
+
max: variadic("max", Math.max),
|
|
54
|
+
min: variadic("min", Math.min),
|
|
55
|
+
hypot: variadic("hypot", Math.hypot),
|
|
56
|
+
abs: unary("abs", Math.abs),
|
|
57
|
+
acos: unary("acos", Math.acos),
|
|
58
|
+
acosh: unary("acosh", Math.acosh),
|
|
59
|
+
asin: unary("asin", Math.asin),
|
|
60
|
+
asinh: unary("asinh", Math.asinh),
|
|
61
|
+
atan: unary("atan", Math.atan),
|
|
62
|
+
atan2: binary("atan2", Math.atan2),
|
|
63
|
+
atanh: unary("atanh", Math.atanh),
|
|
64
|
+
floor: unary("floor", Math.floor),
|
|
65
|
+
ceil: unary("ceil", Math.ceil),
|
|
66
|
+
round: unary("round", Math.round),
|
|
67
|
+
trunc: unary("trunc", Math.trunc),
|
|
68
|
+
sign: unary("sign", Math.sign),
|
|
69
|
+
sqrt: unary("sqrt", Math.sqrt),
|
|
70
|
+
cbrt: unary("cbrt", Math.cbrt),
|
|
71
|
+
pow: binary("pow", Math.pow),
|
|
72
|
+
cos: unary("cos", Math.cos),
|
|
73
|
+
cosh: unary("cosh", Math.cosh),
|
|
74
|
+
sin: unary("sin", Math.sin),
|
|
75
|
+
sinh: unary("sinh", Math.sinh),
|
|
76
|
+
tan: unary("tan", Math.tan),
|
|
77
|
+
tanh: unary("tanh", Math.tanh),
|
|
78
|
+
log: unary("log", Math.log),
|
|
79
|
+
log2: unary("log2", Math.log2),
|
|
80
|
+
log10: unary("log10", Math.log10),
|
|
81
|
+
log1p: unary("log1p", Math.log1p),
|
|
82
|
+
exp: unary("exp", Math.exp),
|
|
83
|
+
expm1: unary("expm1", Math.expm1),
|
|
84
|
+
f16round: unary("f16round", Math.f16round),
|
|
85
|
+
fround: unary("fround", Math.fround),
|
|
86
|
+
clz32: unary("clz32", Math.clz32),
|
|
87
|
+
imul: binary("imul", Math.imul),
|
|
88
|
+
sumPrecise: sumPrecise(runner),
|
|
89
|
+
});
|
package/dist/stdlib/number.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import type
|
|
2
|
-
export declare const
|
|
3
|
-
export declare const
|
|
1
|
+
import { type AstNode } from "../interpreter/model.js";
|
|
2
|
+
export declare const numberMethods: Set<string>;
|
|
3
|
+
export declare const invokeNumberMethod: (value: number, name: string, args: Array<unknown>, node: AstNode) => unknown;
|
|
4
|
+
export declare const numberGlobal: import("../interpreter/host.js").HostFunction<never>;
|