Replace the separate `string` ByteBuffer and `number` double fields in the Parser struct with a single `value` field of type Value. This unifies literal storage, simplifies the parser's state, and eliminates the need for separate buffers and conversion logic for different literal types.
The change modifies `makeNumber` to store parsed numbers as `NUM_VAL` directly into `parser->value`, and adds a guard in `addConstant` to return -1 early if the parser has encountered an error.
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.
- Changed error message in `constructorSignature` from "Expect constructor name after 'this'." to "Expect constructor name after 'construct'."
- Updated comment in `createDefaultConstructor` from "It just invokes 'this new()' on the instance" to "It just invokes 'construct new()' on the instance"
Implement the initial infrastructure for foreign classes in the Wren VM, including new opcodes (FOREIGN_CONSTRUCT, FOREIGN_CLASS), a WrenBindForeignClassFn callback type in the public API, and updated CLI vm.c to store and forward foreign binding callbacks via setForeignCallbacks(). The compiler now tracks whether a class is foreign via a new isForeign flag in ClassCompiler, emits CODE_FOREIGN_CONSTRUCT instead of CODE_CONSTRUCT for foreign class constructors, and errors on field definitions inside foreign classes. The debug dump and opcode header gain entries for the new opcodes, and wrenBindSuperclass handles the -1 numFields sentinel for foreign classes to prevent field inheritance from superclasses.
Extend the wrenCall variadic argument handling to accept a new 'v' type specifier,
which allows callers to pass a previously acquired WrenValue* directly without
implicitly releasing it. This enables reusing existing Wren values across multiple
calls without unnecessary string or number conversions.
The implementation reads a WrenValue* from the variadic arguments and extracts
its internal Value for the call. Additionally, fix the parameter counting logic
in makeCallStub to correctly count underscore parameters only within the
parenthesized signature portion, preventing off-by-one errors for methods with
trailing parentheses in their signature strings.
Introduce WrenValue type and wrenGetArgumentValue/wrenReleaseValue functions to allow C code to hold GC-safe references to Wren objects across foreign calls. Implement doubly-linked list management in VM struct, mark value handles during garbage collection, and add assertion in wrenFreeVM to detect unreleased values. Update test infrastructure with new get_value test case and rename existing test binding functions to camelCase convention.
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.
The addEntry function was incorrectly skipping tombstone entries when inserting new keys, causing the map to fill up with tombstones and eventually deadlock on insert. The fix removes the tombstone check that prevented overwriting tombstone slots with new entries, allowing proper reuse of removed entries.
A regression test (test/core/map/churn.wren) was added to verify that inserting and removing entries in a loop correctly maintains the map count without deadlocking.
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.
- Switch Travis CI from sudo-based apt-get to addons.apt.packages for gcc-multilib
- Enable container-based builds with `sudo: false`
- Update README.md call-to-action links to point to getting-started and browser playground
- Replace `printList_` with `printAll` in IO class and remove redundant `IO.` prefixes
- Add IO.read() method documentation and update IO.print docs for up to 16 arguments
- Reorganize community page with Libraries, Language bindings, and Tools sections
- Add wrenjs JavaScript binding and Sublime Text syntax highlighting
- Fix typo "no where" to "nowhere" in fibers documentation
- Add indentation to preprocessor defines in wren_common.h for consistency
- Remove unreachable `return 0` after UNREACHABLE() in wren_compiler.c
- Fix Windows color output by wrapping text in str() in test script
Replace three duplicated switch-on-type patterns (in wrenDebugPrintStackTrace, wrenAppendCallFrame, and runInterpreter) with a single static inline wrenGetFrameFunction that handles OBJ_FN and OBJ_CLOSURE cases with an UNREACHABLE default.
Rename private `printList_` to public `printAll` across all overloaded `IO.print` methods in both Wren source and embedded C string. Update `IO.read` to require explicit `()` call syntax in test and documentation. Revise IO documentation to clarify `print`, `printAll`, `write`, and `read` semantics with updated examples.
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.
Add support for parsing scientific notation (e.g., 2.55e2, -2.55e-2) in the
readNumber function of wren_compiler.c. The implementation handles optional
negative exponents, validates that exponent digits follow 'e'/'E', and emits
a lex error for unterminated scientific notation. Also adds comprehensive
test cases covering valid scientific literals, missing exponents, floating
exponents, missing fractional parts, and multiple exponents.
Replace the statically-sized CallFrame array in ObjFiber with a dynamically
allocated array that starts at INITIAL_CALL_FRAMES (4) and doubles when
capacity is exceeded. This reduces memory for new fibers and improves
fiber creation benchmark performance by ~45%.
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.
Eliminate the performance penalty of an if-test inside the call instruction loop by using explicit goto to share the common tail-end call-handling code between normal and superclass calls. This improves interpreter throughput across multiple benchmarks, with gains of up to 23% on the 'for' benchmark and 14% on 'fib'.
When a block is passed as an argument to a method call, the generated
function's debug name now includes the method's signature followed by
" block argument" instead of the generic "(fn)" placeholder. This
improves debugging by showing which method the block belongs to.
Add test cases for single-byte incomplete two-octet and three-octet UTF-8 sequences
in code_point_at_incomplete.wren, and remove the resolved TODO comment about testing
truncated UTF-8 buffer reads in wrenUtf8Decode.
The wrenMarkObj function already handles null pointers internally, making the explicit
`if (x != NULL)` guards unnecessary. This change removes three such checks in
wrenMarkCompiler, markFn, and collectGarbage, simplifying the code without changing
behavior.
The constants buffer was not being cleared when the compiler finished,
causing a memory leak since ownership of constants is transferred to
the new function via wrenNewFunction. Added wrenValueBufferClear calls
in both freeCompiler and endCompiler to properly release the buffer.
Super calls were dynamically resolved by walking the receiver's class hierarchy at runtime, which broke when a method containing a super call was inherited by a subclass. This change stores a reference to the superclass in a constant table slot during compilation, and the interpreter reads that constant directly to find the correct superclass method table. Also fixes getNumArguments ordering for CODE_SUPER cases and adds two test cases verifying super calls work correctly in inherited methods and closures within inherited methods.
The super() call resolution is changed from dynamic runtime lookup (walking the receiver's class hierarchy) to static binding at class definition time. This ensures correct method dispatch when a method containing a super call is inherited by another subclass.
Key changes:
- In `callSignature()`, when compiling a `CODE_SUPER_0` instruction, a constant slot is created and filled with NULL, to be populated with the superclass reference when the method is bound.
- In `getNumArguments()`, the `CODE_SUPER_0` through `CODE_SUPER_16` cases are moved after the newly added 2-argument opcodes (`CODE_JUMP`, `CODE_LOOP`, etc.) to maintain correct ordering.
- In `dumpInstruction()`, the debug output now prints the superclass constant index alongside the method symbol.
- In `runInterpreter()`, the super call execution reads the superclass directly from the function's constant table instead of deriving it from the receiver's class at runtime.
The ASCII diagrams in the NaN tagging documentation had misaligned
brackets and inconsistent dash counts that made the bit layout
confusing. Updated the exponent/mantissa separator from parentheses
to brackets, fixed the NaN bits indicator alignment, and corrected
the highest mantissa bit marker position to match the actual bit
positions in the IEEE 754 double representation.
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.
Replace the loop-based single-element writes in readUnicodeEscape and wrenBindMethod with a new BufferFill macro that grows the buffer by a specified count in one allocation. The macro doubles capacity until it fits the requested count, then fills the new slots with the given data. The existing BufferWrite is reimplemented as a call to BufferFill with count=1.
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.
Add a unique numeric ID to each fiber allocation, enabling fibers to be used as map keys. This includes updating the hash function for OBJ_FIBER to return the fiber's ID, modifying key validation to accept fibers, updating documentation to describe the new capability, and adjusting all relevant test expectations and error messages.
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 READ_BYTE and READ_SHORT macros are defined locally within functions
in wren_debug.c and wren_vm.c but were not being undefined after use,
causing potential redefinition warnings or errors when these macros
conflict with other definitions in the same translation unit. This
change adds #undef directives at the end of dumpInstruction in
wren_debug.c and runInterpreter in wren_vm.c to properly clean up
the macro definitions.
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.
When a compile error occurs, the compiler's code is freed but the parent compiler
was not restored as the active compiler. This could cause the garbage collector
to operate on a dangling compiler pointer if a collection happens after the error.
The fix calls wrenSetCompiler to restore the parent compiler before freeing,
ensuring the GC always sees a valid compiler state.
The `.list` method on Sequence was renamed to `.toList` to better reflect its
purpose of converting a sequence into a List object. This change updates the
method definition in `builtin/core.wren` and `src/vm/wren_core.c`, along with
all test files that called `.list` on sequences, maps, ranges, and custom
sequence implementations. The test file `test/core/sequence/list.wren` was also
renamed to `test/core/sequence/to_list.wren` to match the new method name.
Move the definitions of Bool, Fiber, Fn, Null, and Num classes from hardcoded C code in wren_core.c into the core.wren library source, allowing them to be parsed and created during library initialization. Simplify defineClass to always use wrenNewSingleClass, remove redundant root pushing in wrenNewClass, and adjust the class creation in the interpreter to use a Value instead of ObjClass*.
Consolidate the refactoring branch changes from patriciomacadden's fork into the main repository, incorporating the updated class definition logic in wren_core.c that replaces the separate defineSingleClass function with a unified defineClass function capable of handling both raw and subclassed class creation.
Refactor Sequence.map and Sequence.where to return lazy MapSequence and WhereSequence wrappers instead of eagerly building a List. Add new MapSequence and WhereSequence classes that delegate iteration and apply the transformation or predicate on-the-fly. Update documentation to reflect lazy semantics and the need to call .list to materialize results. Adjust all existing tests to call .list on map/where results. Add new tests in test/core/sequence/ verifying lazy behavior with infinite Fibonacci iterators.
Add a new `each` method to the Sequence class in the Wren programming language,
allowing iteration over sequence elements by passing each element to a provided
function. This replaces the previous pattern of using `map` with `Fiber.yield`
in examples, providing a more direct and idiomatic way to perform side effects
per element. The implementation includes a core library method in `core.wren`,
a C source string in `wren_core.c`, documentation in the Sequence markdown file,
and three test cases covering normal iteration, empty sequences, and non-function
argument error handling.
The defineSingleClass helper was only used for the initial Object and Class
definitions during core initialization. By inlining its logic into defineClass
with a check for vm->classClass being NULL, we eliminate a redundant function
while preserving the same behavior for those two special cases.
Introduce MapSequence and WhereSequence subclasses of Sequence that apply transformations lazily during iteration instead of building intermediate lists. Update Sequence.map and Sequence.where to return these deferred wrappers, modify all existing tests to call .list on results, and add new infinite-sequence tests verifying lazy behavior on Fibonacci iterators.
Add a new `each` method to the Sequence class that iterates over elements
calling a provided function for each, serving as a side-effect-only
alternative to `map` when the resulting list is not needed. This is
particularly important for the upcoming change where `map` will return a
new sequence instead of mutating in place, as demonstrated by updating
the README and index examples to use `each` with Fiber.yield. Includes
documentation in the Sequence API reference and three new test cases
covering normal iteration, empty sequences, and non-function argument
error handling.
Rewrite all() and any() to store and return the predicate's result directly, matching && and || semantics. Update documentation to describe the new behavior. Move tests from test/core/list/ to test/core/sequence/ and add cases verifying that the first falsey/truthy value is returned.
The return value of finishBlock() was inverted so that it now returns true
for expression bodies (value left on stack) and false for statement bodies
(no value left). All internal return points and the call site in finishBody()
were updated accordingly to maintain correct code generation behavior.
Implements a new `list` method on the Sequence class that iterates over all elements and returns them as a freshly created List object. Includes documentation with usage example and a test case using a custom TestSequence class to verify correct behavior.
Add `byteAt(index)`, `codePointAt(index)`, and `bytes` sequence to String,
enabling direct byte-level manipulation of UTF-8 encoded strings. Introduce
`\x` hex escape sequence in string literals for specifying raw byte values.
Refactor Unicode escape parsing into a generic `readHexEscape` function
supporting variable digit counts. Implement `wrenUtf8Decode` utility for
decoding UTF-8 sequences from byte buffers. Add comprehensive tests for
`byteAt` including boundary conditions and error cases.
Implements a new `list` method on the Sequence class that iterates over all elements and collects them into a new List instance. Includes documentation in the core sequence docs and a test case verifying correct behavior with a custom sequence implementation.
Implement the `String.fromCodePoint(_)` primitive that creates a string from a Unicode code point, with validation for integer range 0–0x10ffff. Extract inline UTF-8 encoding logic from `readUnicodeEscape` in the compiler into new `wrenUtf8NumBytes` and `wrenUtf8Encode` utility functions in `wren_utils`, and add `wrenStringFromCodePoint` helper in `wren_value`. Update documentation for core classes to add "Methods" and "Static Methods" section headers, and include `String.fromCodePoint` docs with example. Add a test file `from_code_point.wren` covering various code points.
Change bindMethod return type from void to Value to propagate error string when a foreign method's C function pointer is NULL. The call site in runInterpreter now checks for a string error and triggers a runtime error, preventing silent failures on missing foreign bindings.
Add three test cases: foreign method after static declaration, foreign method with a body, and unknown foreign method that expects the new runtime error message.
Add foreign static eval(source) method to Meta class in meta.wren and implement wrenBindMetaForeignMethod in wren_meta.c to handle its binding. Change the implicit module name from "main" to "core" in wren_vm.c and restrict foreign method lookup to only the "core" module, enabling Meta foreign methods to be resolved alongside IO methods. Relax the IO foreign method binder to return NULL instead of asserting for non-IO classes, allowing fallback to other library binders.
Add wren_meta.c and wren_meta.h file references to the Xcode project.pbxproj, including the wren_meta.c source in the PBXBuildFile section and both files in the PBXFileReference section. Also reformat indentation in metaEval function body and add a TODO comment for argument type checking.
Introduce a new Meta built-in class exposing a static eval(_) method for runtime code interpretation, guarded by the WREN_USE_LIB_META compile-time flag (default on). Include the meta.wren source, C implementation files, header, VM integration in wrenNewVM, test runner update to include the meta test directory, and an initial test for evaluating code that modifies an existing scoped variable.
Simplify the allocation API by dropping the unused `oldSize` argument from `WrenReallocateFn` typedef, its documentation, and all internal callers. Update `wrenReallocate` in `wren_vm.c` to pass only `newSize`, remove the `defaultReallocate` wrapper in favor of direct `realloc`, and adjust `generate_baseline` signature in benchmark script to match.
The wren_meta.h header included <stdio.h>, "wren_value.h", and "wren_vm.h"
which were not required for its declarations. These headers are already
included transitively through "wren.h" and "wren_common.h", making the
explicit includes redundant. Removing them reduces unnecessary
dependencies and potential circular inclusion issues.
Implement the `WrenBindForeignMethodFn` callback type and `bindForeignMethodFn` configuration field to allow host applications to resolve foreign method declarations at class definition time. Refactor the IO library to use this new binding mechanism instead of the previous `wrenDefineStaticMethod` approach, adding `foreign` keyword support to the lexer and compiler. Introduce `freeCompiler` helper for cleanup, store module names in `ObjModule`, and update the VM to call the binder when processing `CODE_METHOD_INSTANCE` and `CODE_METHOD_STATIC` opcodes for foreign methods.
Implement a new `count(f)` method on the Sequence class that iterates over elements and returns the number of items for which the given predicate function evaluates to true. Update the core library source, sequence documentation, and add three new test files covering normal usage, non-boolean return values, and non-function argument error handling. Also fix minor terminology in list docs (items → elements).
Rename the `Upvalue` struct and all related type references to `ObjUpvalue` across
wren_value.c, wren_value.h, and wren_vm.c. This aligns with the existing pattern
where Obj-derived types (like ObjModule, ObjClosure) use the Obj prefix even when
the type is not first-class in the language. The change touches function signatures,
variable declarations, pointer arithmetic in memory tracking, and the struct
definition itself.
Remove the `WrenVM* vm` parameter from `wrenValueBufferInit`, `wrenByteBufferInit`,
`wrenIntBufferInit`, `wrenStringBufferInit`, `wrenSymbolTableInit`,
`wrenMethodBufferInit`, `wrenStringFind`, and `wrenDebugPrintStackTrace`
functions across the compiler, core, debug, utils, value, and VM modules.
Update all call sites and macro definitions to match the simplified signatures,
eliminating dead parameters that were never used within the function bodies.
Replace the hand-rolled capacity/count/elements fields in ObjList with a
ValueBuffer struct, and update Compiler to use a ValueBuffer for its
constant pool instead of an ObjList. This eliminates the separate
ensureListCapacity and wrenListAdd functions, centralizing buffer growth
logic in wrenValueBufferWrite. Adjust all list primitives (add, clear,
count, iterate, iteratorValue) and the GC marking path to operate on the
embedded ValueBuffer. Add wrenMarkBuffer helper for marking buffer
contents during sweep.
Add CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES to both Debug and Release Xcode build configurations. Fix the resulting warnings by adding explicit casts in wren_compiler.c (readUnicodeEscape, emit, emitShort, emitByteArg) and wren_vm.c (READ_SHORT macro, makeCallStub bytecode assignment) to prevent unintended truncation or sign extension during implicit integer conversions.
Consolidate temporary variable usage in list_add, list_count, and list_iterate by directly inlining AS_LIST/AS_NUM calls. Remove the entire block of num_abs, num_acos, num_asin, num_atan, num_atan2, num_ceil, num_cos, num_floor, and num_fraction primitive definitions to eliminate boilerplate.
Add acos, asin, atan, atan2, tan methods to Num class and expose Num.pi constant with value π. Include corresponding C primitives in wren_core.c and test files for each new method.
Convert `validateIndexValue` and `validateIndex` return types to `uint32_t` with `UINT32_MAX` sentinel, update `wrenNewList`, `wrenListInsert`, `wrenListRemoveAt` signatures, and remove the TODO comment about type unification with `ObjMap`.
Add early return check in wrenFreeVM that validates the VM pointer is not NULL
and that the methodNames count is non-zero, preventing a crash when the VM
has already been freed or was never properly initialized.
Add a generic `contains(element)` method to the `Sequence` class that iterates over elements using the existing `for` loop protocol, removing the duplicate implementation from `List`. Include comprehensive test files for both `List.contains` and `Range.contains` covering ordered, backwards, and exclusive ranges. Also fix the `generate_builtins.py` script to write to the correct `src/vm/` directory path and add a `float:left` CSS rule to the main content area in the documentation stylesheet.
The contains method is promoted from List to the Sequence base class, making it available to all sequence types (including Range). Tests are added for both List.contains and Range.contains, covering ordered, backwards, and exclusive ranges.