Commit Graph

168 Commits

Author SHA1 Message Date
Bob Nystrom
ff420c816b feat: add wrenGetMethod, wrenCall, and wrenReleaseMethod for invoking Wren methods from C code 2015-02-28 21:31:15 +00:00
Bob Nystrom
08f40299f0 refactor: extract signature stringification into dedicated helper and update callers
The `signatureSymbol` function previously built a method name string as a side effect before hashing it. This change separates the stringification logic into a new `signatureToString` function that writes the full signature name into a provided buffer and updates its length. All callers now use the new helper, making the code clearer and allowing the stringified signature to be reused independently of symbol lookup.
2015-02-27 15:10:44 +00:00
Bob Nystrom
469f64fa9a refactor: remove endToken parameter and error handling from finishParameterList
The finishParameterList function no longer needs to consume the closing delimiter
or produce error messages, as that responsibility has been moved to the callers.
The parameterList wrapper function has been inlined into its single call site,
simplifying the parameter parsing flow.
2015-02-27 14:51:37 +00:00
Bob Nystrom
5382fa05d7 feat: allow empty argument list methods in calls, definitions, and docs
- Compile empty `()` as a valid method signature distinct from no parentheses
- Update `call()`, `clear()`, `run()`, `try()`, and `yield()` to use empty argument lists
- Revise documentation across multiple files to reflect new signature semantics
2015-02-27 07:08:36 +00:00
Bob Nystrom
94f34367f9 feat: switch method signatures to parenthesized parameter notation and update error messages
The method signature format has been changed from space-counted arity (e.g., "== ") to explicit parenthesized parameter lists (e.g., "==(_)"). This required updating the MAX_METHOD_SIGNATURE calculation to account for parentheses and parameter separators, replacing the old copyName helper with a new Signature struct and SignatureType enum, and rewriting the methodNotFound error message to display the full signature string instead of reconstructing arity from trailing spaces. All core method registrations in wren_core.c, wren_io.c, and corresponding test expectations have been updated to use the new signature format.
2015-02-27 05:56:15 +00:00
Marco Lizza
e09d8c9b9e fix: raise '&&' precedence above '||' in wren compiler's operator precedence table
Split the former PREC_LOGIC into PREC_LOGICAL_OR and PREC_LOGICAL_AND, inserting PREC_TERNARY between them, and updated all parsePrecedence calls and grammar rule entries to use the new precedence levels.
2015-02-25 15:04:02 +00:00
Marco Lizza
5ff3e291da fix: adjust bitwise operator precedence between comparison and range in compiler enum 2015-02-25 15:02:29 +00:00
Marco Lizza
4f45d18150 fix: split monolithic PREC_BITWISE into separate precedence levels for | ^ & << >> operators 2015-02-23 16:28:43 +00:00
Bob Nystrom
f51847e9f4 refactor: extract call method helpers and clean up comment formatting in wren_compiler.c
Extract `callMethodInstruction` and `callMethod` helper functions from the
existing `methodCall` function to reduce code duplication and improve
readability. Also fix comment formatting for argument arity overloading
and block argument inclusion.
2015-02-22 19:04:43 +00:00
Bob Nystrom
c1fc6adcb4 feat: extract argument list parsing into finishArgumentList helper
Extract the duplicated argument list parsing logic from methodCall and
subscript into a shared finishArgumentList function. This unifies the
comma-separated expression parsing, arity tracking, and newline handling
into a single location. Also add a new test case verifying that newlines
after commas and before closing delimiters are correctly handled in both
method calls and subscript expressions.
2015-02-22 18:42:49 +00:00
Bob Nystrom
b3ea90f333 docs: correct comments in classDefinition, WREN_NAN_TAGGING define, and fix typo in collectGarbage 2015-02-21 08:09:55 +00:00
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
0d3eae5269 feat: allow zero or multiple imported names in import statement
Make the `for` clause in import statements optional, and support comma-separated lists of imported names when present. This removes the previous restriction of exactly one imported variable per import statement.

