import { expect, describe, test } from 'bun:test' describe('bitwise operators', () => { describe('band (bitwise AND)', () => { test('basic AND operation', () => { expect('5 band 3').toEvaluateTo(1) // 5 = 0101, 3 = 0011, result = 0001 = 1 }) test('AND with zero', () => { expect('5 band 0').toEvaluateTo(0) }) test('AND with all bits set', () => { expect('15 band 7').toEvaluateTo(7) // 15 = 1111, 7 = 0111, result = 0111 = 7 }) test('AND in assignment', () => { expect('x = 12 band 10').toEvaluateTo(8) // 12 = 1100, 10 = 1010, result = 1000 = 8 }) }) describe('bor (bitwise OR)', () => { test('basic OR operation', () => { expect('5 bor 3').toEvaluateTo(7) // 5 = 0101, 3 = 0011, result = 0111 = 7 }) test('OR with zero', () => { expect('5 bor 0').toEvaluateTo(5) }) test('OR with all bits set', () => { expect('8 bor 4').toEvaluateTo(12) // 8 = 1000, 4 = 0100, result = 1100 = 12 }) }) describe('bxor (bitwise XOR)', () => { test('basic XOR operation', () => { expect('5 bxor 3').toEvaluateTo(6) // 5 = 0101, 3 = 0011, result = 0110 = 6 }) test('XOR with itself returns zero', () => { expect('5 bxor 5').toEvaluateTo(0) }) test('XOR with zero returns same value', () => { expect('7 bxor 0').toEvaluateTo(7) }) test('XOR in assignment', () => { expect('result = 8 bxor 12').toEvaluateTo(4) // 8 = 1000, 12 = 1100, result = 0100 = 4 }) }) describe('bnot (bitwise NOT)', () => { test('NOT of positive number', () => { expect('bnot 5').toEvaluateTo(-6) // ~5 = -6 (two\'s complement) }) test('NOT of zero', () => { expect('bnot 0').toEvaluateTo(-1) }) test('NOT of negative number', () => { expect('bnot -1').toEvaluateTo(0) }) test('double NOT returns original', () => { expect('bnot (bnot 5)').toEvaluateTo(5) }) }) describe('<< (left shift)', () => { test('basic left shift', () => { expect('5 << 2').toEvaluateTo(20) // 5 << 2 = 20 }) test('shift by zero', () => { expect('5 << 0').toEvaluateTo(5) }) test('shift by one', () => { expect('3 << 1').toEvaluateTo(6) }) test('large shift', () => { expect('1 << 10').toEvaluateTo(1024) }) }) describe('>> (signed right shift)', () => { test('basic right shift', () => { expect('20 >> 2').toEvaluateTo(5) // 20 >> 2 = 5 }) test('shift by zero', () => { expect('20 >> 0').toEvaluateTo(20) }) test('preserves sign for negative numbers', () => { expect('-20 >> 2').toEvaluateTo(-5) // Sign is preserved }) test('negative number right shift', () => { expect('-8 >> 1').toEvaluateTo(-4) }) }) describe('>>> (unsigned right shift)', () => { test('basic unsigned right shift', () => { expect('20 >>> 2').toEvaluateTo(5) }) test('unsigned shift of -1', () => { expect('-1 >>> 1').toEvaluateTo(2147483647) // -1 >>> 1 = 2147483647 (unsigned, no sign extension) }) test('unsigned shift of negative number', () => { expect('-8 >>> 1').toEvaluateTo(2147483644) }) }) describe('compound expressions', () => { test('multiple bitwise operations', () => { expect('(5 band 3) bor (8 bxor 12)').toEvaluateTo(5) // (5 & 3) | (8 ^ 12) = 1 | 4 = 5 }) test('bitwise with variables', () => { expect(` a = 5 b = 3 a bor b `).toEvaluateTo(7) }) test('shift operations with variables', () => { expect(` x = 16 y = 2 x >> y `).toEvaluateTo(4) }) test('mixing shifts and bitwise', () => { expect('(8 << 1) band 15').toEvaluateTo(0) // (8 << 1) & 15 = 16 & 15 = 0 }) test('mixing shifts and bitwise 2', () => { expect('(7 << 1) band 15').toEvaluateTo(14) // (7 << 1) & 15 = 14 & 15 = 14 }) }) describe('precedence', () => { test('bitwise has correct precedence with arithmetic', () => { expect('1 + 2 band 3').toEvaluateTo(3) // (1 + 2) & 3 = 3 & 3 = 3 }) test('shift has correct precedence', () => { expect('4 + 8 << 1').toEvaluateTo(24) // (4 + 8) << 1 = 12 << 1 = 24 }) }) })