Commit Graph

235 Commits

Author SHA1 Message Date
Bob Nystrom
8abfb4ec7d feat: add fiber.isDone property and runtime error checks for finished fiber operations
Add a new `isDone` native method to the Fiber class that returns true when the fiber has no remaining frames. Replace TODO comments with proper runtime error handling in `fiber_run`, `fiber_run1`, `fiber_yield`, and `fiber_yield1` to prevent running finished fibers or yielding from the main fiber. Include test cases verifying the new property and error conditions.
2014-01-13 14:58:27 +00:00
Bob Nystrom
8cee1f62bd fix: free GC objects in linked list when VM is freed
Add iteration over the VM's object linked list in wrenFreeVM to properly
deallocate all allocated GC objects before freeing the VM memory,
replacing the previous TODO placeholder comment.
2014-01-13 14:48:53 +00:00
Bob Nystrom
08c38f92cb feat: allow implicit null return when return statement has no value
In the compiler, when a `return` token is followed by a newline or right brace, emit CODE_NULL instead of parsing an expression. This enables bare `return` statements to implicitly return null. Also removes a stale TODO comment about setter parameters and fixes a typo in a comment in wren_core.c. Adds three test cases: one for explicit return in a function, one for bare return before a brace, and one for bare return before a newline.
2014-01-13 03:37:11 +00:00
Bob Nystrom
2e34a5c42b feat: add support for escape sequences \a, \b, \f, \r, \v in string parsing
Implement the remaining standard C escape codes in the readString function
of the Wren compiler, removing the TODO comment about missing escapes.
Adds handling for alert (a), backspace (b), form feed (f), carriage return (r),
and vertical tab (v) escape sequences.
2014-01-13 03:24:30 +00:00
Bob Nystrom
fc4880774e feat: implement fiber primitives with create, run, yield and caller tracking
Add core fiber functionality including Fiber.create, Fiber.run, Fiber.yield
primitives with value passing between fibers. Introduce PRIM_RUN_FIBER result
type for interpreter loop, add caller field to ObjFiber struct for yield
resumption, and update GC marking to traverse fiber caller chains. Modify
wrenNewFiber to accept a function/closure argument and initialize the first
call frame. Add debug stack printing with fiber pointer. Include test suite
covering fiber creation, run, yield, value passing, type checking, and
caller resumption.
2014-01-12 19:02:07 +00:00
Bob Nystrom
193e4e30ab feat: add ceil, cos, sin, sqrt, isNan native methods and division-by-zero tests
Implement five new Num methods (ceil, cos, sin, sqrt, isNan) in wren_core.c and register them on the Num class. Add corresponding test files for ceil, floor, is_nan, and sqrt. Extend divide.wren with division-by-zero edge cases (inf, -inf, nan). Remove stale TODO comments from minus, multiply, and plus tests.
2014-01-08 15:47:14 +00:00
Bob Nystrom
33b0fae6f6 feat: extend jump offsets from 8-bit to 16-bit in compiler and VM
Replace single-byte jump offset emission and reading with two-byte (uint16) handling across all jump instructions (JUMP, LOOP, JUMP_IF, AND, OR). Add new emitJump helper that reserves a 16-bit placeholder, update patchJump to write the offset as big-endian short, and change VM opcode handlers to use READ_SHORT instead of READ_BYTE for jump offsets. This increases maximum jump distance from 255 to 65535 bytes, supporting larger generated bytecode.
2014-01-08 07:03:38 +00:00
Bob Nystrom
ce2e227683 feat: add floor method to Num class for rounding down to nearest integer
Implement the `floor` native method on the `Num` class in `wren_core.c`, which delegates to C's `floor()` function to round a number down to the nearest integer value. Register the new method in `wrenInitializeCore` alongside the existing `abs` method.
2014-01-08 07:03:25 +00:00
Bob Nystrom
88c8984549 fix: initialize upvalue closed field to NULL_VAL to prevent GC crash 2014-01-08 07:03:15 +00:00
Bob Nystrom
0ba6456214 fix: properly dispose loop-scoped variables and exit scopes on break
Replace the single `loopBody` index with a `Loop` struct that tracks scope depth, enabling the compiler to emit correct scope-exit code when a `break` statement is encountered inside nested blocks. Also add `WREN_DUMP_COMPILED_CODE` debug flag and new test cases for closures capturing loop variables after break, return inside loops, and nested loop scoping.
2014-01-06 16:01:04 +00:00
Bob Nystrom
488dd3521f fix: ensure null-termination of debug function name after strncpy copy 2014-01-06 15:54:00 +00:00
Bob Nystrom
01cc6538ef fix: increase number-to-string buffer size from 21 to 24 for double precision
The previous buffer size of 21 bytes was insufficient to hold the longest possible
double representation formatted with "%.14g", which can reach 24 bytes including
the null terminator. Updated the buffer to 24 bytes and extracted the numeric
value into a local variable for clarity.
2014-01-06 15:53:41 +00:00
Bob Nystrom
c72db7d594 feat: rename IO.write to IO.print and add Unicode escape support in strings
Rename the IO.write method to IO.print, which now prints without a trailing newline, and add a new IO.print method that appends a newline after output. Update all benchmark, example, and test files to use IO.print instead of IO.write. Additionally, implement Unicode escape sequence parsing in the compiler's string tokenizer, supporting \uXXXX and \u{...} syntax with proper UTF-8 encoding for code points up to U+10FFFF.
2014-01-05 20:27:12 +00:00
Bob Nystrom
e23e0ce6a3 feat: remove hardcoded 256 symbol limit and switch to dynamic symbol table with 16-bit instruction arguments
Replace the fixed-size MAX_SYMBOLS array with a dynamically growing StringBuffer for symbol names, update all instruction encodings to use 16-bit operands for constants and method symbols, and refactor method binding to use a dynamic MethodBuffer per class. Remove the constant deduplication logic in addConstant and the commented-out struct fields in initCompiler.
2014-01-04 19:08:31 +00:00
Bob Nystrom
64dab4db78 feat: add WREN_TRACE_GC flag and timing instrumentation to garbage collection
Introduce a new `WREN_TRACE_GC` compile-time flag in `wren_common.h` to enable
dedicated GC tracing independently from general memory tracing. When either
`WREN_TRACE_MEMORY` or `WREN_TRACE_GC` is set, include `<time.h>` and modify
`collectGarbage()` to measure elapsed wall-clock time using `clock()`. The GC
trace now reports bytes before and after collection, bytes collected, the next
GC threshold, and the duration in seconds. Also move the `-- gc --` header
print and the `nextGC` calculation inside the tracing guard to avoid
side-effects when tracing is disabled.
2014-01-03 21:17:14 +00:00
Bob Nystrom
53884b1332 feat: replace validateIndexOld with validateIndex and add validateString for core methods
Remove the deprecated validateIndexOld function and migrate all callers to the new validateIndex that reports runtime errors. Add validateString helper for string argument checking. Introduce comprehensive runtime error tests for list and string subscript operations, removeAt, and contains methods, replacing old silent null returns with proper error halting.
2014-01-03 18:47:26 +00:00
Bob Nystrom
6fb8804c9e feat: add validateNum/validateInt helpers and runtime type checks for list methods
Replace the old validateIndex function with validateNum and validateInt helpers that produce descriptive runtime error messages. Add new test files covering invalid index types, out-of-bounds indices, and iterator validation for list insert, iterate, and iteratorValue methods. Rename existing number operator error tests to use consistent "must be a number" phrasing.
2014-01-02 15:32:00 +00:00
Bob Nystrom
003d4f77f4 refactor: reorder and document fields in Compiler struct for clarity
Move bytecode and debug source line buffers out of Compiler struct to
simplify initialization, and add inline comments for source path, source
code, constants, locals, upvalues, and fields to improve readability of
the compiler's internal state layout.
2014-01-02 15:31:31 +00:00
Bob Nystrom
720b1b5d76 refactor: replace monolithic Buffer struct with generic macro-generated ByteBuffer and IntBuffer types
Remove the single-purpose Buffer struct from wren_compiler.c and replace it with type-specific ByteBuffer and IntBuffer types generated via a DECLARE_BUFFER macro in wren_utils.h, with shared buffer logic implemented in wren_utils.c using a void* Buffer helper struct. This enables a growable line-number buffer for debug source lines.
2014-01-02 06:23:03 +00:00
Bob Nystrom
b93bd62623 refactor: extract SymbolTable into dedicated wren_utils module with prefixed API
Move SymbolTable struct and its associated functions (initSymbolTable, clearSymbolTable, addSymbol, findSymbol, ensureSymbol, getSymbolName) from wren_vm.c and wren_value.h into new wren_utils.c and wren_utils.h files. Rename all functions with wrenSymbolTable prefix for consistent naming convention, update all call sites across compiler, core, debug, and VM files, and relocate MAX_SYMBOLS constant to wren_common.h.
2014-01-02 04:57:58 +00:00
Bob Nystrom
1b605162ef refactor: move object freeing logic from wren_vm.c to wren_value.c alongside allocation code
Consolidate memory management by relocating the static freeObj function into wren_value.c as the public wrenFreeObj API, keeping allocation and deallocation co-located for better code organization.
2014-01-01 21:31:19 +00:00
Bob Nystrom
547107a086 feat: add runtime error support with source paths, line info, and stack traces
Introduce primitive error signaling, runtime error handling with callstack printing, and fiber termination on error. Add source file path and method name tracking to functions, along with debug line number information. Update arithmetic operators to error on non-numeric operands and implement proper "method not found" runtime errors. Refactor the test runner to expect runtime errors with exit code 70 (EX_SOFTWARE) and update the C API to accept source paths in wrenInterpret and wrenCompile. Rename WrenNativeMethodFn to WrenForeignMethodFn and adjust related typedefs. Add debug source line arrays to compilers and functions, and replace the old debug dump functions with new print-based variants that display line numbers.
2014-01-01 21:25:24 +00:00
Bob Nystrom
8a09c03cdd fix: reorder symbol table insertion before object allocation to prevent GC crashes
In `wren_core.c`, `defineClass` and `wrenInitializeCore` now call `addSymbol` before allocating new class objects (`wrenNewClass`, `wrenNewSingleClass`), ensuring unpinned objects are not live when a GC-triggering symbol insertion occurs. In `wren_compiler.c`, `freeBuffer` now passes zero capacity to `wrenReallocate` and reuses `initBuffer` instead of manually zeroing fields, fixing a potential double-free or stale pointer on buffer reuse.
2013-12-30 15:30:50 +00:00
Bob Nystrom
4f215f6531 feat: allow empty blocks in parser and fix native call slot assertion
Add support for empty block bodies in the Wren compiler by early-returning
from `finishBlock` when a right brace is immediately matched. This permits
syntactically valid constructs like `{}`, `if (true) {}`, and empty function
or method bodies.

