[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Fun with metatables: Infix bitwise operators
- From: HyperHacker <hyperhacker@...>
- Date: Fri, 9 Sep 2011 21:47:07 -0600
Recently I was porting to Lua some horribly messy decompiled code like:
x = (((((Param[1] & 0xF) << 0x12) | (((Param[1] & 0xF0) >> 4) << 0xE))
| ((Param[0] & 0xF) << 8)) | (((Param[0] & 0xF0) >> 4) << 4))
I thought, trying to convert such a mess to prefix (bit.band(a,b)
rather than a & b) would be a nightmare, and it sure would be nice if
I had infix bitwise operators instead. So I threw together this little
module:
local ops = {}
local bit = require('bit')
ops['<<'] = bit.lshift
ops['>>'] = bit.rshift
ops['|'] = bit.bor
ops['&'] = bit.band
ops['^'] = bit.bxor
ops['lsh'] = bit.lshift
ops['rsh'] = bit.rshift
ops['or'] = bit.bor
ops['and'] = bit.band
ops['xor'] = bit.bxor
ops['arsh'] = bit.arshift
ops['rol'] = bit.rol
ops['ror'] = bit.ror
debug.setmetatable(0, {
__call = function(p1, op)
return setmetatable({}, {
__call = function(_, p2)
return ops[op](p1, p2)
end,
})
end,
})
It's quite a hack, and still a bit ugly because it's actually abusing
function call syntax, so rather than "1 << n", you have to write "(1)
'<<' (n)", but it works. I thought some others might find this
interesting. :-)
I'd call this public domain code, but given the debates recently about
whether that has any meaning, I suppose I should release it under the
MIT license instead. :-)
As an example, that messy fragment above (after stripping some
redundant shifts) looks like:
x = (((h) '&' (0x0F)) '<<' (0x12))
'|' (((h) '&' (0xF0)) '<<' (0xA))
'|' (((w) '&' (0x0F)) '<<' (8))
'|' ((w) '&' (0xF0))
Still a bit ugly, but at least you can get an idea what it's doing now! ;-)
--
Sent from my toaster.