Add `^category` front matter to branching, classes, error-handling, fibers, functions, lists, looping, maps, method-calls, performance, and qa markdown files. Create new placeholder pages for contributing, core-libraries, and embedding-api under reference category. Remove old embedding and getting-involved pages. Change all `:::wren` code block annotations to `:::dart` across multiple documentation files. Update index title from "Welcome" to "Welcome!" and fix a typo in the Wren class example string. Refine performance page wording for clarity.
Add `^category` front matter to all language, types, and reference doc pages for site navigation restructuring. Replace `:::wren` and `:::java` code block annotations with `:::dart` across multiple files. Create new stub pages for core-libraries, embedding-api, and contributing under the reference category. Remove the old embedding and getting-involved stub pages.
Add new `fiber.call` method that remembers the calling fiber for symmetric transfer, while `fiber.run` now performs tail-call style switching without preserving the caller. Introduce re-entrancy guards preventing a fiber from being called multiple times, update all test fixtures to use the new API, and add comprehensive test coverage for call semantics including direct/indirect re-entrancy, value passing, and finished fiber errors.
Replace fixed-width `.page` with `max-width`, add `padding` to body, and introduce two breakpoints (639px and 479px) that adjust nav gutter, header centering, and main margin. Convert `.header`, `.content`, `.nav` divs to `<header>`, `<main>`, `<nav>` tags, add viewport meta tag, and hide GitHub ribbon on small screens.
Add a comprehensive Getting Started guide covering Unix/Mac installation via git clone and make, interactive mode usage with code examples, and script execution with a Mandelbrot fractal demo. Also update the site navigation template to link the new page, add placeholder pages for Embedding, Error Handling, and Getting Involved, fix the index page link from "usage.html" to "embedding.html", and reorder the types section in the nav to list Fibers before Functions.
Add 15 static overloads of IO.print in builtin/io.wren and src/wren_io.c, each delegating to a new private printList_ method that iterates over a list of objects. Update all benchmark and test files to use the new multi-argument syntax, removing explicit .toString calls and string concatenation. Add a comprehensive test/io/print.wren verifying single-argument return value, multi-argument null return, and concatenation of up to 16 arguments.
Replace legacy setter syntax `property = value { ... }` with the modern
`property=(value) { ... }` form across all five property setters in the
Variable class (determinedBy, mark, walkStrength, stay, value).
- Replace silent null return with explicit string type check in string_plus native
- Remove outdated TODO comments about string coercion from both num_plus and string_plus
- Add test for basic string concatenation ("a" + "b")
- Add test verifying runtime error when concatenating string with non-string ("a" + 123)
Enforce syntactic requirement for parentheses in operator method signatures (e.g., `+(other)` instead of `+ other`) and setter definitions (e.g., `bar=(value)` instead of `bar = value`). Update the compiler's `infixSignature`, `mixedSignature`, and `namedSignature` functions to consume explicit `(` and `)` tokens around parameter names. Migrate all built-in core library operator definitions and test fixtures to the new parenthesized syntax.
Add `list_instantiate` native to create empty lists, bind it to List's metaclass for `new` support, and remove the related TODO. Also change three `inline` functions in `wren_value.h` to `static inline` to prevent linker errors. Include a new test `test/list/new.wren` verifying `new List` yields an empty list that supports `add`.
Move the wrenIsBool and wrenIsObjType function definitions from wren_value.c
into wren_value.h as inline functions, eliminating function call overhead.
Also relocate OBJ_VAL macro definition to appear before its first use in the
header and add inline for wrenObjectToValue. This yields 3-13% speedup across
benchmarks (binary_trees, delta_blue, fib, for, method_call).
The internal PinnedObj type was renamed to WrenPinnedObj across the codebase to make it publicly accessible, as the WREN_PIN macro expands to stack allocations of this type that must be visible to external consumers. Updated all typedefs, function signatures, and variable declarations in wren_vm.c and wren_vm.h to use the new prefixed name, and removed the TODO comment about moving the struct into wren_vm.c.
Rename boolean defines from `true`/`false` to `1`/`0` for consistency, prefix debug flags with `WREN_DEBUG_`, add `WREN_USE_LIB_IO` flag to guard IO library loading, and wrap IO module includes and function declarations in conditional compilation blocks.
Replace the nested `SymbolTable` struct (containing a `StringBuffer names` field) with a direct `typedef StringBuffer SymbolTable`, updating all internal accesses from `symbols->names.data` to `symbols->data` and `symbols->names.count` to `symbols->count`. Rename `vm->methods` to `vm->methodNames` and `vm->globalSymbols` to `vm->globalNames` across the codebase, including debug printing, compiler symbol resolution, core initialization, and VM interpreter error messages. Remove the stale TODO comment about error codes in `wren.h` and adjust the `instantiate` method name to include a leading space to prevent direct user invocation.
Fix missing space between 'false' and 'for' in the reserved words example
on the syntax documentation page. Also capitalize 'Method calls' to
'Method Calls' and 'Error handling' to 'Error Handling' in the template
navigation sidebar for consistent title casing.
Replace the static `Value globals[MAX_GLOBALS]` array in WrenVM with a dynamic `ValueBuffer` that grows on demand, removing the 256-global limit. Introduce `wrenDefineGlobal()` helper that adds a named global to the symbol table and stores its value in the buffer, returning -2 when the 65536 limit is reached. Update all global access sites (compiler emit, runtime interpreter, GC marking, debug disassembly, core class definition) to use the buffer's data pointer and short (16-bit) opcode arguments instead of byte-sized ones. Add a regression test `many_globals.wren` that defines 8200 globals to verify the new capacity.
Add `addAll(other)` method to the List class in both the Wren core library source and its embedded C string representation. The method iterates over the given `other` sequence, appends each element to the list using the existing `add()` method, and returns the original `other` argument to match the documented return behavior. Include a new test file `test/list/add_all.wren` covering basic appending, empty iterable, range input, and return value verification.
- Delete doc/site/style.css and add doc/site/style.scss with Sass variables, Dosis header font, box-sizing, absolute header positioning, and link hover effects
- Update template.html to reference Dosis font, lowercase nav headings, and change tagline to "a classy little scripting language"
- Add .sass-cache/ to .gitignore and rename Makefile phony target from docs to builtin
- Modify generate_docs.py to compile style.scss via sass subprocess instead of copying static CSS
- Tweak performance.markdown and qa.markdown for minor wording improvements
Replace the placeholder TODO stub with full documentation covering function creation, block arguments, parameters, closures, and usage patterns. The new content includes examples of block argument syntax, method definitions accepting functions, and passing existing function objects as arguments.
Refactor fiber creation from a static `Fiber.create` method to a constructor-based `new Fiber` pattern. This introduces a `fiber_instantiate` native that returns the Fiber class itself, allowing `new Fiber` to invoke `fiber_new` for validation and creation. A shared `validateFn` helper is added to centralize function argument checking, replacing inline validation in both `fiber_new` and `fn_new`. All test files are updated to use the new syntax, and the old `create_wrong_arg_type` test is replaced with `new_wrong_arg_type`.
Add type checking to the `fn_new` native function to ensure the argument
passed to `Fn.new` is either a function or closure. Previously, passing
an invalid type like an integer would silently succeed. Now it returns
a clear runtime error message: "Argument must be a function."
Also remove two stale TODO comments about newline handling in the
compiler that were no longer relevant to current parsing logic.
This change shifts newline tokenization from the lexer's readRawToken into the parser's nextToken, allowing the grammar to selectively ignore newlines in specific contexts (e.g., after operators like "|", "is", "for", "if", "while") while treating them as errors in others (e.g., after "var", "new", "class", "static", before commas in lists). The lexer now emits TOKEN_LINE for semicolons and newlines uniformly, and the parser decides which to elide. Test files are updated to reflect the new error expectations and to remove tests for newlines that are now grammatically allowed.
Refactor `finishBlock` in `wren_compiler.c` to detect single-expression bodies (no newline after `{`) and leave a value on the stack, enabling implicit returns for methods and functions. Add `finishBody` wrapper to handle constructor flag. Update all benchmark and test `.wren` files to remove explicit `return` keywords from getters and single-expression methods, relying on the new implicit return behavior. Remove old `return_null_if_brace.wren` test, add `newline_body.wren`, `newline_in_expression_block.wren`, and `no_newline_before_close.wren` tests for edge cases.
Remove the TOKEN_FN enum value, its keyword mapping in readName, and the
associated function syntax handling from the tokenizer. Also clean up
unnecessary operator tokens from the newline-skipping switch in nextToken
to simplify the token processing logic.
Replace all occurrences of the old `fn` function literal syntax with the new `new Fn {|params| body}` block syntax across benchmark, test, and source files. Update the Wren compiler to handle the pipe operator as a block argument delimiter by removing `TOKEN_PIPE` from the newline-swallowing token list and adding explicit newline matching in `infixOp`. Adjust test expectations in `conditional/precedence.wren` to remove `fn`-based expressions and update `test/assignment/local.wren` to use the new syntax.
Refactor the 'new' operator compilation to emit a method call to 'instantiate' on the class instead of using a dedicated bytecode instruction. This allows built-in types like Fn to override instantiation behavior, enabling `new Fn { ... }` to return the block argument directly. Remove the CODE_NEW opcode from the VM, compiler, and debug printer, and add native methods `class_instantiate`, `fn_instantiate`, `fn_new`, and `object_instantiate` to handle the new dispatch. Update test files to reflect the renamed `Function` class to `Fn`.
Update all fiber test files to replace `Fiber.create(fn { ... })` with `Fiber.create { ... }` block syntax, and add compiler support for parsing block bodies without requiring a newline after the opening brace. The compiler changes include removing `TOKEN_LEFT_BRACE` from the newline-discarding token list and adding `match(compiler, TOKEN_LINE)` calls in `finishBlock`, `methodCall`, `function`, and `block` to handle empty block bodies and inline expressions.
Replace two static error-reporting functions with a single RUNTIME_ERROR macro that stores the fiber frame before calling runtimeError and returning false. This consolidates error handling logic and prepares for catching runtime errors from other fibers by ensuring consistent frame preservation.
In the interpreter's NEW opcode handler, check if the top-of-stack value is a class before attempting construction. If not, raise a runtime error with a descriptive message instead of silently failing or crashing.
Also add a test case (test/new_on_nonclass.wren) that verifies the error is correctly triggered when calling new on a non-class value like an integer.
Implement num_bitwiseAnd and num_bitwiseOr native methods that cast operands to uint32_t before applying bitwise operations, matching the existing bitwiseNot pattern. Register both operators on the number class and add test files covering basic cases, max u32 boundary, overflow behavior, and non-numeric operand error handling.
Add ObjClass parameter to methodNotFound function to display the receiver's class name in runtime error messages, replacing the generic "Receiver" placeholder with specific class names like "Foo" or "Bar metaclass". Update all call sites in runInterpreter to pass classObj, and adjust existing test expectations plus add a new static_method_not_found.wren test for metaclass error messages.
Add two TODO comments to `doc/site/classes.markdown` noting the need to document static methods and to refactor the relationship between method-calls and classes documentation. Also add a matching TODO to `doc/site/method-calls.markdown` to coordinate the refactoring of both pages into using and creating classes.
Swap the order of the site name and page title in the HTML `<title>` tag from "Wren - {title}" to "{title} – Wren", ensuring the specific page title appears first when multiple tabs are open in the browser.
Register TOKEN_PIPE and TOKEN_AMP as infix operators with PREC_BITWISE precedence in the grammar rules table, replacing their previous UNUSED entries. Add corresponding method definitions and test expectations for the `&` and `|` operators in the operator overloading test suite.
Update all lowercase `io` references to uppercase `IO` in doc files including
implicit fields, receiver-less calls, branching, method-calls, syntax, and
variables documentation to match the Wren language's actual API casing.
Extract the common `map` and `where` methods from `List` into a new `Sequence` base class, making `List is Sequence` and `Range is Sequence`. Remove duplicate native method registrations for Range in wren_core.c and add new test files for Range map/where operations.
Replace the TODO-marked manual if-else logic in `Strength.weakest` and `Strength.strongest` with the ternary operator, and refactor the manual while-loop list filtering in `Variable.removeConstraint` to use the `.where()` method for cleaner, more idiomatic Wren code.
Add TOKEN_QUESTION token type and implement conditional() parsing function in wren_compiler.c to support the ternary conditional operator (condition ? then : else). Register fn_toString native in wren_core.c to return "<fn>" string for function objects. Include comprehensive test suite covering precedence, short-circuit evaluation, and error cases for missing tokens.
Implement a `where` method on the List class that takes a function `f` and returns a new list containing only elements for which `f.call(element)` returns true. The implementation is added both in the builtin core.wren source and embedded in the C library source string in wren_core.c. Also includes a new test file `test/list/where.wren` verifying filtering with matching and non-matching predicates.
In classDefinition in wren_compiler.c, add a check for TOKEN_RIGHT_BRACE before
requiring a newline after the last method definition, so that a closing brace
immediately following a method is accepted. Update test/class/syntax.wren with
a test case for this syntax.
Add special case in list_subscript native to return a new empty list when
the source list is empty and the requested range is [0..-1] (inclusive) or
[0...0] (exclusive). This enables using list[0..-1] as a universal copy
idiom that works even for empty lists. Update the List.+ operator to use
this idiom instead of manual iteration. Add test cases for both range
forms on empty lists.
The previous implementation of List.+ used conditional checks (`this.count > 0`, `that.count > 0`) before iterating, which caused the loop body to be skipped entirely for empty lists. This commit removes those guards, allowing the for-in loops to run unconditionally — the Wren VM's iterate/iterateValue protocol already handles the empty case correctly at the native level. Additionally, the `list_iterate` native in `wren_core.c` now returns `false` immediately when the list count is zero and the iterator argument is null, preventing an out-of-bounds index of 0 from being returned for empty lists. The test file `test/list/concat.wren` is renamed to `test/list/plus.wren` and extended with a check that the original list `a` remains unmodified after concatenation. A new test in `test/list/iterate.wren` verifies that iterating over an empty list returns `false`.
Move upvalue closing logic from the else branch to before the fiber completion check
to ensure upvalues are properly closed when a fiber finishes. Add test cases for
closure behavior across fiber yields and for Fiber.create argument type validation.
Add a new test file `this_in_static_method.wren` that validates `this` evaluates to the class object when used inside a static method, and removes the TODO comment from `this_in_method.wren` that previously noted this untested behavior.
In the compiler, when a bare name is encountered inside a class definition and it does not resolve to a local variable or global, emit an implicit `this.` load before the call, enabling getter, setter, and method calls without explicit receiver. Update all benchmark, builtin, and test files to remove redundant `this.` qualifiers, and add comprehensive test suites for implicit receiver behavior across instance, inherited, static, nested, and shadowing scenarios.
Add python3 as a new language entry in the benchmark runner configuration, enabling automated performance testing with Python 3. Update multiple benchmark scripts (binary_trees.py, delta_blue.py, fib.py, for.py, method_call.py) to be compatible with Python 3 by adding `from __future__ import print_function`, replacing `xrange` with a `range` polyfill, converting print statements to function calls, and replacing integer division with floor division. Remove the custom `OrderedCollection` class in delta_blue.py in favor of standard Python lists.
Add the DeltaBlue constraint-solving benchmark ported from Dart to Wren, along with supporting Lua and Python versions for cross-validation. The Wren implementation includes the full constraint hierarchy solver with strength classes, plan execution, and the standard DeltaBlue test harness. Register the benchmark in run_bench with expected output "7032700".
When shrinking a list's capacity, wrenReallocate may return a different
memory address. The previous code ignored the return value, leaving
list->elements pointing to freed memory. This fix assigns the result
back to list->elements and adds a regression test for grow/shrink
behavior.
The previous comparison `classObj->methods.count < symbol` incorrectly allowed
access when `symbol` equals `count`, which is out of bounds for zero-indexed
arrays. Changed both occurrences in `runInterpreter` to use `symbol >= count`
to properly guard against out-of-bounds access.
Add two new public API functions to the Wren VM for foreign function interface
(FFI) return values. wrenReturnNull sets the foreign call slot to a null value,
while wrenReturnString copies the provided text into a new Wren heap string,
supporting both explicit length and strlen-based length calculation. Both
functions include assertions to ensure they are called within a valid foreign
call context.
Add `numParams` field to `ObjFn` and `Compiler` structs to track expected parameter count. Refactor `parameterList` to return count and store it in compiler. Modify `endCompiler` to pass `numParams` to `wrenNewFunction`. Replace single `fn_call` native with 17 arity-specific `fn_call0` through `fn_call16` natives that validate argument count against `fn->numParams` via `callFunction` helper, returning error on missing args. Remove stale TODO comment in VM interpreter. Add test files `call_extra_arguments.wren` and `call_missing_arguments.wren`.
Migrate the clock timing functionality from the OS class to the IO class across all benchmark scripts and the core library. Remove the os_clock native function and its associated OS class definition from wren_core.c, while adding a new ioClock native in wren_io.c that uses the same clock()/CLOCKS_PER_SEC logic. Update all benchmark files (binary_trees, fib, for, method_call) to reference IO.clock instead of OS.clock for both start time and elapsed time calculations.
Replace monolithic corelib.wren with per-class builtin/*.wren files and generate_builtins.py script. Move IO class definition and its native writeString_ method from wren_core.c to new wren_io.c, adding wrenGetArgumentString and wrenDefineStaticMethod to the public API. Update Makefile target from corelib to builtin and remove generate_corelib.py.
Replace the TODO placeholder for error codes with a proper WrenInterpretResult enum
containing WREN_RESULT_SUCCESS, WREN_RESULT_COMPILE_ERROR, and
WREN_RESULT_RUNTIME_ERROR. Update wrenInterpret signature to return the new type
and refactor callers in main.c and wren_vm.c to use the enum values instead of
magic exit codes. Also add a startup banner to the REPL.
Replace TODO comments with proper error reporting for unterminated strings, incomplete Unicode escapes, and invalid escape sequences. Add five new test files covering each error case.
Replace all (void) POP() calls with a dedicated DROP() macro that decrements
fiber->stackSize directly, eliminating unused-value compiler warnings and
making the intent of discarding the stack top explicit throughout the
interpreter loop, logical operators, upvalue closing, and object construction.
Extract CSS modification time comparison into reusable `compare_modification_times` helper and apply it to CSS copying logic, ensuring style.css is recopied when source is newer than destination. Also fix output path from `build/docs/` to `build/site/` for generated HTML files.
Update the shebang line in both generate_corelib.py and generate_docs.py scripts to use
/usr/bin/env python instead of hardcoded /usr/bin/python, improving portability across
different Python installations and virtual environments.
Extend the list subscript operator to accept Range arguments in addition to plain numbers. When a Range is provided, the operator returns a new list containing the elements within that range, supporting inclusive (..) and exclusive (...) bounds, negative indices that count from the end, and automatic reversal for backwards ranges. Added validation functions for integer values and range bounds, with dedicated error messages for non-integer range endpoints and out-of-bounds conditions. Updated the test suite with comprehensive range subscript tests and removed the old test that only checked for non-numeric subscripts.
In the compiler's classDefinition function, the class name constant is now emitted as a separate CODE_CONSTANT instruction before CODE_CLASS, instead of being passed as a short argument to CODE_CLASS. The VM's CLASS case handler is updated to pop the class name string from the stack using PEEK2() instead of reading it from the constant table via READ_SHORT(). The comment in wren_vm.h is revised to document that the class name is now on the stack below the superclass.
Store the class name string in `ObjClass` during compilation and class creation, and expose it through a new `class_name` native method. Also update `object_toString` to return the class name for class instances and "instance of <name>" for regular instances.
Eliminate the dedicated CODE_SUBCLASS opcode and instead push a null value to indicate implicit inheritance from Object. This simplifies the bytecode interpreter by using a single CODE_CLASS instruction that checks the top of stack for a null sentinel to determine whether to use the implicit Object superclass or a user-provided superclass. The change also consolidates argument counting and debug printing logic, removing the now-unnecessary case branches for CODE_SUBCLASS across the compiler, VM, and debug modules.
The getNumArguments function was incorrectly returning the number of upvalues
as a direct count instead of accounting for the two bytes consumed per upvalue
in the bytecode stream. This caused the patching loop to exit prematurely when
processing closures with multiple upvalues, leading to corrupted bytecode offsets
and runtime crashes.
Add a check for feof(stdin) after fgets in the REPL input loop in src/main.c. When the user presses Ctrl-D, stdin is closed and fgets returns NULL without reading input. The new code detects this condition, prints a newline for clean terminal output, and returns 0 to exit the REPL gracefully instead of continuing with an empty or uninitialized line buffer. This resolves issue #6 where Ctrl-D caused undefined behavior or an infinite loop.
Introduce a Makefile providing convenience targets for building the wren
interpreter from source, cleaning build artifacts, running tests,
generating documentation, and building the core library. The default
target compiles all C sources under src/ with headers from include/,
places the resulting binary in build/Release/, and ensures the output
directory exists.
The for-in loop in Wren already increments the loop variable automatically, so the explicit `i = i + 1` inside the loop body was causing every other element to be skipped when building the string representation of a List. This fix removes the unnecessary increment from both the corelib.wren source and the embedded string in wren_core.c.
Replace six separate type-check functions (wrenIsClosure, wrenIsFiber, wrenIsFn, wrenIsInstance, wrenIsRange, wrenIsString) with a single wrenIsObjType that takes an ObjType parameter. Add IS_CLASS macro and runtime validation in the IS bytecode handler to ensure the right operand is a class, producing a clear error message when it is not. Add test case for non-class right operand.
Replace silent RETURN_NULL for non-numeric right operands with explicit runtime error via validateNum in four comparison primitives (num_lt, num_gt, num_lte, num_gte). Also remove redundant IS_NUM check in num_mod. Add four new test files verifying runtime error messages for each comparison operator when given a boolean operand.
Update the VM interpreter to treat null as falsey alongside false in if, while, for, and logical AND/OR operations. Remove the TODO comment and adjust short-circuit logic in OP_JUMP_IF and OP_JUMP_IF_NOT branches. Refactor existing test files into subdirectories (if/, logical_operator/, while/) and add dedicated truthiness tests for each construct. Remove old test/if.wren and update and/or tests to exclude null/0/"" truthiness checks now that null is falsey.
Extract the common pattern of checking and setting the FLAG_MARKED bit on an object into a dedicated static helper function. This eliminates repeated inline code across markInstance, markList, markUpvalue, markFiber, and other marking functions, improving maintainability and reducing the risk of inconsistencies in cycle detection.
The change converts a manual while loop with explicit counter variable `i` and increment
to a more idiomatic Wren for-in loop over the range `1..iterations`, improving code
clarity and reducing boilerplate in the tree check computation section.