Add two new static properties to the Num class: `Num.largest` returns `DBL_MAX`
and `Num.smallest` returns `DBL_EPSILON`. Include corresponding documentation
in the core module markdown and register the primitives in the VM core
initialization.
Rename the static Num class properties from `highest`/`lowest`/`epsilon` to `largest`/`smallest` in wren_core.c, replacing the DBL_MAX/-DBL_MAX/DBL_EPSILON return values with updated DEF_PRIMITIVE implementations and corresponding PRIMITIVE registrations in wrenInitializeCore.
Remove the List.new(_) primitive that initialized a list with null elements, merging its functionality into List.filled(_,_) which now accepts both size and default value. Add validation for negative size with a clear error message, and introduce comprehensive test coverage for filled list creation including edge cases for negative size, non-integer size, and non-numeric size arguments.
Add two new list constructors to the Wren VM: `List.new(size)` creates a list of given size with null elements, and `List.filled(size, value)` creates a list with all elements initialized to a specified default value. Includes corresponding C primitives `list_newWithSize` and `list_newWithSizeDefault`, registration in `wrenInitializeCore`, and a test file verifying both constructors produce correct counts and element values. Also adds Max Ferguson to AUTHORS.
Simplify arithmetic in wrenStringFind by removing startIndex offset from loop range and using start directly as the initial index. Rename internal primitives to string_indexOf1 and string_indexOf2 for clarity. Add validateIndex helper to clamp negative start values and reject out-of-bounds indices. Update documentation to describe the new start parameter behavior. Add comprehensive test suite for indexOf with start, including negative offsets, edge cases, and error conditions.
The two-argument constructor `List.new(size, element)` was renamed to
`List.filled(size, element)` to better convey its purpose of creating a
list filled with a default value. The underlying primitive
`list_newWithSizeDefault` remains unchanged. The test file
`test/core/list/new_extra_args.wren` was updated to use the new name.
Implement two new List constructors: `List.new(size)` creates a list of given size initialized to null, and `List.new(size, default)` creates a list with all elements set to the provided default value. Add corresponding C primitives `list_newWithSize` and `list_newWithSizeDefault` in wren_core.c, register them in the core initialization, and include test coverage for both constructors. Also add Max Ferguson to AUTHORS.
Add a new primitive `string_indexOf_with_startIndex` that accepts a second integer argument to specify the starting position for the search. Modify the existing `wrenStringFind` function to accept a `startIndex` parameter, updating its Boyer-Moore-Horspool algorithm to begin scanning from the given offset. Update the `string_contains` primitive to pass `0` as the start index. Register the new overloaded method as `indexOf(_,_)` on the string class and add test cases covering boundary conditions and out-of-range start indices.
Add three new static primitives to the Num class: `highest` returning `DBL_MAX`, `lowest` returning `-DBL_MAX`, and `epsilon` returning `DBL_EPSILON`. Include `<float.h>` header for the floating-point limit constants. Register the new primitives in `wrenInitializeCore` alongside the existing `pi` static property.
Add MapEntry class to expose key-value pairs during map iteration, and make Map extend Sequence so maps can be directly iterated with `for` loops. Rename the internal `iterate_` primitive to `iterate` and update error messages for invalid map iterators.
Simplify the VM by ensuring all called objects are closures, removing the need for runtime checks between bare functions and closures. This eliminates the `IS_FN`/`IS_CLOSURE` branching in `validateFn`, `checkArity`, `bindMethod`, and `wrenNewFiber`, and changes `CallFrame.fn` from `Obj*` to `ObjClosure*`. The compiler now emits `CODE_CLOSURE` for all function declarations, even those without upvalues, trading a small allocation cost at declaration time for faster and more uniform invocation. Benchmarks show performance is neutral to slightly improved across all tested workloads.
Consolidate repetitive `vm->fiber->error = wrenStringFormat(...)` and `return false` patterns into two new macros defined in wren_primitive.h, reducing code duplication and improving consistency in error reporting for fiber operations, number parsing, and type validation helpers.
Add a `verb` string parameter to the `runFiber` helper function so that
`Fiber.try()` produces consistent error messages like "Cannot try a finished
fiber." instead of the previous generic fallback. Update all call sites
(`fiber_call`, `fiber_call1`, `fiber_transfer`, `fiber_transfer1`) to pass
the appropriate verb string, and add a new test case `try_error.wren`
verifying the error message for trying an aborted fiber.
Remove CODE_LOAD_MODULE and CODE_IMPORT_VARIABLE opcodes, replacing them with calls to System.importModule(_) and System.getModuleVariable(_,_) primitives. This simplifies the interpreter loop, improves performance by reducing bytecode dispatch, and prepares for moving module loading logic into Wren source code for embedder flexibility.
Refactor the C API for invoking Wren methods from C code. Remove the old
wrenGetMethod and wrenCallVarArgs functions that used a type-string-based
argument marshalling system. Introduce a new slot-based approach where
callers first call wrenEnsureSlots to reserve space, then use wrenSetSlot___
functions to place the receiver and arguments on the stack, and finally call
wrenCall with a handle created by wrenMakeCallHandle. Results are retrieved
via wrenGetSlot___. This change simplifies the VM internals, eliminates
varargs parsing overhead, and yields a 185% speed improvement in the call
benchmark. Update all internal modules (scheduler, io, timer) and test files
to use the new API. Also fix fiber suspension to clear the API stack pointer
and adjust the interpreter to store the final fiber result at stack[0] for
C API access.
Add lexer support for `TOKEN_INTERPOLATION` to split string literals at interpolation points, introduce `MAX_INTERPOLATION_NESTING` limit of 8, and compile interpolated strings by emitting calls to `String.interpolate_()`. Optimize list and map literal construction with new `addCore_` primitives to reduce stack churn. Update `String`, `List`, and `Map` `toString` methods in core library to use interpolation syntax, and migrate all benchmark and test files from explicit concatenation to interpolated strings.
Add a new `System.gc()` primitive that calls `wrenCollectGarbage` to allow
scripts to trigger garbage collection. Document the method in the core
System page. Remove the test-only `Api.gc()` foreign method and update
the foreign_class test to use `System.gc()` instead.
Update three inline comments in wren_core.c (defineClass docstring and wrenInitializeCore bootstrap note) and one in wren_core.h (module-level description) to consistently refer to the "core module" instead of "core library", aligning terminology with the actual module-based architecture.
The sourcePath field on ObjModule was redundant since it always matched the module name except for the main script. This change removes the parameter from wrenInterpret, wrenInterpretInModule, and wrenNewModule, and replaces all references to module->sourcePath with module->name in error reporting and debug output.
The PrimitiveResult enum (PRIM_VALUE/PRIM_FIBER) is removed and replaced with a simple bool return value where `true` indicates a normal value return and `false` signals a fiber switch or runtime error. This simplifies the interpreter dispatch in `runInterpreter` by converting the switch on enum cases into a single if/else branch, and reduces branching in the common value-returning path. All primitive function signatures, the `RETURN_VAL`/`RETURN_ERROR` macros, and the `runFiber` helper are updated accordingly.
Replace the special "call" primitive result type (PRIM_CALL) with a new METHOD_FN_CALL method type that marks function call methods. Add checkArity helper to validate argument count before invoking function closures, and update the interpreter dispatch to handle the new method type instead of relying on the removed PRIM_CALL result.
Replace the `ObjFiber* fiber` parameter in `DEF_PRIMITIVE` macro and `Primitive` typedef with direct access to `vm->fiber` inside each primitive implementation. Update all call sites in `fiber_current`, `fiber_try`, `fiber_yield`, `fiber_yield1`, `meta_eval`, and the interpreter dispatch to use `vm->fiber` or a local `current` variable instead of the passed-in `fiber` argument.
Implements two new methods on the Num class: isInfinity checks if a number is positive or negative infinity using isinf(), and isInteger checks if a number has no fractional component, returning false for NaN and infinity. Includes C primitives, documentation, and test files.
Replace separate PRIM_ERROR and PRIM_RUN_FIBER return codes with a unified PRIM_FIBER in PrimitiveResult enum, updating all primitive implementations and the interpreter switch case to use the new combined value.
Refactor runtime error handling to store errors directly in the fiber's error field instead of on the stack, enabling any object (except null) as an error value. Add Fiber.transferError(_) primitive for transferring errors between fibers. Update validation helpers to accept Value arguments directly and modify RETURN_ERROR macro to set fiber error. Adjust GC marking to use wrenMarkValue for the error field. Add tests for aborting with non-string errors and null abort behavior.
Add a `WrenWriteFn` callback to `WrenConfiguration` that allows host applications to control how text from `System.print()` and related functions is displayed. When set, the VM invokes this callback instead of directly calling `printf`. If the callback is NULL, printed text is silently discarded. The CLI's `initVM()` now registers a simple `write` function that prints to stdout, while the core `system_writeString` primitive checks for the callback before outputting. This change also refactors `wrenInitConfiguration` to set `defaultReallocate` as the default reallocation function and consolidates configuration fields into a single `WrenConfiguration` struct stored directly in `WrenVM`, removing separate member fields for reallocate, bindForeignMethod, bindForeignClass, loadModule, minNextGC, and heapScalePercent.
- Delete wren_io.c, wren_io.h, and io.wren source files
- Remove multi-arity print overloads and IO.read/IO.time methods
- Add System class with print, printAll, write, writeAll methods to core.wren
- Update all documentation examples and README to use System.print instead of IO.print
Replace the manually embedded C string constants for builtin Wren modules with
a new build system that automatically generates `.wren.inc` header files from
`.wren` source files. The old `script/generate_builtins.py` is removed and
replaced by `script/wren_to_c_string.py`, which produces standalone include
files with a `PREAMBLE` containing the module name and source path. The Makefile
gains pattern rules to rebuild these `.wren.inc` files whenever the
corresponding `.wren` source changes, and the `builtin` phony target is removed
since the generation is now automatic. The `wren.mk` wildcard lists are updated
to include the new `.wren.inc` files as dependencies. The `timer.c` and
`wren_core.c` source files now `#include` their respective `.wren.inc` headers
instead of defining the string literals inline, and the `timer.wren` trailing
newline is removed.
The string class is now documented as an immutable byte array rather than a
sequence of Unicode code points. The .count getter is removed from the string
primitive and replaced by .codePoints.count on the code point sequence
interface, making the O(n) cost explicit. Updated the doc site and test files
accordingly.
Extract codePointAt() logic into a dedicated StringCodePointSequence class that wraps a string and implements the Sequence interface, enabling iteration over code points. Add a `codePoints` getter to String that returns a new instance of this sequence. Refactor the underlying C implementation of `codePointAt_` to decode UTF-8 into actual code point integers (returning raw bytes for invalid sequences) and rename the primitive to use trailing underscore convention. Update all related tests to reflect the new behavior where mid-sequence byte indices return the raw byte string instead of an empty string, and add new test files for the code point sequence iteration.
Remove the public `byteAt(_)` method from String and its ByteSequence wrapper, renaming it to the private `byteAt_(_)` to eliminate redundancy with `.bytes[_]`. Add a native `byteCount_` primitive on String and expose it as `count` on StringByteSequence, enabling O(1) byte length queries. Update all test files to use the new `.bytes` subscript API and add a dedicated `count.wren` test for the new functionality.
Add wrenNewStringFromRange function to wren_value.c that decodes UTF-8 code points from source string and re-encodes them into result, enabling correct range subscripts on multi-byte characters. Rename wrenUtf8NumBytes to wrenUtf8EncodeNumBytes and make wrenUtf8Encode return written byte count for use in range construction. Add wrenUtf8DecodeNumBytes utility to skip continuation bytes when iterating by byte index. Remove all skip directives from test files and add UTF-8 specific test cases verifying correct slicing across code point boundaries.
The compiler no longer auto-generates a default `new()` constructor for classes. All classes must now explicitly define `construct new() {}` to be instantiable. This change removes the `createDefaultConstructor` function from the compiler, eliminates the `return_this` primitive used by Object's default initializer, and adds explicit constructors to all test and example classes. Core metaclasses (Bool, Class, Null, Num, Object, Range, Sequence) now correctly reject `new()` calls with runtime errors.
Remove the run() method from fibers and introduce transfer() for non-stack-based fiber switching, along with suspend() to pause the interpreter and return control to the host application. Update Timer.sleep() to use runNextScheduled_() instead of Fiber.yield(), and add Timer.schedule() for creating independently scheduled fibers. Refactor the core fiber runtime to support transfer semantics, including proper error handling for aborted fibers and self-transfer edge cases. Fix a missing quote in test.py's runtime error validation string.
Rename the constructor initializer signature prefix from "this " to "init " in
wren_common.h's MAX_METHOD_SIGNATURE calculation, wren_compiler.c's
signatureToString and createDefaultConstructor functions, and wren_core.c's
default Object constructor primitive registration. This changes the syntactic
keyword used to define initializer methods in the Wren language.
Refactor wrenFindVariable to accept an explicit ObjModule* parameter instead of
implicitly using the main module. Promote the internal getCoreModule helper to
a public wrenGetCoreModule function declared in wren_vm.h. Update all call sites
in wren_core.c and wren_meta.c to pass the core module when looking up core
variables, and replace inline getCoreModule calls in wren_vm.c with the new
public function. Remove the NULL-module fallback documentation from
wrenDeclareVariable and wrenDefineVariable.
Add TOKEN_CONSTRUCT as a new reserved word in the Wren compiler lexer and parser, and update the grammar rule table so that 'construct' triggers a constructor signature instead of 'this'. Modify all built-in class definitions in core.wren, wren_core.c, benchmark files, and test fixtures to use 'construct new(...)' and 'construct named(...)' syntax. Update documentation in classes.markdown and syntax.markdown to reflect the new keyword, and remove the deprecated test files for 'new' and infix class expressions.
Replace all uses of the `new` reserved word with explicit `this new()` constructor definitions and `ClassName.new()` instantiation calls in builtin/core.wren. Update all documentation files (classes.markdown, fiber.markdown, fn.markdown, sequence.markdown, error-handling.markdown, expressions.markdown, fibers.markdown, functions.markdown) to reflect the new constructor syntax, removing `new` keyword examples and replacing them with `ClassName.new()` patterns and `this new()` definitions.
Extract the common pattern of returning the receiver argument into a single
DEF_PRIMITIVE(return_this) function, and refactor fiber_instantiate,
fn_instantiate, and the default Object constructor to use it instead of
inline RETURN_VAL(args[0]) calls. Also fix trailing whitespace on isEmpty
and class_toString lines in the core library source string.
Extract class name retrieval from object_toString into a new class_toString primitive, registered on the Class metaclass. This removes the IS_CLASS branch from object_toString, which now only handles instances and falls back to "<object>". The change ensures Class objects return their own name directly via toString rather than relying on the generic object handler.
The safeToString_ mechanism introduced in 40897f33 used per-fiber maps and lists to detect recursive toString calls, but leaked memory when runtime errors occurred before cleanup. This reverts to direct toString implementations for List and Map, removing the recursive detection logic and updating tests to mark self-referencing containers as TODO.
Add `String.safeToString_` static method that tracks objects currently being
converted to string per fiber, returning "..." when recursion is detected.
Wrap List.toString and Map.toString with this guard to handle self-referential
and mutually recursive structures without crashing.
Introduce a new static method `Object.same(obj1, obj2)` that exposes the VM's
built-in equality semantics (`wrenValuesEqual`) directly, bypassing any
user-defined `==` overrides. This required creating a dedicated metaclass for
Object (subclass of Class) to host the static method without polluting every
class with a `same` method. The implementation wires up a new `Object metaclass`
in the core initialization sequence, adjusts the class hierarchy setup order,
and adds comprehensive tests covering value types, identity comparison, and
verification that `Object.same` ignores custom `==` operators.
The static helper `callFunction` in wren_core.c was renamed to `callFn` to prevent symbol conflicts with the public `wrenCallFunction` API, ensuring unique linkage and clearer separation between internal and external call paths.