Skip to content

Instantly share code, notes, and snippets.

@thebirk
Last active August 31, 2019 04:22
Show Gist options
  • Save thebirk/50e44a152089b14b0e4cdc6ad4fa90c3 to your computer and use it in GitHub Desktop.
Save thebirk/50e44a152089b14b0e4cdc6ad4fa90c3 to your computer and use it in GitHub Desktop.
import beeprint
import inspect
class Node:
def eval(self, kwargs):
raise RuntimeException('{} did not implement eval()'.format(self.__class__))
def __eq__(self, other):
return make_binary('==', self, other)
def __lt__(self, other):
return make_binary('<', self, other)
def __gt__(self, other):
return make_binary('>', self, other)
def __add__(self, other):
return make_binary('+', self, other)
def __sub__(self, other):
return make_binary('-', self, other)
def __mul__(self, other):
return make_binary('*', self, other)
def __truediv__(self, other):
return make_binary('/', self, other)
def __floordiv__(self, other):
return make_binary('//', self, other)
def __mod__(self, other):
return make_binary('%', self, other)
def __divmod__(self, other):
return make_binary('divmod', self, other)
def __pow__(self, other, modulo):
assert False
return make_binary('pow', self, other)
def __lshift__(self, other):
return make_binary('<<', self, other)
def __rshift__(self, other):
return make_binary('>>', self, other)
def __and__(self, other):
return make_binary('and', self, other)
def __xor__(self, other):
return make_binary('xor', self, other)
def __or__(self, other):
return make_binary('or', self, other)
def make_binary(op, left, right):
return NodeBinary(op, left, right)
class NodeBinary(Node):
def __init__(self, op, left, right):
self.op = op
self.left = left
self.right = right
def eval(self, kwargs):
if isinstance(self.left, Node):
lhs = self.left.eval(kwargs)
else:
lhs = self.left
if isinstance(self.right, Node):
rhs = self.right.eval(kwargs)
else:
rhs = self.right
if self.op == '==':
return lhs == rhs
elif self.op == '<':
return lhs < rhs
elif self.op == '>':
return lhs > rhs
elif self.op == '+':
return lhs + rhs
elif self.op == '-':
return lhs + rhs
elif self.op == '*':
return lhs * rhs
elif self.op == '/':
return lhs / rhs
elif self.op == '//':
return lhs // rhs
elif self.op == 'divmod':
return divmod(lhs, rhs)
elif self.op == '%':
return lhs % rhs
elif self.op == 'pow':
assert False
elif self.op == '<<':
return lhs << rhs
elif self.op == '>>':
return lhs >> rhs
elif self.op == 'and':
return lhs and rhs
elif self.op == 'xor':
raise RuntimeException("What should XOR do?")
elif self.op == 'or':
return lhs or rhs
else:
raise RuntimeException("Unkown binary operator: '{}'".format(self.op))
class FilterKeyword(Node):
def __init__(self, name):
self.name = name
def eval(self, kwargs):
return kwargs[self.name]
class Filter:
def __init__(self, expression):
self.expression = expression
def __call__(self, **kwargs):
return self.expression.eval(kwargs)
def make_filter_test():
foo = FilterKeyword('foo')
bar = FilterKeyword('bar')
foo_cond = foo == 3
bar_cond = bar > 4
return foo_cond & bar_cond
f = Filter(make_filter_test())
print( f(foo = 3, bar = 5) )
f2 = Filter((FilterKeyword('foo') == 3) & (FilterKeyword('bar') > 4))
print( f(foo = 3, bar = 5) )
beeprint.pp(make_filter_test(), max_depth=999)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment