Last active
July 2, 2017 20:02
-
-
Save stuxcrystal/8d159c6ec705cc74debe7a550c83c7ce to your computer and use it in GitHub Desktop.
lolz
This file contains 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
from itertools import chain | |
from functools import reduce | |
def _force_listop(iterable): | |
if not isinstance(iterable, ListOp): | |
iterable = ListOp(__builtins__.map(Base.conv, iterable), None) | |
return iterable | |
def reduce_op(name): | |
def _func(iterable): | |
return _force_listop(iterable).reduce(name) | |
return _func | |
max = reduce_op("max") | |
min = reduce_op("min") | |
def map(op, iterable): | |
return _force_listop(iterable).map(op) | |
def zip(iterable, *iters): | |
iterable = _force_listop(iterable) | |
iters = __builtins__.map(_force_listop, iters) | |
return iterable.zip(*iters) | |
class Base(object): | |
def emit(self): | |
yield None | |
def _bin_op(name): | |
def _func(self, other): | |
other = self.conv(other) | |
return BinOp(self, other, name) | |
return _func | |
def _rbin_op(name): | |
def _func(self, other): | |
other = self.conv(other) | |
return BinOp(other, self, name) | |
return _func | |
def _sim_op(name): | |
def _func(self): | |
return SimpleOp(self, name) | |
return _func | |
__add__ = _bin_op("+") | |
__sub__ = _bin_op("-") | |
__mul__ = _bin_op("*") | |
__div__ = _bin_op("/") | |
__pow__ = _bin_op("pow") | |
__radd__ = _rbin_op("+") | |
__rsub__ = _rbin_op("-") | |
__rmul__ = _rbin_op("*") | |
__rdiv__ = _rbin_op("/") | |
__rpow__ = _rbin_op("pow") | |
__gt__ = _bin_op(">") | |
__lt__ = _bin_op("<") | |
__eq__ = _bin_op("=") | |
__gte__ = _bin_op(">=") | |
__lte__ = _bin_op("<=") | |
__xor__ = _bin_op("xor") | |
__and__ = _bin_op("and") | |
__or__ = _bin_op("or") | |
__rxor__ = _rbin_op("xor") | |
__rand__ = _rbin_op("and") | |
__ror__ = _rbin_op("or") | |
__invert__ = _sim_op("not") | |
__abs__ = _sim_op("abs") | |
sqrt = _sim_op("sqrt") | |
exp = _sim_op("exp") | |
log = _sim_op("log") | |
def __ne__(self, other): | |
return (self == other).invert() | |
@staticmethod | |
def conv(value): | |
if isinstance(value, Base): | |
return value | |
return Value(value) | |
def invert(self): | |
return SimpleOp(self, "not") | |
def copy(self, count=2): | |
return ListOp([self]*count, None) | |
def when(self, if_true, if_false): | |
if_true, if_false = self.conv(if_true), self.conv(if_false) | |
return IfOp(self, if_true, if_false) | |
def __str__(self): | |
return ' '.join(op for op in self.emit() if op is not None) | |
def __repr__(self): | |
return f"<ExprNotation '{self!s}'>" | |
class SimpleOp(Base): | |
def __init__(self, val, op): | |
self.val = val | |
self.op = op | |
def emit(self): | |
yield from self.val.emit() | |
yield self.op | |
class BinOp(Base): | |
def __init__(self, rhs, lhs, op): | |
self.rhs = rhs | |
self.lhs = lhs | |
self.op = op | |
def emit(self): | |
yield from self.rhs.emit() | |
yield from self.lhs.emit() | |
yield self.op | |
class LambdaOp(Base): | |
def __init__(self, prefix, func): | |
self.prefix = prefix | |
self.func = func | |
def emit(self): | |
yield from self.prefix.emit() | |
yield from self.func() | |
class ListOp(Base): | |
def __init__(self, iterable, op): | |
self.iterable = list(iterable) | |
self.op = op | |
def reduce(self, op): | |
return LambdaOp(self, lambda: self._reduce(op)) | |
def map(self, op): | |
if self.op is not None: | |
return ListOp(self.iterable, self.op + " " + op) | |
else: | |
return ListOp(self.iterable, op) | |
def zip(self, *items): | |
lo = [] | |
for item, func in __builtins__.zip(self, __builtins__.zip(*items)): | |
def _func_cr(val): | |
def _emitter(): | |
for i in val: | |
yield from i.emit() | |
return _emitter | |
lo.append(LambdaOp(item, _func_cr(func))) | |
return ListOp(lo, None) | |
def _reduce(self, op): | |
for l in range(len(self.iterable)-1): | |
yield op | |
def emit(self): | |
for item in self.iterable: | |
yield from item.emit() | |
if self.op is not None: | |
yield self.op | |
def __getitem__(self, item): | |
if isinstance(item, slice): | |
return ListOp(self.iterable[item], self.op) | |
result = self.iterable[item] | |
if self.op is not None: | |
result = LambdaOp(result, lambda: [self.op]) | |
return result | |
def __len__(self): | |
return len(self.iterable) | |
class IfOp(Base): | |
def __init__(self, cond, if_true, if_false): | |
self.cond = cond | |
self.if_true = if_true | |
self.if_false = if_false | |
def emit(self): | |
yield from self.cond.emit() | |
yield from self.if_true.emit() | |
yield from self.if_false.emit() | |
yield '?' | |
class Value(Base): | |
def __init__(self, marshalled): | |
self.marshalled = marshalled | |
def emit(self): | |
yield str(self.marshalled) | |
import string | |
for char, small in __builtins__.zip(string.ascii_uppercase, string.ascii_lowercase): | |
globals()[char] = Value(small) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment