Files

24 KiB

CodeMode Interpreter Support

This is the checkable support matrix for CodeMode's confined JavaScript interpreter. It tracks the language and standard-library surface that programs can use today, plus concrete gaps that may be implemented later.

  • [x] means the feature is implemented at the scope described here.
  • [ ] means a concrete compatibility gap remains.
  • Checked items do not promise complete ECMAScript edge-case parity; known differences are stated explicitly.
  • Intentional boundaries are not listed as compatibility work.

When behavior changes, update this file and the tests in the same change. The implementation and tests remain the ultimate source of truth.

Source and execution model

  • JavaScript parsed with the latest syntax accepted by Acorn, then restricted by the interpreter allowlist.
  • Erasable TypeScript syntax, including type annotations, type declarations, assertions, and non-null assertions. TypeScript is transpiled first; the emitted JavaScript must still use the supported subset.
  • Top-level await and return through the program's implicit async-function scope.
  • Explicit return, final top-level expression as a REPL-style result, and null when no value is produced.
  • Program results use JSON-like boundaries, with undefined and non-finite numbers normalized to null. Tool arguments follow JSON serialization semantics before their schema applies (see the tools section).
  • Live Date, RegExp, Map, Set, URL, and URLSearchParams values inside CodeMode.
  • Tool calls through the host-provided tools tree only.
  • The global search(...) built-in: synchronous tool discovery that counts as an admitted tool call and is shadowable by program declarations like other globals.
  • Cooperative timeout, an optional total tool-call limit, output bounding, and unrestricted tool-call concurrency.

Values and literals

  • null, undefined, booleans, finite and non-finite numbers, and strings.
  • Array literals, including holes and spread from arrays, strings, Maps, Sets, and URLSearchParams.
  • Object literals with shorthand, computed string/number keys, and spread from plain data objects; null and undefined are no-ops, while arrays are rejected.
  • Template literals with interpolation.
  • Regular-expression literals.
  • NaN and Infinity globals.
  • BigInt literals and in-interpreter BigInt arithmetic; BigInt remains invalid at JSON-like host boundaries.
  • Arbitrary Symbol primitive values and symbol-keyed properties. The confined Symbol.iterator and Symbol.asyncIterator keys are available only for custom iterator protocols.
  • Tagged-template calls.
  • Getter and setter definitions in object literals.

Bindings and destructuring

  • const, let, and accepted var declarations.
  • Object and array destructuring in declarations, parameters, assignment expressions, and for...of bindings.
  • Nested patterns, defaults, elisions, and rest elements.
  • Assignment to identifiers, unblocked plain-object fields, non-negative integer array indexes, and writable URL fields.
  • Direct function declarations are hoisted in program and block statement lists.
  • Parameter defaults observe a temporal dead zone for later parameters.
  • JavaScript-correct function scoping, hoisting, and redeclaration for accepted var declarations.
  • Predeclare let and const bindings in every lexical scope, including program/block bodies, switch bodies, and loop headers, so reads before initialization and self- or cross-referential initializers observe the JavaScript temporal dead zone.
  • Hoist function declarations accepted directly in switch cases.
  • Computed object destructuring keys such as const { [field]: value } = record.
  • Object destructuring from arrays, such as const { length } = values.
  • Array destructuring from supported non-array iterables: strings, Maps, Sets, and URLSearchParams.

Statements and control flow

  • Blocks and empty statements.
  • if/else and conditional expressions.
  • switch, including default clauses and fallthrough.
  • for, while, and do...while.
  • for...of over arrays, strings, Maps, Sets, and URLSearchParams.
  • for...in over own keys of plain objects, arrays, and tool references.
  • Unlabeled break and continue.
  • try, catch, optional catch bindings, and finally.
  • throw with arbitrary values.
  • Labeled statements, labeled break, and labeled continue.
  • for await...of over the supported synchronous collections and custom iterator objects using Symbol.asyncIterator or the Symbol.iterator fallback. Each iterator step is sequential, yielded promises and plain values from synchronous collections and sync iterators are awaited before binding, and abrupt loop completion invokes the iterator's optional return(). Custom async iterators control their yielded values, as in JavaScript; only their next() results are awaited. Async generators remain outside the supported subset.

