# 🪸 ReefVM It's where Shrimp live. ## Quickstart bun install bun test ## Use it Execute text bytecode: ./bin/reef examples/loop.reef Validate bytecode: ./bin/validate examples/loop.reef Run the simple debugger to see what the instructions are doing: ./bin/debug examples/loop.reef ./bin/debug -h examples/loop.reef Interactive REPL for exploring instructions: ./bin/repl Type opcodes interactively and see the stack and variables update in real-time. Commands: `clear`, `reset`, `exit`. ## Features - Stack operations (PUSH, POP, DUP) - Arithmetic operations (ADD, SUB, MUL, DIV, MOD) - Comparison operations (EQ, NEQ, LT, GT, LTE, GTE) - Logical operations (NOT, AND/OR patterns with short-circuiting) - Variable operations (LOAD, STORE) with **emoji and Unicode support** (💎 = 5) - Control flow with **relative jumps** (JUMP, JUMP_IF_FALSE, JUMP_IF_TRUE, BREAK, CONTINUE) - Array operations (MAKE_ARRAY, ARRAY_GET, ARRAY_SET, ARRAY_PUSH, ARRAY_LEN) - Dictionary operations (MAKE_DICT, DICT_GET, DICT_SET, DICT_HAS) - Function operations (MAKE_FUNCTION, CALL, TAIL_CALL, RETURN) with parameter binding - Variadic functions with positional rest parameters (`...rest`) - Named arguments (named) that collect unmatched named args into a dict (`@named`) - Mixed positional and named arguments with proper priority binding - Tail call optimization with unbounded recursion (10,000+ iterations without stack overflow) - Exception handling (PUSH_TRY, PUSH_FINALLY, POP_TRY, THROW) with nested try/finally blocks and call stack unwinding - Native function interop with auto-wrapping for native TypeScript types - Native functions stored in scope, called via LOAD + CALL - Native functions support `atXxx` parameters (e.g., `atOptions`) to collect unmatched named args - Pass functions directly to `run(bytecode, { fnName: fn })` or `new VM(bytecode, { fnName: fn })` - Call Reef functions from TypeScript with `vm.call(name, ...args)` with automatic type conversion ## Design Decisions - Relative jumps: All JUMP instructions use PC-relative offsets instead of absolute addresses, making bytecode position-independent - Truthiness: Only `null` and `false` are falsy (unlike JavaScript where `0`, `""`, etc. are also falsy) - Short-circuiting via compiler: No AND/OR opcodes—compilers use JUMP patterns for proper short-circuit evaluation - Variadic parameters: Functions can collect remaining positional arguments into an array using `...rest` syntax - Named parameters: Functions can collect unmatched named arguments into a dict using `@named` syntax - Argument binding priority: Named args bind to regular params first, with unmatched ones going to `@named`