@opencode/codemode 0.0.0-beta-19296 → 0.0.0-beta-19378

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.
Files changed (60) hide show
  1. package/README.md +6 -0
  2. package/dist/codemode.d.ts +8 -11
  3. package/dist/codemode.js +4 -8
  4. package/dist/data.d.ts +28 -0
  5. package/dist/data.js +130 -0
  6. package/dist/index.d.ts +1 -0
  7. package/dist/index.js +1 -0
  8. package/dist/interpreter/errors.d.ts +4 -6
  9. package/dist/interpreter/errors.js +22 -6
  10. package/dist/interpreter/execute.d.ts +3 -3
  11. package/dist/interpreter/execute.js +11 -18
  12. package/dist/interpreter/globals.d.ts +13 -0
  13. package/dist/interpreter/globals.js +59 -0
  14. package/dist/interpreter/host.d.ts +41 -0
  15. package/dist/interpreter/host.js +44 -0
  16. package/dist/interpreter/methods.d.ts +3 -16
  17. package/dist/interpreter/methods.js +42 -239
  18. package/dist/interpreter/model.d.ts +12 -73
  19. package/dist/interpreter/model.js +0 -87
  20. package/dist/interpreter/promises.d.ts +12 -13
  21. package/dist/interpreter/promises.js +49 -26
  22. package/dist/interpreter/references.js +23 -70
  23. package/dist/interpreter/runner.d.ts +23 -0
  24. package/dist/interpreter/runner.js +42 -0
  25. package/dist/interpreter/runtime.d.ts +13 -95
  26. package/dist/interpreter/runtime.js +290 -723
  27. package/dist/openapi/spec.js +1 -1
  28. package/dist/stdlib/array.d.ts +3 -0
  29. package/dist/stdlib/array.js +73 -0
  30. package/dist/stdlib/collections.d.ts +6 -1
  31. package/dist/stdlib/collections.js +120 -1
  32. package/dist/stdlib/console.d.ts +3 -2
  33. package/dist/stdlib/console.js +25 -16
  34. package/dist/stdlib/date.d.ts +5 -4
  35. package/dist/stdlib/date.js +28 -12
  36. package/dist/stdlib/json.d.ts +4 -4
  37. package/dist/stdlib/json.js +23 -28
  38. package/dist/stdlib/math.d.ts +3 -7
  39. package/dist/stdlib/math.js +85 -153
  40. package/dist/stdlib/number.d.ts +2 -4
  41. package/dist/stdlib/number.js +30 -37
  42. package/dist/stdlib/object.d.ts +4 -6
  43. package/dist/stdlib/object.js +106 -75
  44. package/dist/stdlib/regexp.d.ts +4 -6
  45. package/dist/stdlib/regexp.js +35 -12
  46. package/dist/stdlib/string.d.ts +1 -3
  47. package/dist/stdlib/string.js +15 -17
  48. package/dist/stdlib/url.d.ts +10 -6
  49. package/dist/stdlib/url.js +102 -25
  50. package/dist/stdlib/value.d.ts +6 -5
  51. package/dist/stdlib/value.js +33 -32
  52. package/dist/tool-runtime.d.ts +16 -15
  53. package/dist/tool-runtime.js +13 -150
  54. package/dist/values.d.ts +22 -16
  55. package/dist/values.js +23 -17
  56. package/package.json +1 -1
  57. package/dist/interpreter/iterator.d.ts +0 -13
  58. package/dist/interpreter/iterator.js +0 -4
  59. package/dist/stdlib/promise.d.ts +0 -2
  60. package/dist/stdlib/promise.js +0 -1
@@ -1,35 +1,23 @@
1
1
  import { Cause, Deferred, Effect, Exit } from "effect";
2
- import { isBlockedMember, ToolReference, ToolRuntimeError } from "../tool-runtime.js";
3
- import { AsyncIteratorSymbol, asNode, CodeModeFunction, CodeModeGenerator, CoercionFunction, ComputedValue, ErrorConstructorReference, GlobalMethodReference, GlobalNamespace, GeneratorMethodReference, GeneratorReturn, getArray, getBoolean, getNode, getOptionalNode, getString, IntrinsicReference, InterpreterRuntimeError, isRecord, IteratorSymbol, IteratorSymbols, JsonMethodReference, OptionalShortCircuit, PromiseCapabilityFunction, PromiseInstanceMethodReference, PromiseMethodReference, PromiseNamespace, ProgramThrow, SearchFunction, SymbolNamespace, unsupportedSyntax, UriFunction, } from "./model.js";
4
- import { caughtErrorValue, constructAggregateErrorValue, constructErrorValue } from "./errors.js";
5
- import { arrayStatics, invokeArrayFrom, invokeGlobalMethod, invokeGroupBy, invokeIntrinsic, } from "./methods.js";
6
- import { preserveConsumerError } from "./iterator.js";
7
- import { constructPromise, invokePromiseInstanceMethod, invokePromiseMethod, PromiseRuntime, resolvePromise, resolvePromiseValue, } from "./promises.js";
2
+ import { isBlockedMember, ToolRuntimeError, toProgram } from "../data.js";
3
+ import { ToolReference } from "../tool-runtime.js";
4
+ import { AsyncIteratorSymbol, CodeModeFunction, CodeModeGenerator, ComputedValue, GeneratorMethodReference, GeneratorReturn, IntrinsicReference, InterpreterRuntimeError, isRecord, IteratorSymbol, IteratorSymbols, OptionalShortCircuit, PromiseInstanceMethodReference, ProgramThrow, unsupportedSyntax, } from "./model.js";
5
+ import { caughtErrorValue } from "./errors.js";
6
+ import { globals } from "./globals.js";
7
+ import { HostFunction, HostNamespace } from "./host.js";
8
+ import { invokeIntrinsic } from "./methods.js";
9
+ import { preserveConsumerError } from "./runner.js";
10
+ import { invokePromiseInstanceMethod, PromiseRuntime, resolvePromise, resolvePromiseValue } from "./promises.js";
8
11
  import { containsOpaqueReference, isRuntimeReference, rejectCircularInsertion, typeofValue } from "./references.js";
9
12
  import { ScopeStack } from "./scope.js";
10
- import { arrayMethods, mapMethods, mapStatics, setMethods } from "../stdlib/collections.js";
11
- import { consoleMethods, formatConsoleMessage } from "../stdlib/console.js";
12
- import { dateMethods, dateStatics } from "../stdlib/date.js";
13
- import { invokeJsonMethod, jsonStatics } from "../stdlib/json.js";
14
- import { invokeMathSumPrecise, mathConstants, mathMethods } from "../stdlib/math.js";
15
- import { numberConstants, numberMethods, numberStatics } from "../stdlib/number.js";
16
- import { invokeObjectFromEntries, objectMethodsPreservingIdentity, objectStatics } from "../stdlib/object.js";
17
- import { promiseStatics } from "../stdlib/promise.js";
18
- import { escapeRegexHint, regexpMethods, regexpProperties, regexpStatics, regexFailureReason, } from "../stdlib/regexp.js";
19
- import { stringMethods, stringStatics } from "../stdlib/string.js";
20
- import { urlMethods, urlProperties, urlSearchParamsMethods, urlStatics, urlWritableProperties, invokeUriFunction, uriArgument, urlArgument, } from "../stdlib/url.js";
21
- import { boundedData, coerceToNumber, coerceToString, compoundOperators, errorBrandName, errorConstructors, invokeCoercion, valueConstructors, } from "../stdlib/value.js";
22
- import { isCodeModeValue, CodeModeDate, CodeModeMap, CodeModePromise, CodeModeRegExp, CodeModeSet, CodeModeURL, CodeModeURLSearchParams, } from "../values.js";
23
- const globalStaticMembers = {
24
- Object: objectStatics,
25
- Math: mathMethods,
26
- Array: arrayStatics,
27
- console: consoleMethods,
28
- Date: dateStatics,
29
- RegExp: regexpStatics,
30
- Map: mapStatics,
31
- URL: urlStatics,
32
- };
13
+ import { arrayMethods, mapMethods, setMethods } from "../stdlib/collections.js";
14
+ import { dateMethods } from "../stdlib/date.js";
15
+ import { numberMethods } from "../stdlib/number.js";
16
+ import { constructRegExp, regexpMethods, regexpProperties } from "../stdlib/regexp.js";
17
+ import { stringMethods } from "../stdlib/string.js";
18
+ import { uriArgument, urlMethods, urlProperties, urlSearchParamsMethods, urlWritableProperties } from "../stdlib/url.js";
19
+ import { coerceToNumber, coerceToString, compoundOperators } from "../stdlib/value.js";
20
+ import { Values } from "../values.js";
33
21
  const MAX_ARRAY_LENGTH = 4_294_967_295;
