108 lines
2.9 KiB
TypeScript
108 lines
2.9 KiB
TypeScript
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"]
|
|
])
|
|
await expect(bytecode).toBeNumber(1)
|
|
})
|
|
|
|
test('BIT_AND with zero', async () => {
|
|
const bytecode = toBytecode([
|
|
["PUSH", 5], ["PUSH", 0], ["BIT_AND"], ["HALT"]
|
|
])
|
|
await expect(bytecode).toBeNumber(0)
|
|
})
|
|
|
|
test('BIT_OR', async () => {
|
|
const bytecode = toBytecode([
|
|
["PUSH", 5], ["PUSH", 3], ["BIT_OR"], ["HALT"]
|
|
])
|
|
await expect(bytecode).toBeNumber(7)
|
|
})
|
|
|
|
test('BIT_OR with zero', async () => {
|
|
const bytecode = toBytecode([
|
|
["PUSH", 5], ["PUSH", 0], ["BIT_OR"], ["HALT"]
|
|
])
|
|
await expect(bytecode).toBeNumber(5)
|
|
})
|
|
|
|
test('BIT_XOR', async () => {
|
|
const bytecode = toBytecode([
|
|
["PUSH", 5], ["PUSH", 3], ["BIT_XOR"], ["HALT"]
|
|
])
|
|
await expect(bytecode).toBeNumber(6)
|
|
})
|
|
|
|
test('BIT_XOR with itself returns zero', async () => {
|
|
const bytecode = toBytecode([
|
|
["PUSH", 5], ["PUSH", 5], ["BIT_XOR"], ["HALT"]
|
|
])
|
|
await expect(bytecode).toBeNumber(0)
|
|
})
|
|
|
|
test('BIT_SHL', async () => {
|
|
const bytecode = toBytecode([
|
|
["PUSH", 5], ["PUSH", 2], ["BIT_SHL"], ["HALT"]
|
|
])
|
|
await expect(bytecode).toBeNumber(20)
|
|
})
|
|
|
|
test('BIT_SHL by zero', async () => {
|
|
const bytecode = toBytecode([
|
|
["PUSH", 5], ["PUSH", 0], ["BIT_SHL"], ["HALT"]
|
|
])
|
|
await expect(bytecode).toBeNumber(5)
|
|
})
|
|
|
|
test('BIT_SHR', async () => {
|
|
const bytecode = toBytecode([
|
|
["PUSH", 20], ["PUSH", 2], ["BIT_SHR"], ["HALT"]
|
|
])
|
|
await expect(bytecode).toBeNumber(5)
|
|
})
|
|
|
|
test('BIT_SHR preserves sign for negative numbers', async () => {
|
|
const bytecode = toBytecode([
|
|
["PUSH", -20], ["PUSH", 2], ["BIT_SHR"], ["HALT"]
|
|
])
|
|
await expect(bytecode).toBeNumber(-5)
|
|
})
|
|
|
|
test('BIT_USHR', async () => {
|
|
const bytecode = toBytecode([
|
|
["PUSH", -1], ["PUSH", 1], ["BIT_USHR"], ["HALT"]
|
|
])
|
|
await expect(bytecode).toBeNumber(2147483647)
|
|
})
|
|
|
|
test('BIT_USHR does not preserve sign', async () => {
|
|
const bytecode = toBytecode([
|
|
["PUSH", -8], ["PUSH", 1], ["BIT_USHR"], ["HALT"]
|
|
])
|
|
await expect(bytecode).toBeNumber(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"]
|
|
])
|
|
await expect(bytecode).toBeNumber(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)
|
|
await expect(bytecode).toBeNumber(-2147483648)
|
|
})
|
|
})
|