Commit Graph

135 Commits

Author SHA1 Message Date
Bob Nystrom
7afbcd142d feat: add bitwise XOR, left shift, and right shift operators to Wren language
Add three new bitwise operators (^, <<, >>) to the Wren compiler and runtime,
including tokenization, parsing with correct precedence, and native method
implementations operating on 32-bit unsigned integers. New test files verify
correct behavior for edge cases including max u32 values and operand type errors.
2015-02-18 15:55:38 +00:00
Bob Nystrom
4f471203fa feat: replace string import method with dedicated bytecode instruction for module variable loading
Replace the runtime string-based `import_` method call with a new `CODE_IMPORT_VARIABLE` bytecode instruction that directly loads variables from other modules. This eliminates the overhead of calling a native method and string-based module lookup during import, moving the logic into the VM interpreter loop with a dedicated `importVariable` helper function. The change includes adding the opcode to the compiler's `import` function, implementing the runtime lookup in `wren_vm.c`, updating the debug disassembler, and removing the now-unnecessary `string_import` native from `wren_core.c`.
2015-02-17 15:21:51 +00:00
Bob Nystrom
e64e2c01e1 feat: replace string-based module loading with dedicated CODE_LOAD_MODULE bytecode instruction
Replace the previous approach of calling a native `loadModule_` method on string objects with a new `CODE_LOAD_MODULE` bytecode instruction. This eliminates the need for the `string_loadModule` native function and the indirect fiber invocation through `PRIM_RUN_FIBER`. The new implementation directly handles module loading in the VM by compiling the module source, creating a fiber, and switching execution contexts. The compiler now emits `CODE_LOAD_MODULE` followed by a `CODE_POP` to discard the unused fiber result, instead of the previous `CODE_CONSTANT` + `CODE_CALL_0` sequence.
2015-02-17 06:45:58 +00:00
Marco Lizza
cc38b6f35a refactor: rename num_bitwiseLsh and num_bitwiseRsh to num_bitwiseLeftShift and num_bitwiseRightShift for clarity
Renamed the native function identifiers for left and right bitwise shift operations
in wren_core.c to use the more explicit names num_bitwiseLeftShift and
num_bitwiseRightShift, replacing the abbreviated Lsh and Rsh suffixes. Updated
both the DEF_NATIVE macro definitions and the corresponding NATIVE registrations
in wrenInitializeCore to use the new names.
2015-02-16 21:29:30 +00:00
Bob Nystrom
d5149f9a74 refactor: remove builtin import_ method from String class and inline module loading in compiler
The import_ method on String was a builtin that combined module loading and variable lookup. This change removes that method and instead emits separate bytecode instructions in the compiler: first calling loadModule_ on the module, then calling import_ on the module with the variable name. The native function string_lookUpVariable is renamed to string_import to match the new import_ method name on String's metaclass.
2015-02-16 18:21:29 +00:00
Bob Nystrom
2082b64454 feat: move fiber execution of loaded modules from Wren to C runtime
The `loadModule_` primitive now returns a fiber when a module is loaded, and the C runtime handles calling it via `PRIM_RUN_FIBER` instead of the Wren code manually invoking the result. This removes the conditional `if (result != null) result.call` from the `import_` method in both the builtin source and the embedded libSource string, and adds `IS_FIBER` macro to `wren_value.h` for type checking in the native implementation.
2015-02-16 18:16:42 +00:00
Bob Nystrom
f2424f029e refactor: move module load failure handling from Wren to C with error string return
The loadModule_ primitive now returns NULL for already-loaded modules and an error string for missing modules, shifting the error handling from Wren's Fiber.abort to C's native string return. The Wren import_ method simplifies to only call the result when non-null, removing the false/true branching logic.
2015-02-16 18:12:41 +00:00
Marco Lizza
8c8a059dda feat: add bitwise XOR, left-shift, and right-shift primitives for numbers
Implement three new native methods on the Num class: `^` (bitwise XOR), `<<` (left shift), and `>>` (right shift). Each operates on 32-bit unsigned integers, matching the existing bitwise AND/OR convention. The new primitives are registered in `wrenInitializeCore` alongside the existing bitwise operators.
2015-02-16 10:29:14 +00:00
Bob Nystrom
70191aa022 feat: add module loading with String.import_ and embedder-provided loadModuleFn
Implement initial module system allowing Wren code to import other modules via a temporary `String.import_` method. The embedder must supply a `WrenLoadModuleFn` callback that returns source code for a given module name; the VM caches loaded modules and returns a fiber to execute the module body. Add `wrenImportModule` to the VM API, wire `loadModuleFn` into `WrenConfiguration`, and update the CLI interpreter to resolve imports relative to the entry script's directory. Include test cases for importing multiple variables, shared imports across modules, and verifying that variable bindings are independent across import sites.
2015-02-06 15:01:15 +00:00
Bob Nystrom
7cba07a322 feat: add shared library builds and fix string buffer type in symbol table
Add Makefile targets for building shared libraries (.so/.dylib) alongside existing static libraries, with platform-specific linker flags for macOS and Linux. Refactor the internal string representation from raw `char*` to a `String` struct that tracks both buffer and length, updating all symbol table operations, debug printing, and string concatenation calls to use the new type. Fix a null-termination bug in `copyName` and add support for the `\0` escape sequence in string literals.
2015-02-05 20:07:25 +00:00
Bob Nystrom
1fd8308f50 refactor: remove dedicated main module field from WrenVM struct
Instead of storing the main module directly in a dedicated field on WrenVM,
store it as a null-keyed entry in the new modules map. This eliminates the
redundant `vm->main` pointer and paves the way for supporting multiple named
modules. The change also adds `wrenFindVariable` as a public helper to look up
top-level variables in the main module, and updates `wrenNewFunction` to accept
an explicit module parameter instead of always using `vm->main`.
2015-02-05 20:03:19 +00:00
Bob Nystrom
9ed0bdac95 fix: cast index to uint32_t before comparing with string length in string_iterate 2015-02-05 04:28:27 +00:00
Bob Nystrom
8fa4f9c1bb refactor: change wrenStringFind to return UINT32_MAX instead of haystack->length for not-found
The wrenStringFind function previously returned the haystack length to indicate
a missing needle, which was ambiguous when the needle could legitimately appear
at the end of the string. This commit changes the sentinel value to UINT32_MAX,
updates all callers (string_contains, string_indexOf) to check against the new
sentinel, and adds explicit handling for empty needle and empty haystack edge
cases. The Boyer-Moore-Horspool implementation is also cleaned up with clearer
variable names and comments.
2015-02-05 04:23:50 +00:00
Bob Nystrom
84e1b78a7a feat: replace strstr with Boyer-Moore-Horspool string search in core string operations
Implement wrenStringFind function using Boyer-Moore-Horspool algorithm with 256-entry shift table for efficient substring matching. Update string_contains, string_indexOf, and string_count native methods to use the new implementation, fixing the empty string corner case to always return true when search string is empty.
2015-02-05 01:56:29 +00:00
Bob Nystrom
00226268c3 style: reformat string concat calls to 80 cols and fix comment typo
Break long wrenStringConcat calls across multiple lines in validateFn,
validateNum, validateIntValue, and validateString functions in
src/wren_core.c to stay within the 80-column limit. Also fix a comment
typo in src/wren_value.h: change "of" to "with" in the wrenStringConcat
documentation.
2015-02-04 16:15:35 +00:00
Bob Nystrom
80815a279b fix: add explicit length parameters to wrenStringConcat calls in validation and class creation 2015-02-04 16:12:50 +00:00
Marco Lizza
a7ad4ead70 fix: handle empty search string in string_contains by checking search length only
Previously, the corner case for empty strings only returned true when both the source and search strings were empty. This fix changes the condition to return true whenever the search string is empty, as the empty string is always contained within any string.
2015-02-04 12:53:59 +00:00
Marco Lizza
23dcd3feb3 refactor: replace strcpy/strncpy with memcpy for safer string handling across compiler, core, utils, value, and vm modules 2015-02-04 12:51:54 +00:00
Marco Lizza
7127012cf7 fix: cast index to uint32_t in string_iterate to suppress signed comparison warning 2015-02-04 12:47:09 +00:00
Marco Lizza
81a1a5a72f fix: add explicit length parameters to wrenStringConcat for null-containing string support
The function signature was changed from accepting null-terminated C strings to accepting explicit length parameters, with -1 indicating automatic strlen calculation. All call sites were updated to pass -1 for both lengths, and internal implementation switched from strcpy to memcpy to handle embedded null bytes correctly.
2015-02-04 12:44:39 +00:00
Marco Lizza
b43788a221 feat: replace strstr with wrenStringFind using Boyer-Moore-Horspool for 8-bit string support
Implement wrenStringFind function in wren_value.c that uses the Boyer-Moore-Horspool algorithm with a 256-entry shift table for full 8-bit character support. Update string_contains and string_indexOf native methods in wren_core.c to call the new function instead of strstr, fixing substring searches on strings containing null bytes or extended ASCII characters.
2015-02-04 12:38:15 +00:00
Bob Nystrom
6858db260a fix: replace bitfield flags with bool marked and fix empty map lookup crash
Replace the ObjFlags bitfield approach with a simple bool `marked` field on Obj, removing the FLAG_MARKED constant and all bitwise operations. Also add a guard in wrenMapFind to return UINT32_MAX when map capacity is zero, preventing a crash on empty map subscript lookups. Fix the validateKey function to not wrap the error string in OBJ_VAL.
2015-01-30 15:21:41 +00:00
Bob Nystrom
cdfad0a7eb fix: remove redundant OBJ_VAL wrapper in validateKey error string assignment 2015-01-30 04:44:46 +00:00
Bob Nystrom
7febf6cd57 refactor: convert Module struct to heap-allocated ObjModule with GC support
Replace the embedded `Module main` field in WrenVM with a pointer to a dynamically allocated `ObjModule`, adding a new OBJ_MODULE object type. Introduce `wrenNewModule()` constructor and `markModule()` GC tracer, update all references from `&vm->main` to `vm->main`, and remove the old `initModule`/`freeModule` static helpers.
2015-01-27 15:11:45 +00:00
Bob Nystrom
a9f0b89df2 refactor: replace string-specific equality operators with generic wrenValuesEqual and add range equality tests
Remove dedicated string equality and inequality native methods (string_eqeq, string_bangeq) and their registration in wrenInitializeCore, since wrenValuesEqual now handles string comparison correctly using memcmp instead of strncmp. Also add a new test file for range equality and inequality checks.
2015-01-27 05:55:41 +00:00
Bob Nystrom
a794ce4ee1 refactor: move global variable storage from VM into Module struct
Functions now hold a reference to the module where they were defined and load module-level variables from there instead of from the VM's global table. This introduces a new Module struct with its own variable buffer and symbol table, replacing the VM-level globals and globalNames. The main module is stored directly in the VM as a temporary measure. Performance regresses slightly due to the indirection through the function's module pointer.
2015-01-26 15:45:21 +00:00
Bob Nystrom
55851d35ba feat: replace string-specific eqeq/bangeq with generic wrenValuesEqual for range equality support
Remove the dedicated string equality operators (string_eqeq, string_bangeq) and their NATIVE registrations, switching object_eqeq and object_bangeq to use the generic wrenValuesEqual instead of wrenValuesSame. Also fix wrenValuesEqual to use memcmp instead of strncmp for string comparison. Add a new test file test/range/equality.wren verifying inclusive and exclusive range equality and inequality.
2015-01-26 15:01:15 +00:00
Gavin Schulz
4042cd6500 refactor: remove redundant string and range equality natives, delegate to wrenValuesEqual 2015-01-26 07:26:59 +00:00
Bob Nystrom
bee26d2ab2 refactor: remove dedicated CODE_LIST bytecode in favor of new List instantiation with .add() calls
Eliminate the LIST opcode and its interpreter case, debug printing, and enum entry. Instead compile list literals by loading the List class, calling its constructor, then emitting DUP, element expression, CALL_1 for add(), and POP for each element. This removes interpreter loop code and lifts the previous 255-element limit on list literals.
2015-01-26 06:49:30 +00:00
Gavin Schulz
b0b3256335 feat: add == and != operators to Range class with equality tests
Implement equality comparison for Range objects by defining `range_eqeq` and `range_bangeq` native methods that delegate to `wrenValuesEqual`. Register both operators on the Range class in `wrenInitializeCore` and add a comprehensive test suite in `test/range/equality.wren` covering inclusive/exclusive ranges and cross-type inequality checks.
2015-01-26 03:50:54 +00:00
Bob Nystrom
f647680184 feat: add remove() method to Map class with native implementation and tests 2015-01-26 01:42:36 +00:00
Bob Nystrom
a83205ef89 feat: add containsKey method to Map and validate key types in subscript operations
Implement `containsKey()` native method on Map that returns a boolean indicating whether the given key exists in the map. Add `validateKey()` helper to reject non-value-type keys (objects, lists, fibers, etc.) with a clear runtime error. Refactor `wrenMapGet()` signature to return success/failure via bool and output the value through an out-parameter, enabling both `containsKey()` and the existing subscript operator to share the same key validation and lookup logic. Update `map_subscript` to return `null` instead of crashing when a key is not found. Add test cases for `containsKey` success/failure, and runtime error tests for invalid key types in subscript getter, setter, and containsKey.
2015-01-25 20:39:19 +00:00
Bob Nystrom
f093d0a42a feat: implement Map.keys, Map.values iterators and proper toString with key-value formatting
Add MapKeySequence and MapValueSequence classes in core.wren to expose iterable key and value views on Map instances. Implement native iterate_, keyIteratorValue_, and valueIteratorValue_ primitives in wren_core.c to support these sequences. Replace the stub Map.toString with a full implementation that iterates keys and formats each entry as "key: value", handling empty maps and nested maps correctly. Include comprehensive test suites for key iteration, value iteration, iterator type validation, and toString output across multiple orderings.
2015-01-25 18:27:38 +00:00
Bob Nystrom
56123c71e3 feat: implement map clear method to remove all entries
Add DEF_NATIVE(map_clear) that frees the underlying entries array and resets
capacity and count to zero, returning null. Register the "clear" method on
the Map class in wrenInitializeCore and include a test verifying the map is
emptied and the return value is null.
2015-01-25 16:39:44 +00:00
Bob Nystrom
5c33ecc04f feat: add initial Map class with hash table, subscript, and count support
Implement the core Map data structure in Wren, including the ObjMap type with
hash table storage, native methods for instantiation, subscript get/set, and
count. Add Map class declaration to core.wren with a basic toString stub.
Introduce MapEntry struct and hash table growth logic with configurable load
factor. Add test files for map creation, count tracking, key type support
(including null, bool, num, string, range, and class keys), and growth
behavior. Refactor list capacity constants into shared MIN_CAPACITY and
GROW_FACTOR macros. Change object equality operators to use wrenValuesSame
instead of wrenValuesEqual.
2015-01-25 06:27:35 +00:00
Bob Nystrom
239c65201b feat: add join method to Sequence and refactor List toString to use it 2015-01-24 22:39:45 +00:00
Gavin Schulz
9e20b3935a feat: abstract List's toString into generic join method on Sequence
Add `join` and `join(sep)` methods to the `Sequence` class, allowing any sequence to produce a concatenated string of its elements with an optional separator. Refactor `List.toString` to delegate to `join(", ")` with bracket wrapping, removing the manual iteration logic from List. Include new test files for List, Range, and String join behavior, plus runtime error tests for non-string separators.
2015-01-24 04:45:23 +00:00
Bob Nystrom
368d9a3052 feat: add arity getter to Fn class and rename numParams to arity
Add a public `arity` getter to the Fn class that returns the number of required arguments for a function. Internally rename the `numParams` field to `arity` across the codebase for consistency, update the C API parameter name from `numParams` to `arity` in `wrenDefineMethod` and `wrenDefineStaticMethod`, and adjust the error message in `callFunction` to use the new field name. Also update documentation to clarify that extra arguments are ignored rather than causing an error, and add a new test file `test/function/arity.wren` verifying arity values from 0 to 4.
2015-01-24 04:33:05 +00:00
Bob Nystrom
488fb27b91 feat: make String iterable over code points with iterate/iteratorValue primitives
Add String as a subclass of Sequence in core.wren and implement the iterator protocol for strings in wren_core.c. The string_iterate native advances through UTF-8 code point boundaries, while string_iteratorValue extracts the full code point at a given byte index. Includes comprehensive test coverage for iteration, edge cases (empty strings, mid-sequence positions), and error handling for invalid iterator types and out-of-bounds indices. Also updates documentation for String, List, and Sequence classes with iterator protocol details and usage examples.
2015-01-23 04:58:22 +00:00
Bob Nystrom
7e52e36a1c docs: clarify UTF-8 byte indexing in string subscript and add wrenStringCodePointAt helper 2015-01-23 00:38:03 +00:00
Bob Nystrom
6223bb2342 fix: replace broken WREN_PIN macro with proper wrenPushRoot/wrenPopRoot GC root stack 2015-01-21 15:56:06 +00:00
Bob Nystrom
f0f03ec763 refactor: replace CalculatedRange struct with output parameters in calculateRange
The CalculatedRange struct is removed from the header and calculateRange now returns the start index directly while using pointer parameters for length and step, simplifying the API and reducing struct overhead.
2015-01-20 23:33:21 +00:00
Gavin Schulz
2799fa6b58 feat: add range subscripting support for strings with CalculatedRange helper
Extract range validation logic from list_subscript into a reusable calculateRange function that handles inclusive/exclusive bounds, negative indices, and direction stepping. Add CalculatedRange struct to wren_core.h and implement string subscripting via the new helper, including comprehensive test coverage for forward, backward, negative, and half-negative ranges with proper error messages for out-of-bounds and non-integer values.
2015-01-17 07:20:56 +00:00
Luchs
fb14301967 feat: implement single-argument reduce with manual iteration and empty-sequence abort
Replace the previous slice-based single-argument reduce implementation with an explicit iterator loop that seeds from the first element. This avoids the out-of-bounds range error on single-element lists and adds a Fiber.abort for empty sequences. Update the test to verify correct behavior for single-element and empty sequences.
2015-01-16 08:24:18 +00:00
Luchs
afa0a0a8e9 feat: add reduce method to Sequence with two overloads and tests
Implement `reduce` on the `Sequence` class in core.wren with two overloads: one taking an initial accumulator and a function, and another using the first element as the initial accumulator. Add three test files covering normal reduction, single-element edge case, and wrong arity error.
2015-01-15 15:29:49 +00:00
Bob Nystrom
d3ea153a31 feat: implement ! operator for all core types with proper truthiness semantics
Add native `!` methods to Null, Object, Num, String, and List classes so that `!` works reliably on any value. Null returns `true`, all other types return `false` since they are considered truthy. Update documentation to describe the operator as returning the logical complement and add comprehensive tests for each type. Also fix the `all` method test to use a truthy string instead of expecting a runtime error.
2015-01-16 05:50:01 +00:00
Bob Nystrom
4acdc503e4 feat: add Sequence.all method and forall documentation with tests
Implement `all(f)` method on Sequence class that returns true if all elements pass the predicate function. Add corresponding documentation entry for `forall(predicate)` in core-library.markdown. Include three test files covering basic functionality, non-boolean return handling, and non-function argument error cases.
2015-01-15 14:52:43 +00:00
Gavin Schulz
adee8ac482 refactor: rename Sequence method forall to all across core lib, C source, and test files 2015-01-15 07:19:31 +00:00
Gavin Schulz
cb1703409c test: add forall test for empty list and non-bool/non-function args
Add test case verifying that `forall` returns true for an empty list regardless of predicate, and add two new test files covering runtime errors when `forall` receives a non-boolean-returning function or a non-function argument. Also refactor the `forall` implementation to use logical negation (`!`) instead of explicit `!= true` comparison.
2015-01-15 06:42:15 +00:00
Gavin Schulz
580ca8cf27 feat: add forall method to Sequence class for testing all elements pass predicate
Implement a `forall` method on the Sequence class that takes a predicate function and returns true only if every element in the sequence satisfies the predicate. The method iterates through all elements, returning false immediately upon encountering any element where the predicate does not return exactly true. Includes core library documentation and a test file verifying behavior with numeric comparisons and non-boolean predicate returns.
2015-01-14 07:47:01 +00:00