Last active
August 31, 2019 04:22
-
-
Save thebirk/50e44a152089b14b0e4cdc6ad4fa90c3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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