@opencode/codemode 0.0.0-dev-19631 → 0.0.0-dev-19633
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.js +1 -1
- package/dist/data.d.ts +3 -3
- package/dist/data.js +37 -31
- package/dist/interpreter/callback.d.ts +20 -0
- package/dist/interpreter/{runner.js → callback.js} +10 -10
- package/dist/interpreter/errors.d.ts +5 -5
- package/dist/interpreter/errors.js +21 -22
- package/dist/interpreter/execute.d.ts +2 -2
- package/dist/interpreter/execute.js +11 -11
- package/dist/interpreter/extensions.d.ts +2 -2
- package/dist/interpreter/extensions.js +42 -36
- package/dist/interpreter/generators.d.ts +2 -3
- package/dist/interpreter/generators.js +8 -8
- package/dist/interpreter/globals.d.ts +2 -12
- package/dist/interpreter/globals.js +41 -37
- package/dist/interpreter/interpreter.d.ts +31 -0
- package/dist/interpreter/{runtime.js → interpreter.js} +118 -117
- package/dist/interpreter/intrinsics.d.ts +5 -5
- package/dist/interpreter/intrinsics.js +16 -10
- package/dist/interpreter/model.d.ts +3 -3
- package/dist/interpreter/model.js +1 -1
- package/dist/interpreter/native.d.ts +9 -9
- package/dist/interpreter/native.js +9 -9
- package/dist/interpreter/objects.d.ts +51 -46
- package/dist/interpreter/objects.js +57 -40
- package/dist/interpreter/promises.d.ts +13 -13
- package/dist/interpreter/promises.js +70 -70
- package/dist/interpreter/references.js +17 -15
- package/dist/openapi/types.d.ts +1 -1
- package/dist/stdlib/array.d.ts +3 -3
- package/dist/stdlib/array.js +31 -31
- 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 +55 -55
- package/dist/stdlib/console.d.ts +3 -3
- package/dist/stdlib/console.js +24 -22
- package/dist/stdlib/date.d.ts +2 -2
- package/dist/stdlib/date.js +19 -19
- package/dist/stdlib/json.d.ts +3 -3
- package/dist/stdlib/json.js +24 -24
- package/dist/stdlib/math.d.ts +3 -3
- package/dist/stdlib/math.js +7 -7
- package/dist/stdlib/number.d.ts +3 -3
- package/dist/stdlib/number.js +11 -11
- package/dist/stdlib/object.d.ts +5 -5
- package/dist/stdlib/object.js +41 -39
- package/dist/stdlib/regexp.d.ts +6 -6
- package/dist/stdlib/regexp.js +24 -24
- package/dist/stdlib/string.d.ts +2 -2
- package/dist/stdlib/string.js +24 -24
- package/dist/stdlib/url.d.ts +6 -6
- package/dist/stdlib/url.js +39 -39
- package/dist/stdlib/value.d.ts +3 -3
- package/dist/stdlib/value.js +18 -14
- package/dist/stdlib/web.d.ts +4 -4
- package/dist/stdlib/web.js +19 -5
- package/dist/tool-runtime.d.ts +2 -2
- package/dist/tool-runtime.js +2 -2
- package/package.json +1 -1
- package/dist/interpreter/runner.d.ts +0 -27
- package/dist/interpreter/runtime.d.ts +0 -19
|
@@ -2,9 +2,9 @@ import { Effect } from "effect";
|
|
|
2
2
|
import { MAX_VALUE_DEPTH } from "../data.js";
|
|
3
3
|
import { coerceToString } from "../stdlib/value.js";
|
|
4
4
|
import { createErrorValue, isErrorType } from "./intrinsics.js";
|
|
5
|
-
import {
|
|
5
|
+
import { Throw, typeError } from "./model.js";
|
|
6
6
|
import { constructor, fn } from "./native.js";
|
|
7
|
-
import { Callable, define, defineAccessor, entries, get, hidden,
|
|
7
|
+
import { Callable, define, defineAccessor, entries, get, hidden, Arr, Bytes, DateObj, ErrorObj, GeneratorObj, Handle, MapObj, Obj, PromiseObj, RegExpObj, SetObj, URLObj, URLSearchParamsObj, } from "./objects.js";
|
|
8
8
|
import { describeValue } from "./references.js";
|
|
9
9
|
const isClass = (value) => typeof value === "function" && typeof value.prototype === "object" && value.prototype !== null;
|
|
10
10
|
// Own keys the native function already carries.
|
|
@@ -15,11 +15,11 @@ const ownPrototypeKeys = new Set(["constructor"]);
|
|
|
15
15
|
* copied, built-in wrappers are copied, instances of exposed classes travel as handles, and a host Promise becomes
|
|
16
16
|
* a program promise. Prototypes, constructors, and handle identity are all per run.
|
|
17
17
|
*/
|
|
18
|
-
export const extensionGlobals = (
|
|
19
|
-
const
|
|
18
|
+
export const extensionGlobals = (ctx, extensions) => {
|
|
19
|
+
const builtins = ctx.builtins;
|
|
20
20
|
const classes = new Set(extensions.flatMap((extension) => Object.values(extension.globals)).filter(isClass));
|
|
21
21
|
// Host prototype object → this run's program prototype, so an instance wraps as its most-derived exposed class.
|
|
22
|
-
const
|
|
22
|
+
const protoOf = new Map();
|
|
23
23
|
const exposed = new Map();
|
|
24
24
|
const classOf = new Map();
|
|
25
25
|
const handles = new WeakMap();
|
|
@@ -31,28 +31,30 @@ export const extensionGlobals = (host, extensions) => {
|
|
|
31
31
|
return value;
|
|
32
32
|
throw typeError(`${label} contains ${describeValue(value)}, which cannot be passed to an extension.`);
|
|
33
33
|
}
|
|
34
|
-
if (value instanceof
|
|
34
|
+
if (value instanceof Handle)
|
|
35
35
|
return value.instance;
|
|
36
|
-
if (value instanceof
|
|
36
|
+
if (value instanceof Bytes)
|
|
37
|
+
return new Uint8Array(value.bytes);
|
|
38
|
+
if (value instanceof DateObj)
|
|
37
39
|
return new Date(value.time);
|
|
38
|
-
if (value instanceof
|
|
40
|
+
if (value instanceof RegExpObj)
|
|
39
41
|
return new RegExp(value.regex.source, value.regex.flags);
|
|
40
|
-
if (value instanceof
|
|
42
|
+
if (value instanceof URLObj)
|
|
41
43
|
return new URL(value.url.href);
|
|
42
|
-
if (value instanceof
|
|
44
|
+
if (value instanceof URLSearchParamsObj)
|
|
43
45
|
return new URLSearchParams(value.params);
|
|
44
46
|
const next = (item) => toHost(item, label, depth + 1, seen);
|
|
45
|
-
if (value instanceof
|
|
47
|
+
if (value instanceof MapObj)
|
|
46
48
|
return new Map([...value.map].map(([key, item]) => [next(key), next(item)]));
|
|
47
|
-
if (value instanceof
|
|
49
|
+
if (value instanceof SetObj)
|
|
48
50
|
return new Set([...value.set].map(next));
|
|
49
|
-
if (!(value instanceof
|
|
51
|
+
if (!(value instanceof Obj) ||
|
|
50
52
|
value instanceof Callable ||
|
|
51
|
-
value instanceof
|
|
52
|
-
value instanceof
|
|
53
|
+
value instanceof GeneratorObj ||
|
|
54
|
+
value instanceof PromiseObj) {
|
|
53
55
|
throw typeError(`${label} contains ${describeValue(value)}, which cannot be passed to an extension.`);
|
|
54
56
|
}
|
|
55
|
-
if (value instanceof
|
|
57
|
+
if (value instanceof ErrorObj) {
|
|
56
58
|
const name = coerceToString(get(value, "name"));
|
|
57
59
|
const message = get(value, "message");
|
|
58
60
|
const text = message === undefined ? "" : coerceToString(message);
|
|
@@ -61,7 +63,7 @@ export const extensionGlobals = (host, extensions) => {
|
|
|
61
63
|
if (seen.has(value))
|
|
62
64
|
throw typeError(`${label} contains a circular value.`);
|
|
63
65
|
seen.add(value);
|
|
64
|
-
const copied = value instanceof
|
|
66
|
+
const copied = value instanceof Arr
|
|
65
67
|
? value.items.map(next)
|
|
66
68
|
: Object.fromEntries(entries(value)
|
|
67
69
|
.filter(([key]) => key !== "__proto__")
|
|
@@ -80,31 +82,35 @@ export const extensionGlobals = (host, extensions) => {
|
|
|
80
82
|
return existing;
|
|
81
83
|
const proto = handlePrototype(value);
|
|
82
84
|
if (proto !== undefined) {
|
|
83
|
-
const handle = new
|
|
85
|
+
const handle = new Handle(proto, value);
|
|
84
86
|
handles.set(value, handle);
|
|
85
87
|
return handle;
|
|
86
88
|
}
|
|
87
89
|
if (value instanceof Date)
|
|
88
|
-
return new
|
|
90
|
+
return new DateObj(builtins.Date, value.getTime());
|
|
89
91
|
if (value instanceof RegExp)
|
|
90
|
-
return new
|
|
92
|
+
return new RegExpObj(builtins.RegExp, value.source, value.flags);
|
|
93
|
+
if (value instanceof Uint8Array)
|
|
94
|
+
return new Bytes(builtins.Uint8Array, new Uint8Array(value));
|
|
95
|
+
if (value instanceof ArrayBuffer)
|
|
96
|
+
return new Bytes(builtins.Uint8Array, new Uint8Array(value.slice(0)));
|
|
91
97
|
if (value instanceof Error) {
|
|
92
|
-
return createErrorValue(
|
|
98
|
+
return createErrorValue(builtins[isErrorType(value.name) ? value.name : "Error"], value.message);
|
|
93
99
|
}
|
|
94
100
|
if (value instanceof URL)
|
|
95
|
-
return new
|
|
101
|
+
return new URLObj(builtins.URL, builtins.URLSearchParams, new URL(value.href));
|
|
96
102
|
if (value instanceof URLSearchParams) {
|
|
97
|
-
return new
|
|
103
|
+
return new URLSearchParamsObj(builtins.URLSearchParams, new URLSearchParams(value));
|
|
98
104
|
}
|
|
99
105
|
const next = (item) => fromHost(item, label, depth + 1, seen);
|
|
100
106
|
if (value instanceof Map) {
|
|
101
|
-
const wrapped = new
|
|
107
|
+
const wrapped = new MapObj(builtins.Map);
|
|
102
108
|
for (const [key, item] of value)
|
|
103
109
|
wrapped.map.set(next(key), next(item));
|
|
104
110
|
return wrapped;
|
|
105
111
|
}
|
|
106
112
|
if (value instanceof Set) {
|
|
107
|
-
const wrapped = new
|
|
113
|
+
const wrapped = new SetObj(builtins.Set);
|
|
108
114
|
for (const item of value)
|
|
109
115
|
wrapped.set.add(next(item));
|
|
110
116
|
return wrapped;
|
|
@@ -113,13 +119,13 @@ export const extensionGlobals = (host, extensions) => {
|
|
|
113
119
|
throw typeError(`${label} produced a circular value.`);
|
|
114
120
|
seen.add(value);
|
|
115
121
|
if (Array.isArray(value)) {
|
|
116
|
-
const copied = new
|
|
122
|
+
const copied = new Arr(builtins.Array, value.map(next));
|
|
117
123
|
seen.delete(value);
|
|
118
124
|
return copied;
|
|
119
125
|
}
|
|
120
126
|
const prototype = Object.getPrototypeOf(value);
|
|
121
127
|
if (prototype === Object.prototype || prototype === null) {
|
|
122
|
-
const copied = new
|
|
128
|
+
const copied = new Obj(builtins.Object);
|
|
123
129
|
for (const [key, item] of Object.entries(value))
|
|
124
130
|
define(copied, key, next(item));
|
|
125
131
|
seen.delete(value);
|
|
@@ -130,7 +136,7 @@ export const extensionGlobals = (host, extensions) => {
|
|
|
130
136
|
};
|
|
131
137
|
const handlePrototype = (instance) => {
|
|
132
138
|
for (let level = Object.getPrototypeOf(instance); level !== null; level = Object.getPrototypeOf(level)) {
|
|
133
|
-
const proto =
|
|
139
|
+
const proto = protoOf.get(level);
|
|
134
140
|
if (proto !== undefined)
|
|
135
141
|
return proto;
|
|
136
142
|
}
|
|
@@ -139,7 +145,7 @@ export const extensionGlobals = (host, extensions) => {
|
|
|
139
145
|
// Runs host code with already-converted inputs. Whatever it returns, resolves, throws, or rejects with crosses
|
|
140
146
|
// the same way, so the program catches what the author threw.
|
|
141
147
|
const invoke = (run, label) => {
|
|
142
|
-
const thrown = (reason) => new
|
|
148
|
+
const thrown = (reason) => new Throw(fromHost(reason, label));
|
|
143
149
|
let result;
|
|
144
150
|
try {
|
|
145
151
|
result = run();
|
|
@@ -149,7 +155,7 @@ export const extensionGlobals = (host, extensions) => {
|
|
|
149
155
|
}
|
|
150
156
|
if (!(result instanceof Promise))
|
|
151
157
|
return Effect.succeed(fromHost(result, label));
|
|
152
|
-
return
|
|
158
|
+
return ctx.pending.create(Effect.map(Effect.tryPromise({ try: () => result, catch: thrown }), (settled) => fromHost(settled, label)));
|
|
153
159
|
};
|
|
154
160
|
const args = (values, label) => values.map((value, index) => toHost(value, `Argument ${index + 1} to ${label}`));
|
|
155
161
|
// Own members of each level from `from` up to (excluding) `root`, child first, as JS resolves them.
|
|
@@ -166,7 +172,7 @@ export const extensionGlobals = (host, extensions) => {
|
|
|
166
172
|
const converted = args(values, name);
|
|
167
173
|
return invoke(() => method.apply(self, converted), name);
|
|
168
174
|
};
|
|
169
|
-
define(target, key, fn(
|
|
175
|
+
define(target, key, fn(builtins, key, method.length, impl), hidden);
|
|
170
176
|
continue;
|
|
171
177
|
}
|
|
172
178
|
// Data properties stay host-side: a program write to one would change the host class itself.
|
|
@@ -195,10 +201,10 @@ export const extensionGlobals = (host, extensions) => {
|
|
|
195
201
|
return existing;
|
|
196
202
|
const ancestor = exposedAncestor(cls);
|
|
197
203
|
const base = ancestor === undefined ? undefined : expose(ancestor);
|
|
198
|
-
const proto = new
|
|
199
|
-
|
|
204
|
+
const proto = new Obj(base === undefined ? builtins.Object : base.proto);
|
|
205
|
+
protoOf.set(cls.prototype, proto);
|
|
200
206
|
const name = cls.name;
|
|
201
|
-
const ctor = constructor(
|
|
207
|
+
const ctor = constructor(builtins, proto, {
|
|
202
208
|
name,
|
|
203
209
|
length: cls.length,
|
|
204
210
|
call: (_, values) => {
|
|
@@ -223,7 +229,7 @@ export const extensionGlobals = (host, extensions) => {
|
|
|
223
229
|
return called !== undefined && (called === cls || called.prototype instanceof cls) ? called : cls;
|
|
224
230
|
});
|
|
225
231
|
members(proto, cls.prototype, ancestor?.prototype ?? Object.prototype, ownPrototypeKeys, `${name}.prototype`, (thisValue, member) => {
|
|
226
|
-
if (thisValue instanceof
|
|
232
|
+
if (thisValue instanceof Handle && thisValue.instance instanceof cls)
|
|
227
233
|
return thisValue.instance;
|
|
228
234
|
throw typeError(`Illegal invocation: ${member} called on ${describeValue(thisValue)}.`);
|
|
229
235
|
});
|
|
@@ -243,7 +249,7 @@ export const extensionGlobals = (host, extensions) => {
|
|
|
243
249
|
const converted = args(values, name);
|
|
244
250
|
return invoke(() => value.apply(undefined, converted), name);
|
|
245
251
|
};
|
|
246
|
-
return [name, fn(
|
|
252
|
+
return [name, fn(builtins, name, value.length, impl)];
|
|
247
253
|
}));
|
|
248
254
|
};
|
|
249
255
|
const hostErrors = {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { Runner } from "./runner.js";
|
|
1
|
+
import type { Interpreter } from "./interpreter.js";
|
|
3
2
|
/** `next`/`return`/`throw` on the generator prototypes; async generators answer with promises. */
|
|
4
|
-
export declare const generatorGlobals: <R>(
|
|
3
|
+
export declare const generatorGlobals: <R>(ctx: Interpreter<R>) => void;
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
2
|
import { fn, methods, receiver } from "./native.js";
|
|
3
3
|
import { AsyncIteratorSymbol, IteratorSymbol } from "./model.js";
|
|
4
|
-
import { define, hidden,
|
|
4
|
+
import { define, hidden, GeneratorObj } from "./objects.js";
|
|
5
5
|
/** `next`/`return`/`throw` on the generator prototypes; async generators answer with promises. */
|
|
6
|
-
export const generatorGlobals = (
|
|
7
|
-
const
|
|
6
|
+
export const generatorGlobals = (ctx) => {
|
|
7
|
+
const builtins = ctx.builtins;
|
|
8
8
|
const install = (asynchronous) => {
|
|
9
|
-
const proto = asynchronous ?
|
|
9
|
+
const proto = asynchronous ? builtins.AsyncGenerator : builtins.Generator;
|
|
10
10
|
const label = asynchronous ? "AsyncGenerator" : "Generator";
|
|
11
11
|
const request = (kind) => [
|
|
12
12
|
kind,
|
|
13
13
|
1,
|
|
14
14
|
(thisValue, args) => {
|
|
15
|
-
const generator = receiver(
|
|
15
|
+
const generator = receiver(GeneratorObj, thisValue, `${label}.prototype.${kind}`);
|
|
16
16
|
const requested = generator.request(kind, args[0]);
|
|
17
|
-
return generator.asynchronous ?
|
|
17
|
+
return generator.asynchronous ? ctx.pending.create(requested) : requested;
|
|
18
18
|
},
|
|
19
19
|
];
|
|
20
|
-
methods(
|
|
21
|
-
define(asynchronous ?
|
|
20
|
+
methods(builtins, proto, [request("next"), request("return"), request("throw")]);
|
|
21
|
+
define(asynchronous ? builtins.AsyncIterator : builtins.Iterator, asynchronous ? AsyncIteratorSymbol : IteratorSymbol, fn(builtins, asynchronous ? "[Symbol.asyncIterator]" : "[Symbol.iterator]", 0, (thisValue) => thisValue), hidden);
|
|
22
22
|
};
|
|
23
23
|
install(false);
|
|
24
24
|
install(true);
|
|
@@ -1,15 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { type PromiseRuntime } from "./promises.js";
|
|
3
|
-
import type { Runner } from "./runner.js";
|
|
4
|
-
/** What the built-in globals need from the interpreter that owns them. */
|
|
5
|
-
export type Host<R> = {
|
|
6
|
-
readonly runner: Runner<R>;
|
|
7
|
-
readonly promises: PromiseRuntime<R>;
|
|
8
|
-
readonly search: (args: Array<unknown>) => Effect.Effect<unknown, unknown, R>;
|
|
9
|
-
readonly toolKeys: (path: ReadonlyArray<string>) => ReadonlyArray<string>;
|
|
10
|
-
readonly logs: Array<string>;
|
|
11
|
-
};
|
|
1
|
+
import type { Interpreter } from "./interpreter.js";
|
|
12
2
|
/** Names bound in every program before extensions apply. */
|
|
13
3
|
export declare const globalNames: ReadonlySet<string>;
|
|
14
4
|
/** The immutable global bindings of every program, in declaration order. */
|
|
15
|
-
export declare const globals: <R>(
|
|
5
|
+
export declare const globals: <R>(ctx: Interpreter<R>) => ReadonlyArray<readonly [string, unknown]>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
2
|
import { arrayGlobal } from "../stdlib/array.js";
|
|
3
|
+
import { textDecoderGlobal, textEncoderGlobal, uint8ArrayGlobal } from "../stdlib/bytes.js";
|
|
3
4
|
import { mapGlobal, setGlobal } from "../stdlib/collections.js";
|
|
4
5
|
import { consoleGlobal } from "../stdlib/console.js";
|
|
5
6
|
import { dateGlobal } from "../stdlib/date.js";
|
|
@@ -20,19 +21,19 @@ import { AsyncIteratorSymbol, IteratorSymbol, typeError } from "./model.js";
|
|
|
20
21
|
import { generatorGlobals } from "./generators.js";
|
|
21
22
|
import { promiseGlobal } from "./promises.js";
|
|
22
23
|
// Function.prototype.constructor exists so `fn.constructor === Function` holds; dynamic code is unsupported.
|
|
23
|
-
const functionGlobal = (
|
|
24
|
+
const functionGlobal = (ctx) => {
|
|
24
25
|
const reject = () => Effect.sync(() => {
|
|
25
26
|
throw typeError("The Function constructor is not supported; write the function inline.");
|
|
26
27
|
});
|
|
27
|
-
return constructor(
|
|
28
|
+
return constructor(ctx.builtins, ctx.builtins.Function, {
|
|
28
29
|
name: "Function",
|
|
29
30
|
length: 1,
|
|
30
31
|
call: reject,
|
|
31
32
|
construct: reject,
|
|
32
33
|
});
|
|
33
34
|
};
|
|
34
|
-
const symbolGlobal = (
|
|
35
|
-
const symbol = native(
|
|
35
|
+
const symbolGlobal = (ctx) => {
|
|
36
|
+
const symbol = native(ctx.builtins, {
|
|
36
37
|
name: "Symbol",
|
|
37
38
|
call: () => Effect.sync(() => {
|
|
38
39
|
throw typeError("Symbol is not callable; only Symbol.asyncIterator and Symbol.iterator are available.");
|
|
@@ -45,44 +46,47 @@ const symbolGlobal = (runner) => {
|
|
|
45
46
|
// A table rather than a list so the names are known before any runtime exists.
|
|
46
47
|
const table = {
|
|
47
48
|
tools: () => new ToolReference([]),
|
|
48
|
-
search: (
|
|
49
|
+
search: (ctx) => native(ctx.builtins, { name: "search", call: (_, args) => ctx.tools.search(args), callback: false }),
|
|
49
50
|
undefined: () => undefined,
|
|
50
51
|
NaN: () => NaN,
|
|
51
52
|
Infinity: () => Infinity,
|
|
52
|
-
Object: (
|
|
53
|
-
Function: (
|
|
54
|
-
Array: (
|
|
55
|
-
Math: (
|
|
56
|
-
JSON: (
|
|
57
|
-
console: (
|
|
58
|
-
Promise: (
|
|
59
|
-
Symbol: (
|
|
60
|
-
Number: (
|
|
61
|
-
String: (
|
|
62
|
-
Boolean: (
|
|
63
|
-
parseInt: (
|
|
64
|
-
parseFloat: (
|
|
65
|
-
isFinite: (
|
|
66
|
-
isNaN: (
|
|
67
|
-
Date: (
|
|
68
|
-
RegExp: (
|
|
69
|
-
Map: (
|
|
70
|
-
Set: (
|
|
71
|
-
URL: (
|
|
72
|
-
URLSearchParams: (
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
53
|
+
Object: (ctx) => objectGlobal(ctx),
|
|
54
|
+
Function: (ctx) => functionGlobal(ctx),
|
|
55
|
+
Array: (ctx) => arrayGlobal(ctx),
|
|
56
|
+
Math: (ctx) => mathGlobal(ctx),
|
|
57
|
+
JSON: (ctx) => jsonGlobal(ctx),
|
|
58
|
+
console: (ctx) => consoleGlobal(ctx),
|
|
59
|
+
Promise: (ctx) => promiseGlobal(ctx),
|
|
60
|
+
Symbol: (ctx) => symbolGlobal(ctx),
|
|
61
|
+
Number: (ctx) => numberGlobal(ctx),
|
|
62
|
+
String: (ctx) => stringGlobal(ctx),
|
|
63
|
+
Boolean: (ctx) => booleanGlobal(ctx),
|
|
64
|
+
parseInt: (ctx) => coercion(ctx, "parseInt", 2),
|
|
65
|
+
parseFloat: (ctx) => coercion(ctx, "parseFloat"),
|
|
66
|
+
isFinite: (ctx) => coercion(ctx, "isFinite"),
|
|
67
|
+
isNaN: (ctx) => coercion(ctx, "isNaN"),
|
|
68
|
+
Date: (ctx) => dateGlobal(ctx),
|
|
69
|
+
RegExp: (ctx) => regexpGlobal(ctx),
|
|
70
|
+
Map: (ctx) => mapGlobal(ctx),
|
|
71
|
+
Set: (ctx) => setGlobal(ctx),
|
|
72
|
+
URL: (ctx) => urlGlobal(ctx),
|
|
73
|
+
URLSearchParams: (ctx) => urlSearchParamsGlobal(ctx),
|
|
74
|
+
Uint8Array: (ctx) => uint8ArrayGlobal(ctx),
|
|
75
|
+
TextEncoder: (ctx) => textEncoderGlobal(ctx),
|
|
76
|
+
TextDecoder: (ctx) => textDecoderGlobal(ctx),
|
|
77
|
+
encodeURI: (ctx) => uriGlobal(ctx, "encodeURI"),
|
|
78
|
+
encodeURIComponent: (ctx) => uriGlobal(ctx, "encodeURIComponent"),
|
|
79
|
+
decodeURI: (ctx) => uriGlobal(ctx, "decodeURI"),
|
|
80
|
+
decodeURIComponent: (ctx) => uriGlobal(ctx, "decodeURIComponent"),
|
|
81
|
+
atob: (ctx) => base64Global(ctx, "atob"),
|
|
82
|
+
btoa: (ctx) => base64Global(ctx, "btoa"),
|
|
83
|
+
crypto: (ctx) => cryptoGlobal(ctx),
|
|
84
|
+
...Object.fromEntries(errorTypes.map((type) => [type, (ctx) => errorGlobal(type, ctx)])),
|
|
81
85
|
};
|
|
82
86
|
/** Names bound in every program before extensions apply. */
|
|
83
87
|
export const globalNames = new Set(Object.keys(table));
|
|
84
88
|
/** The immutable global bindings of every program, in declaration order. */
|
|
85
|
-
export const globals = (
|
|
86
|
-
generatorGlobals(
|
|
87
|
-
return Object.entries(table).map(([name, factory]) => [name, factory(
|
|
89
|
+
export const globals = (ctx) => {
|
|
90
|
+
generatorGlobals(ctx);
|
|
91
|
+
return Object.entries(table).map(([name, factory]) => [name, factory(ctx)]);
|
|
88
92
|
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Program } from "acorn";
|
|
2
|
+
import { Effect } from "effect";
|
|
3
|
+
import { type ToolRuntime } from "../tool-runtime.js";
|
|
4
|
+
import type { Builtins } from "./intrinsics.js";
|
|
5
|
+
import { PromiseObj } from "./objects.js";
|
|
6
|
+
import { Pending } from "./promises.js";
|
|
7
|
+
/** One program execution: the tool bridge, promise scheduler, captured logs, and the global scope built once. */
|
|
8
|
+
export declare class Interpreter<R> {
|
|
9
|
+
readonly tools: ToolRuntime<R>;
|
|
10
|
+
readonly pending: Pending<R>;
|
|
11
|
+
readonly builtins: Builtins;
|
|
12
|
+
readonly logs: Array<string>;
|
|
13
|
+
private readonly root;
|
|
14
|
+
constructor(options: {
|
|
15
|
+
readonly tools: ToolRuntime<R>;
|
|
16
|
+
readonly pending: Pending<R>;
|
|
17
|
+
readonly builtins: Builtins;
|
|
18
|
+
readonly logs?: Array<string>;
|
|
19
|
+
readonly globals?: (ctx: Interpreter<R>) => ReadonlyArray<readonly [string, unknown]>;
|
|
20
|
+
});
|
|
21
|
+
run(program: Program): Effect.Effect<unknown, unknown, R>;
|
|
22
|
+
call(callable: unknown, thisValue: unknown, args: Array<unknown>): Effect.Effect<unknown, unknown, R>;
|
|
23
|
+
await(promise: PromiseObj): Effect.Effect<unknown, unknown, never>;
|
|
24
|
+
iterate(value: unknown): Effect.Effect<{
|
|
25
|
+
next: Effect.Effect<{
|
|
26
|
+
done: boolean;
|
|
27
|
+
value: unknown;
|
|
28
|
+
}, unknown, R>;
|
|
29
|
+
close: Effect.Effect<void, unknown, R>;
|
|
30
|
+
} | undefined, unknown, R>;
|
|
31
|
+
}
|