Fix a copy-paste error in `wrenGetArgumentDouble` where the assertion
checked `nativeCallSlot` and `nativeCallNumArgs` instead of the correct
`foreignCallSlot` and `foreignCallNumArgs` fields.

Add test cases covering standalone empty blocks, empty blocks in if/else
statements, and empty function and method bodies returning null.
2013-12-29 18:46:21 +00:00
Bob Nystrom
5570f7f46c refactor: rename nativeCallSlot and nativeCallNumArgs to foreignCallSlot and foreignCallNumArgs in WrenVM
Rename the fields `nativeCallSlot` and `nativeCallNumArgs` to `foreignCallSlot` and
`foreignCallNumArgs` across `wren_vm.c` and `wren_vm.h` to accurately reflect that
these fields are used exclusively during foreign function calls, not native method
invocations. Update all references in `callForeign`, `wrenGetArgumentDouble`, and
`wrenReturnDouble` accordingly.
2013-12-29 18:14:38 +00:00
Bob Nystrom
b1e8d3f81e feat: add foreign method interface with native call support and argument passing
Introduce the `WrenNativeMethodFn` callback type and `METHOD_FOREIGN` enum value to allow host applications to define C-implemented methods on Wren classes. Add `wrenDefineMethod`, `wrenGetArgumentDouble`, and `wrenReturnDouble` API functions, along with `nativeCallSlot` and `nativeCallNumArgs` VM fields to manage foreign call state. Implement `callForeign` in the interpreter loop to invoke native methods and handle stack cleanup. Move `MAX_PARAMETERS`, `MAX_METHOD_NAME`, and `MAX_METHOD_SIGNATURE` constants from `wren_compiler.c` to `wren_common.h` for shared use across the VM.
2013-12-29 18:06:35 +00:00
Bob Nystrom
6dd270d7ef refactor: replace explicit free/malloc calls with wrenReallocate in symbol table functions
Pass WrenVM pointer to addSymbol, ensureSymbol, and clearSymbolTable to use
wrenReallocate for memory management instead of raw free/malloc, and remove
truncateSymbolTable and MAX_STRING constant as part of the cleanup.
2013-12-27 17:07:35 +00:00
Bob Nystrom
08f043caba feat: replace fixed-size arrays with growable Buffer struct for bytecode and string storage
Replace the static MAX_STRING-sized char array and fixed bytecode array in the compiler with a dynamic Buffer type that supports reallocation via wrenReallocate. Add initBuffer, ensureBufferCapacity, writeBuffer, and freeBuffer helpers to manage memory. This allows the compiler to handle arbitrarily long string literals and large function bodies without hitting hard-coded limits. Add test/long_function.wren (1013 lines) and test/long_string.wren to verify the fix.
2013-12-27 15:22:43 +00:00
Bob Nystrom
e055360616 refactor: pass constants and bytecode directly to wrenNewFunction instead of post-assignment
Refactor ObjFn creation in endCompiler to pass all data (constants, bytecode, upvalues) directly to wrenNewFunction, eliminating the temporary post-construction assignment loop and memcpy. Update wrenNewFunction signature to accept these parameters, copy constants into a new owned array, and take ownership of the bytecode buffer. Adjust ObjFn struct to use dynamic bytecode pointer and bytecodeLength field instead of fixed-size array. Update memory tracking in markFn and cleanup in freeObj to handle the new dynamic bytecode allocation.
2013-12-27 01:28:33 +00:00
Bob Nystrom
ce60209fcc refactor: replace hardcoded ObjFn arrays with growable buffers in compiler
Restructure Compiler to use dynamic bytecode and constant buffers instead of
relying on ObjFn's fixed-size arrays. Move ObjFn creation to the end of
compilation, add wrenListAdd/Insert/RemoveAt helpers to wren_value, relocate
list capacity macros and ensureListCapacity into wren_value.c, and store a
Compiler pointer in WrenVM for GC safety during compilation.
2013-12-27 00:58:03 +00:00
Bob Nystrom
d972a6a696 refactor: replace unsigned char with uint8_t across debug, value, and vm modules
Migrate bytecode pointer types from `unsigned char*` to `uint8_t*` in `wren_debug.c`, `wren_value.h`, and `wren_vm.c` for consistent fixed-width integer usage. Also expand `ObjFn` bytecode array from 1024 to 2048 elements and update corresponding memory allocation in `markFn` to reflect the doubled capacity.
2013-12-26 00:31:30 +00:00
Bob Nystrom
dfe53d945c feat: inline bytecode array into ObjFn struct to eliminate separate heap allocation
Remove the dynamically allocated `bytecode` pointer from `ObjFn` and replace it with a fixed-size `unsigned char bytecode[1024]` array embedded directly in the struct. This eliminates the need for a separate `allocate` call in `wrenNewFunction`, the associated `deallocate` in `freeObj`, and the pointer indirection, simplifying memory management and improving cache locality for function bytecode access.
2013-12-26 00:19:35 +00:00
Bob Nystrom
d6e4d6bcf7 refactor: change CallFrame and Method fn fields from Value to Obj*
Replace the `fn` field in `CallFrame` and `Method` structs from `Value` to `Obj*`, since it always holds an ObjFn or ObjClosure. Update all callers to use `AS_OBJ` and `markObj` instead of `markValue`. Fix a bug in `freeObj` where `OBJ_CLOSURE` case incorrectly freed the upvalues flexible array instead of falling through to the no-op case.
2013-12-26 00:12:07 +00:00
Bob Nystrom
6c61df3ed7 feat: add range operators and iterator protocol for numeric for loops
Implement `..` and `...` infix operators on Num returning Range objects that support the iterator protocol, enabling concise numeric for loops like `for (i in 1..10)`. Add Range class with min/max properties and iterate/iteratorValue methods. Introduce TOKEN_DOTDOT and TOKEN_DOTDOTDOT lexer tokens with PREC_RANGE precedence in the compiler. Unroll method_call benchmark loops across all languages to stress dynamic dispatch instead of loop overhead, reducing iteration count from 1M to 100K with 10x unrolling. Update Wren benchmarks (binary_trees, fib, for) to use new range syntax. Add benchmark/README.md documenting each benchmark's purpose.
2013-12-25 23:01:45 +00:00
Bob Nystrom
b72a42eedd refactor: replace manual instruction argument counting with getNumArguments() in wrenBindMethod
Remove the large switch statement that manually handled instruction argument counts for each opcode in wrenBindMethod(). Instead, use the existing getNumArguments() helper function to determine how many bytes each instruction consumes, reducing code duplication and making the method more maintainable when new instructions are added.
2013-12-25 06:10:30 +00:00
Bob Nystrom
ad559eabd3 feat: implement for-in loop syntax with iterate/iteratorValue protocol and break support
Add `for (variable in sequence)` syntax to the Wren language, introducing the `in` keyword token and compiler support for iterating over sequences using `iterate` and `iteratorValue` methods. Includes new benchmark files for Lua, Python, Ruby, and Wren, plus test cases covering single-expression bodies, block bodies, closures over loop variables, and break statements. Also fixes a missing POP() in CLOSE_UPVALUE and moves the while test file to a subdirectory.
2013-12-25 05:04:11 +00:00
Bob Nystrom
c58f15fc87 feat: allow statement bodies for flow control in compiler and add return tests
Replace the block() function's expression-only body with a call to definition(), enabling flow control statements like `if (foo) return bar` and `if (i > 2) break` without requiring curly braces. Add new test files for return statements after if, else, while, and inside functions/methods, and update existing break tests to use the simplified syntax.
2013-12-24 18:27:48 +00:00
Bob Nystrom
1a456738f6 feat: add break statement support with loop tracking and error handling
Add TOKEN_BREAK keyword recognition and a loopBody field to the compiler
to track the innermost loop's first instruction index. The break
statement emits a jump to the end of the current loop, and compile-time
errors are reported when break appears outside a loop body, inside a
function defined within a loop, or inside a method defined within a
loop. New test files verify correct behavior for break in while loops,
nested loops, and error cases for invalid break usage.
2013-12-24 18:15:50 +00:00
Bob Nystrom
b081f2622d chore: remove resolved TODO comments and fix buffer size in num_toString
- Remove two TODO comments in wren_compiler.c about parameter length overflow check and assignment in named call
- Remove TODO about interning bool_toString and null_toString strings in wren_core.c
- Replace oversized 100-char temp buffer with precise 21-char buffer in num_toString, referencing Lua implementation
- Rename io_write native to io_writeString and remove TODO about calling toString on argument
2013-12-23 23:38:00 +00:00
Bob Nystrom
f8e5351cf3 feat: add MAX_CONSTANTS limit and overflow check with deduplication in wren_compiler.c 2013-12-23 23:08:47 +00:00
Bob Nystrom
4fc948f2ca fix: add lexError function and fix line counting for unterminated block comments
Add a dedicated lexError function that marks compilation as failed and formats
error messages consistently with a trailing newline. Move line counting from
readRawToken into nextChar so that newlines are tracked during all lexer phases,
including block comment scanning. Replace the TODO placeholder in
skipBlockComment with a proper lexError call for unterminated block comments,
and add test cases for unterminated block and nested block comments.
2013-12-23 22:51:06 +00:00
Bob Nystrom
0067070804 refactor: remove unused CODE_DUP instruction and clean up interpreter dispatch
Remove the CODE_DUP opcode from the compiler, debug printer, VM dispatch table, and enum definition. Also simplify several case blocks in the computed-goto interpreter by removing unnecessary braces and consolidating local variable declarations, and add a critical ordering comment to the dispatch table.
2013-12-23 19:37:47 +00:00
Bob Nystrom
64fdc1876a feat: add optimized field load/store instructions for direct method access
Introduce CODE_LOAD_FIELD_THIS and CODE_STORE_FIELD_THIS opcodes that bypass receiver stack operations when field access occurs directly within a method body. Refactor field() compiler to emit these faster instructions when compiler->methodName is set, and extract loadThis() helper to correctly resolve 'this' in nested functions. Update VM interpreter with dedicated dispatch cases that read receiver from frame->stackStart instead of popping, and add debug disassembly support. Add test cases for field closure capture and nested class field isolation, removing related TODO comments.
2013-12-23 19:17:40 +00:00
Bob Nystrom
a7e29fc967 refactor: replace ResolvedName enum with direct Code instruction in resolveName
Remove the ResolvedName enum and its typedef, replacing the resolved parameter with a Code* loadInstruction pointer that directly returns the appropriate load instruction (CODE_LOAD_LOCAL, CODE_LOAD_UPVALUE, or CODE_LOAD_GLOBAL). This eliminates the intermediate enum and the TODO comment about ditching it, simplifying the variable resolution logic in the compiler.
2013-12-23 04:53:35 +00:00
Bob Nystrom
634e9fbb11 feat: add superclass call support inside closures in wren compiler
Add a new test case `test/super/closure.wren` verifying that `super.toString` correctly resolves to the base class method when called from within a closure defined in a derived class. Refactor `resolveLocal` and `resolveUpvalue` to accept explicit name and length parameters instead of relying on the previously consumed token, enabling proper name resolution in nested closure scopes during superclass method dispatch.
2013-12-23 04:46:12 +00:00
Bob Nystrom
75d9a39040 feat: allow variable declarations without explicit initializers
In the compiler, when parsing a variable declaration, the `=` token is now optional. If present, the initializer expression is compiled as before. If absent, the variable is implicitly initialized to `null` via a call to `null(compiler, false)`. This change removes the previous `TODO` comment and the unconditional `consume` of `TOKEN_EQ`.