Functions and callbacks

  • Function declarations, function expressions, and arrow functions.
  • Synchronous and async functions.
  • Closures, recursion, default parameters, rest parameters, and destructured parameters.
  • Expression and block function bodies.
  • User callbacks for the supported Array, Map, Set, URLSearchParams, sort, string-replacement, and Array.from mapper APIs, with one shared acceptance rule everywhere including promise reactions.
  • Boolean, Number, String, parseInt, parseFloat, isFinite, isNaN, and URI helpers as callbacks.
  • Built-in method references as callbacks, such as values.map(Math.abs), records.map(JSON.stringify), items.forEach(console.log), and Promise.resolve(-1).then(Math.abs). Extra callback arguments a built-in does not consume are ignored, like JS; consumed arguments stay strictly validated (Math.floor still rejects a string). Intrinsic references keep their receiver ("abc".includes works as a predicate), unlike detached JS methods, which lose this.
  • Constructors work as callbacks with JS call semantics: Error types construct (messages.map(Error)), and new-requiring constructors (Map, Set, URL, URLSearchParams, Promise) throw a TypeError, like JS.
  • Tool references and detached Promise statics are rejected as callbacks with a hint to wrap them in an arrow function.
  • Promise-returning string replacers are coerced synchronously to "[object Promise]", like JavaScript; they are not automatically awaited.
  • The optional thisArg of iteration methods is accepted and ignored: CodeMode functions have no this, so ignoring it matches JS arrow-function semantics exactly.
  • this in non-arrow CodeMode functions and callbacks.
  • User-defined constructor calls.
  • Function.prototype.call, apply, and bind for CodeMode functions.
  • Classes and private fields.
  • Generator functions and yield.

Expressions and operators

  • Property access with dot or computed bracket syntax.
  • Optional property access and optional calls.
  • Function/tool calls and spread arguments.
  • Sequence expressions (the comma operator).
  • await for CodeMode promises; a plain value passes through unchanged, though every await still defers its continuation one reaction turn.
  • new for Array, Object, Error types, Date, RegExp, Map, Set, URL, URLSearchParams, and Promise.
  • Arithmetic operators: +, -, *, /, %, and **.
  • Equality and ordering: ==, !=, ===, !==, <, <=, >, and >=.
  • Bitwise operators: &, |, ^, ~, <<, >>, and >>>.
  • Logical operators: &&, ||, ??, and !, with short-circuiting.
  • Unary +, unary -, void, typeof, instanceof, and own-property-only in.
  • Prefix and postfix ++ and --.
  • Plain, arithmetic, bitwise, and logical assignment operators.
  • Property deletion on plain data objects and arrays, including computed and optional forms; deleting an array index creates a hole without changing its length.

