GMod Lua Bit Shifts

I know that normal Lua doesn’t have bit shift operators. However, the GMod wiki says that GMod’s version of Lua has bit shift operators. It also says that they only work on constants. Does GMod Lua support bit shifting, and if so, does it only work on constants? Because it says that that particular wiki page was last edited in '08, and a lot has changed since then.

Yeah, it’s pretty borked. One thing you could do is this:

[lua]
local number = 10
local shifts = 2
RunString(string.Format(“local new = %d << %d”, number, shifts))
print(new)
[/lua]

or this alternative (not entirely sure if this is accurate):

[lua]
local round = math.Round

function bShiftL(number, shifts)
if shifts < 0 then return 0 end
return number * round(2 ^ shifts)
end

function bShiftR(number, shifts)
if shifts < 0 then return 0 end
local new = round(number * 0.5 ^ shifts)
return new
end
[/lua]

:wtc:

Why the hell are you using that RunString and string.Format contraption?
[lua]local number = 10
local shifts = 2
local new = number << shifts
print( new )[/lua]

Apparently it’s broken otherwise. Wiremod had to do this to fix the E2 bit shift functions back in October 2009.

Changed from:
[lua]
e2function number bShr(a, b)
return (a >> b)
end
e2function number bShl(a, b)
return (a << b)
end
[/lua]
to:
[lua]
e2function number bShr(a, b)
RunString(string.format(“garry_sucks = %d >> %d”, a, b))
return garry_sucks
end
e2function number bShl(a, b)
RunString(string.format(“garry_sucks = %d << %d”, a, b))
return garry_sucks
end
[/lua]

There’s been a lot of updates since then though, so maybe it isn’t broken anymore.

This is correct. Bit shifts only work on constants currently.

Good news everyone! I think I found out why bit shifts only work on constants!

It would appear Garry made the same mistake I made with my own modified Lua interpreter. I added the bit-wise operators to the constant folding function, but not to the Lua VM, so it could only process them during compile-time, not run-time. A few changes to lvm.c, ltm.h, and ltm.c made it work. As a side effect, someone using my interpreter could override these operators with metatables (in theory, haven’t tested it.) Now, someone just has to prod Garry with this information, and he should be able to figure out the rest and fix it.

For those who don’t know what constant folding is, it’s when the compiler performs arithmetic on constants to optimize the run-time.