@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
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { Node } from "acorn";
|
|
2
|
-
import type {
|
|
2
|
+
import type { Effect } from "effect";
|
|
3
3
|
import type { DiagnosticKind } from "../codemode.js";
|
|
4
|
+
import type { ProgramObject } from "./objects.js";
|
|
5
|
+
import type { Values } from "../values.js";
|
|
4
6
|
/** Any parsed node; the interpreter narrows on `type` and reads `loc` for diagnostics. */
|
|
5
7
|
export type AstNode = Node;
|
|
6
8
|
export type Binding = {
|
|
@@ -20,10 +22,39 @@ export type StatementResult = {
|
|
|
20
22
|
kind: "continue";
|
|
21
23
|
label?: string;
|
|
22
24
|
};
|
|
25
|
+
export type MemberReference = {
|
|
26
|
+
target: ProgramObject | Values.RegExp | Values.URL;
|
|
27
|
+
key: PropertyKey;
|
|
28
|
+
};
|
|
23
29
|
export type GeneratorRequestKind = "next" | "return" | "throw";
|
|
30
|
+
export declare class CodeModeGenerator {
|
|
31
|
+
readonly asynchronous: boolean;
|
|
32
|
+
readonly request: (kind: GeneratorRequestKind, value: unknown, node: AstNode) => Effect.Effect<unknown, unknown, unknown>;
|
|
33
|
+
constructor(asynchronous: boolean, request: (kind: GeneratorRequestKind, value: unknown, node: AstNode) => Effect.Effect<unknown, unknown, unknown>);
|
|
34
|
+
}
|
|
35
|
+
export declare class GeneratorMethodReference {
|
|
36
|
+
readonly generator: CodeModeGenerator;
|
|
37
|
+
readonly kind: GeneratorRequestKind | "iterator";
|
|
38
|
+
constructor(generator: CodeModeGenerator, kind: GeneratorRequestKind | "iterator");
|
|
39
|
+
}
|
|
40
|
+
export declare class IntrinsicReference {
|
|
41
|
+
readonly receiver: unknown;
|
|
42
|
+
readonly name: string;
|
|
43
|
+
constructor(receiver: unknown, name: string);
|
|
44
|
+
}
|
|
45
|
+
export declare class ComputedValue {
|
|
46
|
+
readonly value: unknown;
|
|
47
|
+
constructor(value: unknown);
|
|
48
|
+
}
|
|
24
49
|
export declare const AsyncIteratorSymbol: unique symbol;
|
|
25
50
|
export declare const IteratorSymbol: unique symbol;
|
|
26
51
|
export declare const IteratorSymbols: readonly [typeof AsyncIteratorSymbol, typeof IteratorSymbol];
|
|
52
|
+
export type PromiseInstanceMethodName = "then" | "catch" | "finally";
|
|
53
|
+
export declare class PromiseInstanceMethodReference {
|
|
54
|
+
readonly promise: Values.Promise;
|
|
55
|
+
readonly name: PromiseInstanceMethodName;
|
|
56
|
+
constructor(promise: Values.Promise, name: PromiseInstanceMethodName);
|
|
57
|
+
}
|
|
27
58
|
export declare class ProgramThrow {
|
|
28
59
|
readonly value: unknown;
|
|
29
60
|
constructor(value: unknown);
|
|
@@ -36,19 +67,11 @@ export declare const OptionalShortCircuit: unique symbol;
|
|
|
36
67
|
export declare class InterpreterRuntimeError extends Error {
|
|
37
68
|
readonly kind: DiagnosticKind;
|
|
38
69
|
readonly suggestions?: ReadonlyArray<string> | undefined;
|
|
39
|
-
/** The JS error class a program sees when it catches this failure. */
|
|
40
|
-
readonly type: ErrorType;
|
|
41
70
|
readonly node?: AstNode;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
/** Attaches a source location to a failure raised where none was known, such as inside a property accessor. */
|
|
47
|
-
export declare const locate: (error: unknown, node: AstNode) => unknown;
|
|
48
|
-
export declare const rangeError: (message: string, node?: AstNode) => InterpreterRuntimeError;
|
|
49
|
-
export declare const referenceError: (message: string, node?: AstNode) => InterpreterRuntimeError;
|
|
50
|
-
export declare const syntaxError: (message: string, node?: AstNode) => InterpreterRuntimeError;
|
|
51
|
-
export declare const uriError: (message: string, node?: AstNode) => InterpreterRuntimeError;
|
|
71
|
+
errorName: string;
|
|
72
|
+
constructor(message: string, node?: AstNode, kind?: DiagnosticKind, suggestions?: ReadonlyArray<string> | undefined);
|
|
73
|
+
as(errorName: string): this;
|
|
74
|
+
}
|
|
52
75
|
export declare const supportedSyntaxMessage = "This is a restricted JavaScript-like language. Supported: plain and async functions, data literals, destructuring, standard control flow, await and Promise, and built-ins such as Array, Object, Math, JSON, Date, RegExp, Map, Set, and URL. Unsupported: classes, this, getters/setters, tagged templates, BigInt, and custom Symbols. Use plain functions and data objects instead.";
|
|
53
76
|
export declare const unsupportedSyntax: (kind: string, node: AstNode) => InterpreterRuntimeError;
|
|
54
77
|
export declare const isRecord: (value: unknown) => value is Record<string, unknown>;
|
|
@@ -1,6 +1,44 @@
|
|
|
1
|
+
export class CodeModeGenerator {
|
|
2
|
+
asynchronous;
|
|
3
|
+
request;
|
|
4
|
+
constructor(asynchronous, request) {
|
|
5
|
+
this.asynchronous = asynchronous;
|
|
6
|
+
this.request = request;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export class GeneratorMethodReference {
|
|
10
|
+
generator;
|
|
11
|
+
kind;
|
|
12
|
+
constructor(generator, kind) {
|
|
13
|
+
this.generator = generator;
|
|
14
|
+
this.kind = kind;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export class IntrinsicReference {
|
|
18
|
+
receiver;
|
|
19
|
+
name;
|
|
20
|
+
constructor(receiver, name) {
|
|
21
|
+
this.receiver = receiver;
|
|
22
|
+
this.name = name;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export class ComputedValue {
|
|
26
|
+
value;
|
|
27
|
+
constructor(value) {
|
|
28
|
+
this.value = value;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
1
31
|
export const AsyncIteratorSymbol = Symbol("codemode.async-iterator");
|
|
2
32
|
export const IteratorSymbol = Symbol("codemode.iterator");
|
|
3
33
|
export const IteratorSymbols = [AsyncIteratorSymbol, IteratorSymbol];
|
|
34
|
+
export class PromiseInstanceMethodReference {
|
|
35
|
+
promise;
|
|
36
|
+
name;
|
|
37
|
+
constructor(promise, name) {
|
|
38
|
+
this.promise = promise;
|
|
39
|
+
this.name = name;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
4
42
|
export class ProgramThrow {
|
|
5
43
|
value;
|
|
6
44
|
constructor(value) {
|
|
@@ -17,32 +55,24 @@ export const OptionalShortCircuit = Symbol("codemode.optional-short-circuit");
|
|
|
17
55
|
export class InterpreterRuntimeError extends Error {
|
|
18
56
|
kind;
|
|
19
57
|
suggestions;
|
|
20
|
-
type;
|
|
21
58
|
node;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
type = "TypeError") {
|
|
59
|
+
errorName = "Error";
|
|
60
|
+
constructor(message, node, kind = "ExecutionFailure", suggestions) {
|
|
25
61
|
super(message);
|
|
26
62
|
this.kind = kind;
|
|
27
63
|
this.suggestions = suggestions;
|
|
28
|
-
this.type = type;
|
|
29
64
|
this.name = "InterpreterRuntimeError";
|
|
30
65
|
if (node)
|
|
31
66
|
this.node = node;
|
|
32
67
|
}
|
|
68
|
+
as(errorName) {
|
|
69
|
+
this.errorName = errorName;
|
|
70
|
+
return this;
|
|
71
|
+
}
|
|
33
72
|
}
|
|
34
|
-
/** Attaches a source location to a failure raised where none was known, such as inside a property accessor. */
|
|
35
|
-
export const locate = (error, node) => error instanceof InterpreterRuntimeError && error.node === undefined
|
|
36
|
-
? new InterpreterRuntimeError(error.message, node, error.kind, error.suggestions, error.type)
|
|
37
|
-
: error;
|
|
38
|
-
const failure = (type) => (message, node) => new InterpreterRuntimeError(message, node, "ExecutionFailure", undefined, type);
|
|
39
|
-
export const rangeError = failure("RangeError");
|
|
40
|
-
export const referenceError = failure("ReferenceError");
|
|
41
|
-
export const syntaxError = failure("SyntaxError");
|
|
42
|
-
export const uriError = failure("URIError");
|
|
43
73
|
// Orient the agent rather than enumerate JavaScript; interpreter-support.md is the full matrix.
|
|
44
74
|
export const supportedSyntaxMessage = "This is a restricted JavaScript-like language. Supported: plain and async functions, data literals, destructuring, standard control flow, await and Promise, and built-ins such as Array, Object, Math, JSON, Date, RegExp, Map, Set, and URL. Unsupported: classes, this, getters/setters, tagged templates, BigInt, and custom Symbols. Use plain functions and data objects instead.";
|
|
45
|
-
export const unsupportedSyntax = (kind, node) => new InterpreterRuntimeError(`Syntax '${kind}' is not supported. ${supportedSyntaxMessage}`, node, "UnsupportedSyntax", [supportedSyntaxMessage]
|
|
75
|
+
export const unsupportedSyntax = (kind, node) => new InterpreterRuntimeError(`Syntax '${kind}' is not supported. ${supportedSyntaxMessage}`, node, "UnsupportedSyntax", [supportedSyntaxMessage]);
|
|
46
76
|
export const isRecord = (value) => typeof value === "object" && value !== null;
|
|
47
77
|
export const sourceLocation = (node) => ({
|
|
48
78
|
line: Math.max(1, (node.loc?.start.line ?? 2) - 1),
|
|
@@ -1,130 +1,37 @@
|
|
|
1
1
|
import type { BlockStatement, Expression, Pattern } from "acorn";
|
|
2
|
-
import
|
|
3
|
-
import { type AstNode, type Binding, type GeneratorRequestKind } from "./model.js";
|
|
4
|
-
/** Property attributes, as in a JS property descriptor. */
|
|
5
|
-
export type Attributes = {
|
|
6
|
-
readonly writable: boolean;
|
|
7
|
-
readonly enumerable: boolean;
|
|
8
|
-
readonly configurable: boolean;
|
|
9
|
-
};
|
|
10
|
-
export type Getter = (receiver: unknown) => unknown;
|
|
11
|
-
export type Setter = (receiver: unknown, value: unknown) => void;
|
|
12
|
-
/** One own property: a data slot or a native accessor pair. */
|
|
13
|
-
export type Slot = {
|
|
14
|
-
value: unknown;
|
|
15
|
-
writable: boolean;
|
|
16
|
-
enumerable: boolean;
|
|
17
|
-
configurable: boolean;
|
|
18
|
-
} | {
|
|
19
|
-
get: Getter | undefined;
|
|
20
|
-
set: Setter | undefined;
|
|
21
|
-
enumerable: boolean;
|
|
22
|
-
configurable: boolean;
|
|
23
|
-
};
|
|
24
|
-
/** Ordinary assignment: writable, enumerable, configurable. */
|
|
25
|
-
export declare const data: Attributes;
|
|
26
|
-
/** Built-in methods and `constructor`: writable and configurable but hidden from enumeration. */
|
|
27
|
-
export declare const hidden: Attributes;
|
|
28
|
-
/** Function `name` and `length`: read-only but deletable. */
|
|
29
|
-
export declare const readonly: Attributes;
|
|
30
|
-
/** Constants such as `Math.PI` and a constructor's `prototype`. */
|
|
31
|
-
export declare const frozen: Attributes;
|
|
2
|
+
import { type Binding } from "./model.js";
|
|
32
3
|
/** An object owned by the program: own properties plus a prototype link. */
|
|
33
4
|
export declare class ProgramObject {
|
|
34
5
|
proto: ProgramObject | null;
|
|
35
|
-
readonly props: Map<
|
|
36
|
-
constructor(proto
|
|
6
|
+
readonly props: Map<PropertyKey, unknown>;
|
|
7
|
+
constructor(proto?: ProgramObject | null);
|
|
37
8
|
}
|
|
38
9
|
export declare class ProgramArray extends ProgramObject {
|
|
39
10
|
readonly items: Array<unknown>;
|
|
40
|
-
constructor(
|
|
11
|
+
constructor(items?: Array<unknown>);
|
|
41
12
|
}
|
|
42
|
-
/** An object with the [[ErrorData]] slot: what `Error.prototype.toString` and the host boundary recognize as an error. */
|
|
43
13
|
export declare class ProgramError extends ProgramObject {
|
|
14
|
+
readonly errorName: string;
|
|
15
|
+
constructor(errorName: string);
|
|
44
16
|
}
|
|
45
|
-
export declare
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
export declare class ProgramFunction extends Callable {
|
|
17
|
+
export declare class ProgramFunction extends ProgramObject {
|
|
18
|
+
readonly name: string;
|
|
49
19
|
readonly parameters: ReadonlyArray<Pattern>;
|
|
50
20
|
readonly body: BlockStatement | Expression;
|
|
51
21
|
readonly capturedScopes: ReadonlyArray<Map<string, Binding>>;
|
|
52
22
|
readonly async: boolean;
|
|
53
23
|
readonly generator: boolean;
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
export type NativeCall<R> = (thisValue: unknown, args: Array<unknown>, node: AstNode) => Effect.Effect<unknown, unknown, R>;
|
|
57
|
-
export type NativeConstruct<R> = (args: Array<unknown>, newTarget: Callable, node: AstNode) => Effect.Effect<unknown, unknown, R>;
|
|
58
|
-
export type NativeOptions<R> = {
|
|
59
|
-
readonly name: string;
|
|
60
|
-
readonly length?: number;
|
|
61
|
-
readonly call: NativeCall<R>;
|
|
62
|
-
/** `new name(...)`; without it the function is not a constructor. */
|
|
63
|
-
readonly construct?: NativeConstruct<R>;
|
|
64
|
-
/** Whether callback sites (array methods, replacers, promise reactions) admit this function. Defaults to true. */
|
|
65
|
-
readonly callback?: boolean;
|
|
66
|
-
};
|
|
67
|
-
export declare class NativeFunction<R = never> extends Callable {
|
|
68
|
-
readonly call: NativeCall<R>;
|
|
69
|
-
readonly construct: NativeConstruct<R> | undefined;
|
|
70
|
-
readonly callback: boolean;
|
|
71
|
-
constructor(proto: ProgramObject, options: NativeOptions<R>);
|
|
72
|
-
}
|
|
73
|
-
export declare class ProgramPromise extends ProgramObject {
|
|
74
|
-
readonly fiber: Fiber.Fiber<unknown, unknown>;
|
|
75
|
-
constructor(proto: ProgramObject, fiber: Fiber.Fiber<unknown, unknown>);
|
|
76
|
-
}
|
|
77
|
-
export declare class ProgramGenerator extends ProgramObject {
|
|
78
|
-
readonly asynchronous: boolean;
|
|
79
|
-
readonly request: (kind: GeneratorRequestKind, value: unknown, node: AstNode) => Effect.Effect<unknown, unknown, unknown>;
|
|
80
|
-
constructor(proto: ProgramObject, asynchronous: boolean, request: (kind: GeneratorRequestKind, value: unknown, node: AstNode) => Effect.Effect<unknown, unknown, unknown>);
|
|
81
|
-
}
|
|
82
|
-
export declare class ProgramDate extends ProgramObject {
|
|
83
|
-
time: number;
|
|
84
|
-
constructor(proto: ProgramObject, time: number);
|
|
85
|
-
}
|
|
86
|
-
export declare class ProgramRegExp extends ProgramObject {
|
|
87
|
-
readonly regex: RegExp;
|
|
88
|
-
constructor(proto: ProgramObject, pattern: string, flags: string);
|
|
89
|
-
}
|
|
90
|
-
export declare class ProgramMap extends ProgramObject {
|
|
91
|
-
readonly map: Map<unknown, unknown>;
|
|
92
|
-
}
|
|
93
|
-
export declare class ProgramSet extends ProgramObject {
|
|
94
|
-
readonly set: Set<unknown>;
|
|
95
|
-
}
|
|
96
|
-
export declare class ProgramURLSearchParams extends ProgramObject {
|
|
97
|
-
readonly params: URLSearchParams;
|
|
98
|
-
constructor(proto: ProgramObject, params: URLSearchParams);
|
|
99
|
-
}
|
|
100
|
-
export declare class ProgramURL extends ProgramObject {
|
|
101
|
-
readonly url: URL;
|
|
102
|
-
readonly searchParams: ProgramURLSearchParams;
|
|
103
|
-
constructor(proto: ProgramObject, searchParamsProto: ProgramObject, url: URL);
|
|
24
|
+
readonly length: number;
|
|
25
|
+
constructor(name: string, parameters: ReadonlyArray<Pattern>, body: BlockStatement | Expression, capturedScopes: ReadonlyArray<Map<string, Binding>>, async: boolean, generator: boolean);
|
|
104
26
|
}
|
|
105
|
-
/** Built-in objects that wrap a host value; data-like, but never plain data. */
|
|
106
|
-
export declare const isWrapper: (value: unknown) => value is ProgramDate | ProgramRegExp | ProgramMap | ProgramSet | ProgramURL | ProgramURLSearchParams;
|
|
107
27
|
export declare const parseArrayIndex: (key: string | number) => number | undefined;
|
|
108
|
-
/** The own property under `key`, including an array's live indexes and `length`. */
|
|
109
|
-
export declare const own: (target: ProgramObject, key: PropertyKey) => Slot | undefined;
|
|
110
28
|
export declare const hasOwn: (target: ProgramObject, key: PropertyKey) => boolean;
|
|
111
29
|
export declare const getOwn: (target: ProgramObject, key: PropertyKey) => unknown;
|
|
112
|
-
|
|
113
|
-
export declare const get: (target: ProgramObject, key: PropertyKey, receiver?: unknown) => unknown;
|
|
30
|
+
export declare const get: (target: ProgramObject, key: PropertyKey) => unknown;
|
|
114
31
|
export declare const has: (target: ProgramObject, key: PropertyKey) => boolean;
|
|
115
|
-
export declare const hasPrototype: (value: unknown, proto: ProgramObject) => boolean;
|
|
116
|
-
/** [[Set]]: an inherited setter or read-only property decides before an own data property is created. */
|
|
117
32
|
export declare const set: (target: ProgramObject, key: PropertyKey, value: unknown) => boolean;
|
|
118
|
-
/** [[DefineOwnProperty]] for a data property, ignoring the chain. */
|
|
119
|
-
export declare const define: (target: ProgramObject, key: PropertyKey, value: unknown, attrs?: Attributes) => void;
|
|
120
|
-
export declare const defineAccessor: (target: ProgramObject, key: PropertyKey, get: Getter, set?: Setter) => void;
|
|
121
33
|
export declare const remove: (target: ProgramObject, key: PropertyKey) => boolean;
|
|
122
34
|
export declare const ownKeys: (target: ProgramObject) => Array<string | symbol>;
|
|
123
|
-
|
|
124
|
-
export declare const
|
|
125
|
-
/** Own enumerable string keys: `Object.keys`. */
|
|
126
|
-
export declare const keys: (target: ProgramObject) => Array<string>;
|
|
127
|
-
/** Own enumerable string entries: `Object.entries` and serialization. */
|
|
128
|
-
export declare const entries: (target: ProgramObject) => Array<[string, unknown]>;
|
|
129
|
-
export declare const record: (proto: ProgramObject, fields: Record<string, unknown>) => ProgramObject;
|
|
35
|
+
export declare const ownEntries: (target: ProgramObject) => Array<[string, unknown]>;
|
|
36
|
+
export declare const record: (entries: Record<string, unknown>) => ProgramObject;
|
|
130
37
|
export declare const assign: (target: ProgramObject, source: ProgramObject, skip?: ReadonlySet<PropertyKey>) => void;
|
|
@@ -1,124 +1,46 @@
|
|
|
1
1
|
import { AsyncIteratorSymbol, IteratorSymbol } from "./model.js";
|
|
2
|
-
/** Ordinary assignment: writable, enumerable, configurable. */
|
|
3
|
-
export const data = { writable: true, enumerable: true, configurable: true };
|
|
4
|
-
/** Built-in methods and `constructor`: writable and configurable but hidden from enumeration. */
|
|
5
|
-
export const hidden = { writable: true, enumerable: false, configurable: true };
|
|
6
|
-
/** Function `name` and `length`: read-only but deletable. */
|
|
7
|
-
export const readonly = { writable: false, enumerable: false, configurable: true };
|
|
8
|
-
/** Constants such as `Math.PI` and a constructor's `prototype`. */
|
|
9
|
-
export const frozen = { writable: false, enumerable: false, configurable: false };
|
|
10
2
|
/** An object owned by the program: own properties plus a prototype link. */
|
|
11
3
|
export class ProgramObject {
|
|
12
4
|
proto;
|
|
13
5
|
props = new Map();
|
|
14
|
-
constructor(proto) {
|
|
6
|
+
constructor(proto = null) {
|
|
15
7
|
this.proto = proto;
|
|
16
8
|
}
|
|
17
9
|
}
|
|
18
10
|
export class ProgramArray extends ProgramObject {
|
|
19
11
|
items;
|
|
20
|
-
constructor(
|
|
21
|
-
super(
|
|
12
|
+
constructor(items = []) {
|
|
13
|
+
super();
|
|
22
14
|
this.items = items;
|
|
23
15
|
}
|
|
24
16
|
}
|
|
25
|
-
/** An object with the [[ErrorData]] slot: what `Error.prototype.toString` and the host boundary recognize as an error. */
|
|
26
17
|
export class ProgramError extends ProgramObject {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
define(this, "length", length, readonly);
|
|
32
|
-
define(this, "name", name, readonly);
|
|
18
|
+
errorName;
|
|
19
|
+
constructor(errorName) {
|
|
20
|
+
super();
|
|
21
|
+
this.errorName = errorName;
|
|
33
22
|
}
|
|
34
23
|
}
|
|
35
|
-
export class ProgramFunction extends
|
|
24
|
+
export class ProgramFunction extends ProgramObject {
|
|
25
|
+
name;
|
|
36
26
|
parameters;
|
|
37
27
|
body;
|
|
38
28
|
capturedScopes;
|
|
39
29
|
async;
|
|
40
30
|
generator;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
super(
|
|
31
|
+
length;
|
|
32
|
+
constructor(name, parameters, body, capturedScopes, async, generator) {
|
|
33
|
+
super();
|
|
34
|
+
this.name = name;
|
|
44
35
|
this.parameters = parameters;
|
|
45
36
|
this.body = body;
|
|
46
37
|
this.capturedScopes = capturedScopes;
|
|
47
38
|
this.async = async;
|
|
48
39
|
this.generator = generator;
|
|
40
|
+
const optional = parameters.findIndex((p) => p.type === "AssignmentPattern" || p.type === "RestElement");
|
|
41
|
+
this.length = optional === -1 ? parameters.length : optional;
|
|
49
42
|
}
|
|
50
43
|
}
|
|
51
|
-
export class NativeFunction extends Callable {
|
|
52
|
-
call;
|
|
53
|
-
construct;
|
|
54
|
-
callback;
|
|
55
|
-
constructor(proto, options) {
|
|
56
|
-
super(proto, options.name, options.length ?? 0);
|
|
57
|
-
this.call = options.call;
|
|
58
|
-
this.construct = options.construct;
|
|
59
|
-
this.callback = options.callback ?? true;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
export class ProgramPromise extends ProgramObject {
|
|
63
|
-
fiber;
|
|
64
|
-
constructor(proto, fiber) {
|
|
65
|
-
super(proto);
|
|
66
|
-
this.fiber = fiber;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
export class ProgramGenerator extends ProgramObject {
|
|
70
|
-
asynchronous;
|
|
71
|
-
request;
|
|
72
|
-
constructor(proto, asynchronous, request) {
|
|
73
|
-
super(proto);
|
|
74
|
-
this.asynchronous = asynchronous;
|
|
75
|
-
this.request = request;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
export class ProgramDate extends ProgramObject {
|
|
79
|
-
time;
|
|
80
|
-
constructor(proto, time) {
|
|
81
|
-
super(proto);
|
|
82
|
-
this.time = time;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
export class ProgramRegExp extends ProgramObject {
|
|
86
|
-
regex;
|
|
87
|
-
constructor(proto, pattern, flags) {
|
|
88
|
-
super(proto);
|
|
89
|
-
this.regex = new RegExp(pattern, flags);
|
|
90
|
-
define(this, "lastIndex", 0, { writable: true, enumerable: false, configurable: false });
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
export class ProgramMap extends ProgramObject {
|
|
94
|
-
map = new Map();
|
|
95
|
-
}
|
|
96
|
-
export class ProgramSet extends ProgramObject {
|
|
97
|
-
set = new Set();
|
|
98
|
-
}
|
|
99
|
-
export class ProgramURLSearchParams extends ProgramObject {
|
|
100
|
-
params;
|
|
101
|
-
constructor(proto, params) {
|
|
102
|
-
super(proto);
|
|
103
|
-
this.params = params;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
export class ProgramURL extends ProgramObject {
|
|
107
|
-
url;
|
|
108
|
-
searchParams;
|
|
109
|
-
constructor(proto, searchParamsProto, url) {
|
|
110
|
-
super(proto);
|
|
111
|
-
this.url = url;
|
|
112
|
-
this.searchParams = new ProgramURLSearchParams(searchParamsProto, url.searchParams);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
/** Built-in objects that wrap a host value; data-like, but never plain data. */
|
|
116
|
-
export const isWrapper = (value) => value instanceof ProgramDate ||
|
|
117
|
-
value instanceof ProgramRegExp ||
|
|
118
|
-
value instanceof ProgramMap ||
|
|
119
|
-
value instanceof ProgramSet ||
|
|
120
|
-
value instanceof ProgramURL ||
|
|
121
|
-
value instanceof ProgramURLSearchParams;
|
|
122
44
|
const MAX_ARRAY_LENGTH = 4_294_967_295;
|
|
123
45
|
export const parseArrayIndex = (key) => {
|
|
124
46
|
const property = String(key);
|
|
@@ -129,119 +51,72 @@ export const parseArrayIndex = (key) => {
|
|
|
129
51
|
};
|
|
130
52
|
const canonical = (key) => (typeof key === "symbol" ? key : String(key));
|
|
131
53
|
const index = (target, key) => target instanceof ProgramArray && typeof key === "string" ? parseArrayIndex(key) : undefined;
|
|
132
|
-
|
|
133
|
-
|
|
54
|
+
// Non-enumerable built-in properties: array length, function name and length.
|
|
55
|
+
const builtin = (target, name) => (name === "length" && target instanceof ProgramArray) ||
|
|
56
|
+
((name === "name" || name === "length") && target instanceof ProgramFunction);
|
|
57
|
+
export const hasOwn = (target, key) => {
|
|
134
58
|
const name = canonical(key);
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
}
|
|
140
|
-
if (name === "length")
|
|
141
|
-
return { value: target.items.length, writable: true, enumerable: false, configurable: false };
|
|
142
|
-
}
|
|
143
|
-
return target.props.get(name);
|
|
59
|
+
const at = index(target, name);
|
|
60
|
+
if (at !== undefined)
|
|
61
|
+
return at in target.items;
|
|
62
|
+
return builtin(target, name) || target.props.has(name);
|
|
144
63
|
};
|
|
145
|
-
const read = (slot, receiver) => "value" in slot ? slot.value : slot.get === undefined ? undefined : slot.get(receiver);
|
|
146
|
-
export const hasOwn = (target, key) => own(target, key) !== undefined;
|
|
147
64
|
export const getOwn = (target, key) => {
|
|
148
|
-
const
|
|
149
|
-
|
|
65
|
+
const name = canonical(key);
|
|
66
|
+
const at = index(target, name);
|
|
67
|
+
if (at !== undefined)
|
|
68
|
+
return target.items[at];
|
|
69
|
+
if (target instanceof ProgramArray && name === "length")
|
|
70
|
+
return target.items.length;
|
|
71
|
+
if (target instanceof ProgramFunction && name === "name")
|
|
72
|
+
return target.name;
|
|
73
|
+
if (target instanceof ProgramFunction && name === "length")
|
|
74
|
+
return target.length;
|
|
75
|
+
return target.props.get(name);
|
|
150
76
|
};
|
|
151
|
-
|
|
152
|
-
export const get = (target, key, receiver = target) => {
|
|
77
|
+
export const get = (target, key) => {
|
|
153
78
|
for (let current = target; current !== null; current = current.proto) {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
return read(slot, receiver);
|
|
79
|
+
if (hasOwn(current, key))
|
|
80
|
+
return getOwn(current, key);
|
|
157
81
|
}
|
|
158
82
|
return undefined;
|
|
159
83
|
};
|
|
160
84
|
export const has = (target, key) => {
|
|
161
85
|
for (let current = target; current !== null; current = current.proto) {
|
|
162
|
-
if (
|
|
86
|
+
if (hasOwn(current, key))
|
|
163
87
|
return true;
|
|
164
88
|
}
|
|
165
89
|
return false;
|
|
166
90
|
};
|
|
167
|
-
export const
|
|
168
|
-
|
|
169
|
-
if (current === proto)
|
|
170
|
-
return true;
|
|
171
|
-
}
|
|
172
|
-
return false;
|
|
173
|
-
};
|
|
174
|
-
const writeArray = (target, name, value) => {
|
|
91
|
+
export const set = (target, key, value) => {
|
|
92
|
+
const name = canonical(key);
|
|
175
93
|
const at = index(target, name);
|
|
176
94
|
if (at !== undefined) {
|
|
95
|
+
;
|
|
177
96
|
target.items[at] = value;
|
|
178
97
|
return true;
|
|
179
98
|
}
|
|
180
|
-
if (name
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
if (!Number.isInteger(length) || length < 0 || length > MAX_ARRAY_LENGTH)
|
|
184
|
-
return false;
|
|
185
|
-
target.items.length = length;
|
|
186
|
-
return true;
|
|
187
|
-
};
|
|
188
|
-
/** [[Set]]: an inherited setter or read-only property decides before an own data property is created. */
|
|
189
|
-
export const set = (target, key, value) => {
|
|
190
|
-
const name = canonical(key);
|
|
191
|
-
for (let current = target; current !== null; current = current.proto) {
|
|
192
|
-
const slot = own(current, name);
|
|
193
|
-
if (slot === undefined)
|
|
194
|
-
continue;
|
|
195
|
-
if (!("value" in slot)) {
|
|
196
|
-
if (slot.set === undefined)
|
|
197
|
-
return false;
|
|
198
|
-
slot.set(target, value);
|
|
199
|
-
return true;
|
|
200
|
-
}
|
|
201
|
-
if (!slot.writable)
|
|
99
|
+
if (name === "length" && target instanceof ProgramArray) {
|
|
100
|
+
const length = typeof value === "number" ? value : Number(value);
|
|
101
|
+
if (!Number.isInteger(length) || length < 0 || length > 4_294_967_295)
|
|
202
102
|
return false;
|
|
203
|
-
|
|
204
|
-
break;
|
|
205
|
-
if (target instanceof ProgramArray) {
|
|
206
|
-
const written = writeArray(target, name, value);
|
|
207
|
-
if (written !== undefined)
|
|
208
|
-
return written;
|
|
209
|
-
}
|
|
210
|
-
slot.value = value;
|
|
103
|
+
target.items.length = length;
|
|
211
104
|
return true;
|
|
212
105
|
}
|
|
213
|
-
if (target
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
return written;
|
|
217
|
-
}
|
|
218
|
-
target.props.set(name, { value, ...data });
|
|
106
|
+
if (builtin(target, name))
|
|
107
|
+
return false;
|
|
108
|
+
target.props.set(name, value);
|
|
219
109
|
return true;
|
|
220
110
|
};
|
|
221
|
-
/** [[DefineOwnProperty]] for a data property, ignoring the chain. */
|
|
222
|
-
export const define = (target, key, value, attrs = data) => {
|
|
223
|
-
const name = canonical(key);
|
|
224
|
-
if (target instanceof ProgramArray && writeArray(target, name, value) !== undefined)
|
|
225
|
-
return;
|
|
226
|
-
target.props.set(name, { value, ...attrs });
|
|
227
|
-
};
|
|
228
|
-
export const defineAccessor = (target, key, get, set) => {
|
|
229
|
-
target.props.set(canonical(key), { get, set, enumerable: false, configurable: true });
|
|
230
|
-
};
|
|
231
111
|
export const remove = (target, key) => {
|
|
232
112
|
const name = canonical(key);
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
if (name === "length")
|
|
238
|
-
return false;
|
|
239
|
-
}
|
|
240
|
-
const slot = target.props.get(name);
|
|
241
|
-
if (slot === undefined)
|
|
242
|
-
return true;
|
|
243
|
-
if (!slot.configurable)
|
|
113
|
+
const at = index(target, name);
|
|
114
|
+
if (at !== undefined)
|
|
115
|
+
return delete target.items[at];
|
|
116
|
+
if (name === "length" && target instanceof ProgramArray)
|
|
244
117
|
return false;
|
|
118
|
+
if (builtin(target, name))
|
|
119
|
+
return true;
|
|
245
120
|
target.props.delete(name);
|
|
246
121
|
return true;
|
|
247
122
|
};
|
|
@@ -250,29 +125,27 @@ export const ownKeys = (target) => {
|
|
|
250
125
|
const strings = [...target.props.keys()].filter((key) => typeof key === "string");
|
|
251
126
|
const symbols = [...target.props.keys()].filter((key) => typeof key === "symbol");
|
|
252
127
|
return [
|
|
253
|
-
...(target instanceof ProgramArray ?
|
|
128
|
+
...(target instanceof ProgramArray ? Object.keys(target.items) : []),
|
|
254
129
|
...strings.filter((key) => parseArrayIndex(key) !== undefined).sort((a, b) => Number(a) - Number(b)),
|
|
255
130
|
...strings.filter((key) => parseArrayIndex(key) === undefined),
|
|
256
131
|
...symbols,
|
|
257
132
|
];
|
|
258
133
|
};
|
|
259
|
-
const
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
export const record = (proto, fields) => {
|
|
267
|
-
const target = new ProgramObject(proto);
|
|
268
|
-
for (const [key, value] of Object.entries(fields))
|
|
269
|
-
define(target, key, value);
|
|
134
|
+
export const ownEntries = (target) => ownKeys(target)
|
|
135
|
+
.filter((key) => typeof key === "string")
|
|
136
|
+
.map((key) => [key, getOwn(target, key)]);
|
|
137
|
+
export const record = (entries) => {
|
|
138
|
+
const target = new ProgramObject();
|
|
139
|
+
for (const [key, value] of Object.entries(entries))
|
|
140
|
+
set(target, key, value);
|
|
270
141
|
return target;
|
|
271
142
|
};
|
|
272
143
|
export const assign = (target, source, skip) => {
|
|
273
|
-
for (const key of
|
|
144
|
+
for (const key of ownKeys(source)) {
|
|
274
145
|
if (skip?.has(key))
|
|
275
146
|
continue;
|
|
147
|
+
if (typeof key === "symbol" && key !== IteratorSymbol && key !== AsyncIteratorSymbol)
|
|
148
|
+
continue;
|
|
276
149
|
set(target, key, getOwn(source, key));
|
|
277
150
|
}
|
|
278
151
|
};
|