- Refactor `import()` in compiler to handle optional `for` clause with loop over comma-separated names
- Update existing tests to use comma-separated imports and omit `for` clause where appropriate
- Add new tests: `inside_block`, `name_collision`, `no_variable`
2015-02-17 15:32:33 +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
668df8d1af fix: rename TOKEN_LEFT_SHIFT and TOKEN_RIGHT_SHIFT to TOKEN_LTLT and TOKEN_GTGT
Rename the token enum values and all references in the compiler to use the more concise
TOKEN_LTLT and TOKEN_GTGT names for the '<<' and '>>' operators, updating both the
token type definitions and the grammar rule table entries.
2015-02-16 21:26:54 +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
Marco Lizza
a9b9c483cc feat: add bitwise shift and XOR operators to compiler tokenizer and parser
Add TOKEN_LEFT_SHIFT, TOKEN_RIGHT_SHIFT, and TOKEN_CARET to the token enum, implement lexing for '^' as single-char token and '<<'/'>>' as two-char tokens in nextToken(), and register them as infix operators at PREC_BITWISE precedence in the grammar rules table.
2015-02-16 10:28:34 +00:00
Bob Nystrom
ea958deeef feat: add import keyword token and parser support with updated test syntax
Add TOKEN_IMPORT to the token enum and wire it into the keyword parser in readName(). Refactor string literal parsing by extracting stringConstant() helper that returns the constant index, allowing the new import parser to reuse it. Update all module test files to replace the old .import_() method calls with the new import "module" for Var syntax, and add new error test cases for missing string and missing for clause after import.
2015-02-15 00:46:00 +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
8eecc5abe3 feat: add '\0' escape sequence support for null characters in string parsing
Add handling for the null character escape sequence '\0' in the readString function within wren_compiler.c. This extends the existing escape sequence handling to include the null character, allowing strings to contain embedded null bytes when explicitly escaped.
2015-02-04 14:57:42 +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
ed38494eba feat: add '\0' escape sequence support in string literal parsing
Add handling for the null character escape sequence '\0' in the
readString function within the Wren compiler. This allows string
literals to include null bytes via the standard C escape syntax,
matching the existing support for other escape sequences like '\a',
'\b', and '\f'.
2015-02-04 12:25:25 +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
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
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
Bob Nystrom
f1d2f2f9c1 fix: add explicit readNumber call for numeric literal tokens in nextToken 2015-01-26 01:51:50 +00:00
Bob Nystrom
7fd1751499 feat: add hex literal parsing with readHexDigit and readHexNumber in wren_compiler.c
Implement hexadecimal number literal support in the Wren compiler by adding a `number` field to the Parser struct, a `readHexDigit` helper that returns -1 for invalid hex chars, and a `readHexNumber` function that skips the 'x' prefix, accumulates hex digits, converts via strtol, and emits a TOKEN_NUMBER. Update `readNumber` to remove the TODO placeholder for hex support. Include test cases for valid hex literals (0xFF, 0x09, negative -0xFF) and an invalid hex literal (2xFF) that triggers a lex error.
2015-01-26 01:49:05 +00:00
Gavin Schulz
992a2aeb96 feat: add hexadecimal number literal parsing to wren compiler
Remove the TOKEN_HEXADECIMAL token type and isHexDigit helper, replacing them with a readHexDigit function and readHexNumber parser that directly converts hex literals to numeric values during lexing. Add a `number` field to the Parser struct to hold the parsed value, and include a test for invalid hex literal error handling.
2015-01-25 21:02:44 +00:00
Bob Nystrom
2ec0a8aef9 feat: implement map literal syntax with curly braces and DUP bytecode
Add support for map literals using `{}` syntax in the compiler, replacing the previous `new Map` constructor pattern. This introduces a new `map()` grammar function that loads the Map class, instantiates it, and compiles key-value pairs using subscript setter calls. A new `CODE_DUP` bytecode is added to duplicate the map reference on the stack for each element insertion. The change includes updated test files to use literal syntax and new error tests for edge cases like EOF after colon, comma, key, or value.
2015-01-25 07:21:50 +00:00
Gavin Schulz
b2c6dfce8d feat: add hexadecimal literal support to lexer and compiler
Add TOKEN_HEXADECIMAL token type and isHexDigit helper function to lexer.
Modify readNumber to detect 'x' prefix after '0' and lex hex digits.
Implement emitNumericConstant for hex values in compiler.
Add test file test/number/hex_literals.wren verifying basic hex parsing,
arithmetic, type checks, and negative hex literals.
2015-01-25 06:07:23 +00:00
Bob Nystrom
2fdb5cddd0 feat: add FLEXIBLE_ARRAY macro and update struct hack usage for C89/C99 portability 2015-01-23 18:38:12 +00:00
Bob Nystrom
2a123400b6 feat: add MSVC 2013 project files and fix C89 compatibility for Windows build
Add Visual Studio 2013 solution and project files under project/msvc2013/ directory, enabling native Windows builds without MinGW. Include Marco Lizza in AUTHORS for the contribution. Fix C89 compatibility issues for MSVC: disable computed goto via _MSC_VER check, define inline as _inline for non-C++ mode, change flexible array members from empty brackets to [0] syntax, and fix char to int type for readHexDigit return value. Refactor single-line if/while/for bodies in wren_compiler.c to use braces to satisfy MSVC stricter parsing.
2015-01-23 18:12:12 +00:00
Marco Lizza
915f403bc7 chore: restore standard header include order and move CRT secure warning to MSVC project
The diff reorders includes across multiple source files to place standard library headers before project headers, removes the `_CRT_SECURE_NO_WARNINGS` define from `wren_common.h`, and adds it as a preprocessor definition in both Debug and Release configurations of the MSVC 2013 project file.
2015-01-23 09:05:10 +00:00
Bob Nystrom
23c67c2e8b feat: remove UTF-8 encoding logic from addStringChar and accept raw bytes in string literals 2015-01-22 23:18:30 +00:00
Marco Lizza
c2f1a962d6 fix: replace WREN_PIN/WREN_UNPIN macros with wrenPushRoot/wrenPopRoot and fix modulo operator precedence 2015-01-22 09:13:16 +00:00
Evan Shaw
ffcdd8ae9e fix: correct operator precedence for % token from PREC_TERM to PREC_FACTOR
The modulo operator was incorrectly assigned PREC_TERM precedence, making it
evaluate at the same level as + and -. This caused expressions like "13 + 1 % 7"
to parse as "(13 + 1) % 7" instead of the correct "13 + (1 % 7)".