Promises and tools

  • Tool calls start eagerly and return supervised, run-once CodeMode promises.
  • Direct await, repeated awaits, and implicit resolution when a promise is returned from a function/program.
  • Promise.resolve and Promise.reject.
  • Promise.all, Promise.allSettled, Promise.race, and Promise.any over supported collections containing promises and plain values.
  • Promise.all preserves result order and rejects on the first observed failure without cancelling siblings.
  • Promise.allSettled returns plain fulfilled/rejected outcome records.
  • Promise.race settles from the first result without cancelling losers at settlement time.
  • Real promise values from Promise.all, Promise.allSettled, and Promise.race; separately constructed combinator batches overlap as in normal JavaScript.
  • Promise chaining with .then, .catch, and .finally: handlers run deferred in attach order, returned promises are adopted, handler throws reject the derived promise, .finally preserves the original settlement unless its cleanup fails, and direct self-resolution rejects with a TypeError.
  • Every await (including of plain values and already-settled promises) defers its continuation one reaction turn, so concurrent async functions interleave at await points as in JavaScript.
  • Combinators settle one reaction turn after their deciding member (V8-observable ordering): reactions already attached to members run first, and an aggregate cannot beat a plain value settling in the same turn into a Promise.race. Exact microtask-count parity beyond this observable ordering is not a documented guarantee.
  • All still-pending work (race losers, fail-fast Promise.all stragglers, and un-awaited calls alike) is interrupted when the program returns; rejections that settled un-awaited become Success.warnings diagnostics. A combinator abandoned inside its final settlement turn counts as pending and is interrupted without a warning.
  • try/catch can handle awaited tool and promise failures.
  • Promise.any: first fulfillment wins; all-rejected rejects with an AggregateError whose errors array holds the catch-normalized reasons in input order, and empty input rejects with an empty AggregateError.
  • new Promise((resolve, reject) => ...): the executor runs synchronously and receives first-class resolve/reject callables that settle the promise exactly once (they may escape the executor and settle later); an executor throw rejects unless the promise already settled, resolving with a promise adopts it, and resolving with the promise itself rejects with a TypeError. Resolver callables work anywhere callbacks are accepted, including .then/.catch handlers and collection callbacks, but remain opaque references that cannot cross the data boundary.
  • Thenable assimilation; objects with a callable then field remain plain data.
  • Dotted tool names are canonicalized into namespace paths; a path can be both callable and a namespace, and the last definition supplied for a canonical path wins.
  • Tool path segments may be named constructor, prototype, or __proto__ because paths use inert Map keys.
  • Outbound tool arguments follow JSON serialization semantics, like JSON.stringify: object properties with undefined values are dropped, undefined array elements and non-finite numbers become null, and sparse arrays densify. Tools never receive undefined inside their input object, though a bare tools.t(undefined) argument still reaches schema decoding as undefined. Program results keep the stricter normalization where every undefined becomes null.
  • Tokenize and case-fold non-ASCII tool paths, descriptions, and queries for tool search.

Objects and properties

  • Own-field reads and writes on plain data objects.
  • Object() and new Object() return {} for nullish arguments and pass objects through unchanged; primitive wrapper objects (Object(1)) are rejected explicitly.
  • Computed property names and object spread.
  • Object.keys, Object.values, Object.entries, Object.hasOwn, Object.assign, and Object.fromEntries.
  • Object.keys over arrays and tool references.
  • Object identity is preserved by in-CodeMode Object helpers.
  • Prototype traversal and mutation through __proto__, constructor, and prototype are blocked.
  • Legal own data fields named __proto__, constructor, or prototype are rejected at JSON/tool boundaries and cannot be created, read, or written in CodeMode; tool path segments with those names remain supported.
  • Object.is for supported data values.
  • Object.groupBy over supported collection iterables, with string-key coercion and null-prototype results.

Arrays

  • The Array constructor with or without new: Array(a, b) collects arguments and Array(n) creates a sparse array of that length; invalid lengths throw RangeError. Iteration, spread, join, and JSON handle holes like JavaScript, and host results normalize holes to null.
  • Static methods: Array.isArray, Array.of, and Array.from, including the Array.from mapper form with (value, index) arguments.
  • Iteration/transformation: map, filter, flatMap, and forEach.
  • Searching/tests: find, findIndex, findLast, findLastIndex, some, every, includes, indexOf, and lastIndexOf.
  • Aggregation: reduce and reduceRight.
  • Ordering: sort, toSorted, reverse, and toReversed.
  • Access/copying: at, slice, concat, flat, with, and join.
  • Mutation: push, pop, shift, unshift, splice, fill, and copyWithin.
  • Materialized iteration helpers: keys, values, and entries return arrays rather than iterators.
  • length, numeric indexing, index assignment, spread, and for...of.
  • The thisArg argument of Array.from is accepted and ignored, like JS arrows.
  • Array.prototype.toSpliced.
  • Canonical array/string index parsing: keys such as "01" remain non-index properties rather than aliasing index 1; arbitrary array-property assignment remains unsupported.
  • Array.prototype.sort preserves trailing holes, while toSorted densifies holes into undefined elements, like JavaScript.

