def mul_op(*args): # super common if len(args) == 1: return args[0] if match(args, (int, int)): return args[0] * args[1] for a in args: assert type(a) != list if p := to_exp2(a): rest = list(args) rest.remove(a) exp = mul_op(*rest) assert type(exp) != list, exp return mask_op(exp, size=256 - p, shl=p)
def div_op(a, b): assert type(a) != list assert type(b) != list if b == 1: return a if type(a) != int and type(b) == int: if b < 0: a = mul_op(-1, a) b = -b if to_exp2(b): return mask_op(a, size=256 - to_exp2(b), shr=to_exp2(b)) if type(a) != int or type(b) != int: # return None return ("div", a, b) else: return a // b
def to_mask(num): num = cleanup_mul_1(num) if opcode(num) == "not": return to_neg_mask(num[1]) if opcode(num) == "sub": if opcode(num[1]) == "exp" and num[2] == 1: mul = to_exp2(num[1][1]) if mul == None: return None mask_pos = 0 mask_len = mul_op(mul, num[1][2]) # add type assert, that num[1][2] < 32? return (mask_len, sub_op(256, mask_len)) if opcode(num) == "add" and num[1] == -1: return to_mask(("sub", num[2], 1,)) if type(num) != int: return None i = 0 while get_bit(num, i) == 0 and i < 256: i += 1 mask_pos = i while get_bit(num, i) == 1 and i < 256: i += 1 mask_pos_plus_len = i while i < 256: if get_bit(num, i) != 0: return None i += 1 return mask_pos_plus_len - mask_pos, mask_pos
def _simplify(exp): op = opcode(exp) if op in arithmetic.opcodes: exp = arithmetic.eval(exp) if op in ('and', 'div', 'mul'): left = exp[1] right = exp[2] if op == 'and': left_mask = to_mask(left) if left_mask: (m1, m2) = left_mask exp = mask_op(right, m1, m2) else: # could be 'elif to_mask(right)', but that's slower bc we have to call to_mask twice then right_mask = to_mask(right) if right_mask: (m1, m2) = right_mask exp = mask_op(left, m1, m2) elif to_neg_mask(left): bounds = to_neg_mask(left) exp = neg_mask_op(right, *bounds) elif to_neg_mask(right): bounds = to_neg_mask(right) exp = neg_mask_op(left, *bounds) elif op == 'div' and len(exp) == 3 and to_exp2(right): shift = to_exp2(right) exp = mask_op(left, size = 256-shift, offset = shift, shr = shift) elif op == 'mul' and len(exp)==3 and to_exp2(left): shift = to_exp2(left) exp = mask_op(right, size = 256-shift, shl = shift) elif op == 'mul' and len(exp) == 3 and to_exp2(right): shift = to_exp2(right) exp = mask_op(left, size = 256-shift, shl = shift) return exp
def bits(exp): return mul_op(exp, 8) def mul_op(*args): # super common if len(args) == 1: return args[0] if args ~ (int:num1, int:num2): return args[0] * args[1] for a in args: assert type(a) != list if p := to_exp2(a): rest = list(args) rest.remove(a) exp = mul_op(*rest) assert type(exp) != list, exp return mask_op(exp, size=256-p, shl=p) # flatten muls res = tuple() for a in args: assert type(a) != list if a ~ ('mul', *terms): res += terms
res += ' - ' + prettify(minus_op(x), add_color=add_color) else: res += ' + ' + prettify(x, add_color=add_color) if parentheses: return f'({res})' else: return res if opcode(exp) == 'not': return COLOR_BOLD+'!'+ENDC+prettify(exp[1], add_color = add_color) if opcode(exp) == 'add': return pretty_adds(exp) if opcode(exp) == 'mul' and len(exp)==3 and to_exp2(exp[1]) != None and to_exp2(exp[1]) > 32: exp = ('shl', to_exp2(exp[1]), exp[2]) if exp ~ ('mul', -1, :val): return "-" + pret(val, parentheses=parentheses) if exp ~ ('mul', 1, :val): return pret(val, parentheses=parentheses) if exp ~ ('mul', 1, *rest): return pret(('mul', ) + rest, parentheses=parentheses) if exp ~ ('div', :num, 1): return pret(num, parentheses=parentheses) if exp ~ ('exp', :a, :n):
res += " - " + prettify(minus_op(x), add_color=add_color) else: res += " + " + prettify(x, add_color=add_color) if parentheses: return f"({res})" else: return res if opcode(exp) == "not": return COLOR_BOLD + "!" + ENDC + prettify(exp[1], add_color=add_color) if opcode(exp) == "add": return pretty_adds(exp) if (opcode(exp) == "mul" and len(exp) == 3 and to_exp2(exp[1]) != None and to_exp2(exp[1]) > 32): exp = ("shl", to_exp2(exp[1]), exp[2]) if m := match(exp, ("mul", -1, ":val")): return "-" + pret(m.val, parentheses=parentheses) if m := match(exp, ("mul", 1, ":val")): return pret(m.val, parentheses=parentheses) if m := match(exp, ("mul", 1, ...)): return pret(("mul", ) + exp[2:], parentheses=parentheses) if m := match(exp, ("div", ":num", 1)): return pret(m.num, parentheses=parentheses)