@opencode/codemode 0.0.0-dev-19971 → 0.0.0-dev-19974
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/interpreter/objects.d.ts +2 -0
- package/dist/interpreter/objects.js +5 -0
- package/dist/stdlib/array.js +23 -44
- package/dist/stdlib/bytes.js +11 -20
- package/dist/stdlib/json.js +3 -5
- package/dist/stdlib/math.js +4 -16
- package/dist/stdlib/number.js +7 -21
- package/dist/stdlib/string.js +1 -6
- package/dist/stdlib/value.js +1 -6
- package/package.json +1 -1
|
@@ -217,6 +217,8 @@ export type Value = string | number | boolean | null | undefined | symbol | Obj
|
|
|
217
217
|
export declare const coerceToString: (value: Value) => string;
|
|
218
218
|
/** ToNumber without consulting program-defined methods; tool references are not numbers. */
|
|
219
219
|
export declare const coerceToNumber: (value: Value) => number;
|
|
220
|
+
/** ToIntegerOrInfinity: NaN is 0, fractions truncate. */
|
|
221
|
+
export declare const coerceToInteger: (value: Value) => number;
|
|
220
222
|
/** Values that cannot cross the data boundary: opaque machinery and host-backed wrappers. */
|
|
221
223
|
export declare const isRuntimeReference: (value: Value) => boolean;
|
|
222
224
|
export declare const parseArrayIndex: (key: string | number) => number | undefined;
|
|
@@ -337,6 +337,11 @@ export const coerceToNumber = (value) => {
|
|
|
337
337
|
return value.toNumber();
|
|
338
338
|
return value instanceof ToolReference ? Number.NaN : Number(value);
|
|
339
339
|
};
|
|
340
|
+
/** ToIntegerOrInfinity: NaN is 0, fractions truncate. */
|
|
341
|
+
export const coerceToInteger = (value) => {
|
|
342
|
+
const number = coerceToNumber(value);
|
|
343
|
+
return Number.isNaN(number) ? 0 : Math.trunc(number);
|
|
344
|
+
};
|
|
340
345
|
/** Values that cannot cross the data boundary: opaque machinery and host-backed wrappers. */
|
|
341
346
|
export const isRuntimeReference = (value) => value instanceof Opaque || value instanceof Wrapper || value instanceof ToolReference;
|
|
342
347
|
const MAX_ARRAY_INDEX = 4_294_967_295;
|
package/dist/stdlib/array.js
CHANGED
|
@@ -2,16 +2,16 @@ import { Effect } from "effect";
|
|
|
2
2
|
import { constructor, methods, prototypeFrom, receiver } from "../interpreter/native.js";
|
|
3
3
|
import { checkArrayLength, checkStringLength, MAX_ARRAY_LENGTH } from "../interpreter/limits.js";
|
|
4
4
|
import { invalidData, IteratorSymbol, rangeError, typeError } from "../interpreter/model.js";
|
|
5
|
-
import { define, get, hidden, Arr, GeneratorObj, hostIterator, Obj, coerceToNumber, coerceToString, } from "../interpreter/objects.js";
|
|
5
|
+
import { define, get, hidden, Arr, GeneratorObj, hostIterator, Obj, PromiseObj, coerceToInteger, coerceToNumber, coerceToString, } from "../interpreter/objects.js";
|
|
6
6
|
import { describeValue, rejectCircularInsertion } from "../interpreter/references.js";
|
|
7
7
|
import { applyCollectionCallback, invoke, preserveConsumerError } from "../interpreter/callback.js";
|
|
8
8
|
import { compareText } from "../tool-runtime.js";
|
|
9
9
|
const arrayLikeSource = (source) => {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
-
checkArrayLength(
|
|
14
|
-
return { length
|
|
10
|
+
// JS would treat a promise as an empty array-like; that would hide a missing `await`.
|
|
11
|
+
if (source instanceof Obj && !(source instanceof PromiseObj)) {
|
|
12
|
+
const length = Math.max(0, coerceToInteger(get(source, "length")));
|
|
13
|
+
checkArrayLength(length);
|
|
14
|
+
return { length, source };
|
|
15
15
|
}
|
|
16
16
|
throw invalidData(`Array.from expects an iterable or array-like value, received ${describeValue(source)}.`);
|
|
17
17
|
};
|
|
@@ -102,14 +102,7 @@ export const arrayGlobal = (ctx) => {
|
|
|
102
102
|
["from", 1, (_, args) => arrayFrom(ctx, args)],
|
|
103
103
|
]);
|
|
104
104
|
const self = (thisValue, name) => receiver(Arr, thisValue, `Array.prototype.${name}`);
|
|
105
|
-
const optNumber = (
|
|
106
|
-
if (value === undefined)
|
|
107
|
-
return undefined;
|
|
108
|
-
if (typeof value !== "number") {
|
|
109
|
-
throw typeError(`Array.${name} expects ${label} to be a number.`);
|
|
110
|
-
}
|
|
111
|
-
return value;
|
|
112
|
-
};
|
|
105
|
+
const optNumber = (value) => (value === undefined ? undefined : coerceToInteger(value));
|
|
113
106
|
// Callback methods fix the iteration length while reading existing elements live.
|
|
114
107
|
const iterate = (name, length, body) => [
|
|
115
108
|
name,
|
|
@@ -124,13 +117,9 @@ export const arrayGlobal = (ctx) => {
|
|
|
124
117
|
"join",
|
|
125
118
|
1,
|
|
126
119
|
(thisValue, args) => {
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
const joined = target
|
|
132
|
-
.map((item) => coerceToString(item ?? ""))
|
|
133
|
-
.join(args.length === 0 ? "," : args[0]);
|
|
120
|
+
const joined = self(thisValue, "join")
|
|
121
|
+
.items.map((item) => coerceToString(item ?? ""))
|
|
122
|
+
.join(args[0] === undefined ? "," : coerceToString(args[0]));
|
|
134
123
|
checkStringLength(joined.length);
|
|
135
124
|
return joined;
|
|
136
125
|
},
|
|
@@ -146,33 +135,23 @@ export const arrayGlobal = (ctx) => {
|
|
|
146
135
|
"includes",
|
|
147
136
|
1,
|
|
148
137
|
(thisValue, args) => {
|
|
149
|
-
|
|
150
|
-
if (args.length === 0 || args.length > 2) {
|
|
151
|
-
throw typeError("Array.includes expects a value and optional start index.");
|
|
152
|
-
}
|
|
153
|
-
return target.includes(args[0], optNumber("includes", args[1], "start index"));
|
|
138
|
+
return self(thisValue, "includes").items.includes(args[0], optNumber(args[1]));
|
|
154
139
|
},
|
|
155
140
|
],
|
|
156
|
-
[
|
|
157
|
-
"indexOf",
|
|
158
|
-
1,
|
|
159
|
-
(thisValue, args) => self(thisValue, "indexOf").items.indexOf(args[0], optNumber("indexOf", args[1], "start index")),
|
|
160
|
-
],
|
|
141
|
+
["indexOf", 1, (thisValue, args) => self(thisValue, "indexOf").items.indexOf(args[0], optNumber(args[1]))],
|
|
161
142
|
[
|
|
162
143
|
"lastIndexOf",
|
|
163
144
|
1,
|
|
164
145
|
(thisValue, args) => {
|
|
165
146
|
const target = self(thisValue, "lastIndexOf").items;
|
|
166
|
-
return args[1] === undefined
|
|
167
|
-
? target.lastIndexOf(args[0])
|
|
168
|
-
: target.lastIndexOf(args[0], optNumber("lastIndexOf", args[1], "start index"));
|
|
147
|
+
return args[1] === undefined ? target.lastIndexOf(args[0]) : target.lastIndexOf(args[0], optNumber(args[1]));
|
|
169
148
|
},
|
|
170
149
|
],
|
|
171
|
-
["at", 1, (thisValue, args) => self(thisValue, "at").items.at(optNumber(
|
|
150
|
+
["at", 1, (thisValue, args) => self(thisValue, "at").items.at(optNumber(args[0]) ?? 0)],
|
|
172
151
|
[
|
|
173
152
|
"slice",
|
|
174
153
|
2,
|
|
175
|
-
(thisValue, args) => wrap(self(thisValue, "slice").items.slice(optNumber(
|
|
154
|
+
(thisValue, args) => wrap(self(thisValue, "slice").items.slice(optNumber(args[0]), optNumber(args[1]))),
|
|
176
155
|
],
|
|
177
156
|
[
|
|
178
157
|
"concat",
|
|
@@ -188,7 +167,7 @@ export const arrayGlobal = (ctx) => {
|
|
|
188
167
|
0,
|
|
189
168
|
(thisValue, args) => {
|
|
190
169
|
const flatten = (items, depth) => items.flatMap((item) => (item instanceof Arr && depth > 0 ? flatten(item.items, depth - 1) : [item]));
|
|
191
|
-
const flattened = flatten(self(thisValue, "flat").items, optNumber(
|
|
170
|
+
const flattened = flatten(self(thisValue, "flat").items, optNumber(args[0]) ?? 1);
|
|
192
171
|
checkArrayLength(flattened.length);
|
|
193
172
|
return wrap(flattened);
|
|
194
173
|
},
|
|
@@ -233,7 +212,7 @@ export const arrayGlobal = (ctx) => {
|
|
|
233
212
|
2,
|
|
234
213
|
(thisValue, args) => {
|
|
235
214
|
const target = self(thisValue, "with").items;
|
|
236
|
-
const index = optNumber(
|
|
215
|
+
const index = optNumber(args[0]) ?? 0;
|
|
237
216
|
const resolved = index < 0 ? target.length + index : index;
|
|
238
217
|
if (resolved < 0 || resolved >= target.length)
|
|
239
218
|
throw rangeError("Array.with index is out of range.");
|
|
@@ -272,10 +251,10 @@ export const arrayGlobal = (ctx) => {
|
|
|
272
251
|
const target = self(thisValue, "splice");
|
|
273
252
|
if (args.length === 0)
|
|
274
253
|
return wrap(target.items.splice(0, 0));
|
|
275
|
-
const start = optNumber(
|
|
254
|
+
const start = optNumber(args[0]) ?? 0;
|
|
276
255
|
if (args.length === 1)
|
|
277
256
|
return wrap(target.items.splice(start));
|
|
278
|
-
const deleteCount = optNumber(
|
|
257
|
+
const deleteCount = optNumber(args[1]) ?? 0;
|
|
279
258
|
const inserted = args.slice(2);
|
|
280
259
|
for (const item of inserted)
|
|
281
260
|
rejectCircularInsertion(target, item, "Array.splice result");
|
|
@@ -289,11 +268,11 @@ export const arrayGlobal = (ctx) => {
|
|
|
289
268
|
const copied = [...self(thisValue, "toSpliced").items];
|
|
290
269
|
if (args.length === 0)
|
|
291
270
|
return wrap(copied);
|
|
292
|
-
const start = optNumber(
|
|
271
|
+
const start = optNumber(args[0]) ?? 0;
|
|
293
272
|
if (args.length === 1)
|
|
294
273
|
copied.splice(start);
|
|
295
274
|
else
|
|
296
|
-
copied.splice(start, optNumber(
|
|
275
|
+
copied.splice(start, optNumber(args[1]) ?? 0, ...args.slice(2));
|
|
297
276
|
return wrap(copied);
|
|
298
277
|
},
|
|
299
278
|
],
|
|
@@ -303,7 +282,7 @@ export const arrayGlobal = (ctx) => {
|
|
|
303
282
|
(thisValue, args) => {
|
|
304
283
|
const target = self(thisValue, "fill");
|
|
305
284
|
rejectCircularInsertion(target, args[0], "Array.fill result");
|
|
306
|
-
target.items.fill(args[0], optNumber(
|
|
285
|
+
target.items.fill(args[0], optNumber(args[1]), optNumber(args[2]));
|
|
307
286
|
return target;
|
|
308
287
|
},
|
|
309
288
|
],
|
|
@@ -312,7 +291,7 @@ export const arrayGlobal = (ctx) => {
|
|
|
312
291
|
2,
|
|
313
292
|
(thisValue, args) => {
|
|
314
293
|
const target = self(thisValue, "copyWithin");
|
|
315
|
-
target.items.copyWithin(optNumber(
|
|
294
|
+
target.items.copyWithin(optNumber(args[0]) ?? 0, optNumber(args[1]) ?? 0, optNumber(args[2]));
|
|
316
295
|
return target;
|
|
317
296
|
},
|
|
318
297
|
],
|
package/dist/stdlib/bytes.js
CHANGED
|
@@ -2,7 +2,7 @@ import { Effect } from "effect";
|
|
|
2
2
|
import { checkArrayLength, checkStringLength } from "../interpreter/limits.js";
|
|
3
3
|
import { constructor, methods, prototypeFrom, receiver, requiresNew } from "../interpreter/native.js";
|
|
4
4
|
import { IteratorSymbol, rangeError, syntaxError, typeError } from "../interpreter/model.js";
|
|
5
|
-
import { define, defineAccessor, get, hidden, Arr, Bytes, hostIterator, Obj, coerceToNumber, coerceToString, } from "../interpreter/objects.js";
|
|
5
|
+
import { define, defineAccessor, get, hidden, Arr, Bytes, hostIterator, Obj, coerceToInteger, coerceToNumber, coerceToString, } from "../interpreter/objects.js";
|
|
6
6
|
import { describeValue } from "../interpreter/references.js";
|
|
7
7
|
/** The bytes a Uint8Array, array, or other iterable of numbers describes; the host array clamps each value. */
|
|
8
8
|
const collectBytes = (ctx, source, name) => {
|
|
@@ -61,34 +61,28 @@ export const uint8ArrayGlobal = (ctx) => {
|
|
|
61
61
|
["fromHex", 1, (_, args) => decode("fromHex", args, (text) => Uint8Array.fromHex(text))],
|
|
62
62
|
]);
|
|
63
63
|
const self = (thisValue, name) => receiver(Bytes, thisValue, `Uint8Array.prototype.${name}`);
|
|
64
|
-
const optNumber = (
|
|
65
|
-
if (value === undefined)
|
|
66
|
-
return undefined;
|
|
67
|
-
if (typeof value !== "number")
|
|
68
|
-
throw typeError(`Uint8Array.${name} expects ${label} to be a number.`);
|
|
69
|
-
return value;
|
|
70
|
-
};
|
|
64
|
+
const optNumber = (value) => (value === undefined ? undefined : coerceToInteger(value));
|
|
71
65
|
const wrapAll = (items) => new Arr(builtins.Array, items);
|
|
72
66
|
defineAccessor(proto, "length", (thisValue) => self(thisValue, "length").bytes.length);
|
|
73
67
|
methods(builtins, proto, [
|
|
74
|
-
["at", 1, (thisValue, args) => self(thisValue, "at").bytes.at(optNumber(
|
|
68
|
+
["at", 1, (thisValue, args) => self(thisValue, "at").bytes.at(optNumber(args[0]) ?? 0)],
|
|
75
69
|
[
|
|
76
70
|
"slice",
|
|
77
71
|
2,
|
|
78
|
-
(thisValue, args) => wrap(self(thisValue, "slice").bytes.slice(optNumber(
|
|
72
|
+
(thisValue, args) => wrap(self(thisValue, "slice").bytes.slice(optNumber(args[0]), optNumber(args[1]))),
|
|
79
73
|
],
|
|
80
74
|
// A view on the same bytes, as in JS: writes through one are visible through the other.
|
|
81
75
|
[
|
|
82
76
|
"subarray",
|
|
83
77
|
2,
|
|
84
|
-
(thisValue, args) => wrap(self(thisValue, "subarray").bytes.subarray(optNumber(
|
|
78
|
+
(thisValue, args) => wrap(self(thisValue, "subarray").bytes.subarray(optNumber(args[0]), optNumber(args[1]))),
|
|
85
79
|
],
|
|
86
80
|
[
|
|
87
81
|
"set",
|
|
88
82
|
1,
|
|
89
83
|
(thisValue, args) => {
|
|
90
84
|
const target = self(thisValue, "set");
|
|
91
|
-
const offset = optNumber(
|
|
85
|
+
const offset = optNumber(args[1]) ?? 0;
|
|
92
86
|
return Effect.map(collectBytes(ctx, args[0], "Uint8Array.set"), (source) => {
|
|
93
87
|
if (!Number.isInteger(offset) || offset < 0 || source.length + offset > target.bytes.length) {
|
|
94
88
|
throw rangeError("Uint8Array.set: the source does not fit at that offset.");
|
|
@@ -103,7 +97,7 @@ export const uint8ArrayGlobal = (ctx) => {
|
|
|
103
97
|
1,
|
|
104
98
|
(thisValue, args) => {
|
|
105
99
|
const target = self(thisValue, "fill");
|
|
106
|
-
target.bytes.fill(coerceToNumber(args[0]), optNumber(
|
|
100
|
+
target.bytes.fill(coerceToNumber(args[0]), optNumber(args[1]), optNumber(args[2]));
|
|
107
101
|
return target;
|
|
108
102
|
},
|
|
109
103
|
],
|
|
@@ -119,7 +113,7 @@ export const uint8ArrayGlobal = (ctx) => {
|
|
|
119
113
|
[
|
|
120
114
|
"indexOf",
|
|
121
115
|
1,
|
|
122
|
-
(thisValue, args) => self(thisValue, "indexOf").bytes.indexOf(coerceToNumber(args[0]), optNumber(
|
|
116
|
+
(thisValue, args) => self(thisValue, "indexOf").bytes.indexOf(coerceToNumber(args[0]), optNumber(args[1])),
|
|
123
117
|
],
|
|
124
118
|
[
|
|
125
119
|
"lastIndexOf",
|
|
@@ -128,22 +122,19 @@ export const uint8ArrayGlobal = (ctx) => {
|
|
|
128
122
|
const target = self(thisValue, "lastIndexOf").bytes;
|
|
129
123
|
return args[1] === undefined
|
|
130
124
|
? target.lastIndexOf(coerceToNumber(args[0]))
|
|
131
|
-
: target.lastIndexOf(coerceToNumber(args[0]), optNumber(
|
|
125
|
+
: target.lastIndexOf(coerceToNumber(args[0]), optNumber(args[1]));
|
|
132
126
|
},
|
|
133
127
|
],
|
|
134
128
|
[
|
|
135
129
|
"includes",
|
|
136
130
|
1,
|
|
137
|
-
(thisValue, args) => self(thisValue, "includes").bytes.includes(coerceToNumber(args[0]), optNumber(
|
|
131
|
+
(thisValue, args) => self(thisValue, "includes").bytes.includes(coerceToNumber(args[0]), optNumber(args[1])),
|
|
138
132
|
],
|
|
139
133
|
[
|
|
140
134
|
"join",
|
|
141
135
|
1,
|
|
142
136
|
(thisValue, args) => {
|
|
143
|
-
|
|
144
|
-
throw typeError("Uint8Array.join expects zero arguments or one string separator.");
|
|
145
|
-
}
|
|
146
|
-
const joined = self(thisValue, "join").bytes.join(args.length === 0 ? "," : args[0]);
|
|
137
|
+
const joined = self(thisValue, "join").bytes.join(args[0] === undefined ? "," : coerceToString(args[0]));
|
|
147
138
|
checkStringLength(joined.length);
|
|
148
139
|
return joined;
|
|
149
140
|
},
|
package/dist/stdlib/json.js
CHANGED
|
@@ -2,10 +2,10 @@ import { Effect } from "effect";
|
|
|
2
2
|
import { methods } from "../interpreter/native.js";
|
|
3
3
|
import { applyCollectionCallback } from "../interpreter/callback.js";
|
|
4
4
|
import { checkStringLength } from "../interpreter/limits.js";
|
|
5
|
-
import { syntaxError
|
|
5
|
+
import { syntaxError } from "../interpreter/model.js";
|
|
6
6
|
import { typeofValue } from "../interpreter/references.js";
|
|
7
7
|
import { fromJson, toJson } from "../data.js";
|
|
8
|
-
import { get, keys, Arr, Obj, record, remove, set } from "../interpreter/objects.js";
|
|
8
|
+
import { get, keys, Arr, Obj, coerceToString, record, remove, set } from "../interpreter/objects.js";
|
|
9
9
|
export const jsonGlobal = (ctx) => {
|
|
10
10
|
const json = new Obj(ctx.builtins.Object);
|
|
11
11
|
methods(ctx.builtins, json, [
|
|
@@ -15,9 +15,7 @@ export const jsonGlobal = (ctx) => {
|
|
|
15
15
|
return json;
|
|
16
16
|
};
|
|
17
17
|
const parse = (ctx, args) => {
|
|
18
|
-
const text = args[0];
|
|
19
|
-
if (typeof text !== "string")
|
|
20
|
-
throw typeError("JSON.parse expects a string.");
|
|
18
|
+
const text = coerceToString(args[0]);
|
|
21
19
|
const parsed = (() => {
|
|
22
20
|
try {
|
|
23
21
|
return fromJson(ctx, JSON.parse(text));
|
package/dist/stdlib/math.js
CHANGED
|
@@ -1,32 +1,20 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
2
|
import { constants, methods } from "../interpreter/native.js";
|
|
3
3
|
import { typeError } from "../interpreter/model.js";
|
|
4
|
-
import { Obj } from "../interpreter/objects.js";
|
|
4
|
+
import { Obj, coerceToNumber } from "../interpreter/objects.js";
|
|
5
5
|
import { preserveConsumerError } from "../interpreter/callback.js";
|
|
6
6
|
// Validate only the arguments a method consumes; like JS, extras are ignored
|
|
7
7
|
// (so built-ins work as callbacks receiving (element, index, array)).
|
|
8
|
-
const
|
|
9
|
-
if (index >= args.length)
|
|
10
|
-
return Number.NaN;
|
|
11
|
-
const arg = args[index];
|
|
12
|
-
if (typeof arg !== "number")
|
|
13
|
-
throw typeError(`Math.${name} expects number arguments.`);
|
|
14
|
-
return arg;
|
|
15
|
-
};
|
|
16
|
-
const unary = (name, op) => [name, 1, (_, args) => op(number(name, args, 0))];
|
|
8
|
+
const unary = (name, op) => [name, 1, (_, args) => op(coerceToNumber(args[0]))];
|
|
17
9
|
const binary = (name, op) => [
|
|
18
10
|
name,
|
|
19
11
|
2,
|
|
20
|
-
(_, args) => op(
|
|
12
|
+
(_, args) => op(coerceToNumber(args[0]), coerceToNumber(args[1])),
|
|
21
13
|
];
|
|
22
14
|
const variadic = (name, op) => [
|
|
23
15
|
name,
|
|
24
16
|
2,
|
|
25
|
-
(_, args) => op(...args.map(
|
|
26
|
-
if (typeof arg !== "number")
|
|
27
|
-
throw typeError(`Math.${name} expects number arguments.`);
|
|
28
|
-
return arg;
|
|
29
|
-
})),
|
|
17
|
+
(_, args) => op(...args.map(coerceToNumber)),
|
|
30
18
|
];
|
|
31
19
|
export const mathGlobal = (ctx) => {
|
|
32
20
|
const builtins = ctx.builtins;
|
package/dist/stdlib/number.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { constructor, constants, methods } from "../interpreter/native.js";
|
|
2
|
-
import { coerceToString } from "../interpreter/objects.js";
|
|
2
|
+
import { coerceToNumber, coerceToString } from "../interpreter/objects.js";
|
|
3
3
|
import { rangeError, typeError } from "../interpreter/model.js";
|
|
4
4
|
import { coercion } from "./value.js";
|
|
5
5
|
export const numberGlobal = (ctx) => {
|
|
@@ -28,11 +28,7 @@ export const numberGlobal = (ctx) => {
|
|
|
28
28
|
"parseInt",
|
|
29
29
|
2,
|
|
30
30
|
(_, args) => {
|
|
31
|
-
|
|
32
|
-
if (radix !== undefined && typeof radix !== "number") {
|
|
33
|
-
throw typeError("Number.parseInt expects a numeric radix.");
|
|
34
|
-
}
|
|
35
|
-
return parseInt(coerceToString(args[0]), radix);
|
|
31
|
+
return parseInt(coerceToString(args[0]), coerceToNumber(args[1]));
|
|
36
32
|
},
|
|
37
33
|
],
|
|
38
34
|
["parseFloat", 1, (_, args) => parseFloat(coerceToString(args[0]))],
|
|
@@ -42,27 +38,17 @@ export const numberGlobal = (ctx) => {
|
|
|
42
38
|
return thisValue;
|
|
43
39
|
throw typeError(`Number.prototype.${name} requires that 'this' be a Number.`);
|
|
44
40
|
};
|
|
45
|
-
const optNum = (
|
|
46
|
-
if (arg === undefined)
|
|
47
|
-
return undefined;
|
|
48
|
-
if (typeof arg !== "number")
|
|
49
|
-
throw typeError(`Number.${name} expects a number argument.`);
|
|
50
|
-
return arg;
|
|
51
|
-
};
|
|
41
|
+
const optNum = (arg) => (arg === undefined ? undefined : coerceToNumber(arg));
|
|
52
42
|
methods(builtins, builtins.Number, [
|
|
53
|
-
["toFixed", 1, (thisValue, args) => self(thisValue, "toFixed").toFixed(optNum(
|
|
43
|
+
["toFixed", 1, (thisValue, args) => self(thisValue, "toFixed").toFixed(optNum(args[0]))],
|
|
54
44
|
["toLocaleString", 0, (thisValue) => self(thisValue, "toLocaleString").toLocaleString("en-US")],
|
|
55
|
-
[
|
|
56
|
-
"toExponential",
|
|
57
|
-
1,
|
|
58
|
-
(thisValue, args) => self(thisValue, "toExponential").toExponential(optNum("toExponential", args[0])),
|
|
59
|
-
],
|
|
45
|
+
["toExponential", 1, (thisValue, args) => self(thisValue, "toExponential").toExponential(optNum(args[0]))],
|
|
60
46
|
[
|
|
61
47
|
"toPrecision",
|
|
62
48
|
1,
|
|
63
49
|
(thisValue, args) => {
|
|
64
50
|
const value = self(thisValue, "toPrecision");
|
|
65
|
-
const digits = optNum(
|
|
51
|
+
const digits = optNum(args[0]);
|
|
66
52
|
return digits === undefined ? value.toString() : value.toPrecision(digits);
|
|
67
53
|
},
|
|
68
54
|
],
|
|
@@ -71,7 +57,7 @@ export const numberGlobal = (ctx) => {
|
|
|
71
57
|
1,
|
|
72
58
|
(thisValue, args) => {
|
|
73
59
|
const value = self(thisValue, "toString");
|
|
74
|
-
const radix = optNum(
|
|
60
|
+
const radix = optNum(args[0]);
|
|
75
61
|
if (radix !== undefined && (radix < 2 || radix > 36)) {
|
|
76
62
|
throw rangeError("Number.toString radix must be between 2 and 36.");
|
|
77
63
|
}
|
package/dist/stdlib/string.js
CHANGED
|
@@ -73,12 +73,7 @@ export const stringGlobal = (ctx) => {
|
|
|
73
73
|
const codeUnits = (name, op) => [
|
|
74
74
|
name,
|
|
75
75
|
1,
|
|
76
|
-
(_, args) => op(...args.map(
|
|
77
|
-
if (typeof arg !== "number") {
|
|
78
|
-
throw typeError(`String.${name} expects number arguments.`);
|
|
79
|
-
}
|
|
80
|
-
return arg;
|
|
81
|
-
})),
|
|
76
|
+
(_, args) => op(...args.map(coerceToNumber)),
|
|
82
77
|
];
|
|
83
78
|
methods(builtins, string, [
|
|
84
79
|
codeUnits("fromCharCode", String.fromCharCode),
|
package/dist/stdlib/value.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { fn } from "../interpreter/native.js";
|
|
2
|
-
import { typeError } from "../interpreter/model.js";
|
|
3
2
|
import { coerceToNumber, coerceToString } from "../interpreter/objects.js";
|
|
4
3
|
export const compoundOperators = new Set(["+=", "-=", "*=", "/=", "%=", "**=", "&=", "|=", "^=", "<<=", ">>=", ">>>="]);
|
|
5
4
|
const coerce = (ctx, name, args) => {
|
|
@@ -21,11 +20,7 @@ const coerce = (ctx, name, args) => {
|
|
|
21
20
|
if (name === "isNaN")
|
|
22
21
|
return Number.isNaN(coerceToNumber(raw));
|
|
23
22
|
if (name === "parseInt") {
|
|
24
|
-
|
|
25
|
-
if (radix !== undefined && typeof radix !== "number") {
|
|
26
|
-
throw typeError("parseInt expects a numeric radix.");
|
|
27
|
-
}
|
|
28
|
-
return parseInt(coerceToString(raw), radix);
|
|
23
|
+
return parseInt(coerceToString(raw), coerceToNumber(args[1]));
|
|
29
24
|
}
|
|
30
25
|
if (name === "parseFloat")
|
|
31
26
|
return parseFloat(coerceToString(raw));
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "@opencode/codemode",
|
|
4
|
-
"version": "0.0.0-dev-
|
|
4
|
+
"version": "0.0.0-dev-19974",
|
|
5
5
|
"description": "Effect-native confined code execution over schema-described tools",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"license": "MIT",
|