Strings

  • Case/normalization: toLowerCase, toUpperCase, normalize.
  • Trimming: trim, trimStart, and trimEnd.
  • Searching/tests: includes, startsWith, endsWith, indexOf, lastIndexOf, and search.
  • Slicing/access: slice, substring, at, charAt, charCodeAt, and codePointAt.
  • Construction/transformation: split, concat, repeat, padStart, padEnd, replace, and replaceAll.
  • Regular-expression integration: match, materialized matchAll, replace, replaceAll, split, and search.
  • localeCompare; locale and options arguments are currently ignored.
  • toString, length, numeric indexing, spread, and for...of by Unicode code point.
  • Static String.fromCharCode and String.fromCodePoint.
  • Native argument coercion for supported String methods; for example, includes(1) and slice("1") coerce like native JS, split(undefined) returns the whole string, and includes/startsWith/endsWith reject regular expressions with a native-style TypeError. Opaque runtime references still reject as data errors, and repeat still requires a finite non-negative count.
  • Native no-argument parity for match(), matchAll(), and search(); all behave as an empty pattern. Present arguments must still be a regular expression or string pattern.

Numbers and Math

  • Coercion functions: Number, parseInt, and parseFloat.
  • Number predicates/parsers: Number.isInteger, Number.isFinite, Number.isNaN, Number.isSafeInteger, Number.parseInt, and Number.parseFloat.
  • Number formatting: toFixed, toPrecision, toExponential, toString, and valueOf.
  • Number constants: MAX_SAFE_INTEGER, MIN_SAFE_INTEGER, MAX_VALUE, MIN_VALUE, EPSILON, NaN, POSITIVE_INFINITY, and NEGATIVE_INFINITY.
  • Math constants: PI, E, LN2, LN10, LOG2E, LOG10E, SQRT2, and SQRT1_2.
  • Math methods: random, max, min, abs, acos, acosh, asin, asinh, atan, atan2, atanh, floor, ceil, round, trunc, sign, sqrt, cbrt, pow, hypot, cos, cosh, sin, sinh, tan, tanh, log, log2, log10, log1p, exp, expm1, f16round, fround, clz32, and imul.
  • Native zero-argument behavior for Number() and String(): they produce 0 and "", while Number(undefined) stays NaN and String(undefined) stays "undefined".
  • ++ and -- use CodeMode numeric coercion (numeric strings increment, plain data objects become NaN, Dates use their epoch time) and reject opaque runtime references as data errors.
  • Unknown static members on global namespaces and on Number/String/the coercion functions read as undefined for feature detection. Calling any undefined value reports a native-style TypeError naming the callee, for example Math.sum is not a function. Blocked members (constructor, __proto__, ...) still throw, and unknown Promise statics keep their descriptive error.
  • Math.sumPrecise over supported collection iterables, rejecting non-number elements without coercion.
  • Global coercing isFinite and isNaN; opaque runtime references reject as data errors, like Number(...).

JSON and console

  • JSON.parse and JSON.stringify for supported data objects; the blocked data-key gap listed above still applies.
  • Numeric/string indentation for JSON.stringify.
  • JSON.parse reviver callbacks, including postorder traversal, deletion through undefined, and root replacement. Revivers receive (key, value) but no this holder because CodeMode functions intentionally have no this.
  • JSON.stringify function and array replacers. Function replacers receive (key, value) in preorder, including the root, but no this holder. Array replacers preserve requested property order, deduplicate names, coerce number primitives, and ignore non-string/non-number entries. Primitive wrapper entries remain unsupported.
  • JSON callbacks retain the blocked-key boundary: parsed or stringified data containing __proto__, constructor, or prototype is rejected before callback traversal.
  • Captured console.log, console.info, console.debug, console.warn, and console.error.
  • Captured console.dir and console.table.

