package org.luaj.vm2.lib;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs;
public class BitLib extends OneArgFunction {
public static LuaTable instance;
public BitLib() {
}
@Override
public LuaValue call(LuaValue arg) {
LuaTable t = new LuaTable();
bind(t, BitLib1.class, new String[] {
"bnot", "bswap"});
bind(t, BitLib2.class, new String[] {
"lshift", "rshift", "arshift", "rol", "ror", "tohex"});
bind(t, BitLibV.class, new String[] {
"bor", "band", "bxor"} );
env.set("bit", t);
instance = t;
PackageLib.instance.LOADED.set("bit", t);
return t;
}
static final class BitLib1 extends OneArgFunction {
@Override
public LuaValue call(LuaValue arg) {
switch ( opcode ) {
case 0: return bnot(arg);
case 1: return bswap(arg);
}
return NIL;
}
public LuaValue bnot(LuaValue arg) {
return valueOf(~arg.checkint());
}
public LuaValue bswap(LuaValue arg) {
int b = arg.checkint();
return valueOf((b >> 24) | ((b >> 8) & 0xff00) | ((b & 0xff00) << 8) | (b << 24));
}
}
static final class BitLib2 extends TwoArgFunction {
@Override
public LuaValue call(LuaValue arg1, LuaValue arg2) {
switch ( opcode ) {
case 0: return lshift(arg1,arg2);
case 1: return rshift(arg1,arg2);
case 2: return arshift(arg1,arg2);
case 3: return rol(arg1,arg2);
case 4: return ror(arg1,arg2);
case 5: return tohex(arg1,arg2);
}
return NIL;
}
public LuaValue lshift(LuaValue num1, LuaValue num2) {
return valueOf(num1.checkint() << num2.checkint());
}
public LuaValue rshift(LuaValue num1, LuaValue num2) {
return valueOf(num1.checkint() >>> num2.checkint());
}
public LuaValue arshift(LuaValue num1, LuaValue num2) {
return valueOf(num1.checkint() >> num2.checkint());
}
public LuaValue rol(LuaValue num1, LuaValue num2) {
int b = num1.checkint();
int n = num2.checkint();
return valueOf((b << n) | (b >> (32-n)));
}
public LuaValue ror(LuaValue num1, LuaValue num2) {
int b = num1.checkint();
int n = num2.checkint();
return valueOf((b << (32-n)) | (b >> n));
}
public LuaValue tohex(LuaValue num1, LuaValue num2) {
int b = num1.checkint();
int n = num2.optint(8);
boolean lower = true;
if (n < 0) {
n = -n;
lower = false;
}
n = Math.max(1, Math.min(8, n));
String s = String.format(lower ? "%08x" : "%08X", b);
if (n < 8)
s = s.substring(8-n);
return valueOf(s);
}
}
static final class BitLibV extends VarArgFunction {
public Varargs invoke(Varargs args) {
switch ( opcode ) {
case 0: return bor(args);
case 1: return band(args);
case 2: return bxor(args);
}
return NIL;
}
public Varargs bor(Varargs args) {
int n = args.checkint(1);
for (int i = 2; i <= args.narg(); ++i) {
n |= args.checkint(i);
}
return valueOf(n);
}
public Varargs band(Varargs args) {
int n = args.checkint(1);
for (int i = 2; i <= args.narg(); ++i) {
n &= args.checkint(i);
}
return valueOf(n);
}
public Varargs bxor(Varargs args) {
int n = args.checkint(1);
for (int i = 2; i <= args.narg(); ++i) {
n ^= args.checkint(i);
}
return valueOf(n);
}
}
}