def test_monad_laws(): "Test if the basic monadic functions conform to the three Monad Laws." from hornet.expressions import unit, bind, lift x = ast.Name(id='x', ctx=load) y = ast.Name(id='y', ctx=load) z = ast.Name(id='z', ctx=load) mx = unit(x) binop = lambda u, op, v: unit(ast.BinOp(left=u, op=op(), right=v)) and_y = lambda u: binop(u, ast.BitAnd, y) or_z = lambda u: binop(u, ast.BitOr, z) y_and = lambda v: binop(y, ast.BitAnd, v) z_or = lambda v: binop(z, ast.BitOr, v) mfuncs = [unit, lift(identity), and_y, or_z, y_and, z_or] # left identity: for mf in mfuncs: ast_eq(bind(mx, mf), mf(x)) # right identity: ast_eq(bind(mx, unit), mx) # associativity: for mf, mg in itertools.product(mfuncs, repeat=2): ast_eq( bind(bind(mx, mf), mg), bind(mx, lambda v: bind(mf(v), mg)) )
def test_rearrange(): from hornet.operators import rearrange, ParseError from hornet.symbols import a, b, c, d, e ast_test_all( ast_eq, rearrange, lift(identity), (a, a), ((((a & b) & c) & d) & e, a & (b & (c & (d & e)))), ((((a << b) & c) & d) & e, a << (b & (c & (d & e)))), #(a & (b | c), a & (b | c)), ) #ast_test_all_raise( #ValueError, #rearrange, #a.foo, #a(1).foo[b, 2].bar, #c({a:1, b:2}), #) #ast_test_all_raise( #TypeError, #rearrange, #a.foo.bar((b & c) & d), #a.foo[(b & c) & d], #a[1], #) ast_test_all_raise( ParseError, rearrange, a << b << c, #a << b >> c, a >> b >> c, #a >> b << c, #a << b & c | d << e, #a << b & c | d >> e, #a >> b & c | d >> e, #a >> b & c | d << e, )
self.append(_rearrange(operand)) def visit_BinOp(self, node): left, op, right = binop_fields(node) op_fixity = make_token(PYTHON_FIXITIES, op) left_fixity = make_token(PYTHON_FIXITIES, left) right_fixity = make_token(PYTHON_FIXITIES, right) if left_fixity > op_fixity: self.visit(left) else: self.append(_rearrange(left)) self.append(op) if op_fixity < right_fixity: self.visit(right) else: self.append(_rearrange(right)) def _rearrange(node): flattened = [] ASTFlattener(flattened).visit(node) return pratt_parse(flattened) rearrange = lift(_rearrange)