This document tracks implemented and planned features for the Paserati TypeScript/JavaScript runtime, based on ES2025 and TypeScript specifications. Headline conformance numbers live in README.md; this is the per-feature surface.
A [x] here means "the syntax/API is wired up and basic cases work." Full spec coverage may still vary suite-by-suite — for live weak-spot data, run ./paserati-test262 -subpath "language" -timeout 0.2s -suite (and see builtin_opportunities.md for the built-ins side).
- Variable declarations (
let,const,var) - Semicolons (optional)
- Comments (
//,/* */) - Block scoping (
{}) - Control flow without braces (single statement bodies)
- Global variables (OpGetGlobal/OpSetGlobal)
- Module system (
import/export) - all patterns, runtime execution, cross-module type checking -
varkeyword with proper hoisting and function scope
- String literals (single/double quotes)
- Number literals (decimal, hex, binary, octal, separators)
- Boolean literals (
true,false) -
nullandundefinedliterals - Array literals (
[]) - Object literals (
{}) - Regular expression literals (
/abc/) - full RegExp support with flags - Template literals (backticks,
${}) - BigInt literals (
100n) - with constructor and arithmetic operations
-
+,-,*,/,%,** -
++,--(prefix/postfix) - Unary
-,+
-
==,!=,===,!== -
>,<,>=,<=
-
&&,||,!
-
&,|,^,~ -
<<,>>,>>>
-
=and all compound assignments (+=,-=, etc.) -
&&=,||=,??=
- Ternary (
? :) - Comma (in
forloops, array literals) -
typeof,instanceof,in,delete,void - Nullish coalescing (
??) - Optional chaining (
?.,?.[],?.()) - Type assertions (
as) - Satisfies operator (
satisfies) - Spread syntax (
...) - in calls, arrays, objects -
yield,yield* -
await - Symbols (
Symbol.iterator,Symbol.for, etc.) - Destructuring assignment (arrays, objects, nested, defaults, rest)
-
if/else if/else -
switch/case/default -
while,do...while -
for,for...in,for...of,for await...of -
break,continue - Labeled statements
-
try/catch/finallywith error stack traces -
throw
- Function declarations and expressions
- Arrow functions
- Default and optional parameters
- Rest parameters (
...) -
argumentsobject - Closures / lexical scoping
-
thiskeyword with proper context -
newoperator / constructor functions - Prototypal inheritance
-
Function.prototype.call(),.apply(),.bind() - Generator functions (
function*) - Async functions (
async function) - Async generators (
async function*)
- Array - all common methods (map, filter, reduce, sort, etc.)
- Object - static methods (keys, values, entries, assign, fromEntries, hasOwn)
- String - 22+ methods including regex integration
- Number - prototype and static methods, formatting
- Math - 30+ methods
- Date - full implementation with getters, setters, locale methods
- JSON - parse and stringify
- Map / Set - with iteration
- TypedArrays & ArrayBuffer - all types
- Promise - constructor, static methods, microtask scheduling
- Proxy & Reflect - all 13 handler traps
- Symbol - well-known symbols, registry
- BigInt - arithmetic operations
- RegExp - literals, constructor, methods
- console - log, error, warn, time, group, etc.
- performance - now, mark, measure
- eval() - direct and indirect
- Dynamic import() - with pluggable resolution
- WeakMap / WeakSet - constructors and core methods
- Timer functions (
setTimeout,setInterval) - planned
-
number,string,boolean,null,undefined -
any,void,unknown,never - Array types (
T[]), tuple types - Enum types (numeric, string, const)
- Literal types
- Union and intersection types
- Function types
- Object type literals
- Callable types
- Interfaces with inheritance
- Index signatures
- Type aliases
- Constructor types
- Generics - functions, classes, constraints, inference
- Conditional types (
T extends U ? X : Y) - Mapped types (
{ [P in K]: T }) - Utility types (Partial, Required, Readonly, Pick, Record, Omit, Extract, Exclude, NonNullable, ReturnType, Parameters)
-
keyofoperator - Indexed access types (
T[K]) - Type predicates (
x is T) - Template literal types
- Type-level
typeof -
inferkeyword
- Assignability checks
- Operator type checking
- Function call checks
- Structural typing
- Type narrowing with
typeof,instanceof, literals - Control flow analysis
- Class declarations and expressions
- Constructors with overloads
- Properties (with initializers, optional)
- Methods
- Inheritance (
extends) withsuper - Access modifiers (
public,private,protected) - Static members
- Abstract classes/methods
-
implementsclause - Generic classes (including recursive)
- Getters/setters
-
overridekeyword -
readonlyproperties - Property parameter shortcuts (
constructor(public name: string)) - Private fields (
#private) - Decorators (TC39 Stage 3 - class, method, getter/setter, static, addInitializer)
- Auto-accessor decorators (
accessorkeyword) - Namespaces (
namespace N {}) - Declaration files (
.d.ts) - Triple-slash directives
- Path mapping
- Project references
- Timer functions (
setTimeout,setInterval) - Strict null checks option
- Sparse arrays (large index optimization)
-
Dynamic Stack Expansion - Currently uses fixed 1024-frame call stack (~6MB). Could use dynamic expansion:
- Start with smaller allocation (e.g., 64 frames) to save memory
- Grow in chunks when needed
- Challenge: Upvalues store raw pointers into register stack. Options:
- Change upvalues from pointers to (frame_index, register_index) pairs
- Use chunked allocator that doesn't move memory
- Close all open upvalues before resizing
- Note: Crypto benchmark hits this limit with deep BigInteger recursion (~2000+ frames)
-
Tail Call Optimization - Already implemented, could extend to more patterns
-
Inline Caching Improvements - Current IC validates property names; could add polymorphic caching
-
Smart Pinning - Only pin registers when captured by closures, not at declaration time
- Implemented in
emitClosure/emitClosureGeneric - Reduces unnecessary register pinning for non-captured variables
- Implemented in
-
Register Spilling - Compiler panics on "ran out of registers" for very large functions
- RegExp benchmark needs ~298 simultaneous registers (exceeds 255 limit)
- Smart pinning doesn't help since all variables are live at the same time
- Need
OpLoadLocal/OpStoreLocalopcodes for spilling to heap