def parse_number_exp(lexer): line, _, token = lexer.get_next_token() i = LuaValue.parse_integer(token) if i is not None: return lua_exp.IntegerExp(line, i) f = LuaValue.parse_float(token) if f is not None: return lua_exp.FloatExp(line, f) raise Exception('not a number: ' + token)
def eq(a, b, ls): if a is None: return b is None if isinstance(a, bool) or isinstance(a, str): return a == b if isinstance(a, int): if isinstance(b, int): return a == b elif isinstance(b, float): return float(a) == b else: return False if isinstance(a, float): if isinstance(b, float): return a == b elif isinstance(b, int): return a == float(b) else: return False if isinstance(a, LuaTable): if isinstance(b, LuaTable) and a != b and ls: mm = ls.get_metamethod(a, b, '__eq') if mm: return LuaValue.to_boolean(ls.call_metamethod(a, mm, b)) return a == b
def put(self, key, val): assert (key is not None) assert (key is not float('NAN')) key = LuaValue.float2integer(key) if isinstance(key, int) and key >= 1: if not self.arr: self.arr = [] arr_len = len(self.arr) if key <= arr_len: self.arr[key - 1] = val if key == arr_len and val is None: self.arr.pop(key) return if key == arr_len + 1: if self.map: self.map.pop(key) if val is not None: self.arr.append(val) self.map_to_arr() return if val is not None: if not self.map: self.map = {key: val} else: self.map.pop(key)
def cast_to_int(exp): if isinstance(exp, lua_exp.IntegerExp): return exp.val, True if isinstance(exp, lua_exp.FloatExp): i = LuaValue.float2integer(exp.val) return i, i is not None return 0, False
def get(self, key): key = LuaValue.float2integer(key) if self.arr and isinstance(key, int): if 1 <= key <= len(self.arr): return self.arr[key - 1] return self.map[key] if key in self.map else None
def optimize_bnot(exp): if isinstance(exp.exp, lua_exp.IntegerExp): exp.exp.val = ~exp.exp.val return exp.exp.val if isinstance(exp.exp, lua_exp.FloatExp): i = LuaValue.float2integer(exp.exp.val) if i is not None: return lua_exp.IntegerExp(exp.exp.line, ~i) return exp
def arith(a, op, b): integer_func = Arithmetic.operators[op].integer_func float_func = Arithmetic.operators[op].float_func if float_func is None: x = LuaValue.to_integer(a) if x: y = LuaValue.to_integer(b) if y: return integer_func(x, y) else: if integer_func is not None: if isinstance(a, int) and isinstance(b, int): return integer_func(int(a), int(b)) x = LuaValue.to_float(a) if x: y = LuaValue.to_float(b) if y: return float_func(x, y) return None
def le(a, b, ls): if isinstance(a, str) and isinstance(b, str): return a <= b if isinstance(a, int): if isinstance(b, int): return a <= b elif isinstance(b, float): return float(a) <= b if isinstance(a, float): if isinstance(b, float): return a <= b elif isinstance(b, int): return a <= float(b) mm = ls.get_metamethod(a, b, '__le') if mm: return LuaValue.to_boolean(ls.call_metamethod(a, mm, b)) mm = ls.get_metamethod(b, a, '__lt') if mm: return LuaValue.to_boolean(ls.call_metamethod(a, mm, b)) raise Exception('Comparison Error')
def newtable(inst, vm): a, b, c = inst.a_b_c() a += 1 vm.create_table(LuaValue.fb2int(b), LuaValue.fb2int(c)) vm.replace(a)
def type(self, idx): if self.stack.is_valid(idx): return LuaValue.type_of(self.stack.get(idx)) return LuaType.NONE
def get_i(self, idx, i): t = self.stack.get(idx) v = LuaState.get_table_val(t, i) self.stack.push(v) return LuaValue.type_of(v)
def get_table(self, idx): t = self.stack.get(idx) k = self.stack.pop() v = LuaState.get_table_val(t, k) self.stack.push(v) return LuaValue.type_of(v)
def to_boolean(self, idx): return LuaValue.to_boolean(self.stack.get(idx))
def get_metatable_k(self, val): if isinstance(val, LuaTable): return val.metatable else: key = '_MT' + str(LuaValue.type_of(val)) return self.registry.get(key)
def set_metatable_kv(self, val, mt): if isinstance(val, LuaTable): val.metatable = mt else: key = '_MT' + LuaValue.type_of(val) self.registry.put(key, mt)
def emit_new_table(self, a, narr, nrec): self.emit_abc(OpCode.NEWTABLE, a, LuaValue.int2fb(narr), LuaValue.int2fb(nrec))