Previously, wrenImportModule unconditionally called vm->config.loadModuleFn,
causing a crash when the host did not set that function pointer. Now the
call is guarded by a NULL check, so hosts without a module loader can still
load built-in optional modules like "random" or "meta".
Move the uv_tty_reset_mode() call to execute before uv_close() on the stdinStream handle, ensuring the terminal is restored to normal mode prior to stream closure rather than after.
Extract the inline character processing logic from the REPL's main loop into a dedicated `handleChar()` method that returns a boolean to indicate whether the loop should exit. Add `_allowAnsi` flag and corresponding getter/setters for cursor and line to support a simpler fallback REPL when ANSI escape sequences are unavailable.
Add tab-completion support to the interactive REPL by introducing a new `Meta.getModuleVariables` foreign method that returns all top-level variable names from a given module. The REPL's `run()` method now handles the tab key to append completions, and the `refreshLine` method accepts a boolean parameter to control whether completion hints are shown. Also fix the Ctrl-D exit logic (inverted condition) and remove the unused `EscapeBracket` class.
Implement cursor movement (ctrl-b left, ctrl-f right), line clearing (ctrl-k kill after cursor, ctrl-u clear entire line, ctrl-l clear screen), and history navigation (ctrl-n next, ctrl-p previous) in the repl module, along with updated TODO comments for future shortcuts.
Implement a history buffer in the REPL class that stores previously entered commands and allows cycling through them using the up and down arrow keys. The `_history` list and `_historyIndex` track the current position, with `previousHistory()` and `nextHistory()` methods restoring lines from the buffer or clearing the input when reaching the end. The `executeInput()` method now appends the current line to history before resetting, and the Ctrl-D exit condition is fixed to check `_line.isEmpty` instead of `_line == ""`.
Add executeInput() method to REPL that lexes input, determines if it's a statement or expression based on the first token, and evaluates accordingly using Meta.eval for statements or the new Meta.compileExpression for expressions. Extend Meta.compile_ foreign method with isExpression and printErrors parameters, update wrenCompile signature to support expression compilation mode, and add newline handling after equals in variable definitions.
Replace the simple fgets-based REPL loop with a full-featured interactive Wren REPL module. The new implementation supports cursor movement via arrow keys, Ctrl-A/E for line start/end, Ctrl-C/D for exit/delete, character insertion/deletion, and syntax highlighting of the current input line. The C side now imports the "repl" Wren module and runs the libuv event loop instead of blocking on stdin reads.
Add a new public API function `wrenAbortFiber()` that allows foreign methods to abort the currently executing fiber with a custom runtime error object. The function validates the API slot, then sets the fiber's error field to the value in the specified slot. The interpreter loop is updated to check for a non-null fiber error after calling a foreign method, triggering a runtime error if set. New test files (error.c, error.h, error.wren) demonstrate usage via a static Error.runtimeError foreign method, verifying that the error is propagated through Fiber.try() and that the fiber's isDone and error properties are correctly set. Xcode project updated to include the new error.c source file.
Add a new `isWindows` static method to the `Platform` class that returns `true` when the host operating system name equals "Windows". This provides a less stringly-typed API compared to checking `Platform.name` directly. The implementation is a simple delegation to the existing `name` foreign method, comparing it against the "Windows" string. Includes a test that verifies `Platform.isWindows` is equivalent to `Platform.name == "Windows"`.
Add a new `isTerminal` static method to the Stdin class that returns `true` when
stdin is connected to a TTY (interactive terminal) and `false` when input comes
from a pipe. Implementation uses libuv's `uv_guess_handle` to check the stdin
descriptor. Includes documentation, foreign method declaration, module
registration, and a test expecting `false` since tests run non-interactively.
Rename the "process" module to "os" across all source files, documentation, tests, and build configuration. Add a new Platform class to the os module with static methods `name` (returns OS string like "Windows", "Linux", "OS X", "iOS", "Unix", "POSIX", or "Unknown") and `isPosix` (returns bool indicating POSIX compliance). Update all import paths from "process" to "os" in test files and module registrations. Move process.c/h to os.c/h, rename processSetArguments to osSetArguments, and regenerate the os.wren.inc bytecode source. Add documentation pages for the os module and Platform class.
Define WREN_VERSION_MAJOR, WREN_VERSION_MINOR, WREN_VERSION_PATCH macros,
WREN_VERSION_STRING "0.1.0", and WREN_VERSION_NUMBER for monotonic checks.
Update REPL banner to use WREN_VERSION_STRING instead of hardcoded "v0.0.0".
Create CHANGELOG.md documenting the first declared version.
Rename the `WrenValue` type to `WrenHandle` in the public C header, update all
function signatures (`wrenMakeCallHandle`, `wrenCall`, `wrenReleaseHandle`),
and rename the documentation page from "Slots and Values" to "Slots and Handles"
with corresponding link updates throughout the embedding guide and module source
files.
Add foreign static getter `isRaw` and setter `isRaw=(value)` to the Stdin class, backed by a new `isStdinRaw` boolean flag and `uv_tty_set_mode` calls. The getter returns the current raw mode state, while the setter initializes the stdin stream if needed and applies raw or normal mode only when stdin is a TTY. Also includes a test file verifying default false, reading bytes in normal mode, enabling raw mode, and reading subsequent bytes.
Implement a new `readByte()` static method on the `Stdin` class that reads one byte from standard input, blocking the current fiber until a byte is received. The method returns the byte value as a number or `null` if stdin is closed.
Refactor the internal buffering mechanism by introducing a shared `read_()` helper method that both `readByte()` and `readLine()` use, replacing the previous per-method buffering logic. The `readByte()` implementation peels off the first byte from the internal `__buffered` string using `bytes[0]` and slicing.
Add two test files: `read_byte.wren` verifying byte-by-byte reading of "first" and "second" input lines, and `read_byte_eof.wren` confirming that reading after stdin is closed returns the expected error message.
Implement two new C API functions to retrieve list metadata and values from Wren slots: wrenGetSlotListSize returns the element count of a list in a slot, and wrenGetSlotListValue returns a captured WrenValue pointer for a specific index. Add corresponding foreign method bindings in test/api/slots.c and test cases in test/api/slots.wren that verify size retrieval and indexed value access on a three-element list. Also add Damien Radtke to AUTHORS.
Add missing loop to count underscore parameters in subscript operator signatures
starting with '['. Previously only counted parameters in parenthesized signatures,
causing incorrect arity for methods like `[_,_]` and `[_,_]=(_)`. Also adds
validation assertions for null and empty signatures, and extends test coverage
with unary, binary, subscript, and subscript-set operator call handles.
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.
Replace direct fprintf(stderr) calls in wrenDebugPrintStackTrace with invocations of the host-provided errorFn callback, passing WREN_ERROR_RUNTIME for the error message and WREN_ERROR_STACK_TRACE for each stack frame. Introduce the WrenErrorType enum in wren.h with WREN_ERROR_COMPILE, WREN_ERROR_RUNTIME, and WREN_ERROR_STACK_TRACE values, update the WrenErrorFn typedef to accept a type parameter, and modify reportError in cli/vm.c to switch on the error type for formatted output. Adjust wrenDebugPrintStackTrace signature to take WrenVM* instead of ObjFiber* to access the config, and update all call sites accordingly.
- Add `WrenErrorFn` typedef in wren.h accepting module, line, and message parameters
- Include `errorFn` slot in `WrenConfiguration` struct with documentation comment
- Initialize `errorFn` to NULL in `wrenInitConfiguration()` in wren_vm.c
- Replace direct `fprintf(stderr, ...)` in wren_compiler.c with call to `parser->vm->config.errorFn()`
- Add guard in wren_compiler.c to skip error reporting when `errorFn` is NULL
- Implement `reportError()` in cli/vm.c that writes formatted errors to stderr
- Wire `reportError` into config during `initVM()` in cli/vm.c
Store the line number of first use in implicitly declared variables as a numeric value, then synthesize a token at that line when reporting the error, ensuring bounded error message length even for pathologically long variable names.
Add inline comments clarifying the purpose of Windows-specific permission and mode flag
definitions in the platform compatibility block. Also remove the conditional `#ifdef O_SYNC`
guard around the O_SYNC flag assignment in `mapFileFlags`, since O_SYNC is now always
defined (as 0) on Windows.
Add conditional preprocessor definitions for Windows builds (WIN32/WIN64) to handle
platform-specific differences in file mode constants (S_IRUSR, S_IWUSR), sync flag
(O_SYNC), and stat macros (S_ISREG, S_ISDIR). Also fix a minor typo in the comment
describing file flag mapping logic.
Add preprocessor conditionals for WIN32/WIN64 to define POSIX-compatible
file mode macros (S_IRUSR, S_IWUSR), O_SYNC flag, and S_ISREG/S_ISDIR
macros using Windows equivalents. Also fix a minor typo in the comment
describing the file flag mapping approach.
Add tracking of static and instance method names during class compilation to detect and report duplicate method definitions. Introduce `hasMethod` helper function and `staticMethods`/`instanceMethods` buffers in the `ClassCompiler` struct, along with a `name` field for identification. Include a new test case `duplicate_methods.wren` verifying error generation for duplicate instance and static methods, while allowing same-named methods across static/instance boundaries.
Replace the generic `wrenIntBufferFind` function with a specialized `hasMethod` helper that performs exact method symbol matching in the compiler. This change removes the generic `BufferFind` macro from the buffer utility system and introduces a focused implementation in `wren_compiler.c` that directly compares method symbols using `memcmp`. The error message for duplicate methods is also simplified to exclude the module name. Additionally, a new test file `duplicate_methods.wren` is added to verify error handling for duplicate instance and static method definitions.
Replace multiple fprintf calls in lexError and compileError with a unified printError function that formats the entire error message into a fixed-size buffer before outputting it as a single fprintf call. This centralizes error formatting logic and prepares for future integration of a host-provided error callback by eliminating scattered fprintf invocations.
Guard the O_SYNC flag usage in mapFileFlags() with a preprocessor
conditional to fix compilation on Windows where this constant is not
defined. Additionally, add the required Windows socket and system
libraries (ws2_32, iphlpapi, psapi, userenv) to LIBUV_LIBS when
building under mingw32, replacing the Linux-specific pthread and rt
libraries.
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.
When wrenNewVM is called with a NULL config pointer, the previous code
dereferenced it without checking, causing a crash. This commit adds a
NULL guard: if config is NULL, the VM is allocated using the default
reallocator and initialized with default configuration via
wrenInitConfiguration. The gray array allocation and nextGC field now
correctly reference vm->config instead of the potentially NULL config
parameter.
Fix the misspelled function name `wrenUpwrapClosure` to the correct `wrenUnwrapClosure` in wren_debug.c, wren_value.c, wren_value.h, and wren_vm.c. Also fix a minor grammar typo in wren_vm.c comment changing 'arguments' to 'argument'.
Implement a new static method `File.realPath(path)` that resolves the given path by traversing symlinks and removing redundant `./` and `../` components, returning the canonical absolute path. The implementation uses libuv's `uv_fs_realpath` via an asynchronous callback pattern consistent with other File operations. Includes documentation, foreign method declarations, and two error-case tests for nonexistent paths and wrong argument types.
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.