Date

  • Date.now, Date.parse, and Date.UTC.
  • new Date() from the current time, epoch milliseconds, a date string, another Date, or local components.
  • Date() without new returns the current time as a string, like JS, but in deterministic ISO format rather than the host's locale/timezone string.
  • getTime, valueOf, toISOString, toJSON, and deterministic ISO toString.
  • Local getters: getFullYear, getMonth, getDate, getDay, getHours, getMinutes, getSeconds, and getMilliseconds.
  • UTC getters: getUTCFullYear, getUTCMonth, getUTCDate, getUTCDay, getUTCHours, getUTCMinutes, getUTCSeconds, and getUTCMilliseconds.
  • getTimezoneOffset, arithmetic, relational comparison, and instanceof Date.
  • Date values serialize to ISO strings; invalid dates serialize to null.
  • Local and UTC Date setters, including native argument coercion, mutation, rollover, invalid-Date recovery, and TimeClip behavior.
  • Date.prototype.toUTCString and its toGMTString alias.
  • Native one-argument Date coercion for supported values, including booleans, null, arrays, and plain objects.
  • Native Date loose-equality and default primitive-coercion semantics, using CodeMode's deterministic ISO string representation for the string primitive.
  • Native RangeError branding for invalid toISOString() calls.

Regular expressions

  • Literal and RegExp(pattern, flags) construction, with or without new.
  • test, exec, and toString.
  • Readable source, flags, lastIndex, hasIndices, global, ignoreCase, multiline, sticky, unicode, unicodeSets, and dotAll.
  • Captures, safe named groups (blocked member names are omitted), match .index, and stateful global matching.
  • Integration with supported String methods, including function replacers.
  • Writable lastIndex.
  • Match indices metadata for the d flag, including named groups on exec, match, and matchAll results.
  • RegExp.escape.

Map and Set

  • Static Map.groupBy over supported collection iterables, preserving key identity.
  • new Map() from entry arrays or another Map.
  • Map get, set, has, delete, clear, size, and forEach.
  • new Set() from arrays, strings, or another Set.
  • Set add, has, delete, clear, size, and forEach.
  • Materialized keys, values, and entries arrays for Map and Set.
  • Spread, for...of, Array.from, and Object.fromEntries integration.
  • Map and Set values serialize to {} at host/JSON boundaries.
  • Set composition and relation methods: union, intersection, difference, symmetricDifference, isSubsetOf, isSupersetOf, and isDisjointFrom, including supported Set-like operands.

URL and URI helpers

  • encodeURI, encodeURIComponent, decodeURI, and decodeURIComponent.
  • new URL(input, base), URL.canParse, and URL.parse.
  • URL toString, toJSON, and linked searchParams.
  • Readable URL fields: href, origin, protocol, username, password, host, hostname, port, pathname, search, and hash.
  • Writable URL fields except origin.
  • new URLSearchParams() from query strings, data objects, pairs, Maps, and URLSearchParams.
  • URLSearchParams append, delete, get, getAll, has, set, sort, forEach, keys, values, entries, toString, and size.
  • URL values serialize to their href; URLSearchParams serialize to {}.

Errors and diagnostics

  • Error, TypeError, RangeError, SyntaxError, ReferenceError, EvalError, and URIError, callable with or without new.
  • AggregateError with the (errors, message?) signature and an own errors array, constructed directly or by an all-rejected Promise.any.
  • Error name/message, error inheritance through instanceof, and plain-data serialization.
  • instanceof for Date, RegExp, Map, Set, URL, URLSearchParams, Array, Object, Promise, and Error types.
  • Catchable user throws, runtime failures raised during interpreted evaluation, awaited tool failures, and awaited tool-call-limit failures; parse/compile failures, cooperative timeout, and output bounding remain outside program catch.
  • Source locations on unsupported-syntax diagnostics for JavaScript-shaped input; TypeScript transpilation may shift them.
  • Sanitized model-visible diagnostics and explicit safe ToolError messages.
  • Distinguish user-thrown failures from interpreter defects and explicit tool refusals from sanitized internal tool failures; preserve those categories in caught errors, promise rejection handlers, and Promise.allSettled reasons.