Changed the grammar rule for TOKEN_PERCENT to use PREC_FACTOR, matching the
precedence of * and / operators. Added a precedence test case in mod.wren to
verify the fix.
2015-01-21 20:49:43 +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
Marco Lizza
ff9625a80d chore: reorder include directives to place wren_common.h first across all source files
Enforce a consistent include ordering convention across the codebase: wren_common.h (as configuration header) first, followed by the module's own header, then other wren_*.h headers in lexicographic order, and finally standard library includes. Also add missing wren_common.h include to main.c and wren_io.c, and add _CRT_SECURE_NO_WARNINGS define for MSVC in wren_common.h.
2015-01-21 09:30:37 +00:00
Marco Lizza
a70a23e03d fix: avoid returning void function result in for/while/class/var statements 2015-01-21 09:23:46 +00:00
Marco Lizza
19862a2959 fix: change readHexDigit return type from char to int to prevent sign extension bugs 2015-01-21 09:22:56 +00:00
Bob Nystrom
a4baa42d6f feat: add user-defined subscript operators with bracket parameter lists
Refactor parameter list parsing to support bracket-delimited parameters for
subscript operators. Extract finishParameterList from parameterList to handle
the common closing logic, and add TOKEN_RIGHT_BRACKET case for error messages.
Add comprehensive test suite for subscript getters and setters with 1-3
parameters in test/method/subscript_operators.wren.
2015-01-21 02:25:54 +00:00
Bob Nystrom
f99f61376d refactor: remove unused return values from consume() and consumeLine() in wren_compiler.c
The consume() function previously returned a pointer to the consumed token,
and consumeLine() returned a boolean indicating success. Both return values
were never used by any callers. This change converts both functions to void,
eliminating dead code and simplifying the interface.
2015-01-20 22:40:34 +00:00
Bob Nystrom
850d6d1b5d fix: raise precedence of is above equality operators in parser
The `is` operator was placed at `PREC_IS` which had lower precedence than `PREC_EQUALITY`, causing expressions like `true == 10 is Num` to parse incorrectly. Moved `PREC_IS` above `PREC_EQUALITY` in the precedence enum to give `is` higher binding power than `==` and `!=`. Added precedence tests in new `test/precedence.wren` file and removed TODO comments about precedence from `test/is/is.wren`.
2015-01-18 18:20:13 +00:00
Bob Nystrom
ba81988800 fix: cast malloc result and adjust compiler emit functions for C++ compatibility
- Cast malloc return to char* in src/main.c to avoid C++ implicit void* conversion
- Rename emit to emitByteArg and emitShort to emitShortArg in src/wren_compiler.c to avoid conflict with new emit and emitShort helpers
- Add new emit function taking uint8_t byte and emitShort helper for 16-bit big-endian emission
- Remove stray semicolon in script/test.py
2015-01-15 23:59:14 +00:00
Bob Nystrom
ee239f2bb6 feat: add undefined sentinel value and implicit global declaration for forward references
Add a new singleton value `VAL_UNDEFINED` to represent globals that have been implicitly declared via forward reference but not yet explicitly defined. Introduce `wrenDeclareGlobal()` to create such entries in the global table, and modify `wrenDefineGlobal()` to check for and resolve undefined slots. Update the compiler's `findUpvalue()` to stop closure capture at method boundaries, preventing methods from closing over local variables. Refactor `wrenSymbolTableAdd()` to always add symbols without duplicate checking, moving that logic to callers. Adjust error messages in the compiler to handle EOF tokens and improve newline formatting. Fix the delta_blue benchmark by renaming the global `planner` variable to `ThePlanner` to avoid shadowing the forward-declared function.
2015-01-15 07:08:34 +00:00
Bob Nystrom
72291f8b74 feat: implicitly declare nonlocal names as globals for forward references
Add support for forward references to top-level variables by implicitly
declaring unresolved capitalized names as globals during compilation.
If a real definition is not found later, a compile-time error is raised.
This enables mutual recursion at the top level and fixes issues #101 and #106.

