@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/value.d.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import
|
|
1
|
+
import { type HostFunction, type SyncOptions } from "../interpreter/host.js";
|
|
2
|
+
import { ProgramError } from "../interpreter/objects.js";
|
|
3
|
+
export declare const errorConstructors: Set<string>;
|
|
3
4
|
export declare const compoundOperators: Set<string>;
|
|
4
|
-
|
|
5
|
+
export declare const createErrorValue: (name: string, message: string) => ProgramError;
|
|
6
|
+
export declare const createAggregateErrorValue: (errors: Array<unknown>, message: string) => ProgramError;
|
|
7
|
+
export declare const errorBrandName: (value: unknown) => string | undefined;
|
|
5
8
|
export declare const coerceToString: (value: unknown) => string;
|
|
6
9
|
export declare const coerceToNumber: (value: unknown) => number;
|
|
7
|
-
|
|
10
|
+
type Coercion = "Number" | "String" | "Boolean" | "parseInt" | "parseFloat" | "isFinite" | "isNaN";
|
|
8
11
|
/** A global coercion function such as `Number` or `parseInt`. */
|
|
9
|
-
export declare const coercion:
|
|
12
|
+
export declare const coercion: (name: Coercion, options?: SyncOptions) => HostFunction;
|
|
13
|
+
export {};
|
package/dist/stdlib/value.js
CHANGED
|
@@ -1,25 +1,47 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { fn } from "../interpreter/native.js";
|
|
1
|
+
import { sync } from "../interpreter/host.js";
|
|
3
2
|
import { InterpreterRuntimeError } from "../interpreter/model.js";
|
|
4
|
-
import {
|
|
3
|
+
import { toProgram } from "../data.js";
|
|
4
|
+
import { get, ProgramArray, ProgramError, set } from "../interpreter/objects.js";
|
|
5
|
+
import { Values } from "../values.js";
|
|
6
|
+
export const errorConstructors = new Set([
|
|
7
|
+
"Error",
|
|
8
|
+
"TypeError",
|
|
9
|
+
"RangeError",
|
|
10
|
+
"SyntaxError",
|
|
11
|
+
"ReferenceError",
|
|
12
|
+
"EvalError",
|
|
13
|
+
"URIError",
|
|
14
|
+
"AggregateError",
|
|
15
|
+
]);
|
|
5
16
|
export const compoundOperators = new Set(["+=", "-=", "*=", "/=", "%=", "**=", "&=", "|=", "^=", "<<=", ">>=", ">>>="]);
|
|
6
|
-
|
|
17
|
+
export const createErrorValue = (name, message) => {
|
|
18
|
+
const value = new ProgramError(name);
|
|
19
|
+
set(value, "name", name);
|
|
20
|
+
set(value, "message", message);
|
|
21
|
+
return value;
|
|
22
|
+
};
|
|
23
|
+
export const createAggregateErrorValue = (errors, message) => {
|
|
24
|
+
const value = createErrorValue("AggregateError", message);
|
|
25
|
+
set(value, "errors", new ProgramArray(errors));
|
|
26
|
+
return value;
|
|
27
|
+
};
|
|
28
|
+
export const errorBrandName = (value) => value instanceof ProgramError ? value.errorName : undefined;
|
|
7
29
|
export const coerceToString = (value) => {
|
|
8
30
|
if (value === null)
|
|
9
31
|
return "null";
|
|
10
32
|
if (value === undefined)
|
|
11
33
|
return "undefined";
|
|
12
|
-
if (value instanceof
|
|
34
|
+
if (value instanceof Values.Date)
|
|
13
35
|
return Number.isFinite(value.time) ? new Date(value.time).toISOString() : "Invalid Date";
|
|
14
|
-
if (value instanceof
|
|
36
|
+
if (value instanceof Values.RegExp)
|
|
15
37
|
return `/${value.regex.source}/${value.regex.flags}`;
|
|
16
|
-
if (value instanceof
|
|
38
|
+
if (value instanceof Values.Map)
|
|
17
39
|
return "[object Map]";
|
|
18
|
-
if (value instanceof
|
|
40
|
+
if (value instanceof Values.Set)
|
|
19
41
|
return "[object Set]";
|
|
20
|
-
if (value instanceof
|
|
42
|
+
if (value instanceof Values.URL)
|
|
21
43
|
return value.url.href;
|
|
22
|
-
if (value instanceof
|
|
44
|
+
if (value instanceof Values.URLSearchParams)
|
|
23
45
|
return value.params.toString();
|
|
24
46
|
if (value instanceof ProgramError) {
|
|
25
47
|
// Match Error.prototype.toString: "name: message", or just one when the other is empty.
|
|
@@ -41,15 +63,15 @@ export const coerceToString = (value) => {
|
|
|
41
63
|
return String(value);
|
|
42
64
|
};
|
|
43
65
|
export const coerceToNumber = (value) => {
|
|
44
|
-
if (value instanceof
|
|
66
|
+
if (value instanceof Values.Date)
|
|
45
67
|
return value.time;
|
|
46
|
-
if (
|
|
68
|
+
if (Values.isValue(value))
|
|
47
69
|
return Number.NaN;
|
|
48
70
|
if (value instanceof ProgramArray)
|
|
49
71
|
return Number(coerceToString(value));
|
|
50
72
|
return value !== null && typeof value === "object" ? Number.NaN : Number(value);
|
|
51
73
|
};
|
|
52
|
-
const coerce = (
|
|
74
|
+
const coerce = (name, args, node) => {
|
|
53
75
|
// Native: Number() is 0 and String() is "", unlike their undefined-argument forms; the
|
|
54
76
|
// other coercers match native through the undefined-argument path below.
|
|
55
77
|
if (args.length === 0) {
|
|
@@ -59,7 +81,7 @@ const coerce = (runner, name, args, node) => {
|
|
|
59
81
|
return "";
|
|
60
82
|
}
|
|
61
83
|
const raw = args[0];
|
|
62
|
-
if (
|
|
84
|
+
if (Values.isValue(raw)) {
|
|
63
85
|
if (name === "Boolean")
|
|
64
86
|
return true;
|
|
65
87
|
if (name === "Number")
|
|
@@ -74,7 +96,7 @@ const coerce = (runner, name, args, node) => {
|
|
|
74
96
|
return parseInt(coerceToString(raw));
|
|
75
97
|
return parseFloat(coerceToString(raw));
|
|
76
98
|
}
|
|
77
|
-
const value = toProgram(
|
|
99
|
+
const value = toProgram(raw, `${name} input`);
|
|
78
100
|
if (name === "Number")
|
|
79
101
|
return coerceToNumber(value);
|
|
80
102
|
if (name === "Boolean")
|
|
@@ -95,4 +117,4 @@ const coerce = (runner, name, args, node) => {
|
|
|
95
117
|
return coerceToString(value);
|
|
96
118
|
};
|
|
97
119
|
/** A global coercion function such as `Number` or `parseInt`. */
|
|
98
|
-
export const coercion = (
|
|
120
|
+
export const coercion = (name, options = {}) => sync(name, (args, node) => toProgram(coerce(name, args, node), `${name} result`), options);
|
package/dist/stdlib/web.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
export declare const
|
|
4
|
-
export declare const cryptoGlobal:
|
|
1
|
+
import { HostNamespace } from "../interpreter/host.js";
|
|
2
|
+
export declare const atobGlobal: import("../interpreter/host.js").HostFunction<never>;
|
|
3
|
+
export declare const btoaGlobal: import("../interpreter/host.js").HostFunction<never>;
|
|
4
|
+
export declare const cryptoGlobal: HostNamespace;
|
package/dist/stdlib/web.js
CHANGED
|
@@ -1,22 +1,20 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { HostNamespace, sync } from "../interpreter/host.js";
|
|
2
2
|
import { InterpreterRuntimeError } from "../interpreter/model.js";
|
|
3
|
-
import { ProgramObject } from "../interpreter/objects.js";
|
|
4
3
|
import { coerceToString } from "./value.js";
|
|
5
|
-
// WebIDL DOMString conversion: a missing argument is a TypeError, anything else stringifies.
|
|
6
|
-
|
|
7
|
-
export const base64Global = (runner, name) => fn(runner.prototypes, name, 1, (_, args, node) => {
|
|
4
|
+
// WebIDL DOMString conversion: a missing argument is a TypeError, anything else stringifies.
|
|
5
|
+
const base64 = (name) => sync(name, (args, node) => {
|
|
8
6
|
if (args.length === 0)
|
|
9
|
-
throw new InterpreterRuntimeError(`${name} requires 1 argument (a string)`, node);
|
|
7
|
+
throw new InterpreterRuntimeError(`${name} requires 1 argument (a string)`, node).as("TypeError");
|
|
10
8
|
const input = coerceToString(args[0]);
|
|
11
9
|
try {
|
|
12
10
|
return name === "atob" ? atob(input) : btoa(input);
|
|
13
11
|
}
|
|
14
12
|
catch {
|
|
15
|
-
throw new InterpreterRuntimeError("The string contains invalid characters.", node);
|
|
13
|
+
throw new InterpreterRuntimeError("The string contains invalid characters.", node).as("InvalidCharacterError");
|
|
16
14
|
}
|
|
17
15
|
});
|
|
18
|
-
export const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
};
|
|
16
|
+
export const atobGlobal = base64("atob");
|
|
17
|
+
export const btoaGlobal = base64("btoa");
|
|
18
|
+
export const cryptoGlobal = new HostNamespace("crypto", {
|
|
19
|
+
randomUUID: sync("crypto.randomUUID", () => crypto.randomUUID()),
|
|
20
|
+
});
|
package/dist/tool-runtime.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
|
-
import type { Prototypes } from "./interpreter/intrinsics.js";
|
|
3
2
|
import { type Namespace } from "./namespace.js";
|
|
4
3
|
import { type Tool } from "./tool.js";
|
|
5
4
|
import type { Tools } from "./tools.js";
|
|
@@ -66,5 +65,5 @@ export type ToolRuntime<R = never> = {
|
|
|
66
65
|
readonly keys: (path: ReadonlyArray<string>) => ReadonlyArray<string>;
|
|
67
66
|
};
|
|
68
67
|
/** Per-execution call state over tools prepared once for the runtime. */
|
|
69
|
-
export declare const make: <R>(prepared: Prepared<R>,
|
|
68
|
+
export declare const make: <R>(prepared: Prepared<R>, maxToolCalls: number | undefined, hooks?: ToolCallHooks<R>) => ToolRuntime<R>;
|
|
70
69
|
export * as ToolRuntime from "./tool-runtime.js";
|
package/dist/tool-runtime.js
CHANGED
|
@@ -184,7 +184,7 @@ const resolve = (root, path) => {
|
|
|
184
184
|
return node.tool;
|
|
185
185
|
};
|
|
186
186
|
/** Per-execution call state over tools prepared once for the runtime. */
|
|
187
|
-
export const make = (prepared,
|
|
187
|
+
export const make = (prepared, maxToolCalls, hooks) => {
|
|
188
188
|
const calls = [];
|
|
189
189
|
const root = prepared.root;
|
|
190
190
|
const searchTool = makeSearchTool(prepared.searchIndex);
|
|
@@ -234,7 +234,7 @@ export const make = (prepared, prototypes, maxToolCalls, hooks) => {
|
|
|
234
234
|
.join("\n")));
|
|
235
235
|
}));
|
|
236
236
|
return yield* Effect.try({
|
|
237
|
-
try: () => fromData(
|
|
237
|
+
try: () => fromData(decodeToolOutput(tool, raw), `Result from tool '${name}'`),
|
|
238
238
|
catch: (cause) => new ToolRuntimeError("InvalidToolOutput", `Invalid output from tool '${name}': ${cause}`),
|
|
239
239
|
});
|
|
240
240
|
}), call);
|
package/dist/values.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export * as Values from "./values.js";
|
|
2
|
+
import type { Fiber } from "effect";
|
|
3
|
+
/**
|
|
4
|
+
* Runtime values the interpreter recognizes by class. Each wraps the host value it stands for,
|
|
5
|
+
* so hosts construct these to hand a value to a program and receive them back unchanged.
|
|
6
|
+
*/
|
|
7
|
+
export declare class Promise {
|
|
8
|
+
readonly fiber: Fiber.Fiber<unknown, unknown>;
|
|
9
|
+
constructor(fiber: Fiber.Fiber<unknown, unknown>);
|
|
10
|
+
}
|
|
11
|
+
export declare class Date {
|
|
12
|
+
time: number;
|
|
13
|
+
constructor(time: number);
|
|
14
|
+
}
|
|
15
|
+
export declare class RegExp {
|
|
16
|
+
readonly regex: globalThis.RegExp;
|
|
17
|
+
constructor(pattern: string, flags: string);
|
|
18
|
+
get lastIndex(): unknown;
|
|
19
|
+
set lastIndex(value: unknown);
|
|
20
|
+
}
|
|
21
|
+
export declare class Map {
|
|
22
|
+
readonly map: globalThis.Map<unknown, unknown>;
|
|
23
|
+
}
|
|
24
|
+
export declare class Set {
|
|
25
|
+
readonly set: globalThis.Set<unknown>;
|
|
26
|
+
}
|
|
27
|
+
export declare class URLSearchParams {
|
|
28
|
+
readonly params: globalThis.URLSearchParams;
|
|
29
|
+
constructor(params: globalThis.URLSearchParams);
|
|
30
|
+
}
|
|
31
|
+
export declare class URL {
|
|
32
|
+
readonly url: globalThis.URL;
|
|
33
|
+
readonly searchParams: URLSearchParams;
|
|
34
|
+
constructor(url: globalThis.URL);
|
|
35
|
+
}
|
|
36
|
+
/** Data-like runtime values; excludes Promise, which never crosses a boundary. */
|
|
37
|
+
export declare const isValue: (value: unknown) => value is Date | RegExp | Map | Set | URL | URLSearchParams;
|
package/dist/values.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export * as Values from "./values.js";
|
|
2
|
+
/**
|
|
3
|
+
* Runtime values the interpreter recognizes by class. Each wraps the host value it stands for,
|
|
4
|
+
* so hosts construct these to hand a value to a program and receive them back unchanged.
|
|
5
|
+
*/
|
|
6
|
+
export class Promise {
|
|
7
|
+
fiber;
|
|
8
|
+
constructor(fiber) {
|
|
9
|
+
this.fiber = fiber;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export class Date {
|
|
13
|
+
time;
|
|
14
|
+
constructor(time) {
|
|
15
|
+
this.time = time;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export class RegExp {
|
|
19
|
+
regex;
|
|
20
|
+
constructor(pattern, flags) {
|
|
21
|
+
this.regex = new globalThis.RegExp(pattern, flags);
|
|
22
|
+
}
|
|
23
|
+
get lastIndex() {
|
|
24
|
+
return Reflect.get(this.regex, "lastIndex");
|
|
25
|
+
}
|
|
26
|
+
set lastIndex(value) {
|
|
27
|
+
Reflect.set(this.regex, "lastIndex", value);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export class Map {
|
|
31
|
+
map = new globalThis.Map();
|
|
32
|
+
}
|
|
33
|
+
export class Set {
|
|
34
|
+
set = new globalThis.Set();
|
|
35
|
+
}
|
|
36
|
+
export class URLSearchParams {
|
|
37
|
+
params;
|
|
38
|
+
constructor(params) {
|
|
39
|
+
this.params = params;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export class URL {
|
|
43
|
+
url;
|
|
44
|
+
searchParams;
|
|
45
|
+
constructor(url) {
|
|
46
|
+
this.url = url;
|
|
47
|
+
this.searchParams = new URLSearchParams(url.searchParams);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/** Data-like runtime values; excludes Promise, which never crosses a boundary. */
|
|
51
|
+
export const isValue = (value) => value instanceof Date ||
|
|
52
|
+
value instanceof RegExp ||
|
|
53
|
+
value instanceof Map ||
|
|
54
|
+
value instanceof Set ||
|
|
55
|
+
value instanceof URL ||
|
|
56
|
+
value instanceof URLSearchParams;
|
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": "
|
|
4
|
+
"version": "2.0.0",
|
|
5
5
|
"description": "Effect-native confined code execution over schema-described tools",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"license": "MIT",
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { PromiseRuntime } from "./promises.js";
|
|
2
|
-
import type { Runner } from "./runner.js";
|
|
3
|
-
/** `next`/`return`/`throw` on the generator prototypes; async generators answer with promises. */
|
|
4
|
-
export declare const generatorGlobals: <R>(runner: Runner<R>, promises: PromiseRuntime<R>) => void;
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { Effect } from "effect";
|
|
2
|
-
import { fn, methods, receiver } from "./native.js";
|
|
3
|
-
import { AsyncIteratorSymbol, IteratorSymbol } from "./model.js";
|
|
4
|
-
import { define, hidden, ProgramGenerator } from "./objects.js";
|
|
5
|
-
/** `next`/`return`/`throw` on the generator prototypes; async generators answer with promises. */
|
|
6
|
-
export const generatorGlobals = (runner, promises) => {
|
|
7
|
-
const protos = runner.prototypes;
|
|
8
|
-
const install = (asynchronous) => {
|
|
9
|
-
const proto = asynchronous ? protos.AsyncGenerator : protos.Generator;
|
|
10
|
-
const label = asynchronous ? "AsyncGenerator" : "Generator";
|
|
11
|
-
const request = (kind) => [
|
|
12
|
-
kind,
|
|
13
|
-
1,
|
|
14
|
-
(thisValue, args, node) => {
|
|
15
|
-
const generator = receiver(ProgramGenerator, thisValue, `${label}.prototype.${kind}`, node);
|
|
16
|
-
const requested = generator.request(kind, args[0], node);
|
|
17
|
-
return generator.asynchronous ? promises.create(requested) : requested;
|
|
18
|
-
},
|
|
19
|
-
];
|
|
20
|
-
methods(protos, proto, [request("next"), request("return"), request("throw")]);
|
|
21
|
-
define(asynchronous ? protos.AsyncIterator : protos.Iterator, asynchronous ? AsyncIteratorSymbol : IteratorSymbol, fn(protos, asynchronous ? "[Symbol.asyncIterator]" : "[Symbol.iterator]", 0, (thisValue) => thisValue), hidden);
|
|
22
|
-
};
|
|
23
|
-
install(false);
|
|
24
|
-
install(true);
|
|
25
|
-
};
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { ProgramError, ProgramObject } from "./objects.js";
|
|
2
|
-
export declare const errorTypes: readonly ["Error", "TypeError", "RangeError", "SyntaxError", "ReferenceError", "EvalError", "URIError", "AggregateError"];
|
|
3
|
-
export type ErrorType = (typeof errorTypes)[number];
|
|
4
|
-
export declare const isErrorType: (name: string) => name is ErrorType;
|
|
5
|
-
declare const builtins: readonly ["Object", "Function", "Array", "String", "Number", "Boolean", "Date", "RegExp", "Map", "Set", "URL", "URLSearchParams", "Promise", "Iterator", "AsyncIterator", "Generator", "AsyncGenerator"];
|
|
6
|
-
/**
|
|
7
|
-
* The built-in prototype objects of one runtime, allocated empty in dependency order. The globals populate them
|
|
8
|
-
* and attach their constructors when the runtime is built.
|
|
9
|
-
*/
|
|
10
|
-
export type Prototypes = Readonly<Record<(typeof builtins)[number] | ErrorType, ProgramObject>>;
|
|
11
|
-
export declare const createErrorValue: (prototype: ProgramObject, message: string | undefined) => ProgramError;
|
|
12
|
-
export declare const createPrototypes: () => Prototypes;
|
|
13
|
-
export {};
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { Effect } from "effect";
|
|
2
|
-
import { define, hidden, NativeFunction, ProgramArray, ProgramError, ProgramObject } from "./objects.js";
|
|
3
|
-
export const errorTypes = [
|
|
4
|
-
"Error",
|
|
5
|
-
"TypeError",
|
|
6
|
-
"RangeError",
|
|
7
|
-
"SyntaxError",
|
|
8
|
-
"ReferenceError",
|
|
9
|
-
"EvalError",
|
|
10
|
-
"URIError",
|
|
11
|
-
"AggregateError",
|
|
12
|
-
];
|
|
13
|
-
export const isErrorType = (name) => errorTypes.includes(name);
|
|
14
|
-
const builtins = [
|
|
15
|
-
"Object",
|
|
16
|
-
"Function",
|
|
17
|
-
"Array",
|
|
18
|
-
"String",
|
|
19
|
-
"Number",
|
|
20
|
-
"Boolean",
|
|
21
|
-
"Date",
|
|
22
|
-
"RegExp",
|
|
23
|
-
"Map",
|
|
24
|
-
"Set",
|
|
25
|
-
"URL",
|
|
26
|
-
"URLSearchParams",
|
|
27
|
-
"Promise",
|
|
28
|
-
"Iterator",
|
|
29
|
-
"AsyncIterator",
|
|
30
|
-
"Generator",
|
|
31
|
-
"AsyncGenerator",
|
|
32
|
-
];
|
|
33
|
-
export const createErrorValue = (prototype, message) => {
|
|
34
|
-
const value = new ProgramError(prototype);
|
|
35
|
-
if (message !== undefined)
|
|
36
|
-
define(value, "message", message, hidden);
|
|
37
|
-
return value;
|
|
38
|
-
};
|
|
39
|
-
export const createPrototypes = () => {
|
|
40
|
-
const object = new ProgramObject(null);
|
|
41
|
-
// Function.prototype is itself callable and returns undefined.
|
|
42
|
-
const fn = new NativeFunction(object, { name: "", call: () => Effect.undefined });
|
|
43
|
-
const plain = () => new ProgramObject(object);
|
|
44
|
-
const error = plain();
|
|
45
|
-
define(error, "name", "Error", hidden);
|
|
46
|
-
define(error, "message", "", hidden);
|
|
47
|
-
const derived = (type) => {
|
|
48
|
-
const proto = new ProgramObject(error);
|
|
49
|
-
define(proto, "name", type, hidden);
|
|
50
|
-
define(proto, "message", "", hidden);
|
|
51
|
-
return proto;
|
|
52
|
-
};
|
|
53
|
-
const iterator = plain();
|
|
54
|
-
const asyncIterator = plain();
|
|
55
|
-
return {
|
|
56
|
-
Object: object,
|
|
57
|
-
Function: fn,
|
|
58
|
-
Array: new ProgramArray(object),
|
|
59
|
-
String: plain(),
|
|
60
|
-
Number: plain(),
|
|
61
|
-
Boolean: plain(),
|
|
62
|
-
Date: plain(),
|
|
63
|
-
RegExp: plain(),
|
|
64
|
-
Map: plain(),
|
|
65
|
-
Set: plain(),
|
|
66
|
-
URL: plain(),
|
|
67
|
-
URLSearchParams: plain(),
|
|
68
|
-
Promise: plain(),
|
|
69
|
-
Iterator: iterator,
|
|
70
|
-
AsyncIterator: asyncIterator,
|
|
71
|
-
Generator: new ProgramObject(iterator),
|
|
72
|
-
AsyncGenerator: new ProgramObject(asyncIterator),
|
|
73
|
-
Error: error,
|
|
74
|
-
TypeError: derived("TypeError"),
|
|
75
|
-
RangeError: derived("RangeError"),
|
|
76
|
-
SyntaxError: derived("SyntaxError"),
|
|
77
|
-
ReferenceError: derived("ReferenceError"),
|
|
78
|
-
EvalError: derived("EvalError"),
|
|
79
|
-
URIError: derived("URIError"),
|
|
80
|
-
AggregateError: derived("AggregateError"),
|
|
81
|
-
};
|
|
82
|
-
};
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { Effect } from "effect";
|
|
2
|
-
import type { Prototypes } from "./intrinsics.js";
|
|
3
|
-
import { type AstNode } from "./model.js";
|
|
4
|
-
import { type Callable, NativeFunction, type NativeOptions, ProgramObject } from "./objects.js";
|
|
5
|
-
/** A native function body: a plain value, a thrown `InterpreterRuntimeError`, or an Effect. */
|
|
6
|
-
export type Impl = (thisValue: unknown, args: Array<unknown>, node: AstNode) => unknown;
|
|
7
|
-
export declare const native: <R>(protos: Prototypes, options: NativeOptions<R>) => NativeFunction<R>;
|
|
8
|
-
export declare const fn: <R>(protos: Prototypes, name: string, length: number, impl: Impl) => NativeFunction<R>;
|
|
9
|
-
export type Method = readonly [name: string, length: number, impl: Impl];
|
|
10
|
-
export declare const methods: (protos: Prototypes, target: ProgramObject, table: ReadonlyArray<Method>) => void;
|
|
11
|
-
export declare const constants: (target: ProgramObject, table: Record<string, unknown>) => void;
|
|
12
|
-
/** A constructor wired to its prototype: `C.prototype === proto` and `proto.constructor === C`. */
|
|
13
|
-
export declare const constructor: <R>(protos: Prototypes, proto: ProgramObject, options: NativeOptions<R>) => NativeFunction<R>;
|
|
14
|
-
/** The `call` of a constructor that JS requires to be invoked with `new`. */
|
|
15
|
-
export declare const requiresNew: (name: string) => (_: unknown, __: Array<unknown>, node: AstNode) => Effect.Effect<never, unknown, never>;
|
|
16
|
-
/** The instance prototype for `new` via `newTarget.prototype`, falling back to the built-in's own. */
|
|
17
|
-
export declare const prototypeFrom: (newTarget: Callable, fallback: ProgramObject) => ProgramObject;
|
|
18
|
-
/** Narrows a method receiver to the built-in it belongs to, or throws the TypeError JS would. */
|
|
19
|
-
export declare const receiver: <T extends ProgramObject>(cls: abstract new (...args: never) => T, thisValue: unknown, method: string, node?: AstNode) => T;
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { Effect } from "effect";
|
|
2
|
-
import { InterpreterRuntimeError } from "./model.js";
|
|
3
|
-
import { define, frozen, hidden, NativeFunction, ProgramObject } from "./objects.js";
|
|
4
|
-
import { describeValue } from "./references.js";
|
|
5
|
-
const lift = (impl) => (thisValue, args, node) => Effect.suspend(() => {
|
|
6
|
-
const result = impl(thisValue, args, node);
|
|
7
|
-
return Effect.isEffect(result) ? result : Effect.succeed(result);
|
|
8
|
-
});
|
|
9
|
-
export const native = (protos, options) => new NativeFunction(protos.Function, options);
|
|
10
|
-
export const fn = (protos, name, length, impl) => native(protos, { name, length, call: lift(impl) });
|
|
11
|
-
export const methods = (protos, target, table) => {
|
|
12
|
-
for (const [name, length, impl] of table)
|
|
13
|
-
define(target, name, fn(protos, name, length, impl), hidden);
|
|
14
|
-
};
|
|
15
|
-
export const constants = (target, table) => {
|
|
16
|
-
for (const [name, value] of Object.entries(table))
|
|
17
|
-
define(target, name, value, frozen);
|
|
18
|
-
};
|
|
19
|
-
/** A constructor wired to its prototype: `C.prototype === proto` and `proto.constructor === C`. */
|
|
20
|
-
export const constructor = (protos, proto, options) => {
|
|
21
|
-
const ctor = native(protos, options);
|
|
22
|
-
define(ctor, "prototype", proto, frozen);
|
|
23
|
-
define(proto, "constructor", ctor, hidden);
|
|
24
|
-
return ctor;
|
|
25
|
-
};
|
|
26
|
-
/** The `call` of a constructor that JS requires to be invoked with `new`. */
|
|
27
|
-
export const requiresNew = (name) => (_, __, node) => Effect.sync(() => {
|
|
28
|
-
throw new InterpreterRuntimeError(`Constructor ${name} requires 'new'.`, node);
|
|
29
|
-
});
|
|
30
|
-
/** The instance prototype for `new` via `newTarget.prototype`, falling back to the built-in's own. */
|
|
31
|
-
export const prototypeFrom = (newTarget, fallback) => {
|
|
32
|
-
const proto = newTarget.props.get("prototype");
|
|
33
|
-
return proto !== undefined && "value" in proto && proto.value instanceof ProgramObject ? proto.value : fallback;
|
|
34
|
-
};
|
|
35
|
-
/** Narrows a method receiver to the built-in it belongs to, or throws the TypeError JS would. */
|
|
36
|
-
export const receiver = (cls, thisValue, method, node) => {
|
|
37
|
-
if (thisValue instanceof cls)
|
|
38
|
-
return thisValue;
|
|
39
|
-
throw new InterpreterRuntimeError(`${method} called on incompatible receiver ${describeValue(thisValue)}.`, node);
|
|
40
|
-
};
|