lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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.