Repository navigation
Add bitwise operators - #77
Merged
Merged
Conversation
Lyte gains &, |, ~ (xor), <<, >> and prefix ~ on i32 and u32. Since ^ is already power, xor follows Lua and uses ~. Shift amounts may be i32 or u32 and are taken modulo 32 on every backend; >> is arithmetic on i32 and logical on u32. - Lexer, parser (four new precedence levels between comparisons and arithmetic), checker, and pretty-printer. Nested type argument lists like Wrapper<Wrapper<i32>> still parse: the closing >> is split. - Codegen on Cranelift, LLVM, the register VM, the ARM64 interpreter, and the stack VM. The VMs hold i32 values sign-extended in 64-bit slots, so a new I64ToI32 opcode re-normalizes after a left shift. - Overloadable for structs via __and, __or, __xor, __shl, __shr. The overload rewrite now also fires when only the right operand is a named type, which previously broke codegen for e.g. __mul(f32, Point). - Safety checker narrows `i & mask` with a non-negative mask and `x >> n` with non-negative x, so buf[i & 1023] is provably in bounds. - Docs, VS Code grammar, differential fuzzer, and golden tests updated. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Lyte gains bitwise operators on
i32andu32:a & b,a | ba ~ b^is already power, so this follows Lua)~aa << n,a >> n>>is arithmetic oni32, logical onu32Both sides of
&,|,~must share a type. The shift amount may bei32oru32, sow << 24works on au32with an unsuffixed literal. Shift amounts are taken modulo 32 on every backend. Precedence matches Rust and Lua: looser than arithmetic, tighter than comparisons, sox & 7 == 0is(x & 7) == 0.Motivation: the Audulus MIDI 2.0 script template currently says "Lyte has no bit operators, so build and split words by multiplying and dividing by powers of 256." That example becomes:
Changes
Binopvariants plusUnop::BitNot, four new precedence levels (sharedparse_left_assochelper), checker overload tables. Nested type argument lists likeWrapper<Wrapper<i32>>still parse; the closing>>is split back into two>.i32values sign-extended in 64-bit slots, a newI64ToI32opcode re-normalizes after a left shift, andu32results are re-masked after<<and~.__and,__or,__xor,__shl,__shrfor structs. The overload rewrite pass now fires when either operand is a named type; before,__mul(f32, Point)-style overloads type-checked but broke codegen.i & maskwith a non-negative mask lies in[0, mask], andx >> nwith non-negativexin[0, x], sobuf[i & 1023]is accepted without arequiresclause.&,|,~; shifts left out because VM multiplication is 64-bit and would surface the pre-existing overflow divergence as noise).Tests
Six new golden tests: operator semantics on both types, precedence, MIDI word packing, struct overloads on either side, the mask bounds proof, nested generics, and a float type error. Full suite passes on JIT, VM, ASM, stack, and LLVM backends.
Known follow-ups
~is not overloadable for structs, matching unary-today.+ - *equally.🤖 Generated with Claude Code