34
22
  const parseArrayIndex = (key) => {
35
23
  const property = String(key);
@@ -39,74 +27,46 @@ const parseArrayIndex = (key) => {
39
27
  return index < MAX_ARRAY_LENGTH ? index : undefined;
40
28
  };
41
29
  const calleeDescription = (callee) => {
42
- if (callee.type === "Identifier")
43
- return getString(callee, "name");
44
- if (callee.type === "MemberExpression") {
45
- const object = getNode(callee, "object");
46
- const property = getNode(callee, "property");
47
- const key = callee.computed !== true && property.type === "Identifier"
48
- ? getString(property, "name")
30
+ if (callee?.type === "Identifier")
31
+ return callee.name;
32
+ if (callee?.type === "MemberExpression") {
33
+ const object = callee.object;
34
+ const property = callee.property;
35
+ const key = !callee.computed && property.type === "Identifier"
36
+ ? property.name
49
37
  : property.type === "Literal" && typeof property.value === "string"
50
38
  ? property.value
51
39
  : undefined;
52
40
  if (object.type === "Identifier" && key !== undefined)
53
- return `${getString(object, "name")}.${key}`;
41
+ return `${object.name}.${key}`;
54
42
  }
55
43
  return "The called value";
56
44
  };
57
45
  const instanceofValue = (lhs, rhs, node) => {
58
- if (rhs instanceof ErrorConstructorReference) {
59
- const brand = errorBrandName(lhs);
60
- return brand !== undefined && (rhs.name === "Error" || brand === rhs.name);
61
- }
62
- if (rhs instanceof GlobalNamespace) {
63
- switch (rhs.name) {
64
- case "Date":
65
- return lhs instanceof CodeModeDate;
66
- case "RegExp":
67
- return lhs instanceof CodeModeRegExp;
68
- case "Map":
69
- return lhs instanceof CodeModeMap;
70
- case "Set":
71
- return lhs instanceof CodeModeSet;
72
- case "URL":
73
- return lhs instanceof CodeModeURL;
74
- case "URLSearchParams":
75
- return lhs instanceof CodeModeURLSearchParams;
76
- case "Array":
77
- return Array.isArray(lhs);
78
- case "Object":
79
- return lhs !== null && (typeof lhs === "object" || typeofValue(lhs) === "function");
80
- }
81
- }
82
- if (rhs instanceof PromiseNamespace)
83
- return lhs instanceof CodeModePromise;
84
- if (rhs instanceof CoercionFunction && (rhs.name === "Number" || rhs.name === "String" || rhs.name === "Boolean")) {
85
- return false;
86
- }
46
+ if (rhs instanceof HostFunction && rhs.instanceOf !== undefined)
47
+ return rhs.instanceOf(lhs);
87
48
  throw new InterpreterRuntimeError("The right-hand side of 'instanceof' must be a supported constructor: Error (or a specific error type like TypeError), Date, RegExp, Map, Set, URL, URLSearchParams, Array, Object, or Promise.", node);
88
49
  };
89
50
  const collectPatternNames = (pattern, out = []) => {
90
51
  switch (pattern.type) {
91
52
  case "Identifier":
92
- out.push(getString(pattern, "name"));
53
+ out.push(pattern.name);
93
54
  break;
94
55
  case "AssignmentPattern":
95
- collectPatternNames(getNode(pattern, "left"), out);
56
+ collectPatternNames(pattern.left, out);
96
57
  break;
97
58
  case "RestElement":
98
- collectPatternNames(getNode(pattern, "argument"), out);
59
+ collectPatternNames(pattern.argument, out);
99
60
  break;
100
61
  case "ArrayPattern":
101
- for (const element of getArray(pattern, "elements")) {
62
+ for (const element of pattern.elements) {
102
63
  if (element !== null)
103
- collectPatternNames(asNode(element, "elements"), out);
64
+ collectPatternNames(element, out);
104
65
  }
105
66
  break;
106
67
  case "ObjectPattern":
107
- for (const property of getArray(pattern, "properties")) {
108
- const prop = asNode(property, "properties");
109
- collectPatternNames(prop.type === "RestElement" ? getNode(prop, "argument") : getNode(prop, "value"), out);
68
+ for (const prop of pattern.properties) {
69
+ collectPatternNames(prop.type === "RestElement" ? prop.argument : prop.value, out);
110
70
  }
111
71
  break;
112
72
  }
@@ -115,23 +75,20 @@ const collectPatternNames = (pattern, out = []) => {
115
75
  const loopDeclaration = (left, statement) => {
116
76
  if (left.type !== "VariableDeclaration")
117
77
  return undefined;
118
- const declarations = getArray(left, "declarations");
119
- if (declarations.length !== 1) {
78
+ const declaration = left.declarations.length === 1 ? left.declarations[0] : undefined;
79
+ if (declaration === undefined) {
120
80
  throw new InterpreterRuntimeError(`${statement} supports one declared binding.`, left);
121
81
  }
122
- const kind = getString(left, "kind");
82
+ const kind = left.kind;
123
83
  return {
124
- pattern: getNode(asNode(declarations[0], "declarations[0]"), "id"),
84
+ pattern: declaration.id,
125
85
  mutable: kind !== "const",
126
86
  lexical: kind !== "var",
127
87
  };
128
88
  };
129
89
  const isOpaqueMemberReference = (value) => value instanceof ToolReference ||
130
- value instanceof PromiseMethodReference ||
131
90
  value instanceof PromiseInstanceMethodReference ||
132
91
  value instanceof IntrinsicReference ||
133
- value instanceof GlobalMethodReference ||
134
- value instanceof JsonMethodReference ||
135
92
  value instanceof GeneratorMethodReference;
136
93
  const copyIteratorSymbols = (source, target, consumed) => {
137
94
  for (const symbol of IteratorSymbols) {
@@ -139,62 +96,47 @@ const copyIteratorSymbols = (source, target, consumed) => {
139
96
  Reflect.set(target, symbol, Reflect.get(source, symbol));
140
97
  }
141
98
  };
142
- const promiseResolutionNode = { type: "PromiseResolution" };
143
- export class Interpreter {
144
- scopes;
99
+ const promiseResolutionNode = { type: "PromiseResolution", start: 0, end: 0 };
100
+ /** One program execution: the tool bridge, promise scheduler, captured logs, and the global scope built once. */
101
+ export class Runtime {
145
102
  executeTool;
146
- invokeSearch;
103
+ search;
147
104
  toolKeys;
148
- logs;
149
105
  promises;
150
- generatorState;
151
- generatorAsync = false;
152
- runner = {
153
- invokeFunction: (fn, args) => this.invokeFunction(fn, args),
154
- invokeCallable: (callable, args, node) => this.invokeCallable(callable, args, node),
155
- settlePromise: (promise) => this.settlePromise(promise),
156
- syncIterator: (value, node) => this.syncIterator(value, node),
157
- };
158
- constructor(executeTool, invokeSearch, toolKeys, promises, logs = []) {
159
- const globalScope = new Map();
160
- this.scopes = new ScopeStack([globalScope]);
106
+ logs;
107
+ runner;
108
+ root;
109
+ constructor(executeTool, search, toolKeys, promises, logs = []) {
161
110
  this.executeTool = executeTool;
162
- this.invokeSearch = invokeSearch;
111
+ this.search = search;
163
112
  this.toolKeys = toolKeys;
164
- this.logs = logs;
165
113
  this.promises = promises;
166
- globalScope.set("tools", { mutable: false, value: new ToolReference([]) });
167
- globalScope.set("search", { mutable: false, value: new SearchFunction() });
168
- globalScope.set("Promise", { mutable: false, value: new PromiseNamespace() });
169
- globalScope.set("Symbol", { mutable: false, value: new SymbolNamespace() });
170
- globalScope.set("undefined", { mutable: false, value: undefined });
171
- globalScope.set("Object", { mutable: false, value: new GlobalNamespace("Object") });
172
- globalScope.set("Math", { mutable: false, value: new GlobalNamespace("Math") });
173
- globalScope.set("JSON", { mutable: false, value: new GlobalNamespace("JSON") });
174
- globalScope.set("Number", { mutable: false, value: new CoercionFunction("Number") });
175
- globalScope.set("String", { mutable: false, value: new CoercionFunction("String") });
176
- globalScope.set("Boolean", { mutable: false, value: new CoercionFunction("Boolean") });
177
- globalScope.set("Array", { mutable: false, value: new GlobalNamespace("Array") });
178
- globalScope.set("console", { mutable: false, value: new GlobalNamespace("console") });
179
- globalScope.set("parseInt", { mutable: false, value: new CoercionFunction("parseInt") });
180
- globalScope.set("parseFloat", { mutable: false, value: new CoercionFunction("parseFloat") });
181
- globalScope.set("isFinite", { mutable: false, value: new CoercionFunction("isFinite") });
182
- globalScope.set("isNaN", { mutable: false, value: new CoercionFunction("isNaN") });
183
- globalScope.set("Date", { mutable: false, value: new GlobalNamespace("Date") });
184
- globalScope.set("RegExp", { mutable: false, value: new GlobalNamespace("RegExp") });
185
- globalScope.set("Map", { mutable: false, value: new GlobalNamespace("Map") });
186
- globalScope.set("Set", { mutable: false, value: new GlobalNamespace("Set") });
187
- globalScope.set("URL", { mutable: false, value: new GlobalNamespace("URL") });
188
- globalScope.set("URLSearchParams", { mutable: false, value: new GlobalNamespace("URLSearchParams") });
189
- globalScope.set("encodeURI", { mutable: false, value: new UriFunction("encodeURI") });
190
- globalScope.set("encodeURIComponent", { mutable: false, value: new UriFunction("encodeURIComponent") });
191
- globalScope.set("decodeURI", { mutable: false, value: new UriFunction("decodeURI") });
192
- globalScope.set("decodeURIComponent", { mutable: false, value: new UriFunction("decodeURIComponent") });
193
- for (const name of errorConstructors) {
194
- globalScope.set(name, { mutable: false, value: new ErrorConstructorReference(name) });
195
- }
196
- globalScope.set("NaN", { mutable: false, value: NaN });
197
- globalScope.set("Infinity", { mutable: false, value: Infinity });
114
+ this.logs = logs;
115
+ const globalScope = new Map();
116
+ // Calling back into the program never reads frame state, so any frame serves; the root is always alive.
117
+ this.root = new Frame(this, new ScopeStack([globalScope]));
118
+ this.runner = {
119
+ invokeFunction: (fn, args) => this.root.invokeFunction(fn, args),
120
+ invokeCallable: (callable, args, node) => this.root.invokeCallable(callable, args, node),
121
+ settlePromise: (promise) => this.root.settlePromise(promise),
122
+ syncIterator: (value, node) => this.root.syncIterator(value, node),
123
+ };
124
+ for (const [name, value] of globals(this))
125
+ globalScope.set(name, { mutable: false, value });
126
+ }
127
+ run(program) {
128
+ return this.root.run(program);
129
+ }
130
+ }
131
+ /** One activation: the top-level program or a single function call, evaluating against its own scope chain. */
132
+ class Frame {
133
+ runtime;
134
+ scopes;
135
+ generatorState;
136
+ generatorAsync = false;
137
+ constructor(runtime, scopes) {
138
+ this.runtime = runtime;
139
+ this.scopes = scopes;
198
140
  }
199
141
  run(program) {
200
142
  const self = this;
@@ -206,7 +148,7 @@ export class Interpreter {
206
148
  let value = undefined;
207
149
  for (const [index, statement] of program.body.entries()) {
208
150
  if (index === program.body.length - 1 && statement.type === "ExpressionStatement") {
209
- value = yield* self.evaluateExpression(getNode(statement, "expression"));
151
+ value = yield* self.evaluateExpression(statement.expression);
210
152
  break;
211
153
  }
212
154
  const result = yield* self.evaluateStatement(statement);
@@ -219,20 +161,20 @@ export class Interpreter {
219
161
  }
220
162
  }
221
163
  // The implicit async body adopts returned promises before copy-out.
222
- value = yield* resolvePromiseValue(self.runner, value, program);
164
+ value = yield* resolvePromiseValue(self.runtime.runner, value, program);
223
165
  return value;
224
166
  }).pipe(Effect.ensuring(Effect.sync(() => self.scopes.pop())));
225
167
  }
226
168
  // Fork at the call site so admission and hooks occur when the call is made.
227
169
  createToolCallPromise(path, args) {
228
- return this.createPromise(Effect.suspend(() => this.executeTool(path, args)));
170
+ return this.createPromise(Effect.suspend(() => this.runtime.executeTool(path, args)));
229
171
  }
230
172
  createPromise(effect) {
231
- return this.promises.create(effect);
173
+ return this.runtime.promises.create(effect);
232
174
  }
233
175
  // Fiber exits make settlement idempotent; yielding prevents inline continuation.
234
176
  settlePromise(promise) {
235
- const promises = this.promises;
177
+ const promises = this.runtime.promises;
236
178
  return Effect.suspend(() => {
237
179
  promises.markObserved(promise);
238
180
  return Effect.flatMap(promises.await(promise), (exit) => Effect.andThen(Effect.yieldNow, exit));
@@ -241,11 +183,11 @@ export class Interpreter {
241
183
  evaluateStatement(node) {
242
184
  switch (node.type) {
243
185
  case "ExpressionStatement":
244
- return Effect.as(this.evaluateExpression(getNode(node, "expression")), { kind: "none" });
186
+ return Effect.as(this.evaluateExpression(node.expression), { kind: "none" });
245
187
  case "VariableDeclaration":
246
188
  return Effect.map(this.evaluateVariableDeclaration(node), () => ({ kind: "none" }));
247
189
  case "ReturnStatement": {
248
- const argumentNode = getOptionalNode(node, "argument");
190
+ const argumentNode = node.argument;
249
191
  return argumentNode
250
192
  ? Effect.map(this.evaluateExpression(argumentNode), (value) => ({ kind: "return", value }))
251
193
  : Effect.succeed({ kind: "return", value: undefined });
@@ -288,11 +230,10 @@ export class Interpreter {
288
230
  this.scopes.push();
289
231
  const self = this;
290
232
  return Effect.gen(function* () {
291
- const body = getArray(node, "body");
233
+ const body = node.body;
292
234
  self.predeclareLexical(body);
293
235
  self.hoistFunctions(body);
294
- for (const statementValue of body) {
295
- const statement = asNode(statementValue, "body");
236
+ for (const statement of body) {
296
237
  const result = yield* self.evaluateStatement(statement);
297
238
  if (result.kind !== "none") {
298
239
  return result;
@@ -302,27 +243,24 @@ export class Interpreter {
302
243
  }).pipe(Effect.ensuring(Effect.sync(() => self.scopes.pop())));
303
244
  }
304
245
  createFunction(node) {
305
- return new CodeModeFunction(getArray(node, "params").map((parameter, index) => asNode(parameter, `params[${index}]`)), getNode(node, "body"), this.scopes.capture(), node.async === true, node.generator === true);
246
+ return new CodeModeFunction(node.params, node.body, this.scopes.capture(), node.async, node.generator);
306
247
  }
307
248
  hoistFunctions(statements) {
308
- for (const statementValue of statements) {
309
- if (!isRecord(statementValue) || statementValue.type !== "FunctionDeclaration")
249
+ for (const node of statements) {
250
+ if (node.type !== "FunctionDeclaration")
310
251
  continue;
311
- const node = statementValue;
312
- this.scopes.declare(getString(getNode(node, "id"), "name"), this.createFunction(node), true, node);
252
+ this.scopes.declare(node.id.name, this.createFunction(node), true, node);
313
253
  }
314
254
  }
315
255
  predeclareLexical(statements) {
316
- for (const statementValue of statements) {
317
- if (!isRecord(statementValue) || statementValue.type !== "VariableDeclaration")
256
+ for (const statement of statements) {
257
+ if (statement.type !== "VariableDeclaration")
318
258
  continue;
319
- const statement = statementValue;
320
- const kind = getString(statement, "kind");
259
+ const kind = statement.kind;
321
260
  if (kind === "var")
322
261
  continue;
323
- for (const declarationValue of getArray(statement, "declarations")) {
324
- const declaration = asNode(declarationValue, "declarations");
325
- for (const name of collectPatternNames(getNode(declaration, "id"))) {
262
+ for (const declaration of statement.declarations) {
263
+ for (const name of collectPatternNames(declaration.id)) {
326
264
  this.scopes.reserve(name, kind !== "const", declaration);
327
265
  }
328
266
  }
@@ -333,30 +271,27 @@ export class Interpreter {
333
271
  this.scopes.reserve(name, mutable, node);
334
272
  }
335
273
  evaluateIfStatement(node) {
336
- const testNode = getNode(node, "test");
337
- const consequentNode = getNode(node, "consequent");
338
- const alternateNode = getOptionalNode(node, "alternate");
339
- return Effect.flatMap(this.evaluateExpression(testNode), (test) => test
340
- ? this.evaluateStatement(consequentNode)
341
- : alternateNode
342
- ? this.evaluateStatement(alternateNode)
274
+ return Effect.flatMap(this.evaluateExpression(node.test), (test) => test
275
+ ? this.evaluateStatement(node.consequent)
276
+ : node.alternate
277
+ ? this.evaluateStatement(node.alternate)
343
278
  : Effect.succeed({ kind: "none" }));
344
279
  }
345
280
  evaluateSwitchStatement(node) {
346
281
  const self = this;
347
282
  return Effect.gen(function* () {
348
- const discriminant = yield* self.evaluateExpression(getNode(node, "discriminant"));
283
+ const discriminant = yield* self.evaluateExpression(node.discriminant);
349
284
  if (containsOpaqueReference(discriminant)) {
350
285
  throw new InterpreterRuntimeError("Switch discriminants must be data values.", node, "InvalidDataValue");
351
286
  }
352
287
  self.scopes.push();
353
288
  return yield* Effect.gen(function* () {
354
- const cases = getArray(node, "cases").map((value, index) => asNode(value, `cases[${index}]`));
355
- self.predeclareLexical(cases.flatMap((branch) => getArray(branch, "consequent")));
289
+ const cases = node.cases;
290
+ self.predeclareLexical(cases.flatMap((branch) => branch.consequent));
356
291
  let defaultIndex;
357
292
  let selected;
358
293
  for (const [index, branch] of cases.entries()) {
359
- const test = getOptionalNode(branch, "test");
294
+ const test = branch.test;
360
295
  if (!test) {
361
296
  defaultIndex = index;
362
297
  continue;
@@ -374,8 +309,8 @@ export class Interpreter {
374
309
  if (start === undefined)
375
310
  return { kind: "none" };
376
311
  for (let index = start; index < cases.length; index += 1) {
377
- for (const statementValue of getArray(cases[index], "consequent")) {
378
- const result = yield* self.evaluateStatement(asNode(statementValue, "consequent"));
312
+ for (const statement of cases[index].consequent) {
313
+ const result = yield* self.evaluateStatement(statement);
379
314
  if (result.kind === "break") {
380
315
  if (result.label === undefined)
381
316
  return { kind: "none" };
@@ -390,12 +325,10 @@ export class Interpreter {
390
325
  });
391
326
  }
392
327
  evaluateWhileStatement(node, labels) {
393
- const testNode = getNode(node, "test");
394
- const bodyNode = getNode(node, "body");
395
328
  const self = this;
396
329
  return Effect.gen(function* () {
397
- while (yield* self.evaluateExpression(testNode)) {
398
- const result = yield* self.evaluateStatement(bodyNode);
330
+ while (yield* self.evaluateExpression(node.test)) {
331
+ const result = yield* self.evaluateStatement(node.body);
399
332
  if (result.kind === "continue") {
400
333
  if (result.label !== undefined && !labels?.has(result.label))
401
334
  return result;
@@ -414,12 +347,10 @@ export class Interpreter {
414
347
  });
415
348
  }
416
349
  evaluateDoWhileStatement(node, labels) {
417
- const bodyNode = getNode(node, "body");
418
- const testNode = getNode(node, "test");
419
350
  const self = this;
420
351
  return Effect.gen(function* () {
421
352
  do {
422
- const result = yield* self.evaluateStatement(bodyNode);
353
+ const result = yield* self.evaluateStatement(node.body);
423
354
  if (result.kind === "continue") {
424
355
  if (result.label !== undefined && !labels?.has(result.label))
425
356
  return result;
@@ -433,7 +364,7 @@ export class Interpreter {
433
364
  if (result.kind === "return") {
434
365
  return result;
435
366
  }
436
- } while (yield* self.evaluateExpression(testNode));
367
+ } while (yield* self.evaluateExpression(node.test));
437
368
  return { kind: "none" };
438
369
  });
439
370
  }
@@ -441,11 +372,10 @@ export class Interpreter {
441
372
  this.scopes.push();
442
373
  const self = this;
443
374
  return Effect.gen(function* () {
444
- const initNode = getOptionalNode(node, "init");
445
- const testNode = getOptionalNode(node, "test");
446
- const updateNode = getOptionalNode(node, "update");
447
- const bodyNode = getNode(node, "body");
448
- if (initNode?.type === "VariableDeclaration" && getString(initNode, "kind") !== "var") {
375
+ const initNode = node.init;
376
+ const testNode = node.test;
377
+ const updateNode = node.update;
378
+ if (initNode?.type === "VariableDeclaration" && initNode.kind !== "var") {
449
379
  self.predeclareLexical([initNode]);
450
380
  }
451
381
  if (initNode) {
@@ -456,7 +386,7 @@ export class Interpreter {
456
386
  yield* self.evaluateExpression(initNode);
457
387
  }
458
388
  }
459
- const perIterationBindings = initNode?.type === "VariableDeclaration" && getString(initNode, "kind") !== "var"
389
+ const perIterationBindings = initNode?.type === "VariableDeclaration" && initNode.kind !== "var"
460
390
  ? Array.from(self.scopes.current().keys())
461
391
  : [];
462
392
  const nextIteration = () => {
@@ -468,7 +398,7 @@ export class Interpreter {
468
398
  };
469
399
  nextIteration();
470
400
  while (testNode ? yield* self.evaluateExpression(testNode) : true) {
471
- const result = yield* self.evaluateStatement(bodyNode);
401
+ const result = yield* self.evaluateStatement(node.body);
472
402
  if (result.kind === "return") {
473
403
  return result;
474
404
  }
@@ -491,8 +421,8 @@ export class Interpreter {
491
421
  }).pipe(Effect.ensuring(Effect.sync(() => self.scopes.pop())));
492
422
  }
493
423
  evaluateForOfStatement(node, labels) {
494
- const awaiting = getBoolean(node, "await");
495
- const left = getNode(node, "left");
424
+ const awaiting = node.await;
425
+ const left = node.left;
496
426
  const declared = loopDeclaration(left, "for...of");
497
427
  if (declared?.lexical)
498
428
  this.scopes.push();
@@ -500,8 +430,7 @@ export class Interpreter {
500
430
  return Effect.gen(function* () {
501
431
  if (declared?.lexical)
502
432
  self.predeclarePattern(declared.pattern, declared.mutable, left);
503
- const right = yield* self.evaluateExpression(getNode(node, "right"));
504
- const body = getNode(node, "body");
433
+ const right = yield* self.evaluateExpression(node.right);
505
434
  const iterator = yield* self.customIterator(right, node, awaiting);
506
435
  const cursor = iterator === undefined ? yield* self.syncIterator(right, node) : undefined;
507
436
  if (iterator === undefined && cursor === undefined) {
@@ -512,17 +441,10 @@ export class Interpreter {
512
441
  : awaiting
513
442
  ? Effect.andThen(cursor?.close ?? Effect.void, Effect.yieldNow)
514
443
  : (cursor?.close ?? Effect.void);
515
- let assignment;
516
- if (left.type !== "VariableDeclaration" &&
517
- (left.type === "Identifier" ||
518
- left.type === "MemberExpression" ||
519
- left.type === "ArrayPattern" ||
520
- left.type === "ObjectPattern")) {
521
- assignment = left;
522
- }
523
- else if (left.type !== "VariableDeclaration") {
444
+ if (left.type === "RestElement" || left.type === "AssignmentPattern") {
524
445
  throw new InterpreterRuntimeError("Unsupported for...of binding.", left);
525
446
  }
447
+ const assignment = left.type === "VariableDeclaration" ? undefined : left;
526
448
  const evaluateBody = (value) => Effect.gen(function* () {
527
449
  if (declared) {
528
450
  self.scopes.push();
@@ -533,7 +455,7 @@ export class Interpreter {
533
455
  else if (assignment) {
534
456
  yield* self.assignPattern(assignment, value, left);
535
457
  }
536
- return yield* self.evaluateStatement(body);
458
+ return yield* self.evaluateStatement(node.body);
537
459
  }).pipe(Effect.ensuring(Effect.sync(() => {
538
460
  if (declared)
539
461
  self.scopes.pop();
@@ -575,7 +497,7 @@ export class Interpreter {
575
497
  })));
576
498
  }
577
499
  awaitValue(value, node = promiseResolutionNode) {
578
- return Effect.flatMap(resolvePromise(this.runner, this.promises, value, node), (promise) => this.settlePromise(promise));
500
+ return Effect.flatMap(resolvePromise(this.runtime.runner, this.runtime.promises, value, node), (promise) => this.settlePromise(promise));
579
501
  }
580
502
  awaitAsyncFromSyncValue(iterator, value, node, closeOnRejection) {
581
503
  const self = this;
@@ -594,11 +516,11 @@ export class Interpreter {
594
516
  ? value[Symbol.iterator]()
595
517
  : typeof value === "string"
596
518
  ? value[Symbol.iterator]()
597
- : value instanceof CodeModeMap
519
+ : value instanceof Values.Map
598
520
  ? value.map.entries()
599
- : value instanceof CodeModeSet
521
+ : value instanceof Values.Set
600
522
  ? value.set.values()
601
- : value instanceof CodeModeURLSearchParams
523
+ : value instanceof Values.URLSearchParams
602
524
  ? value.params.entries()
603
525
  : undefined;
604
526
  if (iterator !== undefined) {
@@ -722,7 +644,7 @@ export class Interpreter {
722
644
  }
723
645
  enumerableKeys(value) {
724
646
  if (value instanceof ToolReference) {
725
- return [...this.toolKeys(value.path)];
647
+ return [...this.runtime.toolKeys(value.path)];
726
648
  }
727
649
  if (Array.isArray(value)) {
728
650
  return Object.keys(value);
@@ -733,7 +655,7 @@ export class Interpreter {
733
655
  return undefined;
734
656
  }
735
657
  evaluateForInStatement(node, labels) {
736
- const left = getNode(node, "left");
658
+ const left = node.left;
737
659
  const declared = loopDeclaration(left, "for...in");
738
660
  if (declared?.lexical)
739
661
  this.scopes.push();
@@ -741,19 +663,15 @@ export class Interpreter {
741
663
  return Effect.gen(function* () {
742
664
  if (declared?.lexical)
743
665
  self.predeclarePattern(declared.pattern, declared.mutable, left);
744
- const right = yield* self.evaluateExpression(getNode(node, "right"));
745
- const body = getNode(node, "body");
666
+ const right = yield* self.evaluateExpression(node.right);
746
667
  const keys = self.enumerableKeys(right);
747
668
  if (keys === undefined) {
748
669
  throw new InterpreterRuntimeError("for...in requires a plain object, array, or tools reference. Use for...of for arrays/strings/Maps/Sets, or Object.keys(value) for a key list.", node);
749
670
  }
750
- let assignmentName;
751
- if (left.type === "Identifier") {
752
- assignmentName = getString(left, "name");
753
- }
754
- else if (left.type !== "VariableDeclaration") {
671
+ if (left.type !== "Identifier" && left.type !== "VariableDeclaration") {
755
672
  throw new InterpreterRuntimeError("Unsupported for...in binding.", left);
756
673
  }
674
+ const assignmentName = left.type === "Identifier" ? left.name : undefined;
757
675
  for (const key of keys) {
758
676
  const result = yield* Effect.gen(function* () {
759
677
  if (declared) {
@@ -765,7 +683,7 @@ export class Interpreter {
765
683
  else if (assignmentName) {
766
684
  self.scopes.set(assignmentName, key, left);
767
685
  }
768
- return yield* self.evaluateStatement(body);
686
+ return yield* self.evaluateStatement(node.body);
769
687
  }).pipe(Effect.ensuring(Effect.sync(() => {
770
688
  if (declared)
771
689
  self.scopes.pop();
@@ -791,19 +709,17 @@ export class Interpreter {
791
709
  })));
792
710
  }
793
711
  evaluateBreakStatement(node) {
794
- const labelNode = getOptionalNode(node, "label");
795
- return labelNode ? { kind: "break", label: getString(labelNode, "name") } : { kind: "break" };
712
+ return node.label ? { kind: "break", label: node.label.name } : { kind: "break" };
796
713
  }
797
714
  evaluateContinueStatement(node) {
798
- const labelNode = getOptionalNode(node, "label");
799
- return labelNode ? { kind: "continue", label: getString(labelNode, "name") } : { kind: "continue" };
715
+ return node.label ? { kind: "continue", label: node.label.name } : { kind: "continue" };
800
716
  }
801
717
  evaluateLabeledStatement(node) {
802
718
  const labels = new Set();
803
719
  let body = node;
804
720
  while (body.type === "LabeledStatement") {
805
- labels.add(getString(getNode(body, "label"), "name"));
806
- body = getNode(body, "body");
721
+ labels.add(body.label.name);
722
+ body = body.body;
807
723
  }
808
724
  const evaluated = (() => {
809
725
  if (body.type === "WhileStatement")
@@ -823,13 +739,12 @@ export class Interpreter {
823
739
  : result);
824
740
  }
825
741
  evaluateThrowStatement(node) {
826
- const argument = getNode(node, "argument");
827
- return Effect.flatMap(this.evaluateExpression(argument), (value) => Effect.fail(new ProgramThrow(value)));
742
+ return Effect.flatMap(this.evaluateExpression(node.argument), (value) => Effect.fail(new ProgramThrow(value)));
828
743
  }
829
744
  evaluateTryStatement(node) {
830
- const body = getNode(node, "block");
831
- const handler = getOptionalNode(node, "handler");
832
- const finalizer = getOptionalNode(node, "finalizer");
745
+ const body = node.block;
746
+ const handler = node.handler;
747
+ const finalizer = node.finalizer;
833
748
  const self = this;
834
749
  const attempted = Effect.matchCauseEffect(this.evaluateStatement(body), {
835
750
  onFailure: (cause) => {
@@ -837,12 +752,12 @@ export class Interpreter {
837
752
  return Effect.failCause(cause);
838
753
  }
839
754
  const caught = caughtErrorValue(Cause.squash(cause));
840
- const parameter = getOptionalNode(handler, "param");
755
+ const parameter = handler.param;
841
756
  self.scopes.push();
842
757
  return Effect.gen(function* () {
843
758
  if (parameter)
844
759
  yield* self.declarePattern(parameter, caught, true, handler);
845
- return yield* self.evaluateStatement(getNode(handler, "body"));
760
+ return yield* self.evaluateStatement(handler.body);
846
761
  }).pipe(Effect.ensuring(Effect.sync(() => self.scopes.pop())));
847
762
  },
848
763
  onSuccess: Effect.succeed,
@@ -858,18 +773,16 @@ export class Interpreter {
858
773
  });
859
774
  }
860
775
  evaluateVariableDeclaration(node) {
861
- const kind = getString(node, "kind");
862
- const declarations = getArray(node, "declarations");
776
+ const kind = node.kind;
863
777
  const self = this;
864
778
  return Effect.gen(function* () {
865
- for (const declarationValue of declarations) {
866
- const declaration = asNode(declarationValue, "declarations");
779
+ for (const declaration of node.declarations) {
867
780
  if (declaration.type !== "VariableDeclarator") {
868
781
  throw new InterpreterRuntimeError("Unsupported variable declaration shape.", declaration);
869
782
  }
870
- const init = getOptionalNode(declaration, "init");
783
+ const init = declaration.init;
871
784
  const value = init ? yield* self.evaluateExpression(init) : undefined;
872
- yield* self.declarePattern(getNode(declaration, "id"), value, kind !== "const", declaration, kind !== "var");
785
+ yield* self.declarePattern(declaration.id, value, kind !== "const", declaration, kind !== "var");
873
786
  }
874
787
  });
875
788
  }
@@ -877,7 +790,7 @@ export class Interpreter {
877
790
  const self = this;
878
791
  return Effect.gen(function* () {
879
792
  if (pattern.type === "Identifier") {
880
- const name = getString(pattern, "name");
793
+ const name = pattern.name;
881
794
  if (initialize)
882
795
  self.scopes.initialize(name, value, node);
883
796
  else
@@ -885,8 +798,8 @@ export class Interpreter {
885
798
  return;
886
799
  }
887
800
  if (pattern.type === "AssignmentPattern") {
888
- const resolved = value === undefined ? yield* self.evaluateExpression(getNode(pattern, "right")) : value;
889
- yield* self.declarePattern(getNode(pattern, "left"), resolved, mutable, node, initialize);
801
+ const resolved = value === undefined ? yield* self.evaluateExpression(pattern.right) : value;
802
+ yield* self.declarePattern(pattern.left, resolved, mutable, node, initialize);
890
803
  return;
891
804
  }
892
805
  if (pattern.type === "ObjectPattern") {
@@ -894,8 +807,7 @@ export class Interpreter {
894
807
  throw new InterpreterRuntimeError("Object destructuring requires a data object or array value.", pattern, "InvalidDataValue");
895
808
  }
896
809
  const consumed = new Set();
897
- for (const propertyValue of getArray(pattern, "properties")) {
898
- const property = asNode(propertyValue, "properties");
810
+ for (const property of pattern.properties) {
899
811
  if (property.type === "RestElement") {
900
812
  const rest = Object.create(null);
901
813
  for (const [key, item] of Object.entries(value)) {
@@ -903,7 +815,7 @@ export class Interpreter {
903
815
  rest[key] = item;
904
816
  }
905
817
  copyIteratorSymbols(value, rest, consumed);
906
- yield* self.declarePattern(getNode(property, "argument"), rest, mutable, property, initialize);
818
+ yield* self.declarePattern(property.argument, rest, mutable, property, initialize);
907
819
  continue;
908
820
  }
909
821
  const key = yield* self.destructuringPropertyKey(property);
@@ -911,7 +823,7 @@ export class Interpreter {
911
823
  throw new InterpreterRuntimeError(`Property '${String(key)}' is not available.`, property);
912
824
  }
913
825
  consumed.add(typeof key === "symbol" ? key : String(key));
914
- yield* self.declarePattern(getNode(property, "value"), self.destructuringPropertyValue(value, key), mutable, property, initialize);
826
+ yield* self.declarePattern(property.value, self.destructuringPropertyValue(value, key), mutable, property, initialize);
915
827
  }
916
828
  return;
917
829
  }
@@ -925,7 +837,7 @@ export class Interpreter {
925
837
  const self = this;
926
838
  return Effect.gen(function* () {
927
839
  if (pattern.type === "Identifier") {
928
- self.scopes.set(getString(pattern, "name"), value, pattern);
840
+ self.scopes.set(pattern.name, value, pattern);
929
841
  return;
930
842
  }
931
843
  if (pattern.type === "MemberExpression") {
@@ -933,8 +845,8 @@ export class Interpreter {
933
845
  return;
934
846
  }
935
847
  if (pattern.type === "AssignmentPattern") {
936
- const resolved = value === undefined ? yield* self.evaluateExpression(getNode(pattern, "right")) : value;
937
- yield* self.assignPattern(getNode(pattern, "left"), resolved, node);
848
+ const resolved = value === undefined ? yield* self.evaluateExpression(pattern.right) : value;
849
+ yield* self.assignPattern(pattern.left, resolved, node);
938
850
  return;
939
851
  }
940
852
  if (pattern.type === "ObjectPattern") {
@@ -943,8 +855,7 @@ export class Interpreter {
943
855
  }
944
856
  const source = value;
945
857
  const consumed = new Set();
946
- for (const propertyValue of getArray(pattern, "properties")) {
947
- const property = asNode(propertyValue, "properties");
858
+ for (const property of pattern.properties) {
948
859
  if (property.type === "RestElement") {
949
860
  const rest = Object.create(null);
950
861
  for (const [key, item] of Object.entries(source)) {
@@ -952,7 +863,7 @@ export class Interpreter {
952
863
  rest[key] = item;
953
864
  }
954
865
  copyIteratorSymbols(source, rest, consumed);
955
- yield* self.assignPattern(getNode(property, "argument"), rest, property);
866
+ yield* self.assignPattern(property.argument, rest, property);
956
867
  continue;
957
868
  }
958
869
  const key = yield* self.destructuringPropertyKey(property);
@@ -960,7 +871,7 @@ export class Interpreter {
960
871
  throw new InterpreterRuntimeError(`Property '${String(key)}' is not available.`, property);
961
872
  }
962
873
  consumed.add(typeof key === "symbol" ? key : String(key));
963
- yield* self.assignPattern(getNode(property, "value"), self.destructuringPropertyValue(source, key), property);
874
+ yield* self.assignPattern(property.value, self.destructuringPropertyValue(source, key), property);
964
875
  }
965
876
  return;
966
877
  }
@@ -978,21 +889,19 @@ export class Interpreter {
978
889
  throw new InterpreterRuntimeError("Array destructuring requires a supported iterable value.", pattern).as("TypeError");
979
890
  }
980
891
  let done = false;
981
- for (const [index, item] of getArray(pattern, "elements").entries()) {
892
+ for (const element of pattern.elements) {
982
893
  if (done) {
983
- if (item === null)
894
+ if (element === null)
984
895
  continue;
985
- const element = asNode(item, `elements[${index}]`);
986
- yield* consume(element.type === "RestElement" ? getNode(element, "argument") : element, element.type === "RestElement" ? [] : undefined, element);
896
+ yield* consume(element.type === "RestElement" ? element.argument : element, element.type === "RestElement" ? [] : undefined, element);
987
897
  if (element.type === "RestElement")
988
898
  return;
989
899
  continue;
990
900
  }
991
901
  const step = yield* cursor.next;
992
902
  done = step.done;
993
- if (item === null)
903
+ if (element === null)
994
904
  continue;
995
- const element = asNode(item, `elements[${index}]`);
996
905
  if (element.type === "RestElement") {
997
906
  const rest = [];
998
907
  if (!step.done)
@@ -1003,7 +912,7 @@ export class Interpreter {
1003
912
  if (!done)
1004
913
  rest.push(next.value);
1005
914
  }
1006
- yield* consume(getNode(element, "argument"), rest, element);
915
+ yield* consume(element.argument, rest, element);
1007
916
  return;
1008
917
  }
1009
918
  const consumed = consume(element, step.done ? undefined : step.value, pattern);
@@ -1014,14 +923,18 @@ export class Interpreter {
1014
923
  });
1015
924
  }
1016
925
  destructuringPropertyKey(property) {
1017
- if (property.type !== "Property" || getString(property, "kind") !== "init") {
926
+ if (property.type !== "Property" || property.kind !== "init") {
1018
927
  throw new InterpreterRuntimeError("Unsupported object destructuring property.", property);
1019
928
  }
1020
- const keyNode = getNode(property, "key");
1021
- if (getBoolean(property, "computed")) {
929
+ const keyNode = property.key;
930
+ if (property.computed) {
1022
931
  return Effect.map(this.evaluateExpression(keyNode), (value) => this.toPropertyKey(value, keyNode));
1023
932
  }
1024
- return Effect.succeed(keyNode.type === "Identifier" ? getString(keyNode, "name") : String(keyNode.value));
933
+ if (keyNode.type === "Identifier")
934
+ return Effect.succeed(keyNode.name);
935
+ if (keyNode.type === "Literal")
936
+ return Effect.succeed(String(keyNode.value));
937
+ throw unsupportedSyntax(keyNode.type, keyNode);
1025
938
  }
1026
939
  destructuringPropertyValue(source, key) {
1027
940
  if (!Array.isArray(source))
@@ -1040,13 +953,12 @@ export class Interpreter {
1040
953
  switch (node.type) {
1041
954
  case "Literal": {
1042
955
  const regex = node.regex;
1043
- if (isRecord(regex) && typeof regex.pattern === "string") {
1044
- return Effect.sync(() => this.constructRegExp([regex.pattern, typeof regex.flags === "string" ? regex.flags : ""], node));
1045
- }
1046
- return Effect.sync(() => boundedData(node.value, "Literal"));
956
+ if (regex)
957
+ return Effect.sync(() => constructRegExp([regex.pattern, regex.flags], node));
958
+ return Effect.sync(() => toProgram(node.value, "Literal"));
1047
959
  }
1048
960
  case "Identifier":
1049
- return Effect.sync(() => this.scopes.get(getString(node, "name"), node));
961
+ return Effect.sync(() => this.scopes.get(node.name, node));
1050
962
  case "BinaryExpression":
1051
963
  return this.evaluateBinaryExpression(node);
1052
964
  case "LogicalExpression":
@@ -1059,8 +971,8 @@ export class Interpreter {
1059
971
  const self = this;
1060
972
  return Effect.gen(function* () {
1061
973
  let result;
1062
- for (const expression of getArray(node, "expressions")) {
1063
- result = yield* self.evaluateExpression(asNode(expression, "expressions"));
974
+ for (const expression of node.expressions) {
975
+ result = yield* self.evaluateExpression(expression);
1064
976
  }
1065
977
  return result;
1066
978
  });
@@ -1073,7 +985,7 @@ export class Interpreter {
1073
985
  case "MemberExpression":
1074
986
  return this.readMember(node);
1075
987
  case "ChainExpression":
1076
- return Effect.map(this.evaluateExpression(getNode(node, "expression")), (value) => value === OptionalShortCircuit ? undefined : value);
988
+ return Effect.map(this.evaluateExpression(node.expression), (value) => value === OptionalShortCircuit ? undefined : value);
1077
989
  case "ObjectExpression":
1078
990
  return this.evaluateObjectExpression(node);
1079
991
  case "ArrayExpression":
@@ -1086,7 +998,7 @@ export class Interpreter {
1086
998
  return this.evaluateUpdateExpression(node);
1087
999
  case "AwaitExpression": {
1088
1000
  // Await always suspends, including for plain values.
1089
- return Effect.flatMap(this.evaluateExpression(getNode(node, "argument")), (value) => this.awaitValue(value, node));
1001
+ return Effect.flatMap(this.evaluateExpression(node.argument), (value) => this.awaitValue(value, node));
1090
1002
  }
1091
1003
  case "YieldExpression":
1092
1004
  return this.evaluateYieldExpression(node);
@@ -1097,240 +1009,29 @@ export class Interpreter {
1097
1009
  }
1098
1010
  }
1099
1011
  evaluateNewExpression(node) {
1100
- const callee = getNode(node, "callee");
1101
- if (callee.type !== "Identifier") {
1102
- throw unsupportedSyntax("NewExpression", node);
1103
- }
1104
- const name = getString(callee, "name");
1105
- const argNodes = getArray(node, "arguments");
1106
- const self = this;
1107
- if (name === "Promise") {
1108
- return Effect.flatMap(this.evaluateCallArguments(argNodes), (args) => constructPromise(self.runner, self.promises, args[0], node));
1109
- }
1110
- if (errorConstructors.has(name)) {
1111
- return Effect.flatMap(this.evaluateCallArguments(argNodes), (args) => name === "AggregateError"
1112
- ? constructAggregateErrorValue(self.runner, args, node)
1113
- : Effect.succeed(constructErrorValue(name, args)));
1114
- }
1115
- // Array and Object construct identically with or without new, like JS.
1116
- if (name === "Array") {
1117
- return Effect.map(this.evaluateCallArguments(argNodes), (args) => self.constructArray(args, node));
1118
- }
1119
- if (name === "Object") {
1120
- return Effect.map(this.evaluateCallArguments(argNodes), (args) => self.constructObject(args, node));
1121
- }
1122
- if (valueConstructors.has(name)) {
1123
- return Effect.gen(function* () {
1124
- const args = yield* self.evaluateCallArguments(argNodes);
1125
- switch (name) {
1126
- case "Date":
1127
- return yield* self.constructDate(args, node);
1128
- case "RegExp":
1129
- return self.constructRegExp(args, node);
1130
- case "Map":
1131
- return yield* self.constructMap(args[0], node);
1132
- case "Set":
1133
- return yield* self.constructSet(args[0], node);
1134
- case "URL":
1135
- return self.constructURL(args, node);
1136
- default:
1137
- return yield* self.constructURLSearchParams(args[0], node);
1138
- }
1139
- });
1140
- }
1141
- throw unsupportedSyntax("NewExpression", node);
1142
- }
1143
- constructArray(args, node) {
1144
- if (args.length !== 1)
1145
- return [...args];
1146
- const first = args[0];
1147
- if (typeof first !== "number")
1148
- return [first];
1149
- if (!Number.isInteger(first) || first < 0 || first > 4294967295) {
1150
- throw new InterpreterRuntimeError("Invalid array length.", node).as("RangeError");
1151
- }
1152
- // Sparse like JS: Array(3) has holes, and combinator loops already skip them.
1153
- return new Array(first);
1154
- }
1155
- constructObject(args, node) {
1156
- const first = args[0];
1157
- if (first === null || first === undefined)
1158
- return {};
1159
- if (typeof first === "object")
1160
- return first;
1161
- throw new InterpreterRuntimeError(`Object(${typeof first}) wrapper objects are not supported; use the primitive value directly.`, node);
1162
- }
1163
- constructDate(args, node) {
1164
- if (args.length === 0)
1165
- return Effect.succeed(new CodeModeDate(Date.now()));
1166
- if (args.length === 1) {
1167
- const arg = args[0];
1168
- if (arg instanceof CodeModeDate)
1169
- return Effect.succeed(new CodeModeDate(arg.time));
1170
- return Effect.map(this.toDatePrimitive(arg, node), (value) => typeof value === "string"
1171
- ? new CodeModeDate(Date.parse(value))
1172
- : new CodeModeDate(new Date(coerceToNumber(value)).getTime()));
1173
- }
1174
- const parts = args.map((arg) => coerceToNumber(arg));
1175
- return Effect.succeed(new CodeModeDate(new Date(...parts).getTime()));
1176
- }
1177
- toDatePrimitive(value, node) {
1178
- if (value === null || (typeof value !== "object" && typeof value !== "function"))
1179
- return Effect.succeed(value);
1180
- const object = value;
1181
- const self = this;
1182
- return Effect.gen(function* () {
1183
- if (Object.hasOwn(object, "valueOf") && typeofValue(object.valueOf) === "function") {
1184
- const result = yield* self.runner.invokeCallable(object.valueOf, [], node);
1185
- if (result === null || (typeof result !== "object" && typeof result !== "function"))
1186
- return result;
1187
- }
1188
- if (!Object.hasOwn(object, "toString"))
1189
- return coerceToString(value);
1190
- if (typeofValue(object.toString) === "function") {
1191
- const result = yield* self.runner.invokeCallable(object.toString, [], node);
1192
- if (result === null || (typeof result !== "object" && typeof result !== "function"))
1193
- return result;
1194
- }
1195
- throw new InterpreterRuntimeError("Cannot convert object to primitive value.", node).as("TypeError");
1196
- });
1197
- }
1198
- constructRegExp(args, node) {
1199
- const first = args[0];
1200
- const pattern = first instanceof CodeModeRegExp ? first.regex.source : first === undefined ? "" : coerceToString(first);
1201
- const flagsArg = args[1];
1202
- if (flagsArg !== undefined && typeof flagsArg !== "string") {
1203
- throw new InterpreterRuntimeError(`RegExp flags must be a string of flag characters (e.g. "g", "gi"), not ${flagsArg === null ? "null" : typeof flagsArg}.`, node).as("SyntaxError");
1204
- }
1205
- const flags = flagsArg ?? (first instanceof CodeModeRegExp ? first.regex.flags : "");
1206
- try {
1207
- return new CodeModeRegExp(pattern, flags);
1208
- }
1209
- catch (error) {
1210
- const reason = regexFailureReason(error);
1211
- throw new InterpreterRuntimeError(/flag/i.test(reason)
1212
- ? `new RegExp(...) received invalid flags ${JSON.stringify(flags)} (${reason}). Valid flags are d, g, i, m, s, u, v, and y.`
1213
- : `new RegExp(...) received ${JSON.stringify(pattern)}, which is not a valid regular expression pattern (${reason}). ${escapeRegexHint}`, node).as("SyntaxError");
1214
- }
1215
- }
1216
- constructMap(init, node) {
1217
- const target = new CodeModeMap();
1218
- if (init === undefined || init === null)
1219
- return Effect.succeed(target);
1220
- const self = this;
1221
- return Effect.gen(function* () {
1222
- const cursor = yield* self.syncIterator(init, node);
1223
- if (cursor === undefined) {
1224
- throw new InterpreterRuntimeError("new Map(...) expects an iterable of [key, value] pairs or no argument.", node).as("TypeError");
1225
- }
1226
- while (true) {
1227
- const step = yield* cursor.next;
1228
- if (step.done)
1229
- return target;
1230
- yield* preserveConsumerError(cursor, Effect.sync(() => {
1231
- if (!isRecord(step.value) || isRuntimeReference(step.value)) {
1232
- throw new InterpreterRuntimeError("new Map(...) expects [key, value] pairs as entry objects.", node).as("TypeError");
1233
- }
1234
- target.map.set(step.value[0], step.value[1]);
1235
- }));
1236
- }
1237
- });
1238
- }
1239
- constructSet(init, node) {
1240
- const target = new CodeModeSet();
1241
- if (init === undefined || init === null)
1242
- return Effect.succeed(target);
1243
1012
  const self = this;
1244
1013
  return Effect.gen(function* () {
1245
- const cursor = yield* self.syncIterator(init, node);
1246
- if (cursor === undefined) {
1247
- throw new InterpreterRuntimeError("new Set(...) expects a synchronous iterable or no argument.", node).as("TypeError");
1248
- }
1249
- while (true) {
1250
- const step = yield* cursor.next;
1251
- if (step.done)
1252
- return target;
1253
- target.set.add(step.value);
1254
- }
1255
- });
1256
- }
1257
- constructURL(args, node) {
1258
- if (args.length === 0) {
1259
- throw new InterpreterRuntimeError("new URL(...) requires a URL string and an optional base URL.", node).as("TypeError");
1260
- }
1261
- const input = urlArgument(args[0], "new URL input");
1262
- const base = args[1] === undefined ? undefined : urlArgument(args[1], "new URL base");
1263
- try {
1264
- return new CodeModeURL(new URL(input, base));
1265
- }
1266
- catch {
1267
- throw new InterpreterRuntimeError(`new URL(...) received an invalid URL${base === undefined ? "" : " or base URL"}.`, node).as("TypeError");
1268
- }
1269
- }
1270
- constructURLSearchParams(init, node) {
1271
- if (init === undefined)
1272
- return Effect.succeed(new CodeModeURLSearchParams(new URLSearchParams()));
1273
- if (init instanceof CodeModeURLSearchParams) {
1274
- return Effect.succeed(new CodeModeURLSearchParams(new URLSearchParams(init.params)));
1275
- }
1276
- if (typeof init === "string")
1277
- return Effect.succeed(new CodeModeURLSearchParams(new URLSearchParams(init)));
1278
- if (init === null || typeof init === "number" || typeof init === "boolean") {
1279
- return Effect.succeed(new CodeModeURLSearchParams(new URLSearchParams(coerceToString(init))));
1280
- }
1281
- const self = this;
1282
- return Effect.gen(function* () {
1283
- const cursor = yield* self.syncIterator(init, node);
1284
- if (cursor !== undefined) {
1285
- const entries = [];
1286
- while (true) {
1287
- const step = yield* cursor.next;
1288
- if (step.done) {
1289
- if (entries.some((entry) => entry.length !== 2)) {
1290
- throw new InterpreterRuntimeError("new URLSearchParams(...) expects iterable [name, value] pairs.", node).as("TypeError");
1291
- }
1292
- return new CodeModeURLSearchParams(new URLSearchParams(entries.map((entry) => [entry[0] ?? "", entry[1] ?? ""])));
1293
- }
1294
- entries.push(yield* preserveConsumerError(cursor, self.readURLSearchParamsPair(step.value, node)));
1295
- }
1296
- }
1297
- if (isRuntimeReference(init)) {
1298
- throw new InterpreterRuntimeError("new URLSearchParams(...) expects a query string, data object, or synchronous iterable pairs.", node).as("TypeError");
1299
- }
1300
- if (isCodeModeValue(init))
1301
- return new CodeModeURLSearchParams(new URLSearchParams());
1302
- const data = boundedData(init, "new URLSearchParams input");
1303
- if (data === null || typeof data !== "object") {
1304
- throw new InterpreterRuntimeError("new URLSearchParams(...) expects a query string, data object, iterable pairs, or URLSearchParams.", node).as("TypeError");
1305
- }
1306
- return new CodeModeURLSearchParams(new URLSearchParams(Object.fromEntries(Object.entries(data).map(([key, value]) => [key, coerceToString(value)]))));
1307
- });
1308
- }
1309
- readURLSearchParamsPair(value, node) {
1310
- const self = this;
1311
- return Effect.gen(function* () {
1312
- const cursor = yield* self.syncIterator(value, node);
1313
- if (cursor === undefined) {
1314
- throw new InterpreterRuntimeError("new URLSearchParams(...) expects iterable [name, value] pairs.", node).as("TypeError");
1315
- }
1316
- const items = [];
1317
- while (true) {
1318
- const step = yield* cursor.next;
1319
- if (step.done)
1320
- return items;
1321
- items.push(yield* preserveConsumerError(cursor, Effect.sync(() => uriArgument(step.value, "URLSearchParams pair value"))));
1322
- }
1014
+ const callee = yield* self.evaluateExpression(node.callee);
1015
+ // Globals are built with this interpreter's R; `instanceof` cannot recover the type argument.
1016
+ const construct = callee instanceof HostFunction ? callee.construct : undefined;
1017
+ if (construct === undefined)
1018
+ throw unsupportedSyntax("NewExpression", node);
1019
+ const args = yield* self.evaluateCallArguments(node.arguments);
1020
+ return yield* construct(args, node);
1323
1021
  });
1324
1022
  }
1325
1023
  evaluateBinaryExpression(node) {
1326
- const operator = getString(node, "operator");
1024
+ const operator = node.operator;
1025
+ const left = node.left;
1026
+ if (left.type === "PrivateIdentifier")
1027
+ throw unsupportedSyntax(left.type, left);
1327
1028
  const self = this;
1328
1029
  return Effect.gen(function* () {
1329
- const lhs = yield* self.evaluateExpression(getNode(node, "left"));
1330
- const rhs = yield* self.evaluateExpression(getNode(node, "right"));
1030
+ const lhs = yield* self.evaluateExpression(left);
1031
+ const rhs = yield* self.evaluateExpression(node.right);
1331
1032
  if (operator === "instanceof")
1332
1033
  return instanceofValue(lhs, rhs, node);
1333
- return boundedData(self.applyBinaryOperator(operator, lhs, rhs, node), "Binary expression result");
1034
+ return toProgram(self.applyBinaryOperator(operator, lhs, rhs, node), "Binary expression result");
1334
1035
  });
1335
1036
  }
1336
1037
  applyBinaryOperator(operator, lhs, rhs, node) {
@@ -1344,7 +1045,7 @@ export class Interpreter {
1344
1045
  // Null-prototype data needs explicit primitive coercion; identity and `in` retain raw objects.
1345
1046
  // Dates use their default string hint for addition and loose equality, and epoch time elsewhere.
1346
1047
  const coerceOperand = (operand) => {
1347
- if (operand instanceof CodeModeDate) {
1048
+ if (operand instanceof Values.Date) {
1348
1049
  return operator === "+" || operator === "==" || operator === "!=" ? coerceToString(operand) : operand.time;
1349
1050
  }
1350
1051
  return operand !== null && typeof operand === "object" ? coerceToString(operand) : operand;
@@ -1400,26 +1101,24 @@ export class Interpreter {
1400
1101
  }
1401
1102
  }
1402
1103
  evaluateLogicalExpression(node) {
1403
- const operator = getString(node, "operator");
1404
- return Effect.flatMap(this.evaluateExpression(getNode(node, "left")), (left) => {
1104
+ const operator = node.operator;
1105
+ return Effect.flatMap(this.evaluateExpression(node.left), (left) => {
1405
1106
  if (operator === "&&")
1406
- return left ? this.evaluateExpression(getNode(node, "right")) : Effect.succeed(left);
1107
+ return left ? this.evaluateExpression(node.right) : Effect.succeed(left);
1407
1108
  if (operator === "||")
1408
- return left ? Effect.succeed(left) : this.evaluateExpression(getNode(node, "right"));
1109
+ return left ? Effect.succeed(left) : this.evaluateExpression(node.right);
1409
1110
  if (operator === "??")
1410
- return left !== null && left !== undefined
1411
- ? Effect.succeed(left)
1412
- : this.evaluateExpression(getNode(node, "right"));
1111
+ return left !== null && left !== undefined ? Effect.succeed(left) : this.evaluateExpression(node.right);
1413
1112
  throw new InterpreterRuntimeError(`Unsupported logical operator '${operator}'.`, node);
1414
1113
  });
1415
1114
  }
1416
1115
  evaluateUnaryExpression(node) {
1417
- const operator = getString(node, "operator");
1418
- const argument = getNode(node, "argument");
1116
+ const operator = node.operator;
1117
+ const argument = node.argument;
1419
1118
  if (operator === "delete")
1420
1119
  return this.evaluateDeleteExpression(argument);
1421
1120
  // Undeclared names short-circuit, but declared TDZ bindings must still throw.
1422
- if (operator === "typeof" && argument.type === "Identifier" && !this.scopes.resolve(getString(argument, "name"))) {
1121
+ if (operator === "typeof" && argument.type === "Identifier" && !this.scopes.resolve(argument.name)) {
1423
1122
  return Effect.succeed("undefined");
1424
1123
  }
1425
1124
  return Effect.map(this.evaluateExpression(argument), (value) => {
@@ -1432,7 +1131,7 @@ export class Interpreter {
1432
1131
  if (containsOpaqueReference(value)) {
1433
1132
  throw new InterpreterRuntimeError("Unary operators require data values.", node, "InvalidDataValue");
1434
1133
  }
1435
- const operand = value instanceof CodeModeDate
1134
+ const operand = value instanceof Values.Date
1436
1135
  ? value.time
1437
1136
  : value !== null && typeof value === "object"
1438
1137
  ? coerceToString(value)
@@ -1451,38 +1150,38 @@ export class Interpreter {
1451
1150
  default:
1452
1151
  throw new InterpreterRuntimeError(`Unsupported unary operator '${operator}'.`, node);
1453
1152
  }
1454
- return boundedData(result, "Unary expression result");
1153
+ return toProgram(result, "Unary expression result");
1455
1154
  });
1456
1155
  }
1457
1156
  evaluateAssignmentExpression(node) {
1458
- const left = getNode(node, "left");
1459
- const operator = getString(node, "operator");
1157
+ const left = node.left;
1158
+ const operator = node.operator;
1460
1159
  const self = this;
1461
1160
  return Effect.gen(function* () {
1462
1161
  if (operator === "??=" || operator === "||=" || operator === "&&=") {
1463
1162
  return yield* self.evaluateLogicalAssignment(node, left, operator);
1464
1163
  }
1465
1164
  if (operator === "=" && (left.type === "ObjectPattern" || left.type === "ArrayPattern")) {
1466
- const rightValue = yield* self.evaluateExpression(getNode(node, "right"));
1165
+ const rightValue = yield* self.evaluateExpression(node.right);
1467
1166
  yield* self.assignPattern(left, rightValue, node);
1468
1167
  return rightValue;
1469
1168
  }
1470
1169
  if (left.type === "Identifier") {
1471
- const name = getString(left, "name");
1170
+ const name = left.name;
1472
1171
  if (operator !== "=") {
1473
1172
  const current = self.scopes.get(name, left);
1474
- const rightValue = yield* self.evaluateExpression(getNode(node, "right"));
1475
- const next = boundedData(self.applyCompoundAssignment(operator, current, rightValue, node), "Assignment result");
1173
+ const rightValue = yield* self.evaluateExpression(node.right);
1174
+ const next = toProgram(self.applyCompoundAssignment(operator, current, rightValue, node), "Assignment result");
1476
1175
  return self.scopes.set(name, next, left);
1477
1176
  }
1478
- const rightValue = yield* self.evaluateExpression(getNode(node, "right"));
1177
+ const rightValue = yield* self.evaluateExpression(node.right);
1479
1178
  return self.scopes.set(name, rightValue, left);
1480
1179
  }
1481
1180
  if (left.type === "MemberExpression") {
1482
- return yield* self.modifyMember(left, (current) => Effect.map(self.evaluateExpression(getNode(node, "right")), (rightValue) => {
1181
+ return yield* self.modifyMember(left, (current) => Effect.map(self.evaluateExpression(node.right), (rightValue) => {
1483
1182
  if (operator === "=")
1484
1183
  return { write: true, next: rightValue, result: rightValue };
1485
- const next = boundedData(self.applyCompoundAssignment(operator, current, rightValue, node), "Assignment result");
1184
+ const next = toProgram(self.applyCompoundAssignment(operator, current, rightValue, node), "Assignment result");
1486
1185
  return { write: true, next, result: next };
1487
1186
  }));
1488
1187
  }
@@ -1493,18 +1192,18 @@ export class Interpreter {
1493
1192
  const self = this;
1494
1193
  const shouldAssign = (current) => operator === "??=" ? current === null || current === undefined : operator === "||=" ? !current : Boolean(current);
1495
1194
  if (left.type === "Identifier") {
1496
- const name = getString(left, "name");
1195
+ const name = left.name;
1497
1196
  return Effect.gen(function* () {
1498
1197
  const current = self.scopes.get(name, left);
1499
1198
  if (!shouldAssign(current))
1500
1199
  return current;
1501
- const rightValue = yield* self.evaluateExpression(getNode(node, "right"));
1200
+ const rightValue = yield* self.evaluateExpression(node.right);
1502
1201
  return self.scopes.set(name, rightValue, left);
1503
1202
  });
1504
1203
  }
1505
1204
  if (left.type === "MemberExpression") {
1506
1205
  return self.modifyMember(left, (current) => shouldAssign(current)
1507
- ? Effect.map(self.evaluateExpression(getNode(node, "right")), (rightValue) => ({
1206
+ ? Effect.map(self.evaluateExpression(node.right), (rightValue) => ({
1508
1207
  write: true,
1509
1208
  next: rightValue,
1510
1209
  result: rightValue,
@@ -1514,9 +1213,9 @@ export class Interpreter {
1514
1213
  throw new InterpreterRuntimeError("Assignment target must be an Identifier or MemberExpression.", left);
1515
1214
  }
1516
1215
  evaluateUpdateExpression(node) {
1517
- const operator = getString(node, "operator");
1518
- const argument = getNode(node, "argument");
1519
- const prefix = getBoolean(node, "prefix");
1216
+ const operator = node.operator;
1217
+ const argument = node.argument;
1218
+ const prefix = node.prefix;
1520
1219
  const increment = operator === "++" ? 1 : operator === "--" ? -1 : undefined;
1521
1220
  if (increment === undefined) {
1522
1221
  throw new InterpreterRuntimeError(`Unsupported update operator '${operator}'.`, node);
@@ -1531,7 +1230,7 @@ export class Interpreter {
1531
1230
  };
1532
1231
  if (argument.type === "Identifier") {
1533
1232
  return Effect.sync(() => {
1534
- const name = getString(argument, "name");
1233
+ const name = argument.name;
1535
1234
  const current = operand(this.scopes.get(name, argument));
1536
1235
  const next = current + increment;
1537
1236
  this.scopes.set(name, next, argument);
@@ -1548,34 +1247,30 @@ export class Interpreter {
1548
1247
  throw new InterpreterRuntimeError("Update target must be an Identifier or MemberExpression.", argument);
1549
1248
  }
1550
1249
  evaluateCallExpression(node) {
1551
- const callee = getNode(node, "callee");
1552
- const argNodes = getArray(node, "arguments");
1250
+ const callee = node.callee;
1553
1251
  const self = this;
1554
1252
  return Effect.gen(function* () {
1253
+ if (callee.type === "Super")
1254
+ throw unsupportedSyntax(callee.type, callee);
1555
1255
  const callable = yield* self.evaluateExpression(callee);
1556
1256
  if (callable === OptionalShortCircuit)
1557
1257
  return OptionalShortCircuit;
1558
- if ((callable === null || callable === undefined) && node.optional === true)
1258
+ if ((callable === null || callable === undefined) && node.optional)
1559
1259
  return OptionalShortCircuit;
1560
- const args = yield* self.evaluateCallArguments(argNodes);
1260
+ const args = yield* self.evaluateCallArguments(node.arguments);
1561
1261
  return yield* self.invokeCallable(callable, args, node, callee);
1562
1262
  });
1563
1263
  }
1564
1264
  // The single dispatch for every invocation: call expressions and callbacks share it.
1565
- invokeCallable(callable, args, node, callee = node) {
1265
+ invokeCallable(callable, args, node, callee) {
1566
1266
  const self = this;
1567
1267
  return Effect.gen(function* () {
1568
1268
  if (callable instanceof ToolReference) {
1569
- if (callable.path.length === 0)
1570
- throw new InterpreterRuntimeError("The tools root is not callable.", callee);
1269
+ if (callable.path.length === 0) {
1270
+ throw new InterpreterRuntimeError("The tools root is not callable.", callee ?? node);
1271
+ }
1571
1272
  return yield* self.createToolCallPromise(callable.path, args);
1572
1273
  }
1573
- if (callable instanceof PromiseMethodReference) {
1574
- return yield* invokePromiseMethod(self.runner, self.promises, callable, args, node);
1575
- }
1576
- if (callable instanceof PromiseInstanceMethodReference) {
1577
- return yield* invokePromiseInstanceMethod(self.runner, self.promises, callable, args, node);
1578
- }
1579
1274
  if (callable instanceof CodeModeFunction) {
1580
1275
  return yield* self.invokeFunction(callable, args);
1581
1276
  }
@@ -1586,103 +1281,26 @@ export class Interpreter {
1586
1281
  return callable.generator.asynchronous ? yield* self.createPromise(requested) : yield* requested;
1587
1282
  }
1588
1283
  if (callable instanceof IntrinsicReference) {
1589
- return yield* invokeIntrinsic(self.runner, callable, args, node);
1590
- }
1591
- if (callable instanceof GlobalMethodReference) {
1592
- if (callable.namespace === "console")
1593
- return self.invokeConsole(callable.name, args, node);
1594
- if (callable.namespace === "Object" && args[0] instanceof ToolReference) {
1595
- return self.invokeObjectMethodOnTools(callable.name, args[0], node);
1596
- }
1597
- if (callable.namespace === "Object" && objectMethodsPreservingIdentity.has(callable.name)) {
1598
- if (callable.name === "fromEntries")
1599
- return yield* invokeObjectFromEntries(self.runner, args[0], node);
1600
- return invokeGlobalMethod(callable, args, node);
1601
- }
1602
- if (callable.namespace === "Array" && callable.name === "from") {
1603
- return yield* invokeArrayFrom(self.runner, args, node);
1604
- }
1605
- if ((callable.namespace === "Object" || callable.namespace === "Map") && callable.name === "groupBy") {
1606
- return yield* invokeGroupBy(self.runner, callable.namespace, args, node);
1607
- }
1608
- if (callable.namespace === "Math" && callable.name === "sumPrecise") {
1609
- return yield* invokeMathSumPrecise(self.runner, args[0], node);
1610
- }
1611
- if (callable.namespace === "Array" && callable.name === "of") {
1612
- return invokeGlobalMethod(callable, args, node);
1613
- }
1614
- return boundedData(invokeGlobalMethod(callable, args, node), `${callable.namespace}.${callable.name} result`);
1284
+ return yield* invokeIntrinsic(self.runtime.runner, callable, args, node);
1615
1285
  }
1616
- if (callable instanceof JsonMethodReference) {
1617
- return yield* invokeJsonMethod(self.runner, callable.name, args, node);
1618
- }
1619
- if (callable instanceof CoercionFunction) {
1620
- return boundedData(invokeCoercion(callable, args, node), `${callable.name} result`);
1621
- }
1622
- if (callable instanceof UriFunction) {
1623
- return invokeUriFunction(callable, args, node);
1624
- }
1625
- if (callable instanceof SearchFunction) {
1626
- return yield* self.invokeSearch(args);
1627
- }
1628
- if (callable instanceof ErrorConstructorReference) {
1629
- if (callable.name === "AggregateError")
1630
- return yield* constructAggregateErrorValue(self.runner, args, node);
1631
- return constructErrorValue(callable.name, args);
1632
- }
1633
- if (callable instanceof GlobalNamespace) {
1634
- // Real JS permits calling Array, Object, Date, and RegExp without new.
1635
- if (callable.name === "Array")
1636
- return self.constructArray(args, node);
1637
- if (callable.name === "Object")
1638
- return self.constructObject(args, node);
1639
- // ISO instead of the host's locale string: CodeMode date strings are
1640
- // deterministic and must not leak the host timezone.
1641
- if (callable.name === "Date")
1642
- return new Date().toISOString();
1643
- if (callable.name === "RegExp")
1644
- return self.constructRegExp(args, node);
1645
- if (typeofValue(callable) === "function") {
1646
- throw new InterpreterRuntimeError(`Constructor ${callable.name} requires 'new'.`, node).as("TypeError");
1647
- }
1648
- throw new InterpreterRuntimeError(`${callable.name} is not a function.`, node).as("TypeError");
1649
- }
1650
- if (callable instanceof PromiseNamespace) {
1651
- throw new InterpreterRuntimeError("Constructor Promise requires 'new'.", node).as("TypeError");
1652
- }
1653
- if (callable instanceof SymbolNamespace) {
1654
- throw new InterpreterRuntimeError("Symbol is not callable; only Symbol.asyncIterator and Symbol.iterator are available.", node).as("TypeError");
1655
- }
1656
- if (callable instanceof PromiseCapabilityFunction) {
1657
- callable.settle(args[0]);
1658
- return undefined;
1286
+ if (callable instanceof PromiseInstanceMethodReference) {
1287
+ return yield* invokePromiseInstanceMethod(self.runtime.runner, self.runtime.promises, callable, args, node);
1659
1288
  }
1289
+ if (callable instanceof HostFunction)
1290
+ return yield* callable.call(args, node);
1660
1291
  if (callable === undefined || callable === null) {
1661
- throw new InterpreterRuntimeError(`${calleeDescription(callee)} is not a function.`, callee).as("TypeError");
1292
+ throw new InterpreterRuntimeError(`${calleeDescription(callee)} is not a function.`, callee ?? node).as("TypeError");
1662
1293
  }
1663
- throw new InterpreterRuntimeError("Only tools are callable here.", callee);
1294
+ throw new InterpreterRuntimeError("Only tools are callable here.", callee ?? node);
1664
1295
  });
1665
1296
  }
1666
- invokeObjectMethodOnTools(name, ref, node) {
1667
- if (name === "keys") {
1668
- return boundedData(this.enumerableKeys(ref), "Object.keys result");
1669
- }
1670
- throw new InterpreterRuntimeError(`Object.${name}(...) cannot read tool references: they are not plain data. Use Object.keys(tools) for names, or search({ query }) for signatures.`, node, "InvalidDataValue");
1671
- }
1672
- invokeConsole(name, args, node) {
1673
- if (!consoleMethods.has(name))
1674
- throw new InterpreterRuntimeError(`console.${name} is not available.`, node);
1675
- this.logs.push(formatConsoleMessage(name, args));
1676
- return undefined;
1677
- }
1678
1297
  evaluateCallArguments(argNodes) {
1679
1298
  const self = this;
1680
1299
  return Effect.gen(function* () {
1681
1300
  const args = [];
1682
- for (const [index, arg] of argNodes.entries()) {
1683
- const argNode = asNode(arg, `arguments[${index}]`);
1301
+ for (const argNode of argNodes) {
1684
1302
  if (argNode.type === "SpreadElement") {
1685
- const spread = yield* self.evaluateExpression(getNode(argNode, "argument"));
1303
+ const spread = yield* self.evaluateExpression(argNode.argument);
1686
1304
  const cursor = yield* self.syncIterator(spread, argNode);
1687
1305
  if (cursor === undefined)
1688
1306
  throw new InterpreterRuntimeError("Spread arguments require a synchronous iterable.", argNode).as("TypeError");
@@ -1701,8 +1319,7 @@ export class Interpreter {
1701
1319
  });
1702
1320
  }
1703
1321
  invokeFunction(fn, args) {
1704
- const invocation = new Interpreter(this.executeTool, this.invokeSearch, this.toolKeys, this.promises, this.logs);
1705
- invocation.scopes = new ScopeStack([...fn.capturedScopes, new Map()]);
1322
+ const invocation = new Frame(this.runtime, new ScopeStack([...fn.capturedScopes, new Map()]));
1706
1323
  const run = Effect.gen(function* () {
1707
1324
  // Seed all parameters first so defaults cannot fall through to same-named outer bindings.
1708
1325
  const paramScope = invocation.scopes.current();
@@ -1713,7 +1330,7 @@ export class Interpreter {
1713
1330
  }
1714
1331
  for (const [index, parameter] of fn.parameters.entries()) {
1715
1332
  if (parameter.type === "RestElement") {
1716
- yield* invocation.declarePattern(getNode(parameter, "argument"), args.slice(index), true, parameter, true);
1333
+ yield* invocation.declarePattern(parameter.argument, args.slice(index), true, parameter, true);
1717
1334
  break;
1718
1335
  }
1719
1336
  yield* invocation.declarePattern(parameter, args[index], true, parameter, true);
@@ -1730,7 +1347,7 @@ export class Interpreter {
1730
1347
  return run;
1731
1348
  // The initial yield assigns the promise before the body can self-resolve.
1732
1349
  const box = {};
1733
- return Effect.map(this.createPromise(Effect.flatMap(run, (value) => resolvePromiseValue(invocation.runner, value, fn.body, box))), (promise) => {
1350
+ return Effect.map(this.createPromise(Effect.flatMap(run, (value) => resolvePromiseValue(invocation.runtime.runner, value, fn.body, box))), (promise) => {
1734
1351
  box.promise = promise;
1735
1352
  return promise;
1736
1353
  });
@@ -1751,7 +1368,7 @@ export class Interpreter {
1751
1368
  if (state.draining)
1752
1369
  return Deferred.await(request.response);
1753
1370
  state.draining = true;
1754
- return Effect.andThen(this.promises.fork(invocation
1371
+ return Effect.andThen(this.runtime.promises.fork(invocation
1755
1372
  .completeGeneratorRequests(state, true)
1756
1373
  .pipe(Effect.ensuring(Effect.sync(() => (state.draining = false))))), Deferred.await(request.response));
1757
1374
  }
@@ -1789,7 +1406,7 @@ export class Interpreter {
1789
1406
  yield* invocation.completeGeneratorRequests(state, asynchronous);
1790
1407
  state.completed = true;
1791
1408
  });
1792
- return Effect.andThen(this.promises.fork(body), Deferred.await(request.response));
1409
+ return Effect.andThen(this.runtime.promises.fork(body), Deferred.await(request.response));
1793
1410
  }
1794
1411
  return Deferred.await(request.response);
1795
1412
  });
@@ -1834,12 +1451,12 @@ export class Interpreter {
1834
1451
  return request;
1835
1452
  }
1836
1453
  evaluateYieldExpression(node) {
1837
- const argument = getOptionalNode(node, "argument");
1454
+ const argument = node.argument;
1838
1455
  const self = this;
1839
1456
  return Effect.gen(function* () {
1840
1457
  if (!self.generatorState)
1841
1458
  throw new InterpreterRuntimeError("yield is only valid inside a generator.", node);
1842
- if (node.delegate === true) {
1459
+ if (node.delegate) {
1843
1460
  const value = argument ? yield* self.evaluateExpression(argument) : undefined;
1844
1461
  return yield* self.delegateYield(value, node);
1845
1462
  }
@@ -1870,9 +1487,9 @@ export class Interpreter {
1870
1487
  return Effect.gen(function* () {
1871
1488
  if (Array.isArray(value) ||
1872
1489
  typeof value === "string" ||
1873
- value instanceof CodeModeMap ||
1874
- value instanceof CodeModeSet ||
1875
- value instanceof CodeModeURLSearchParams) {
1490
+ value instanceof Values.Map ||
1491
+ value instanceof Values.Set ||
1492
+ value instanceof Values.URLSearchParams) {
1876
1493
  const cursor = yield* self.syncIterator(value, node);
1877
1494
  if (!cursor)
1878
1495
  throw new InterpreterRuntimeError("Built-in iterator is unavailable.", node);
@@ -1940,14 +1557,12 @@ export class Interpreter {
1940
1557
  }
1941
1558
  evaluateObjectExpression(node) {
1942
1559
  const objectValue = Object.create(null);
1943
- const properties = getArray(node, "properties");
1944
1560
  const self = this;
1945
1561
  return Effect.gen(function* () {
1946
- for (const propertyValue of properties) {
1947
- const property = asNode(propertyValue, "properties");
1562
+ for (const property of node.properties) {
1948
1563
  if (property.type === "SpreadElement") {
1949
- const spread = yield* self.evaluateExpression(getNode(property, "argument"));
1950
- if (spread === null || spread === undefined || isCodeModeValue(spread))
1564
+ const spread = yield* self.evaluateExpression(property.argument);
1565
+ if (spread === null || spread === undefined || Values.isValue(spread))
1951
1566
  continue;
1952
1567
  if (typeof spread !== "object" || Array.isArray(spread) || isRuntimeReference(spread)) {
1953
1568
  throw new InterpreterRuntimeError("Object spread requires a data object.", property, "InvalidDataValue");
@@ -1960,21 +1575,16 @@ export class Interpreter {
1960
1575
  copyIteratorSymbols(spread, objectValue);
1961
1576
  continue;
1962
1577
  }
1963
- if (property.type !== "Property") {
1964
- throw new InterpreterRuntimeError("Only standard object properties are supported.", property);
1965
- }
1966
- if (getString(property, "kind") !== "init") {
1578
+ if (property.kind !== "init") {
1967
1579
  throw new InterpreterRuntimeError("Only init object properties are supported.", property);
1968
1580
  }
1969
- const keyNode = getNode(property, "key");
1970
- const valueNode = getNode(property, "value");
1971
- const computed = getBoolean(property, "computed");
1581
+ const keyNode = property.key;
1972
1582
  let key;
1973
- if (computed) {
1583
+ if (property.computed) {
1974
1584
  key = self.toPropertyKey(yield* self.evaluateExpression(keyNode), keyNode);
1975
1585
  }
1976
1586
  else if (keyNode.type === "Identifier") {
1977
- key = getString(keyNode, "name");
1587
+ key = keyNode.name;
1978
1588
  }
1979
1589
  else if (keyNode.type === "Literal") {
1980
1590
  key = self.toPropertyKey(keyNode.value, keyNode);
@@ -1985,25 +1595,23 @@ export class Interpreter {
1985
1595
  if (isBlockedMember(String(key))) {
1986
1596
  throw new InterpreterRuntimeError(`Property '${String(key)}' is not available.`, keyNode);
1987
1597
  }
1988
- Reflect.set(objectValue, key, yield* self.evaluateExpression(valueNode));
1598
+ Reflect.set(objectValue, key, yield* self.evaluateExpression(property.value));
1989
1599
  }
1990
1600
  return objectValue;
1991
1601
  });
1992
1602
  }
1993
1603
  evaluateArrayExpression(node) {
1994
- const elements = getArray(node, "elements");
1995
1604
  const values = [];
1996
1605
  const self = this;
1997
1606
  return Effect.gen(function* () {
1998
- for (const elementValue of elements) {
1999
- if (elementValue === null) {
1607
+ for (const element of node.elements) {
1608
+ if (element === null) {
2000
1609
  // A literal elision is a real hole, like JS: extend length without an own index.
2001
1610
  values.length += 1;
2002
1611
  continue;
2003
1612
  }
2004
- const element = asNode(elementValue, "elements");
2005
1613
  if (element.type === "SpreadElement") {
2006
- const spread = yield* self.evaluateExpression(getNode(element, "argument"));
1614
+ const spread = yield* self.evaluateExpression(element.argument);
2007
1615
  const cursor = yield* self.syncIterator(spread, element);
2008
1616
  if (cursor === undefined)
2009
1617
  throw new InterpreterRuntimeError("Array spread requires a synchronous iterable.", element).as("TypeError");
@@ -2022,28 +1630,28 @@ export class Interpreter {
2022
1630
  });
2023
1631
  }
2024
1632
  evaluateTemplateLiteral(node) {
2025
- const quasis = getArray(node, "quasis");
2026
- const expressions = getArray(node, "expressions");
1633
+ const quasis = node.quasis;
1634
+ const expressions = node.expressions;
2027
1635
  let output = "";
2028
1636
  const self = this;
2029
1637
  return Effect.gen(function* () {
2030
1638
  for (let index = 0; index < quasis.length; index += 1) {
2031
- const quasi = asNode(quasis[index], "quasis");
2032
- const rawValue = quasi.value;
2033
- if (!isRecord(rawValue) || typeof rawValue.cooked !== "string") {
1639
+ const quasi = quasis[index];
1640
+ // acorn only omits `cooked` for invalid escapes in tagged templates, which are unsupported.
1641
+ if (typeof quasi.value.cooked !== "string") {
2034
1642
  throw new InterpreterRuntimeError("Invalid template literal quasi.", quasi);
2035
1643
  }
2036
- output += rawValue.cooked;
1644
+ output += quasi.value.cooked;
2037
1645
  if (index < expressions.length) {
2038
- const raw = yield* self.evaluateExpression(asNode(expressions[index], "expressions"));
2039
- output += coerceToString(boundedData(raw, "Template interpolation"));
1646
+ const raw = yield* self.evaluateExpression(expressions[index]);
1647
+ output += coerceToString(toProgram(raw, "Template interpolation"));
2040
1648
  }
2041
1649
  }
2042
1650
  return output;
2043
1651
  });
2044
1652
  }
2045
1653
  evaluateConditionalExpression(node) {
2046
- return Effect.flatMap(this.evaluateExpression(getNode(node, "test")), (test) => this.evaluateExpression(getNode(node, test ? "consequent" : "alternate")));
1654
+ return Effect.flatMap(this.evaluateExpression(node.test), (test) => this.evaluateExpression(test ? node.consequent : node.alternate));
2047
1655
  }
2048
1656
  applyCompoundAssignment(operator, current, incoming, node) {
2049
1657
  if (!compoundOperators.has(operator)) {
@@ -2052,21 +1660,23 @@ export class Interpreter {
2052
1660
  return this.applyBinaryOperator(operator.slice(0, -1), current, incoming, node);
2053
1661
  }
2054
1662
  getMemberReference(node, operation = "read") {
2055
- const objectNode = getNode(node, "object");
2056
- const propertyNode = getNode(node, "property");
2057
- const computed = getBoolean(node, "computed");
2058
- const optional = node.optional === true;
1663
+ const objectNode = node.object;
1664
+ const propertyNode = node.property;
1665
+ if (objectNode.type === "Super")
1666
+ throw unsupportedSyntax(objectNode.type, objectNode);
1667
+ if (propertyNode.type === "PrivateIdentifier")
1668
+ throw unsupportedSyntax(propertyNode.type, propertyNode);
2059
1669
  const self = this;
2060
1670
  return Effect.gen(function* () {
2061
1671
  const objectValue = yield* self.evaluateExpression(objectNode);
2062
1672
  if (objectValue === OptionalShortCircuit)
2063
1673
  return OptionalShortCircuit;
2064
- if ((objectValue === null || objectValue === undefined) && optional)
1674
+ if ((objectValue === null || objectValue === undefined) && node.optional)
2065
1675
  return OptionalShortCircuit;
2066
- const key = computed
1676
+ const key = node.computed
2067
1677
  ? self.toPropertyKey(yield* self.evaluateExpression(propertyNode), propertyNode)
2068
1678
  : propertyNode.type === "Identifier"
2069
- ? getString(propertyNode, "name")
1679
+ ? propertyNode.name
2070
1680
  : self.toPropertyKey(yield* self.evaluateExpression(propertyNode), propertyNode);
2071
1681
  if (objectValue instanceof ToolReference) {
2072
1682
  if (typeof key !== "string") {
@@ -2074,38 +1684,12 @@ export class Interpreter {
2074
1684
  }
2075
1685
  return new ToolReference([...objectValue.path, key]);
2076
1686
  }
2077
- if (objectValue instanceof PromiseNamespace) {
2078
- if (typeof key === "string" && promiseStatics.has(key)) {
2079
- return new PromiseMethodReference(key);
2080
- }
2081
- throw new InterpreterRuntimeError(`Promise.${String(key)} is not available. Available: Promise.all, Promise.allSettled, Promise.race, Promise.any, Promise.resolve, and Promise.reject; consume promises with await.`, propertyNode);
2082
- }
2083
- if (objectValue instanceof SymbolNamespace) {
2084
- if (key === "asyncIterator")
2085
- return new ComputedValue(AsyncIteratorSymbol);
2086
- if (key === "iterator")
2087
- return new ComputedValue(IteratorSymbol);
2088
- return new ComputedValue(undefined);
2089
- }
2090
- if (objectValue instanceof GlobalNamespace) {
1687
+ if (objectValue instanceof HostFunction || objectValue instanceof HostNamespace) {
2091
1688
  if (typeof key === "string" && isBlockedMember(key)) {
2092
1689
  throw new InterpreterRuntimeError(`${objectValue.name}.${key} is not available.`, propertyNode);
2093
1690
  }
2094
- if (typeof key !== "string")
2095
- return new ComputedValue(undefined);
2096
- if (objectValue.name === "Math" && mathConstants.has(key)) {
2097
- return new ComputedValue(Math[key]);
2098
- }
2099
- if (objectValue.name === "JSON") {
2100
- if (jsonStatics.has(key))
2101
- return new JsonMethodReference(key);
2102
- return new ComputedValue(undefined);
2103
- }
2104
- if (globalStaticMembers[objectValue.name]?.has(key)) {
2105
- return new GlobalMethodReference(objectValue.name, key);
2106
- }
2107
1691
  // Unknown static members read as undefined so feature detection works like native JS.
2108
- return new ComputedValue(undefined);
1692
+ return new ComputedValue(objectValue.member(key, propertyNode));
2109
1693
  }
2110
1694
  if (typeof objectValue === "string") {
2111
1695
  if (key === "length")
@@ -2122,29 +1706,12 @@ export class Interpreter {
2122
1706
  return new IntrinsicReference(objectValue, key);
2123
1707
  return new ComputedValue(undefined);
2124
1708
  }
2125
- if (objectValue instanceof CoercionFunction) {
2126
- if (typeof key === "string" && isBlockedMember(key)) {
2127
- throw new InterpreterRuntimeError(`${objectValue.name}.${key} is not available.`, propertyNode);
2128
- }
2129
- if (typeof key !== "string")
2130
- return new ComputedValue(undefined);
2131
- if (objectValue.name === "Number" && numberConstants.has(key)) {
2132
- return new ComputedValue(Number[key]);
2133
- }
2134
- if (objectValue.name === "Number" && numberStatics.has(key)) {
2135
- return new GlobalMethodReference("Number", key);
2136
- }
2137
- if (objectValue.name === "String" && stringStatics.has(key)) {
2138
- return new GlobalMethodReference("String", key);
2139
- }
2140
- return new ComputedValue(undefined);
2141
- }
2142
- if (objectValue instanceof CodeModeDate) {
1709
+ if (objectValue instanceof Values.Date) {
2143
1710
  if (typeof key === "string" && dateMethods.has(key))
2144
1711
  return new IntrinsicReference(objectValue, key);
2145
1712
  return new ComputedValue(undefined);
2146
1713
  }
2147
- if (objectValue instanceof CodeModeRegExp) {
1714
+ if (objectValue instanceof Values.RegExp) {
2148
1715
  if (key === "lastIndex")
2149
1716
  return { target: objectValue, key };
2150
1717
  if (typeof key === "string" && regexpProperties.has(key)) {
@@ -2154,21 +1721,21 @@ export class Interpreter {
2154
1721
  return new IntrinsicReference(objectValue, key);
2155
1722
  return new ComputedValue(undefined);
2156
1723
  }
2157
- if (objectValue instanceof CodeModeMap) {
1724
+ if (objectValue instanceof Values.Map) {
2158
1725
  if (key === "size")
2159
1726
  return new ComputedValue(objectValue.map.size);
2160
1727
  if (typeof key === "string" && mapMethods.has(key))
2161
1728
  return new IntrinsicReference(objectValue, key);
2162
1729
  return new ComputedValue(undefined);
2163
1730
  }
2164
- if (objectValue instanceof CodeModeSet) {
1731
+ if (objectValue instanceof Values.Set) {
2165
1732
  if (key === "size")
2166
1733
  return new ComputedValue(objectValue.set.size);
2167
1734
  if (typeof key === "string" && setMethods.has(key))
2168
1735
  return new IntrinsicReference(objectValue, key);
2169
1736
  return new ComputedValue(undefined);
2170
1737
  }
2171
- if (objectValue instanceof CodeModeURL) {
1738
+ if (objectValue instanceof Values.URL) {
2172
1739
  if (key === "searchParams") {
2173
1740
  return new ComputedValue(objectValue.searchParams);
2174
1741
  }
@@ -2178,7 +1745,7 @@ export class Interpreter {
2178
1745
  return { target: objectValue, key };
2179
1746
  return new ComputedValue(undefined);
2180
1747
  }
2181
- if (objectValue instanceof CodeModeURLSearchParams) {
1748
+ if (objectValue instanceof Values.URLSearchParams) {
2182
1749
  if (key === "size")
2183
1750
  return new ComputedValue(objectValue.params.size);
2184
1751
  if (typeof key === "string" && urlSearchParamsMethods.has(key)) {
@@ -2187,7 +1754,7 @@ export class Interpreter {
2187
1754
  return new ComputedValue(undefined);
2188
1755
  }
2189
1756
  // Reject unknown promise properties so a missing await cannot hide.
2190
- if (objectValue instanceof CodeModePromise) {
1757
+ if (objectValue instanceof Values.Promise) {
2191
1758
  if (key === "then" || key === "catch" || key === "finally") {
2192
1759
  return new PromiseInstanceMethodReference(objectValue, key);
2193
1760
  }
@@ -2242,9 +1809,9 @@ export class Interpreter {
2242
1809
  return new IntrinsicReference(reference.target, reference.key);
2243
1810
  return Reflect.get(reference.target, reference.key);
2244
1811
  }
2245
- if (reference.target instanceof CodeModeRegExp)
1812
+ if (reference.target instanceof Values.RegExp)
2246
1813
  return reference.target.lastIndex;
2247
- if (reference.target instanceof CodeModeURL) {
1814
+ if (reference.target instanceof Values.URL) {
2248
1815
  return Reflect.get(reference.target.url, reference.key);
2249
1816
  }
2250
1817
  return Reflect.get(reference.target, reference.key);
@@ -2254,7 +1821,7 @@ export class Interpreter {
2254
1821
  return this.modifyMember(node, () => Effect.succeed({ write: true, next: value, result: value }));
2255
1822
  }
2256
1823
  evaluateDeleteExpression(argument) {
2257
- const target = argument.type === "ChainExpression" ? getNode(argument, "expression") : argument;
1824
+ const target = argument.type === "ChainExpression" ? argument.expression : argument;
2258
1825
  if (target.type !== "MemberExpression") {
2259
1826
  throw new InterpreterRuntimeError("Only data fields may be deleted.", argument);
2260
1827
  }
@@ -2264,10 +1831,10 @@ export class Interpreter {
2264
1831
  if (reference instanceof ComputedValue ||
2265
1832
  reference === undefined ||
2266
1833
  isOpaqueMemberReference(reference) ||
2267
- reference.target instanceof CodeModeURL) {
1834
+ reference.target instanceof Values.URL) {
2268
1835
  throw new InterpreterRuntimeError("Only data fields may be deleted.", target, "InvalidDataValue");
2269
1836
  }
2270
- if (reference.target instanceof CodeModeRegExp) {
1837
+ if (reference.target instanceof Values.RegExp) {
2271
1838
  return Reflect.deleteProperty(reference.target.regex, reference.key);
2272
1839
  }
2273
1840
  return Reflect.deleteProperty(reference.target, reference.key);
@@ -2299,10 +1866,10 @@ export class Interpreter {
2299
1866
  });
2300
1867
  }
2301
1868
  readReferenceValue(reference, key) {
2302
- if (reference.target instanceof CodeModeURL) {
1869
+ if (reference.target instanceof Values.URL) {
2303
1870
  return Reflect.get(reference.target.url, key);
2304
1871
  }
2305
- if (reference.target instanceof CodeModeRegExp)
1872
+ if (reference.target instanceof Values.RegExp)
2306
1873
  return reference.target.lastIndex;
2307
1874
  return Reflect.get(reference.target, key);
2308
1875
  }
@@ -2316,7 +1883,7 @@ export class Interpreter {
2316
1883
  target[key] = next;
2317
1884
  return;
2318
1885
  }
2319
- if (reference.target instanceof CodeModeURL) {
1886
+ if (reference.target instanceof Values.URL) {
2320
1887
  const property = key;
2321
1888
  if (!urlWritableProperties.has(property)) {
2322
1889
  throw new InterpreterRuntimeError(`URL.${property} is read-only.`, node).as("TypeError");
@@ -2332,7 +1899,7 @@ export class Interpreter {
2332
1899
  throw new InterpreterRuntimeError(`URL.${property} received an invalid value.`, node).as("TypeError");
2333
1900
  }
2334
1901
  }
2335
- if (reference.target instanceof CodeModeRegExp) {
1902
+ if (reference.target instanceof Values.RegExp) {
2336
1903
  reference.target.lastIndex = next;
2337
1904
  return;
2338
1905
  }