Two new test files verify the behavior for both global and local variables without initializers, asserting that reading such a variable yields `null`.
2013-12-23 02:47:58 +00:00
Bob Nystrom
8c13258ef6 feat: promote Fiber from raw struct to heap-allocated ObjFiber with GC support
Refactor the VM's fiber representation from a stack-allocated `Fiber` struct embedded in `WrenVM` to a full `ObjFiber` object managed by the garbage collector. This includes adding the `OBJ_FIBER` object type enum, a `wrenNewFiber` allocation function, a `markFiber` traversal routine for GC marking, and updating all internal APIs (`DEF_FIBER_NATIVE`, `wrenDebugDumpStack`) to use `ObjFiber*` instead of `Fiber*`. The `Fiber` struct definition and its associated `CallFrame` type are moved from `wren_vm.h` into `wren_value.h`, and the `STACK_SIZE`/`MAX_CALL_FRAMES` constants are relocated accordingly. Additionally, the `vm->fiber` singleton pointer is removed, the `vm->unsupported` sentinel value is eliminated (replaced by returning `NULL_VAL` for invalid numeric operands), and the `wrenInterpret` function is temporarily removed. The `wrenNewClass` function's metaclass pinning order is also corrected to prevent premature GC collection.
2013-12-22 22:31:33 +00:00
Bob Nystrom
54c4f231ee fix: change ip from integer index to direct pointer in CallFrame and interpreter loop 2013-12-22 21:46:13 +00:00
Bob Nystrom
7e8edd68ea feat: make IO.write call toString on argument and add corelib with List.toString 2013-12-22 19:50:00 +00:00
Bob Nystrom
91873b3a90 refactor: split class creation into raw single-class and superclass binding phases
The bootstrapping of Object and Class now uses a two-phase approach: first creating a raw class with no metaclass or superclass via wrenNewSingleClass, then explicitly wiring superclass relationships with wrenBindSuperclass. This eliminates the need for special-case handling of null superclasses in the old newClass function and makes the metaclass chain setup explicit in wrenInitializeCore.
2013-12-22 04:44:37 +00:00
Bob Nystrom
8bb1a94a25 refactor: convert IO from singleton instance to static class with metaclass native methods
Replace the global `io` singleton object with a static `IO` class, moving the `write` native from the instance to the metaclass. Update all benchmark, example, and test files to use `IO.write()` instead of `io.write()`.
2013-12-22 03:25:09 +00:00
Bob Nystrom
1a77a43fa0 feat: implement closure over "this" in methods and fix upvalue closing order
Add support for closing over "this" in function closures defined inside methods by naming the receiver local variable "this" in method compilers. Fix upvalue closing to copy the actual value instead of the stack top, and reorder return handling to close upvalues before storing the result. Add test cases for closure over "this", nested closures, and nested classes.
2013-12-21 23:55:08 +00:00
Bob Nystrom
b1243ac532 feat: add list subscript setter and refactor parameter validation
Implement list subscript setter (`[ ]=`) native method in wren_core.c, enabling assignment to list elements via bracket syntax. Extract duplicate parameter count validation logic into a shared `validateNumParameters` function in wren_compiler.c, replacing inline checks in both `parameterList` and `methodCall`. Add comprehensive test suite covering basic assignment, return value semantics, negative indices, and error cases for out-of-range and excessive arguments.
2013-12-21 17:37:59 +00:00
Bob Nystrom
d9255666f4 fix: add list newline handling and resolve multiple test TODOs across compiler and test suite
- Add TOKEN_LINE matching after list elements in compiler to allow newlines before commas or closing brackets
- Add tests for list newline handling, EOF after comma/element, and class name inside body
- Remove resolved TODOs for default constructors, inherited fields, metaclass is checks, zero comparison, and bitwise not behavior
2013-12-20 20:42:11 +00:00
Bob Nystrom
46f53e4421 feat: add configurable heap growth, initial, and minimum heap size to WrenVM
Replace the single `WrenReallocateFn` parameter in `wrenNewVM` with a `WrenConfiguration` struct containing `reallocateFn`, `initialHeapSize`, `minHeapSize`, and `heapGrowthPercent` fields. Update the VM to use these values for GC thresholds instead of hardcoded constants, and modify the CLI entry point to pass a configuration with a 100MB initial heap.
2013-12-20 15:41:35 +00:00
Bob Nystrom
517844fbda feat: implement setter syntax and assignment in named method calls
Add support for setter methods in the compiler by detecting '=' after a method name in namedCall, compiling the assigned value, and emitting the setter instruction. Includes new test cases for instance setters, static setters, assignment associativity, grouping, operator precedence errors, setter result values, and same-name getter/setter methods. Also updates the super call test with a TODO for super setter calls.
2013-12-20 15:05:31 +00:00
Bob Nystrom
7d12f64af4 feat: increase default GC heap threshold from 10MB to 100MB
The default heap size for the Wren VM is raised by a factor of 10, from
1024*1024*10 bytes to 1024*1024*100 bytes. This change significantly
reduces garbage collection frequency, resulting in a substantial
performance improvement for the binary_trees benchmark.
2013-12-20 15:05:13 +00:00
Bob Nystrom
0e70d98169 refactor: replace Foo.new constructor syntax with new Foo and simplify superclass constructor calls
Remove the `this new` constructor declaration syntax in favor of a `new` keyword that creates instances directly. Superclass constructors are now invoked via bare `super(args)` instead of `super.new(args)`, eliminating the semantic weirdness of calling a constructor on a partially-constructed instance. Update the compiler to treat `new` as a keyword token, replace the `isMethod` flag with `methodName`/`methodLength` fields, and change the VM's `NEW` opcode to pop the class from the stack before creating the instance. Add a default `new` native method on Object that returns `this`. Update all benchmarks and tests to use the new syntax.
2013-12-19 15:02:27 +00:00
Bob Nystrom
f5a61e4241 fix: expand TODO comments for superclass constructor resolution edge cases
Add detailed TODO notes in wren_compiler.c's method() function to document two unresolved issues: the lack of validation for matching superclass constructors, and the problematic instance context during super() compilation where field access like _someField in super(_someField) expressions could cause undefined behavior since the receiver is still the class at that point.
2013-12-18 15:39:46 +00:00
Bob Nystrom
7ac04b9e3d feat: refactor method_call benchmark to use inheritance and fix constructor binding
Refactor the method_call benchmark across Lua, Python, Ruby, and Wren to use proper inheritance with super calls instead of direct state manipulation. This ensures all languages benchmark super method invocations consistently.

