import { expect, describe, test } from 'bun:test' import { toBytecode, run } from '#reef' describe('bitwise operations', () => { test('BIT_AND', async () => { const bytecode = toBytecode([ ["PUSH", 5], ["PUSH", 3], ["BIT_AND"], ["HALT"] ]) expect(await run(bytecode)).toEqual({ type: 'number', value: 1 }) }) test('BIT_AND with zero', async () => { const bytecode = toBytecode([ ["PUSH", 5], ["PUSH", 0], ["BIT_AND"], ["HALT"] ]) expect(await run(bytecode)).toEqual({ type: 'number', value: 0 }) }) test('BIT_OR', async () => { const bytecode = toBytecode([ ["PUSH", 5], ["PUSH", 3], ["BIT_OR"], ["HALT"] ]) expect(await run(bytecode)).toEqual({ type: 'number', value: 7 }) }) test('BIT_OR with zero', async () => { const bytecode = toBytecode([ ["PUSH", 5], ["PUSH", 0], ["BIT_OR"], ["HALT"] ]) expect(await run(bytecode)).toEqual({ type: 'number', value: 5 }) }) test('BIT_XOR', async () => { const bytecode = toBytecode([ ["PUSH", 5], ["PUSH", 3], ["BIT_XOR"], ["HALT"] ]) expect(await run(bytecode)).toEqual({ type: 'number', value: 6 }) }) test('BIT_XOR with itself returns zero', async () => { const bytecode = toBytecode([ ["PUSH", 5], ["PUSH", 5], ["BIT_XOR"], ["HALT"] ]) expect(await run(bytecode)).toEqual({ type: 'number', value: 0 }) }) test('BIT_SHL', async () => { const bytecode = toBytecode([ ["PUSH", 5], ["PUSH", 2], ["BIT_SHL"], ["HALT"] ]) expect(await run(bytecode)).toEqual({ type: 'number', value: 20 }) }) test('BIT_SHL by zero', async () => { const bytecode = toBytecode([ ["PUSH", 5], ["PUSH", 0], ["BIT_SHL"], ["HALT"] ]) expect(await run(bytecode)).toEqual({ type: 'number', value: 5 }) }) test('BIT_SHR', async () => { const bytecode = toBytecode([ ["PUSH", 20], ["PUSH", 2], ["BIT_SHR"], ["HALT"] ]) expect(await run(bytecode)).toEqual({ type: 'number', value: 5 }) }) test('BIT_SHR preserves sign for negative numbers', async () => { const bytecode = toBytecode([ ["PUSH", -20], ["PUSH", 2], ["BIT_SHR"], ["HALT"] ]) expect(await run(bytecode)).toEqual({ type: 'number', value: -5 }) }) test('BIT_USHR', async () => { const bytecode = toBytecode([ ["PUSH", -1], ["PUSH", 1], ["BIT_USHR"], ["HALT"] ]) expect(await run(bytecode)).toEqual({ type: 'number', value: 2147483647 }) }) test('BIT_USHR does not preserve sign', async () => { const bytecode = toBytecode([ ["PUSH", -8], ["PUSH", 1], ["BIT_USHR"], ["HALT"] ]) expect(await run(bytecode)).toEqual({ type: 'number', value: 2147483644 }) }) test('compound bitwise operations', async () => { const bytecode = toBytecode([ // (5 & 3) | (8 ^ 12) ["PUSH", 5], ["PUSH", 3], ["BIT_AND"], // stack: [1] ["PUSH", 8], ["PUSH", 12], ["BIT_XOR"], // stack: [1, 4] ["BIT_OR"], // stack: [5] ["HALT"] ]) expect(await run(bytecode)).toEqual({ type: 'number', value: 5 }) }) test('shift with large shift amounts', async () => { const bytecode = toBytecode([ ["PUSH", 1], ["PUSH", 31], ["BIT_SHL"], ["HALT"] ]) // 1 << 31 = -2147483648 (most significant bit set) expect(await run(bytecode)).toEqual({ type: 'number', value: -2147483648 }) }) })