Introduce an `UNDEFINED` singleton value to mark implicitly declared globals
that have not yet been explicitly defined. Update `wrenDeclareGlobal` to add
such entries, and modify `wrenDefineGlobal` to check for and replace undefined
placeholders. Adjust the symbol table API to allow duplicate additions for
implicit declarations. Add test cases for mutual recursion, forward references
in functions and methods, and undefined variable errors.
2015-01-15 07:08:25 +00:00
Bob Nystrom
82ef82cdb9 fix: prevent redundant keyword checks after first match in readName
Replace sequential `if` statements with `else if` chains in `readName` so that once a keyword matches (e.g. "break"), the remaining keyword checks are skipped, fixing issue #110 where later keywords could incorrectly override an already-matched token type.
2015-01-14 14:46:02 +00:00
Bob Nystrom
54ef9bbc73 feat: stop closure upvalue search at method boundaries and treat capitalized names as globals
Modify `findUpvalue` in the compiler to return -1 when the enclosing function is a method, preventing closures from capturing outer local variables. Add a new `nonlocal` variable resolution path that treats capitalized identifiers as global variables rather than method receivers. Update existing test files to use capitalized global names and add new test cases for nonlocal assignment, duplicate nonlocal declarations, block scoping, and method-local variable shadowing.
2015-01-14 05:36:42 +00:00