Fix a bug in the Wren compiler where constructors weren't being bound correctly by extracting method binding logic into a dedicated `bindMethod` function that properly handles both instance and static methods against the class object.

Optimize if-statement compilation by restructuring jump instruction emission to eliminate unnecessary CODE_JUMP instructions when no else branch exists, reducing bytecode size for conditional blocks.

Update the superclass constructor test to verify inherited field access through super constructor chains, confirming correct field initialization across multiple inheritance levels.
2013-12-18 15:37:41 +00:00
Bob Nystrom
656238f286 feat: implement superclass constructor calls and metaclass inheritance chain
Add support for explicit superclass constructor invocation in subclass constructors using `super.constructorName(args)` syntax before the opening brace. The metaclass inheritance hierarchy now mirrors the regular class chain, with `Class` as the root metaclass superclass instead of `Object`. Includes test cases for multi-level constructor delegation and static method inheritance.
2013-12-17 17:39:05 +00:00
Bob Nystrom
93cf4e6b87 feat: add compile-time error for 'super' used outside method context
Add isInsideMethod helper that walks the compiler's parent chain to detect
if the current compilation scope is within a method. Use it in super_()
to emit a compile error when 'super' is used at top level or inside a
top-level function, with corresponding test cases for both scenarios.
2013-12-16 06:08:40 +00:00
Bob Nystrom
7638dd2ee2 refactor: embed upvalue array directly in ObjClosure using flexible array member
Replace the separate heap-allocated `Upvalue** upvalues` pointer in `ObjClosure` with a C99 flexible array member `Upvalue* upvalues[]`. This eliminates an extra allocation per closure, reduces memory fragmentation, and simplifies the allocation logic in `wrenNewClosure` by computing the total size as `sizeof(ObjClosure) + sizeof(Upvalue*) * fn->numUpvalues`. The upvalue array is still zero-initialized to prevent GC issues during partial construction.
2013-12-16 06:02:22 +00:00
Bob Nystrom
55041f4640 feat: replace int-based booleans with stdbool.h bool type across core source files
Migrate all boolean-typed parameters, return values, struct fields, and local variables from `int` (with 0/1 convention) to C99 `bool` (`true`/`false`). Update corresponding comments, macro definitions, and documentation strings to use `true`/`false` terminology instead of "non-zero"/"zero". Add `#include <stdbool.h>` to `src/main.c`, `src/wren_compiler.c`, and `src/wren_value.h`. Remove the stale TODO comment in `src/wren_common.h` that originally proposed this change.
2013-12-15 07:41:23 +00:00
Bob Nystrom
34db2b2b9f chore: remove author attribution from TODO comments across multiple source files
Remove "(bob)" author prefix from all TODO comments in benchmark/method_call.wren, include/wren.h, src/main.c, src/wren_common.h, src/wren_compiler.c, src/wren_core.c, src/wren_value.c, src/wren_value.h, and src/wren_vm.c. Update the TODO_PATTERN regex in metrics script to match the new format without author parentheses. Also refactor test file counting in metrics to use os.walk with fnmatch for recursive directory traversal instead of glob.iglob.
2013-12-14 23:28:18 +00:00
Bob Nystrom
07c3dff92f fix: track live memory via bytesAllocated instead of subtracting freed sizes
The old code subtracted oldSize from totalAllocated during deallocation,
which required knowing the object size at free time. This was unsafe
because it could read a freed object to determine its size. The new
approach tracks bytesAllocated by only adding new allocations and
relying on GC marking to account for freed memory, making it both
correct and faster with less code.
2013-12-14 22:17:16 +00:00
Bob Nystrom
78f6e3b96d perf: inline wrenObjectToValue and switch Xcode project to C99 for speed bump 2013-12-14 19:34:49 +00:00
Bob Nystrom
fc3ebb924c refactor: replace raw #ifdef NAN_TAGGING with WREN_NAN_TAGGING flag and add WREN_COMPUTED_GOTO, WREN_DEBUG_GC_STRESS, WREN_TRACE_MEMORY configurable defines
Convert all conditional compilation guards from bare `#ifdef NAN_TAGGING` to `#if WREN_NAN_TAGGING` across wren_common.h, wren_value.c, wren_value.h, and wren_vm.c. Introduce new `#ifndef`-based defaults for WREN_NAN_TAGGING, WREN_COMPUTED_GOTO, WREN_DEBUG_GC_STRESS, and WREN_TRACE_MEMORY in wren_common.h, replacing the old TODO comments and commented-out debug flags. Update preprocessor indentation style for consistency.
2013-12-14 19:06:54 +00:00
Bob Nystrom
d7a0063f4b feat: replace constructor method special-casing with dedicated CODE_NEW instruction
Remove the METHOD_CTOR method type and CODE_METHOD_CTOR opcode, replacing them with a new CODE_NEW instruction that creates class instances directly in the bytecode. This simplifies the compiler by emitting CODE_NEW at the start of constructor bodies instead of relying on a separate method dispatch path, and eliminates the redundant METHOD_CTOR enum value from the method lookup logic.
2013-12-13 19:32:47 +00:00
Bob Nystrom
42b32acef4 feat: implement superclass method dispatch with new SUPER bytecodes and named call compiler
Add CODE_SUPER_0 through CODE_SUPER_16 bytecodes to the VM for invoking inherited methods, along with a `namedCall` compiler helper that parses method names and argument lists after a dot. The interpreter dispatches super calls by walking up the class hierarchy from the receiver's immediate class, skipping methods defined on that class. Includes three test cases covering calling a different superclass method, calling the same method name, and indirectly inherited methods. Also fixes error formatting to handle newline tokens gracefully and adds a TODO note about not deduplicating placeholder constants for super calls.
2013-12-13 16:37:49 +00:00
Bob Nystrom
a7dbdc4cba perf: reorder opcode switch cases to move less frequent CODE_LIST and CODE_CLOSURE lower
Reorder the opcode enum values, dispatch table entries, switch-case handlers, and debug dump cases for CODE_LIST and CODE_CLOSURE to appear after CODE_RETURN and before CODE_CLASS, improving interpreter performance by reducing branch prediction misses for the more common instructions that now appear earlier in the switch.
2013-12-13 14:47:34 +00:00
Bob Nystrom
5e62b5856e perf: reorder MethodType enum and switch cases to improve branch prediction
Reorder the `MethodType` enum values so that `METHOD_NONE` is placed last instead of first,
and correspondingly move the `METHOD_NONE` case in the interpreter's dispatch switch to the
end of the case list. This places the most frequently executed method types (`METHOD_PRIMITIVE`,
`METHOD_FOREIGN`, `METHOD_BLOCK`, `METHOD_CTOR`) earlier in both the enum and the switch,
which can improve branch prediction and instruction cache locality in the hot dispatch loop.
2013-12-12 15:39:27 +00:00
Bob Nystrom
c107d26c93 feat: generate default constructors at compile time and reorder interpret loop for branch alignment
Add a `defaultConstructor` function in the compiler that emits bytecode for a constructor returning the receiver, invoked during class compilation. Reorder `CODE_CLASS`, `CODE_SUBCLASS`, and method opcodes to the end of the interpret loop's jump table and switch cases, moving `CODE_CALL_0` through `CODE_CALL_16` earlier to compensate for branch alignment issues caused by removing code from `CODE_CLASS` and `CODE_CALL` handlers.
2013-12-12 15:34:16 +00:00
Bob Nystrom
1737b649a4 feat: add TOKEN_SUPER enum and keyword recognition to wren compiler
Add the TOKEN_SUPER token type to the token enum and register "super" as a reserved keyword in the readName function. Include TOKEN_SUPER in the nextToken skip-newlines switch and mark it as UNUSED in the grammar rules table, preparing the compiler for future super keyword support.
2013-12-11 16:02:17 +00:00
Bob Nystrom
eb97920905 docs: expand TODO comment on default constructor performance tradeoff in wren_vm.c 2013-12-11 16:00:25 +00:00
Bob Nystrom
d8c31a4391 feat: add wrenBindMethod to patch field indices and superclass dispatch in inherited methods
When a class is defined, its superclass is not known until runtime since class definitions are imperative statements. This adds a new wrenBindMethod function that walks the bytecode of a method after it is bound to a class, adjusting LOAD_FIELD/STORE_FIELD indices to account for inherited fields and patching superclass dispatch targets. The newClass function now correctly accumulates numFields from the superclass chain, and the VM calls wrenBindMethod when binding methods to a class. Includes new test files for inherited field access and the is operator.
2013-12-11 00:13:25 +00:00
Bob Nystrom
e910186f51 fix: remove stack pop for loop body in LOOP opcode since bodies are now statements 2013-12-08 02:47:40 +00:00
Bob Nystrom
ffc58724d7 feat: enforce maximum method name length of 64 characters in compiler
Add MAX_METHOD_NAME constant and validation in copyName() to prevent method names exceeding 64 characters. When a method name is too long, the compiler now reports an error and truncates the name to the maximum allowed length. Also update MAX_METHOD_SIGNATURE to be derived from MAX_METHOD_NAME and MAX_PARAMETERS. Add test cases for valid 64-character method names, names that exceed the limit, and a call to an overlong method name.
2013-12-07 04:09:43 +00:00
Bob Nystrom
071239aa35 feat: add bitwise NOT operator (~) with token, parser, and native implementation
Add TOKEN_TILDE token type and lexer support for the '~' character in the compiler. Implement the bitwise NOT operation as a native method on the Num class, operating on 32-bit unsigned integers. Include a new OPERATOR macro for prefix/infix operator grammar rules and add comprehensive test cases covering positive, negative, floating-point, and boundary values.
2013-12-05 06:09:31 +00:00
Bob Nystrom
6451c86b28 feat: treat semicolons as line tokens in wren compiler lexer
Add a new case in the `readRawToken` function within `src/wren_compiler.c` to map the semicolon character to the `TOKEN_LINE` token type, enabling semicolons to function as line separators in the Wren language parser.

Include a test file `test/semicolon.wren` that verifies the new behavior by using a semicolon to separate two statements on a single line, with the expected output "ok".
2013-12-05 03:12:21 +00:00
Bob Nystrom
5b05c477c6 feat: implement closures with upvalue support and statement/expression separation
Add closure objects that wrap functions with captured upvalues, enabling
first-class closures that close over local variables from enclosing scopes.
Introduce new bytecode instructions (CODE_CLOSURE, CODE_LOAD_UPVALUE,
CODE_STORE_UPVALUE, CODE_CLOSE_UPVALUE, CODE_RETURN) and a CompilerUpvalue
tracking system with a MAX_UPVALUES limit of 256. Refactor the grammar to
strictly separate statements from expressions, fixing a bug where block
expressions incorrectly popped locals while temporaries remained on the
stack. Rename internal functions (wrenCallFunction, wrenDebugDumpInstruction,
wrenDebugDumpStack) and add Upvalue allocation, closure creation, and
debug dump support for the new instructions.
2013-12-04 15:43:50 +00:00
Bob Nystrom
7e7a508096 refactor: replace integer offset fields with direct char* pointers in token and lexer structs
Change Token struct to store `const char* start` pointer and `int length` instead of integer start/end offsets. Update Lexer struct similarly, replacing `tokenStart` and `currentChar` offsets with direct pointers into the source string. Adjust Local struct's `length` field type from `size_t` to `int` for consistency. Simplify error reporting in `endCompiler` to use `printf` with `%.*s` format specifier and the new pointer/length fields, eliminating manual character-by-character printing loops.
2013-12-01 23:22:24 +00:00
Bob Nystrom
ed005573ad refactor: unify compiler end-of-chunk code path into single endCompiler function
Extract the common bytecode finalization logic into a dedicated endCompiler function that emits CODE_END and handles parent compiler function loading, replacing duplicated inline code. Update VM method definition opcodes to pop function from stack instead of reading from constants, enabling future closure support. Add TODO comments outlining planned closure capture mechanism and upvalue tracking requirements.
2013-12-01 22:59:56 +00:00
Bob Nystrom
eaf69b892f feat: replace direct malloc/free calls with user-provided allocator in VM
The `wrenNewVM` function now uses the provided `reallocateFn` for fiber allocation instead of calling `malloc` directly, and stores the allocator in `vm->reallocate` for later use. The `wrenReallocate` function delegates all memory operations (including freeing) to the stored allocator, removing the fallback to `realloc` and `free`. This ensures consistent memory management through the external allocator, enabling custom allocation strategies like memory pools or tracking.
2013-12-01 18:22:32 +00:00
Bob Nystrom
0496b4e79d refactor: rename MAX_METHOD_NAME to MAX_METHOD_SIGNATURE and extract copyName helper
Extract identifier copying logic from subscript and call functions into a dedicated copyName helper function, reducing code duplication. Rename the method signature length constant to MAX_METHOD_SIGNATURE with updated documentation to clarify it includes arity spaces. Update subscript function to use the new constant name and remove stale TODO comment about handling >10 args.
2013-12-01 08:04:46 +00:00
Bob Nystrom
d9ed245dd4 feat: enforce MAX_LOCALS limit of 256 in declareVariable and add test cases for boundary conditions
Add a compile-time check in declareVariable() that emits an error when the number of simultaneous local variables reaches MAX_LOCALS (256), replacing the previous placeholder TODO. The limit is derived from the bytecode encoding constraint where CODE_LOAD_LOCAL and CODE_STORE_LOCAL use a single argument byte. Also move the MAX_LOCALS definition from a TODO comment to a proper #define, increasing the value from 255 to 256. Include four new test files: many_locals.wren (exactly 256 simultaneous locals), many_nonsimultaneous_locals.wren (more than 256 locals across nested scopes), too_many_locals.wren (257 simultaneous locals triggering the error), and too_many_locals_nested.wren (exceeding the limit across nested blocks).
2013-12-01 02:51:27 +00:00
Bob Nystrom
4240e46e05 feat: replace Scope stack with Local array to fix variable shadowing in nested blocks
Replace the linked-list Scope structure with a flat Local array indexed by depth, enabling proper shadowing semantics where inner declarations correctly hide outer ones. Remove the PUSH_SCOPE/POP_SCOPE macros and the SymbolTable-based locals tracking, replacing them with a MAX_LOCALS (255) fixed-size array that stores variable name, length, and depth. Add four new test cases covering local/parameter collision, nested block scoping, global shadowing, and local shadowing to validate the new behavior.
2013-12-01 02:28:01 +00:00
Bob Nystrom
50b1a381e0 feat: add binary_trees benchmark suite and fix string escape for tab character
Add Lua, Python, Ruby, and Wren implementations of the binary_trees benchmark from the Computer Language Benchmarks Game. Update the benchmark runner to support multiple benchmarks with output validation, and fix the Wren compiler to handle the '\t' escape sequence in string literals.
2013-11-30 00:19:13 +00:00
Bob Nystrom
f0f74c6785 fix: correct compiler pointer in method constructor code emission
The method function was incorrectly using the outer `compiler` pointer instead of the inner `methodCompiler` when emitting `CODE_LOAD_LOCAL` and its operand, causing incorrect bytecode generation for constructor receiver loading.
2013-11-30 00:17:43 +00:00
Bob Nystrom
88f7444f0c feat: extract bytecode dumpInstruction into new wren_debug module
Move the dumpInstruction function and its associated opcode printing logic from wren_vm.c into a dedicated wren_debug.c source file with a corresponding wren_debug.h header. Add the new source file to the Xcode project build configuration.
2013-11-30 00:17:33 +00:00
Bob Nystrom
230017a616 feat: raise max method parameters from 10 to 16 with proper error handling
Add MAX_PARAMETERS constant set to 16 and extend VM bytecode instructions CODE_CALL_11 through CODE_CALL_16 to support the new limit. Introduce compile-time error messages when parameter or argument count exceeds 16 in function definitions, method declarations, subscript calls, and regular method calls. Add new native fiber call stubs fn_call9 through fn_call16 and register them in the core initialization. Include comprehensive test coverage for 9-16 parameter functions and methods, plus error tests for exceeding the limit in all contexts.
2013-11-29 23:08:27 +00:00
Bob Nystrom
1b3b50374f feat: disallow field references outside class definitions with explicit error
Add a check in the `field()` function to detect when a field is referenced outside of a class context. When `compiler->fields` is NULL (indicating no enclosing class), emit a clear error message "Cannot reference a field outside of a class definition." and assign a dummy field index of 255 to allow continued parsing with minimal cascading errors.

