@opencode/codemode 2.0.3 → 2.0.4
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/codemode.d.ts +3 -0
- package/dist/codemode.js +12 -1
- package/dist/data.d.ts +14 -21
- package/dist/data.js +72 -140
- package/dist/extension.d.ts +11 -0
- package/dist/extension.js +9 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/interpreter/callback.d.ts +20 -0
- package/dist/interpreter/{runner.js → callback.js} +14 -14
- package/dist/interpreter/errors.d.ts +12 -5
- package/dist/interpreter/errors.js +66 -54
- package/dist/interpreter/execute.d.ts +2 -2
- package/dist/interpreter/execute.js +15 -15
- package/dist/interpreter/extensions.d.ts +8 -0
- package/dist/interpreter/extensions.js +155 -0
- package/dist/interpreter/generators.d.ts +2 -3
- package/dist/interpreter/generators.js +10 -10
- package/dist/interpreter/globals.d.ts +4 -12
- package/dist/interpreter/globals.js +56 -49
- package/dist/interpreter/interpreter.d.ts +34 -0
- package/dist/interpreter/{runtime.js → interpreter.js} +250 -215
- package/dist/interpreter/intrinsics.d.ts +5 -5
- package/dist/interpreter/intrinsics.js +16 -10
- package/dist/interpreter/limits.d.ts +10 -0
- package/dist/interpreter/limits.js +19 -0
- package/dist/interpreter/model.d.ts +27 -14
- package/dist/interpreter/model.js +22 -14
- package/dist/interpreter/native.d.ts +12 -13
- package/dist/interpreter/native.js +17 -16
- package/dist/interpreter/objects.d.ts +55 -48
- package/dist/interpreter/objects.js +64 -44
- package/dist/interpreter/promises.d.ts +13 -15
- package/dist/interpreter/promises.js +89 -85
- package/dist/interpreter/references.d.ts +1 -2
- package/dist/interpreter/references.js +18 -16
- package/dist/interpreter/scope.js +6 -6
- package/dist/openapi/types.d.ts +1 -1
- package/dist/stdlib/array.d.ts +3 -4
- package/dist/stdlib/array.js +115 -110
- package/dist/stdlib/bytes.d.ts +10 -0
- package/dist/stdlib/bytes.js +228 -0
- package/dist/stdlib/collections.d.ts +4 -4
- package/dist/stdlib/collections.js +89 -89
- package/dist/stdlib/console.d.ts +5 -3
- package/dist/stdlib/console.js +30 -37
- package/dist/stdlib/date.d.ts +2 -2
- package/dist/stdlib/date.js +35 -35
- package/dist/stdlib/json.d.ts +3 -3
- package/dist/stdlib/json.js +29 -67
- package/dist/stdlib/math.d.ts +3 -3
- package/dist/stdlib/math.js +17 -21
- package/dist/stdlib/number.d.ts +3 -3
- package/dist/stdlib/number.js +32 -36
- package/dist/stdlib/object.d.ts +5 -5
- package/dist/stdlib/object.js +59 -62
- package/dist/stdlib/regexp.d.ts +7 -8
- package/dist/stdlib/regexp.js +40 -48
- package/dist/stdlib/string.d.ts +2 -2
- package/dist/stdlib/string.js +110 -88
- package/dist/stdlib/url.d.ts +4 -6
- package/dist/stdlib/url.js +86 -90
- package/dist/stdlib/value.d.ts +3 -3
- package/dist/stdlib/value.js +26 -24
- package/dist/stdlib/web.d.ts +4 -4
- package/dist/stdlib/web.js +22 -8
- package/dist/tool-runtime.d.ts +12 -5
- package/dist/tool-runtime.js +25 -11
- package/package.json +1 -1
- package/dist/interpreter/runner.d.ts +0 -28
- package/dist/interpreter/runtime.d.ts +0 -19
package/dist/stdlib/object.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type AstNode } from "../interpreter/model.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
export declare const enumerableSource: <R>(
|
|
5
|
-
export declare const objectAssign: <R>(
|
|
2
|
+
import { Obj } from "../interpreter/objects.js";
|
|
3
|
+
import type { Interpreter } from "../interpreter/interpreter.js";
|
|
4
|
+
export declare const enumerableSource: <R>(ctx: Interpreter<R>, label: string, value: unknown, node?: AstNode) => Obj;
|
|
5
|
+
export declare const objectAssign: <R>(ctx: Interpreter<R>, args: Array<unknown>) => unknown;
|
|
6
6
|
export declare const classTag: (value: unknown) => string;
|
|
7
|
-
export declare const objectGlobal: <R>(
|
|
7
|
+
export declare const objectGlobal: <R>(ctx: Interpreter<R>) => import("../interpreter/objects.js").Native<R>;
|
package/dist/stdlib/object.js
CHANGED
|
@@ -1,66 +1,65 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
|
-
import { toProgram } from "../data.js";
|
|
3
2
|
import { constructor, methods, receiver } from "../interpreter/native.js";
|
|
4
|
-
import { AsyncIteratorSymbol,
|
|
5
|
-
import { Callable, define, entries, enumerableKeys, getOwn, hasOwn, hasPrototype, hidden, keys, own,
|
|
3
|
+
import { AsyncIteratorSymbol, invalidData, IteratorSymbol, rangeError, typeError, } from "../interpreter/model.js";
|
|
4
|
+
import { Callable, define, entries, enumerableKeys, getOwn, hasOwn, hasPrototype, hidden, keys, own, Arr, Bytes, DateObj, ErrorObj, Obj, PromiseObj, RegExpObj, set, } from "../interpreter/objects.js";
|
|
6
5
|
import { containsOpaqueReference, describeValue, rejectCircularInsertion } from "../interpreter/references.js";
|
|
7
|
-
import { preserveConsumerError } from "../interpreter/
|
|
6
|
+
import { preserveConsumerError } from "../interpreter/callback.js";
|
|
8
7
|
import { ToolReference } from "../tool-runtime.js";
|
|
9
8
|
import { groupBy } from "./collections.js";
|
|
10
9
|
import { coerceToString } from "./value.js";
|
|
11
10
|
// ToObject for enumeration.
|
|
12
|
-
export const enumerableSource = (
|
|
11
|
+
export const enumerableSource = (ctx, label, value, node) => {
|
|
13
12
|
if (value === null || value === undefined) {
|
|
14
|
-
throw
|
|
13
|
+
throw typeError(`${label} cannot convert ${describeValue(value)} to an object.`, node);
|
|
15
14
|
}
|
|
16
|
-
if (value instanceof
|
|
17
|
-
throw
|
|
15
|
+
if (value instanceof PromiseObj) {
|
|
16
|
+
throw invalidData(`${label} received an un-awaited Promise; await it before inspecting the result.`, node);
|
|
18
17
|
}
|
|
19
18
|
if (value instanceof ToolReference) {
|
|
20
|
-
throw
|
|
19
|
+
throw invalidData(`${label} cannot read tool references: they are not plain data. Use Object.keys(tools) for names, or search({ query }) for signatures.`, node);
|
|
21
20
|
}
|
|
22
21
|
if (typeof value === "string")
|
|
23
|
-
return new
|
|
24
|
-
if (value instanceof
|
|
22
|
+
return new Arr(ctx.builtins.Array, [...value]);
|
|
23
|
+
if (value instanceof Obj)
|
|
25
24
|
return value;
|
|
26
|
-
return new
|
|
25
|
+
return new Obj(ctx.builtins.Object);
|
|
27
26
|
};
|
|
28
|
-
export const objectAssign = (
|
|
27
|
+
export const objectAssign = (ctx, args) => {
|
|
29
28
|
const target = args[0];
|
|
30
29
|
// JS would box a primitive target; wrappers and primitives cannot hold fields here.
|
|
31
|
-
if (!(target instanceof
|
|
32
|
-
throw
|
|
30
|
+
if (!(target instanceof Obj)) {
|
|
31
|
+
throw typeError(`Object.assign expects a data object or array target, received ${describeValue(target)}.`);
|
|
33
32
|
}
|
|
34
33
|
const seen = new Set();
|
|
35
34
|
for (const source of args.slice(1)) {
|
|
36
35
|
if (source === null || source === undefined)
|
|
37
36
|
continue;
|
|
38
|
-
const from = enumerableSource(
|
|
37
|
+
const from = enumerableSource(ctx, "Object.assign(...)", source);
|
|
39
38
|
for (const key of enumerableKeys(from)) {
|
|
40
|
-
rejectCircularInsertion(target, getOwn(from, key), "Object.assign result",
|
|
39
|
+
rejectCircularInsertion(target, getOwn(from, key), "Object.assign result", seen);
|
|
41
40
|
if (!set(target, key, getOwn(from, key))) {
|
|
42
|
-
if (target instanceof
|
|
43
|
-
throw rangeError("Invalid array length"
|
|
44
|
-
throw
|
|
41
|
+
if (target instanceof Arr && key === "length")
|
|
42
|
+
throw rangeError("Invalid array length");
|
|
43
|
+
throw typeError(`Cannot assign to read only property '${String(key)}'.`);
|
|
45
44
|
}
|
|
46
45
|
}
|
|
47
46
|
}
|
|
48
47
|
return target;
|
|
49
48
|
};
|
|
50
|
-
const objectFromEntries = (
|
|
51
|
-
const out = new
|
|
49
|
+
const objectFromEntries = (ctx, source) => {
|
|
50
|
+
const out = new Obj(ctx.builtins.Object);
|
|
52
51
|
return Effect.gen(function* () {
|
|
53
|
-
const cursor = yield*
|
|
52
|
+
const cursor = yield* ctx.iterate(source);
|
|
54
53
|
if (cursor === undefined) {
|
|
55
|
-
throw
|
|
54
|
+
throw typeError("Object.fromEntries expects a synchronous iterable of entries.");
|
|
56
55
|
}
|
|
57
56
|
while (true) {
|
|
58
57
|
const step = yield* cursor.next;
|
|
59
58
|
if (step.done)
|
|
60
59
|
return out;
|
|
61
60
|
yield* preserveConsumerError(cursor, Effect.sync(() => {
|
|
62
|
-
if (!(step.value instanceof
|
|
63
|
-
throw
|
|
61
|
+
if (!(step.value instanceof Obj) || containsOpaqueReference(step.value)) {
|
|
62
|
+
throw typeError("Object.fromEntries expects [key, value] entry objects.");
|
|
64
63
|
}
|
|
65
64
|
define(out, coerceToString(getOwn(step.value, 0)), getOwn(step.value, 1));
|
|
66
65
|
}));
|
|
@@ -72,16 +71,18 @@ export const classTag = (value) => {
|
|
|
72
71
|
return "Null";
|
|
73
72
|
if (value === undefined)
|
|
74
73
|
return "Undefined";
|
|
75
|
-
if (value instanceof
|
|
74
|
+
if (value instanceof Arr)
|
|
76
75
|
return "Array";
|
|
77
76
|
if (value instanceof Callable)
|
|
78
77
|
return "Function";
|
|
79
|
-
if (value instanceof
|
|
78
|
+
if (value instanceof ErrorObj)
|
|
80
79
|
return "Error";
|
|
81
|
-
if (value instanceof
|
|
80
|
+
if (value instanceof DateObj)
|
|
82
81
|
return "Date";
|
|
83
|
-
if (value instanceof
|
|
82
|
+
if (value instanceof RegExpObj)
|
|
84
83
|
return "RegExp";
|
|
84
|
+
if (value instanceof Bytes)
|
|
85
|
+
return "Uint8Array";
|
|
85
86
|
if (typeof value === "string")
|
|
86
87
|
return "String";
|
|
87
88
|
if (typeof value === "number")
|
|
@@ -93,84 +94,80 @@ export const classTag = (value) => {
|
|
|
93
94
|
const propertyKey = (value) => value === AsyncIteratorSymbol || value === IteratorSymbol ? value : coerceToString(value);
|
|
94
95
|
// Object constructs identically with or without new, like JS. Only `keys` copies its result into the
|
|
95
96
|
// program; `values`, `entries`, `assign`, and `fromEntries` hand back the program's own values.
|
|
96
|
-
export const objectGlobal = (
|
|
97
|
-
const
|
|
98
|
-
const construct = (args
|
|
97
|
+
export const objectGlobal = (ctx) => {
|
|
98
|
+
const builtins = ctx.builtins;
|
|
99
|
+
const construct = (args) => {
|
|
99
100
|
const first = args[0];
|
|
100
101
|
if (first === null || first === undefined)
|
|
101
|
-
return new
|
|
102
|
-
if (
|
|
102
|
+
return new Obj(builtins.Object);
|
|
103
|
+
if (first instanceof Obj)
|
|
103
104
|
return first;
|
|
104
|
-
throw
|
|
105
|
+
throw typeError(`Object(${typeof first}) wrapper objects are not supported; use the primitive value directly.`);
|
|
105
106
|
};
|
|
106
|
-
const object = constructor(
|
|
107
|
+
const object = constructor(builtins, builtins.Object, {
|
|
107
108
|
name: "Object",
|
|
108
109
|
length: 1,
|
|
109
|
-
call: (_, args
|
|
110
|
-
construct: (args
|
|
110
|
+
call: (_, args) => Effect.sync(() => construct(args)),
|
|
111
|
+
construct: (args) => Effect.sync(() => construct(args)),
|
|
111
112
|
});
|
|
112
|
-
methods(
|
|
113
|
+
methods(builtins, object, [
|
|
113
114
|
[
|
|
114
115
|
"keys",
|
|
115
116
|
1,
|
|
116
|
-
(_, args
|
|
117
|
-
? [...
|
|
118
|
-
: keys(enumerableSource(
|
|
117
|
+
(_, args) => new Arr(builtins.Array, args[0] instanceof ToolReference
|
|
118
|
+
? [...ctx.tools.keys(args[0].path)]
|
|
119
|
+
: keys(enumerableSource(ctx, "Object.keys(...)", args[0]))),
|
|
119
120
|
],
|
|
120
121
|
[
|
|
121
122
|
"values",
|
|
122
123
|
1,
|
|
123
|
-
(_, args
|
|
124
|
+
(_, args) => new Arr(builtins.Array, entries(enumerableSource(ctx, "Object.values(...)", args[0])).map((entry) => entry[1])),
|
|
124
125
|
],
|
|
125
126
|
[
|
|
126
127
|
"entries",
|
|
127
128
|
1,
|
|
128
|
-
(_, args
|
|
129
|
-
],
|
|
130
|
-
[
|
|
131
|
-
"hasOwn",
|
|
132
|
-
2,
|
|
133
|
-
(_, args, node) => hasOwn(enumerableSource(runner, "Object.hasOwn(...)", args[0], node), propertyKey(args[1])),
|
|
129
|
+
(_, args) => new Arr(builtins.Array, entries(enumerableSource(ctx, "Object.entries(...)", args[0])).map((entry) => new Arr(builtins.Array, entry))),
|
|
134
130
|
],
|
|
131
|
+
["hasOwn", 2, (_, args) => hasOwn(enumerableSource(ctx, "Object.hasOwn(...)", args[0]), propertyKey(args[1]))],
|
|
135
132
|
[
|
|
136
133
|
"is",
|
|
137
134
|
2,
|
|
138
|
-
(_, args
|
|
135
|
+
(_, args) => {
|
|
139
136
|
if (containsOpaqueReference(args[0]) || containsOpaqueReference(args[1])) {
|
|
140
|
-
throw
|
|
137
|
+
throw invalidData("Object.is requires data values.");
|
|
141
138
|
}
|
|
142
139
|
return Object.is(args[0], args[1]);
|
|
143
140
|
},
|
|
144
141
|
],
|
|
145
|
-
["assign", 2, (_, args
|
|
146
|
-
["fromEntries", 1, (_, args
|
|
142
|
+
["assign", 2, (_, args) => objectAssign(ctx, args)],
|
|
143
|
+
["fromEntries", 1, (_, args) => objectFromEntries(ctx, args[0])],
|
|
147
144
|
]);
|
|
148
|
-
define(object, "groupBy", groupBy(
|
|
149
|
-
methods(
|
|
145
|
+
define(object, "groupBy", groupBy(ctx, "Object"), hidden);
|
|
146
|
+
methods(builtins, builtins.Object, [
|
|
150
147
|
[
|
|
151
148
|
"hasOwnProperty",
|
|
152
149
|
1,
|
|
153
|
-
(thisValue, args
|
|
150
|
+
(thisValue, args) => hasOwn(receiver(Obj, thisValue, "Object.prototype.hasOwnProperty"), propertyKey(args[0])),
|
|
154
151
|
],
|
|
155
152
|
[
|
|
156
153
|
"isPrototypeOf",
|
|
157
154
|
1,
|
|
158
|
-
(thisValue, args
|
|
155
|
+
(thisValue, args) => hasPrototype(args[0], receiver(Obj, thisValue, "Object.prototype.isPrototypeOf")),
|
|
159
156
|
],
|
|
160
157
|
[
|
|
161
158
|
"propertyIsEnumerable",
|
|
162
159
|
1,
|
|
163
|
-
(thisValue, args
|
|
164
|
-
|
|
160
|
+
(thisValue, args) => own(receiver(Obj, thisValue, "Object.prototype.propertyIsEnumerable"), propertyKey(args[0]))?.enumerable ===
|
|
161
|
+
true,
|
|
165
162
|
],
|
|
166
163
|
["toString", 0, (thisValue) => `[object ${classTag(thisValue)}]`],
|
|
167
164
|
["toLocaleString", 0, (thisValue) => `[object ${classTag(thisValue)}]`],
|
|
168
165
|
[
|
|
169
166
|
"valueOf",
|
|
170
167
|
0,
|
|
171
|
-
(thisValue
|
|
168
|
+
(thisValue) => {
|
|
172
169
|
if (thisValue === null || thisValue === undefined) {
|
|
173
|
-
throw
|
|
170
|
+
throw typeError("Object.prototype.valueOf called on null or undefined.");
|
|
174
171
|
}
|
|
175
172
|
return thisValue;
|
|
176
173
|
},
|
package/dist/stdlib/regexp.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
export declare const
|
|
6
|
-
export declare const
|
|
7
|
-
export declare const
|
|
8
|
-
export declare const regexpGlobal: <R>(runner: Runner<R>) => import("../interpreter/objects.js").NativeFunction<R>;
|
|
1
|
+
import type { Builtins } from "../interpreter/intrinsics.js";
|
|
2
|
+
import { Arr, Obj, RegExpObj } from "../interpreter/objects.js";
|
|
3
|
+
import type { Interpreter } from "../interpreter/interpreter.js";
|
|
4
|
+
export declare const toHostRegex: (arg: unknown, method: string, extraFlags?: string) => RegExp;
|
|
5
|
+
export declare const matchToValue: (builtins: Builtins, match: RegExpMatchArray) => Arr;
|
|
6
|
+
export declare const constructRegExp: (builtins: Builtins, args: Array<unknown>, proto?: Obj) => RegExpObj;
|
|
7
|
+
export declare const regexpGlobal: <R>(ctx: Interpreter<R>) => import("../interpreter/objects.js").Native<R>;
|
package/dist/stdlib/regexp.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
2
|
import { constructor, methods, prototypeFrom, receiver } from "../interpreter/native.js";
|
|
3
|
-
import {
|
|
4
|
-
import { define, defineAccessor,
|
|
3
|
+
import { syntaxError, typeError } from "../interpreter/model.js";
|
|
4
|
+
import { define, defineAccessor, Arr, Obj, RegExpObj, record } from "../interpreter/objects.js";
|
|
5
5
|
import { coerceToNumber, coerceToString } from "./value.js";
|
|
6
6
|
const flagProperties = [
|
|
7
7
|
"hasIndices",
|
|
@@ -15,114 +15,106 @@ const flagProperties = [
|
|
|
15
15
|
];
|
|
16
16
|
const regexFailureReason = (error) => (error instanceof Error ? error.message : String(error)).replace(/^Invalid regular expression:\s*/i, "");
|
|
17
17
|
const escapeRegexHint = 'To match special characters like ( ) [ ] { } + * ? . literally, escape them with a backslash (e.g. "\\\\(") or test for them with String.includes instead.';
|
|
18
|
-
export const toHostRegex = (arg, method,
|
|
18
|
+
export const toHostRegex = (arg, method, extraFlags = "") => {
|
|
19
19
|
// Native parity: an undefined pattern behaves as an empty pattern.
|
|
20
20
|
if (arg === undefined)
|
|
21
21
|
return new RegExp("", extraFlags);
|
|
22
|
-
if (arg instanceof
|
|
22
|
+
if (arg instanceof RegExpObj)
|
|
23
23
|
return arg.regex;
|
|
24
24
|
if (typeof arg === "string") {
|
|
25
25
|
try {
|
|
26
26
|
return new RegExp(arg, extraFlags);
|
|
27
27
|
}
|
|
28
28
|
catch (error) {
|
|
29
|
-
throw syntaxError(`String.${method} received the string ${JSON.stringify(arg)}, which is not a valid regular expression pattern (${regexFailureReason(error)}). ${escapeRegexHint}
|
|
29
|
+
throw syntaxError(`String.${method} received the string ${JSON.stringify(arg)}, which is not a valid regular expression pattern (${regexFailureReason(error)}). ${escapeRegexHint}`);
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
|
-
throw
|
|
32
|
+
throw typeError(`String.${method} expects a regular expression (a /pattern/flags literal or new RegExp(...)) or a string pattern, not ${arg === null ? "null" : typeof arg}.`);
|
|
33
33
|
};
|
|
34
|
-
export const matchToValue = (
|
|
35
|
-
const result = new
|
|
34
|
+
export const matchToValue = (builtins, match) => {
|
|
35
|
+
const result = new Arr(builtins.Array, Array.from(match, (group) => group));
|
|
36
36
|
if (match.index !== undefined)
|
|
37
37
|
define(result, "index", match.index);
|
|
38
38
|
if (match.input !== undefined)
|
|
39
39
|
define(result, "input", match.input);
|
|
40
40
|
if (match.groups)
|
|
41
|
-
define(result, "groups", record(
|
|
41
|
+
define(result, "groups", record(builtins.Object, match.groups));
|
|
42
42
|
if (match.indices)
|
|
43
|
-
define(result, "indices", indicesToValue(
|
|
43
|
+
define(result, "indices", indicesToValue(builtins, match.indices));
|
|
44
44
|
return result;
|
|
45
45
|
};
|
|
46
|
-
export const constructRegExp = (
|
|
46
|
+
export const constructRegExp = (builtins, args, proto = builtins.RegExp) => {
|
|
47
47
|
const first = args[0];
|
|
48
|
-
const pattern = first instanceof
|
|
48
|
+
const pattern = first instanceof RegExpObj ? first.regex.source : first === undefined ? "" : coerceToString(first);
|
|
49
49
|
const flagsArg = args[1];
|
|
50
50
|
if (flagsArg !== undefined && typeof flagsArg !== "string") {
|
|
51
|
-
throw syntaxError(`RegExp flags must be a string of flag characters (e.g. "g", "gi"), not ${flagsArg === null ? "null" : typeof flagsArg}
|
|
51
|
+
throw syntaxError(`RegExp flags must be a string of flag characters (e.g. "g", "gi"), not ${flagsArg === null ? "null" : typeof flagsArg}.`);
|
|
52
52
|
}
|
|
53
|
-
const flags = flagsArg ?? (first instanceof
|
|
53
|
+
const flags = flagsArg ?? (first instanceof RegExpObj ? first.regex.flags : "");
|
|
54
54
|
try {
|
|
55
|
-
return new
|
|
55
|
+
return new RegExpObj(proto, pattern, flags);
|
|
56
56
|
}
|
|
57
57
|
catch (error) {
|
|
58
58
|
const reason = regexFailureReason(error);
|
|
59
59
|
throw syntaxError(/flag/i.test(reason)
|
|
60
60
|
? `new RegExp(...) received invalid flags ${JSON.stringify(flags)} (${reason}). Valid flags are d, g, i, m, s, u, v, and y.`
|
|
61
|
-
: `new RegExp(...) received ${JSON.stringify(pattern)}, which is not a valid regular expression pattern (${reason}). ${escapeRegexHint}
|
|
61
|
+
: `new RegExp(...) received ${JSON.stringify(pattern)}, which is not a valid regular expression pattern (${reason}). ${escapeRegexHint}`);
|
|
62
62
|
}
|
|
63
63
|
};
|
|
64
|
-
const toLength = (value) => {
|
|
65
|
-
const number = coerceToNumber(value);
|
|
66
|
-
if (Number.isNaN(number) || number <= 0)
|
|
67
|
-
return 0;
|
|
68
|
-
return Math.min(Math.floor(number), Number.MAX_SAFE_INTEGER);
|
|
69
|
-
};
|
|
70
64
|
// RegExp constructs identically with or without new, like JS.
|
|
71
|
-
export const regexpGlobal = (
|
|
72
|
-
const
|
|
73
|
-
const proto =
|
|
74
|
-
const regexp = constructor(
|
|
65
|
+
export const regexpGlobal = (ctx) => {
|
|
66
|
+
const builtins = ctx.builtins;
|
|
67
|
+
const proto = builtins.RegExp;
|
|
68
|
+
const regexp = constructor(builtins, proto, {
|
|
75
69
|
name: "RegExp",
|
|
76
70
|
length: 2,
|
|
77
|
-
call: (_, args
|
|
78
|
-
construct: (args, newTarget
|
|
71
|
+
call: (_, args) => Effect.sync(() => constructRegExp(builtins, args)),
|
|
72
|
+
construct: (args, newTarget) => Effect.sync(() => constructRegExp(builtins, args, prototypeFrom(newTarget, proto))),
|
|
79
73
|
});
|
|
80
|
-
methods(
|
|
74
|
+
methods(builtins, regexp, [
|
|
81
75
|
[
|
|
82
76
|
"escape",
|
|
83
77
|
1,
|
|
84
|
-
(_, args
|
|
78
|
+
(_, args) => {
|
|
85
79
|
if (typeof args[0] !== "string")
|
|
86
|
-
throw
|
|
80
|
+
throw typeError("RegExp.escape expects a string.");
|
|
87
81
|
return RegExp.escape(args[0]);
|
|
88
82
|
},
|
|
89
83
|
],
|
|
90
84
|
]);
|
|
91
|
-
const self = (thisValue, name
|
|
85
|
+
const self = (thisValue, name) => receiver(RegExpObj, thisValue, `RegExp.prototype.${name}`);
|
|
92
86
|
defineAccessor(proto, "source", (thisValue) => self(thisValue, "source").regex.source);
|
|
93
87
|
defineAccessor(proto, "flags", (thisValue) => self(thisValue, "flags").regex.flags);
|
|
88
|
+
// The host regex holds the only lastIndex, so exec/test and the String methods share one counter.
|
|
89
|
+
defineAccessor(proto, "lastIndex", (thisValue) => self(thisValue, "lastIndex").regex.lastIndex, (thisValue, value) => {
|
|
90
|
+
self(thisValue, "lastIndex").regex.lastIndex = coerceToNumber(value);
|
|
91
|
+
});
|
|
94
92
|
for (const name of flagProperties)
|
|
95
93
|
defineAccessor(proto, name, (thisValue) => self(thisValue, name).regex[name]);
|
|
96
|
-
// exec/test run the host regex from the program-visible lastIndex and write it back only when g or y is set.
|
|
97
94
|
const run = (name) => [
|
|
98
95
|
name,
|
|
99
96
|
1,
|
|
100
|
-
(thisValue, args
|
|
101
|
-
const value = self(thisValue, name
|
|
102
|
-
const
|
|
103
|
-
const stateful = value.regex.global || value.regex.sticky;
|
|
104
|
-
value.regex.lastIndex = toLength(getOwn(value, "lastIndex"));
|
|
105
|
-
const matched = value.regex.exec(input);
|
|
106
|
-
if (stateful)
|
|
107
|
-
set(value, "lastIndex", value.regex.lastIndex);
|
|
97
|
+
(thisValue, args) => {
|
|
98
|
+
const value = self(thisValue, name);
|
|
99
|
+
const matched = value.regex.exec(coerceToString(args[0]));
|
|
108
100
|
if (name === "test")
|
|
109
101
|
return matched !== null;
|
|
110
|
-
return matched === null ? null : matchToValue(
|
|
102
|
+
return matched === null ? null : matchToValue(builtins, matched);
|
|
111
103
|
},
|
|
112
104
|
];
|
|
113
|
-
methods(
|
|
105
|
+
methods(builtins, proto, [
|
|
114
106
|
run("exec"),
|
|
115
107
|
run("test"),
|
|
116
|
-
["toString", 0, (thisValue
|
|
108
|
+
["toString", 0, (thisValue) => coerceToString(self(thisValue, "toString"))],
|
|
117
109
|
]);
|
|
118
110
|
return regexp;
|
|
119
111
|
};
|
|
120
|
-
const indicesToValue = (
|
|
121
|
-
const range = (pair) => pair === undefined ? undefined : new
|
|
122
|
-
const result = new
|
|
112
|
+
const indicesToValue = (builtins, indices) => {
|
|
113
|
+
const range = (pair) => pair === undefined ? undefined : new Arr(builtins.Array, [...pair]);
|
|
114
|
+
const result = new Arr(builtins.Array, Array.from(indices, range));
|
|
123
115
|
const groups = indices.groups;
|
|
124
116
|
define(result, "groups", groups === undefined
|
|
125
117
|
? undefined
|
|
126
|
-
: record(
|
|
118
|
+
: record(builtins.Object, Object.fromEntries(Object.entries(groups).map(([key, pair]) => [key, range(pair)]))));
|
|
127
119
|
return result;
|
|
128
120
|
};
|
package/dist/stdlib/string.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare const stringGlobal: <R>(
|
|
1
|
+
import type { Interpreter } from "../interpreter/interpreter.js";
|
|
2
|
+
export declare const stringGlobal: <R>(ctx: Interpreter<R>) => import("../interpreter/objects.js").Native<R>;
|