Commit Graph
100 Commits
Author SHA1 Message Date
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 14b6eb04d2 docs: expand method-calls documentation with setters and operator sections, add is operator note to syntax page 2013-12-21 17:15:30 +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 278f84a745 feat: convert benchmark runner from time-based stats to score-based comparison
Replace time-based statistics (best, mean, median, std_dev) with a score system using inverse time scaling (1000.0 / time). Increase NUM_TRIALS from 7 to 10 for more reliable results. Update comparison logic to use score ratios instead of time ratios, and swap color highlighting to show green for faster scores (>105%) and red for slower scores (<95%).
2013-12-20 15:04:04 +00:00
Bob Nystrom 1cf8f2d999 feat: add test for infix class expression after constructor call
Add a new test file `test/constructor/infix_class_expression.wren` that verifies
the ability to use an infix operator on a freshly constructed object instance.
The test creates a `Foo` class with a `+` method and checks that `new Foo + "value"`
correctly evaluates to `"Foo value"`. Also includes a TODO comment noting other
constructor expression patterns that should be tested.
2013-12-19 17:10:45 +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 e26afd7de3 docs: add method-calls and variables pages, update sidebar links, revise statement-terminator and performance docs 2013-12-17 17:39:26 +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 c92ba58f5f test: add scope edge case tests for variable initialization and shadowing
Add four new test files covering variable scope edge cases:
- global_in_initializer: verify global variable can reference itself in initializer
- local_in_initializer: verify local variable referencing itself in initializer produces error
- shadow_and_local: verify shadowed variable correctly resolves to outer scope before inner declaration
- shadow_in_initializer: verify shadowed variable in initializer correctly references outer scope value
2013-12-15 00:36:19 +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 8842efbab7 feat: remove JS benchmarks and reduce depth for faster binary_trees/fib runs
Switch binary_trees max depth from 14 to 12 across all languages and reduce fib argument from 30 to 28, dropping JS entirely since its performance is incomparable. Update expected output patterns in run_bench script to match new tab-free format and use best-time comparison instead of mean.
2013-12-13 00:59:57 +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 e97ec653e6 feat: add --language flag to filter benchmarks by language in run_bench
Add a new `--language` / `-l` CLI argument that accepts multiple language
identifiers, and pass the list through to `run_benchmark` so it skips
languages not in the user-specified set. Also remove the short form `-b`
from `--generate-baseline` to avoid conflict with the new `-l` flag.
2013-12-11 07:02:24 +00:00
Bob Nystrom 51dffa8c02 feat: add test verifying default constructor behavior for classes without explicit constructors
Add a new test file `test/constructor/default.wren` that validates the Wren language
behavior where a class with no explicit constructors automatically receives a
parameterless `new` constructor. The test creates a `Foo` class with only a
`toString` method, instantiates it via `Foo.new`, and asserts both the type check
(`foo is Foo`) and the string representation (`foo.toString`). Also includes a
TODO comment noting the need for a future test case covering classes that define
explicit constructors.
2013-12-11 05:58:02 +00:00
Bob Nystrom 813cbbc5a2 docs: add initial performance documentation covering Wren's speed and value representation
Create new doc/site/performance.markdown explaining Wren's position in the bytecode interpreter performance bucket and introducing NaN tagging for compact value storage. Also update doc/site/template.html to include a link to the new performance page in the "Other" navigation section.
2013-12-11 05:51:58 +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 6695580df4 feat: add baseline comparison tracking to benchmark script with color-coded regression/improvement output 2013-12-08 06:14:56 +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 6ba77ea2cd fix: add explicit return statements in benchmark functions and add method_call benchmark suite 2013-12-08 02:43:39 +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 d076abc8b1 docs: add script file format and reserved words sections to syntax docs
Expand the syntax documentation with a new section explaining Wren's script file format (.wren extension) and top-to-bottom execution model. Replace the previous "Literals" section with a comprehensive list of reserved words, and add a new "Newlines" section covering line break handling in the language.
2013-12-05 05:51:23 +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 67aea3f676 docs: add flow-control and values documentation pages with updated template and build script 2013-12-04 15:46:41 +00:00
Bob Nystrom 398cede489 feat: include "include" directory in source code metrics glob
Extend the file scanning loop to also cover header and source files under the `include/` directory by using `itertools.chain` to combine both glob patterns, ensuring metrics are computed for all relevant source locations.
2013-12-04 15:46:23 +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 2cb7522812 feat: add sidebar navigation layout and restructure docs page template
Introduce a `.nav` sidebar with categorized links (Welcome, Language, Objects, Usage) alongside a `.content` area, replacing the old inline header list. Widen the page container from 640px to 840px, rename `.column` to `.page`, and update the header to show a subtitle instead of a small tagline. Adjust the GitHub ribbon z-index to prevent overlap with the new sidebar.
2013-12-01 17:54:51 +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 2f37b99eef feat: add JavaScript binary tree benchmark and update runner with trial count and graph improvements 2013-11-30 04:25:00 +00:00
Bob Nystrom f0db2cbacd chore: add scratch.wren to gitignore for temporary Wren script testing
The .gitignore file now includes an entry for scratch.wren, a temporary Wren script left at the top level for quick testing purposes. This prevents accidental commits of ad-hoc experimentation files.
2013-11-30 00:20:44 +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 fa92ce86ad test: add constructor overload tests for Foo class with arity dispatch
Add test file for Foo class constructors covering zero, one, and two argument overloads by arity. Verify each overload produces correct output and that new instances return proper type and toString behavior.
2013-11-29 23:21:36 +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 91c675b28a chore: reorganize test files into domain-specific subdirectories
- Moved unit tests for user authentication into `tests/unit/auth/`
- Relocated integration tests for payment processing to `tests/integration/payments/`
- Grouped API endpoint tests under `tests/api/` with separate files for each resource
- Updated test runner configuration to discover tests in new directory structure
2013-11-27 06:52:00 +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
Bob Nystrom 6996f5a48d feat: replace per-type equality primitives with unified object_eqeq and wrenGetClass
Move equality and inequality primitives from Bool and Function to a single Object-level implementation using valuesEqual, and add wrenGetClass to return the runtime class of any value. Refactor newSingleClass to inherit methods from superclass and wire metaclass superclass to classClass. Add type-checking tests for all built-in types and class inheritance.
2013-11-26 15:52:37 +00:00
Bob Nystrom 4f73052934 feat: add JavaScript benchmark runner with fib(30) test and node integration
Add a new JavaScript benchmark file `benchmark/fib.js` that implements a recursive Fibonacci function and measures execution time using `process.hrtime()`. Register the JavaScript language entry in `benchmark/run_all` with the `node` interpreter and `.js` extension, enabling JS benchmarks to be included in the full benchmark suite alongside existing languages.
2013-11-26 15:50:12 +00:00
Bob Nystrom 05eab7f82b feat: add public C API header wren.h and refactor internal types to WrenVM prefix 2013-11-25 15:47:02 +00:00
Bob Nystrom b21c774891 feat: unify memory management into single reallocate function with GC triggers
Replace separate allocation, deallocation, and reallocation logic with a single `reallocate` function that handles all memory operations (alloc, grow, shrink, free) and integrates garbage collection triggers based on total allocated memory thresholds. Add `allocate` and `deallocate` convenience wrappers that delegate to `reallocate`.
2013-11-25 15:14:51 +00:00
Bob Nystrom 4e87680dd1 feat: add optional computed gotos support for ~5% interpreter speedup
Introduce a `COMPUTED_GOTOS` preprocessor flag in `src/common.h` that, when defined, replaces the interpreter's traditional `for(;;) switch(instruction)` dispatch loop with a computed-goto dispatch table using GCC/LLVM labels-as-values extension. The new implementation defines a static `dispatchTable[]` array mapping opcodes to their corresponding `&&code_*` labels, and uses `DISPATCH()` macro to `goto` the next handler directly. When `COMPUTED_GOTOS` is not defined, the fallback retains the original `switch`-based loop. This change yields approximately a 5% performance improvement in benchmarks, though optimal GCC performance may require additional flags like `-fno-gcse`.
2013-11-25 05:48:27 +00:00
Bob Nystrom b098c60f7c feat: implement subscript operator for lists with negative index and bounds checking
Add list_subscript primitive that supports integer indexing with negative indices counting from the end, returns null for out-of-bounds access, non-integer indices, and non-numeric argument types. Register the `[ ]` operator on the List class in loadCore and include comprehensive test coverage in test/list_subscript.wren.
2013-11-25 03:08:46 +00:00
Bob Nystrom cc117912fa feat: implement list literal syntax and List class with count property
Add support for list literals in the compiler with bracket-delimited syntax and comma-separated elements. Introduce the ObjList runtime type with a contiguous elements array, garbage collection marking, and proper memory deallocation. Expose a `List` class in the core library with a `count` method returning the number of elements. Update the grammar table to register `[` as a prefix token for list compilation instead of an infix subscript operator, and reorder opcode enum entries to place CODE_LIST before the load/store group.
2013-11-24 21:38:31 +00:00
Bob Nystrom 2490e6a425 feat: add subscript operator for array indexing and string character access
Implement the `[]` subscript operator as an infix parser at `PREC_CALL` precedence, compiling to a method call on the receiver. Add a `string_subscript` primitive that handles integer indices (including negative for reverse indexing), returns `null` for out-of-bounds or non-integer arguments, and returns a one-character string. Register the `[ ]` method on the string class and include tests for basic indexing, negative indices, out-of-bounds, wrong types, and non-integer indices.
2013-11-24 18:45:07 +00:00
Bob Nystrom cc55fd2a57 feat: implement string escape sequence parsing in lexer and add test coverage
Add escape sequence handling to the string literal lexer in compiler.c, translating
common escape sequences (\", \\, \n) into their literal character equivalents during
tokenization. Introduce a fixed-size buffer (MAX_STRING 1024) in the Parser struct to
accumulate the unescaped string content, along with a helper function addStringChar()
to append characters. The readString() function now loops over input characters,
breaking on an unescaped double quote, and processing backslash-prefixed escapes via
a switch statement. Remove the previous TODO placeholder comment and the elapsed time
computation simplification in benchmark/fib.lua. Add a new test file
test/string_escapes.wren that verifies the three supported escape sequences, and
remove the now-obsolete TODO about escapes from test/string_literals.wren.
2013-11-24 05:00:47 +00:00
Bob Nystrom 56f0f1639b refactor: remove redundant explicit casts to Value in string and primitives functions 2013-11-24 01:35:11 +00:00
Bob Nystrom f50453e24e feat: add instance field support with lexer, compiler, and GC tracing
Add TOKEN_FIELD token type and '_' prefix handling in lexer to distinguish field identifiers from regular names. Extend Compiler struct with fields symbol table pointer for tracking enclosing class fields. Implement field() parse function and CODE_LOAD_FIELD/CODE_STORE_FIELD bytecodes in VM. Modify ObjClass to store numFields count and ObjInstance to use flexible array member for field storage. Update GC markInstance to trace all instance fields. Add newClass signature to accept numFields parameter. Include test cases for field default null, multiple fields, object references with GC, and use-before-set ordering.
2013-11-23 22:55:05 +00:00
Bob Nystrom f4982f7b21 docs: add classes documentation content, usage page stub, and fix page title in template
Add full introductory content to the classes documentation page covering class definition, inheritance, and the Object superclass. Create a new usage documentation page with a TODO placeholder. Update the HTML page title format from "wren {title}" to "Wren - {title}" and add a navigation link to the new usage page.
2013-11-23 22:52:50 +00:00
Bob Nystrom 65615f4aa8 feat: add ASCII art graph of benchmark results with configurable trial count
Extract hardcoded trial count into NUM_TRIALS constant set to 7, collect all timing results into a list, and add graph_results function that prints a horizontal ASCII bar chart scaling each run's times relative to the global maximum across all benchmarks and languages.
2013-11-22 17:17:45 +00:00
Bob Nystrom 95faef89d5 feat: add benchmark runner with fib implementations and OS.clock primitive
Add a benchmark runner script (benchmark/run_all) that executes multiple
fibonacci implementations across languages (Lua, Python, Ruby, Wren) and
computes mean, median, and standard deviation from 7 runs. Update existing
fib benchmarks to loop 5 times at fib(30) with elapsed timing. Introduce
OS.clock primitive in C core and OS class to support timing in Wren.
Adjust number formatting to "%.14g" for consistent output precision.
2013-11-22 16:55:22 +00:00
Bob Nystrom 4a9ea2f0b4 feat: add MIT license file for the Wren programming language project
This commit introduces a LICENSE file containing the full text of the MIT License, attributed to Robert Nystrom (2013), which governs the distribution and use of the Wren software.
2013-11-22 05:41:44 +00:00
Bob Nystrom 67c9435b03 feat: add initial documentation site with markdown pages and build script 2013-11-22 05:38:36 +00:00
Bob Nystrom 456c7e87e0 docs: document receiver-less call ambiguity in private getter vs field access 2013-11-22 05:38:21 +00:00
Bob Nystrom b9264e4c5a feat: add named user-defined constructors with this keyword prefix in class bodies 2013-11-20 15:20:16 +00:00
Bob Nystrom ca400d725e chore: disable DEBUG_GC_STRESS and refactor initCompiler with addConstant helper 2013-11-20 04:54:47 +00:00
Bob Nystrom 36c3f0b704 refactor: extract twoCharToken helper and remove skipWhitespace from lexer
Extract repeated two-character token matching logic into a dedicated
twoCharToken function, reducing code duplication in readRawToken.
Remove the unused skipWhitespace helper that only handled single spaces
and was replaced by more robust whitespace handling elsewhere.
Fix indentation in isKeyword and remove stale TODO comment in readName.
2013-11-20 04:19:02 +00:00
Bob Nystrom 643a7c4f97 feat: add logical OR operator with short-circuit evaluation and token support
Add TOKEN_PIPEPIPE token for '||' syntax, implement or() parsing function with CODE_OR bytecode, and add VM interpreter logic that short-circuits on truthy left operand. Update .gitignore to exclude *.xccheckout files, extend test coverage for falsy behavior in and.wren and if.wren, and add comprehensive or.wren test suite verifying short-circuit semantics and truthiness rules.
2013-11-20 02:24:58 +00:00
Bob Nystrom 06be5808da feat: add IS_FALSE macro for non-NaN-tag boolean false check in value.h
The new IS_FALSE macro checks if a Value's type field equals VAL_FALSE,
complementing the existing IS_NULL and IS_NUM macros for type discrimination
without relying on NaN-boxing tag bits.
2013-11-19 15:36:59 +00:00
Bob Nystrom 9e8eed6c29 feat: implement logical AND operator with short-circuit evaluation and new CODE_AND instruction
Add TOKEN_AMPAMP token to the lexer for parsing '&&' operator, introduce PREC_LOGIC precedence level for proper expression parsing, implement the `and()` compiler function that emits CODE_AND with a patchable jump offset, and add runtime support in the VM with IS_FALSE macro for truthiness checking. Include comprehensive test cases in test/and.wren verifying short-circuit behavior and return values.
2013-11-19 15:35:25 +00:00
Bob Nystrom ed9f4ec9f3 feat: add block scope support with push/pop macros and scope tracking in compiler
Introduce Scope struct and PUSH_SCOPE/POP_SCOPE macros to manage nested variable scopes during compilation. Update declareVariable to distinguish global declarations from local ones based on scope presence rather than parent compiler. Add truncateSymbolTable helper to clean up local symbols when exiting a scope. Include new test files verifying scoped variable isolation in if, while, and block constructs.
2013-11-18 17:19:03 +00:00
Bob Nystrom dc2f053d76 feat: add while loop token, parser support, CODE_LOOP opcode, and patchJump helper
Add TOKEN_WHILE to the token enum and keyword lookup in the compiler, enabling the parser to recognize 'while' statements. Introduce the CODE_LOOP opcode in the VM for backward jumps, and implement the patchJump helper to resolve forward jump offsets during compilation. Include comprehensive test cases for while loops covering single-expression bodies, block bodies, newline handling, and null result semantics.
2013-11-18 06:38:59 +00:00
Bob Nystrom 9c663aa13c feat: implement NaN tagging for Value union and hoist bytecode/IP into locals in interpret loop
Switch Value from a struct with type/num/obj fields to a NaN-tagged uint64_t/double union, enabling faster type checks and unboxed numbers. Refactor all macros and accessors (IS_OBJ, AS_OBJ, AS_NUM, etc.) to work with the new representation. Hoist CallFrame pointer, instruction pointer, and bytecode array into local variables inside the interpret loop, updating them on frame push/pop. Enable NAN_TAGGING define and DEBUG_GC_STRESS in common.h. Update Xcode project to use c99 standard, pedantic warnings, and treat warnings as errors. Add benchmark/fib.txt with timing comparisons showing fib benchmark within 25% of Lua.
2013-11-17 22:20:15 +00:00