Also includes minor cleanup: remove two stale TODO comments about EOF checking and better error messages in `nextToken()` and `consume()`, and add a new test file `test/field/outside_class.wren` that verifies the error is produced for top-level field assignment.
2013-11-29 18:53:56 +00:00
Bob Nystrom
fe7e9041d1 refactor: replace hardcoded pinned array with linked list in WrenVM GC root tracking
Replace the fixed-size `MAX_PINNED` array of `Obj*` pointers with a dynamically allocated linked list of `PinnedObj` nodes, removing the 16-object limit and eliminating the `numPinned` counter. Update `pinObj` to accept a caller-provided `PinnedObj` stack variable and link it at the head of the list, and simplify `unpinObj` to pop the head without requiring the object argument. Adjust `wrenNewVM` to initialize the new `pinned` pointer to NULL, and modify `collectGarbage` to iterate the linked list instead of the array.
2013-11-29 17:14:19 +00:00
Bob Nystrom
f9c534aef9 chore: rename source files to wren_ prefix and add module-level documentation headers 2013-11-28 16:11:50 +00:00
Bob Nystrom
4091fe4911 refactor: rename primitives module to wren_core and update all references
Rename the `primitives.h` and `primitives.c` files to `wren_core.h` and `wren_core.c` respectively, reflecting the module's purpose of defining built-in classes and native methods. Update all includes, macro names (PRIMITIVE -> NATIVE, DEF_PRIMITIVE -> DEF_NATIVE, etc.), and function calls (wrenLoadCore -> wrenInitializeCore) across the codebase and Xcode project file to match the new naming convention.
2013-11-28 16:00:55 +00:00
Bob Nystrom
f36118a451 refactor: rename internal value creation functions to wren-prefixed public API names
Move `allocate`, `initObj`, `newClass`, and related static helpers from `vm.c` into `value.c` with consistent `wren` prefix, and update all call sites in `compiler.c`, `primitives.c`, and `vm.c` to use the new names (`wrenNewFunction`, `wrenNewString`, `wrenNewClass`, `wrenNewInstance`, `wrenNewList`). Remove the old declarations from `vm.h` and add comprehensive documentation comments to `value.h` explaining the NaN-tagging representation and type system.
2013-11-28 04:00:03 +00:00
Bob Nystrom
12d27a05b4 chore: remove stale TODO comment about capacity shrinking in list_removeAt 2013-11-27 19:34:35 +00:00
Bob Nystrom
b17c2667c0 feat: implement list_removeAt primitive with capacity shrink and test suite
Add DEF_PRIMITIVE(list_removeAt) to src/primitives.c that removes an element at a given index from an ObjList, shifts remaining elements up, shrinks capacity when excess is detected via LIST_GROW_FACTOR, and returns the removed Value. Register the primitive as "removeAt " on vm->listClass. Create test/list/remove_at.wren covering removal at positive indices 0,1,2, negative indices -1,-2,-3, out-of-bounds cases returning null, and verification that the removed value is returned.
2013-11-27 18:20:32 +00:00
Bob Nystrom
3c3fa2bfd9 feat: add list clear and insert primitives with capacity growth and index validation
Extract inline list growth logic into `ensureListCapacity` helper and add `validateIndex` function supporting negative indices. Implement `list_clear` primitive that resets count to zero without freeing memory, and `list_insert` primitive that shifts elements right and inserts at validated position. Add comprehensive test suites for both operations covering empty lists, normal/negative indices, and return values.
2013-11-27 07:11:11 +00:00
Bob Nystrom
cd1bd39ce1 feat: implement list.add() with dynamic growth and add wrenPrintValue helper
Add the `list_add` primitive to support appending elements to lists with automatic capacity management using `LIST_MIN_CAPACITY` and `LIST_GROW_FACTOR` constants. Rename internal `valuesEqual` and `reallocate` functions to `wrenValuesEqual` and `wrenReallocate` for consistent naming, and introduce `wrenPrintValue` to handle formatted output of all value types including lists. Add a test file `test/list_add.wren` verifying basic add operations and return value behavior.
2013-11-27 02:02:10 +00:00