Skip to content

Instantly share code, notes, and snippets.

@stuxcrystal
Last active July 2, 2017 20:02
Show Gist options
  • Save stuxcrystal/8d159c6ec705cc74debe7a550c83c7ce to your computer and use it in GitHub Desktop.
Save stuxcrystal/8d159c6ec705cc74debe7a550c83c7ce to your computer and use it in GitHub Desktop.
lolz
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