from .utils import generated_library as genlib
from .utils.types import (
+ compose,
+ ef,
stack_effect,
AnyJoyType,
BooleanJoyType,
FloatJoyType,
IntJoyType,
TextJoyType,
+ _functions,
)
T = t0, t1, t2, t3, t4, t5, t6, t7, t8, t9 = map(TextJoyType, _R)
+sec0 = stack_effect(t1)()
+sec1 = stack_effect(s0, i1)(s1)
+sec2 = stack_effect(s0, i1)(a1)
+sec_binary_cmp = stack_effect(n1, n2)(b1)
+sec_binary_ints = stack_effect(i1, i2)(i3)
+sec_binary_logic = stack_effect(b1, b2)(b3)
+sec_binary_math = stack_effect(n1, n2)(n3)
+sec_unary_logic = stack_effect(a1)(b1)
+sec_unary_math = stack_effect(n1)(n2)
+
+
_dictionary = {}
('and', ['&']),
('bool', ['truthy']),
('mul', ['*']),
+ ('floordiv', ['/floor', '//']),
+ ('floor', ['round']),
('truediv', ['/']),
('mod', ['%', 'rem', 'remainder', 'modulus']),
('eq', ['=']),
D[alias] = F
+def yin_functions():
+ '''
+ Return a dict of named stack effects.
+
+ "Yin" functions are those that only rearrange items in stacks and
+ can be defined completely by their stack effects. This means they
+ can be auto-compiled.
+ '''
+ cons = ef(a1, s0)((a1, s0))
+ ccons = compose(cons, cons)
+ dup = ef(a1)(a1, a1)
+ dupd = ef(a2, a1)(a2, a2, a1)
+ dupdd = ef(a3, a2, a1)(a3, a3, a2, a1)
+ first = ef((a1, s1),)(a1,)
+ over = ef(a2, a1)(a2, a1, a2)
+ pop = ef(a1)()
+ popd = ef(a2, a1,)(a1)
+ popdd = ef(a3, a2, a1,)(a2, a1,)
+ popop = ef(a2, a1,)()
+ popopd = ef(a3, a2, a1,)(a1)
+ popopdd = ef(a4, a3, a2, a1,)(a2, a1)
+ rest = ef((a1, s0),)(s0,)
+ rolldown = ef(a1, a2, a3)(a2, a3, a1)
+ rollup = ef(a1, a2, a3)(a3, a1, a2)
+ rrest = compose(rest, rest)
+ second = compose(rest, first)
+ stack = s0, (s0, s0)
+ swaack = (s1, s0), (s0, s1)
+ swap = ef(a1, a2)(a2, a1)
+ swons = compose(swap, cons)
+ third = compose(rest, second)
+ tuck = ef(a2, a1)(a1, a2, a1)
+ uncons = ef((a1, s0),)(a1, s0)
+ unswons = compose(uncons, swap)
+ stuncons = compose(stack, uncons)
+ stununcons = compose(stack, uncons, uncons)
+ unit = ef(a1)((a1, ()))
+
+ first_two = compose(uncons, uncons, pop)
+ fourth = compose(rest, third)
+
+ _Tree_add_Ee = compose(pop, swap, rolldown, rrest, ccons)
+ _Tree_get_E = compose(popop, second)
+ _Tree_delete_clear_stuff = compose(rollup, popop, rest)
+ _Tree_delete_R0 = compose(over, first, swap, dup)
+
+ return {
+ name.rstrip('_'): stack_effect
+ for name, stack_effect in locals().iteritems()
+ }
+
+
definitions = ('''\
of == swap at
product == 1 swap [*] step
return (line.strip() for line in text.splitlines() if '==' in line)
+
+## eh = compose(dup, bool_)
+## sqr = compose(dup, mul)
+## of = compose(swap, at)
+
+
#
# Functions
#
# Load the auto-generated primitives into the dictionary.
+_functions.update(yin_functions())
for name, primitive in getmembers(genlib, isfunction):
inscribe(SimpleFunctionWrapper(primitive))
+
@inscribe
+@sec0
@FunctionWrapper
-@stack_effect(t1)()
def inscribe_(stack, expression, dictionary):
- '''
- Create a new Joy function definition in the Joy dictionary. A
- definition is given as a string with a name followed by a double
- equal sign then one or more Joy functions, the body. for example:
+ '''
+ Create a new Joy function definition in the Joy dictionary. A
+ definition is given as a string with a name followed by a double
+ equal sign then one or more Joy functions, the body. for example:
- sqr == dup mul
+ sqr == dup mul
- If you want the definition to persist over restarts, enter it into
- the definitions.txt resource.
- '''
- definition, stack = stack
- DefinitionWrapper.add_def(definition, dictionary)
- return stack, expression, dictionary
+ If you want the definition to persist over restarts, enter it into
+ the definitions.txt resource.
+ '''
+ definition, stack = stack
+ DefinitionWrapper.add_def(definition, dictionary)
+ return stack, expression, dictionary
@inscribe
@inscribe
+@sec2
@SimpleFunctionWrapper
def getitem(stack):
'''
@inscribe
+@sec1
@SimpleFunctionWrapper
def drop(stack):
'''
@inscribe
+@sec1
@SimpleFunctionWrapper
def take(stack):
'''
return list_to_stack(sorted(iter_stack(tos))), stack
+_functions['clear'] = s0, s1
@inscribe
@SimpleFunctionWrapper
def clear(stack):
for F in (
- BinaryBuiltinWrapper(operator.add),
- BinaryBuiltinWrapper(operator.and_),
- BinaryBuiltinWrapper(operator.div),
- BinaryBuiltinWrapper(operator.eq),
- BinaryBuiltinWrapper(operator.floordiv),
- BinaryBuiltinWrapper(operator.ge),
- BinaryBuiltinWrapper(operator.gt),
- BinaryBuiltinWrapper(operator.le),
- BinaryBuiltinWrapper(operator.lshift),
- BinaryBuiltinWrapper(operator.lt),
- BinaryBuiltinWrapper(operator.mod),
- BinaryBuiltinWrapper(operator.mul),
- BinaryBuiltinWrapper(operator.ne),
- BinaryBuiltinWrapper(operator.or_),
- BinaryBuiltinWrapper(operator.pow),
- BinaryBuiltinWrapper(operator.rshift),
- BinaryBuiltinWrapper(operator.sub),
- BinaryBuiltinWrapper(operator.truediv),
- BinaryBuiltinWrapper(operator.xor),
-
- UnaryBuiltinWrapper(abs),
- UnaryBuiltinWrapper(bool),
- UnaryBuiltinWrapper(floor),
- UnaryBuiltinWrapper(operator.neg),
- UnaryBuiltinWrapper(operator.not_),
- UnaryBuiltinWrapper(sqrt),
+
+ #divmod_ = pm = __(n2, n1), __(n4, n3)
+
+ sec_binary_cmp(BinaryBuiltinWrapper(operator.eq)),
+ sec_binary_cmp(BinaryBuiltinWrapper(operator.ge)),
+ sec_binary_cmp(BinaryBuiltinWrapper(operator.gt)),
+ sec_binary_cmp(BinaryBuiltinWrapper(operator.le)),
+ sec_binary_cmp(BinaryBuiltinWrapper(operator.lt)),
+ sec_binary_cmp(BinaryBuiltinWrapper(operator.ne)),
+
+ sec_binary_ints(BinaryBuiltinWrapper(operator.xor)),
+ sec_binary_ints(BinaryBuiltinWrapper(operator.lshift)),
+ sec_binary_ints(BinaryBuiltinWrapper(operator.rshift)),
+
+ sec_binary_logic(BinaryBuiltinWrapper(operator.and_)),
+ sec_binary_logic(BinaryBuiltinWrapper(operator.or_)),
+
+ sec_binary_math(BinaryBuiltinWrapper(operator.add)),
+ sec_binary_math(BinaryBuiltinWrapper(operator.floordiv)),
+ sec_binary_math(BinaryBuiltinWrapper(operator.mod)),
+ sec_binary_math(BinaryBuiltinWrapper(operator.mul)),
+ sec_binary_math(BinaryBuiltinWrapper(operator.pow)),
+ sec_binary_math(BinaryBuiltinWrapper(operator.sub)),
+ sec_binary_math(BinaryBuiltinWrapper(operator.truediv)),
+
+ sec_unary_logic(UnaryBuiltinWrapper(bool)),
+ sec_unary_logic(UnaryBuiltinWrapper(operator.not_)),
+
+ sec_unary_math(UnaryBuiltinWrapper(abs)),
+ sec_unary_math(UnaryBuiltinWrapper(operator.neg)),
+ sec_unary_math(UnaryBuiltinWrapper(sqrt)),
+
+ stack_effect(n1)(i1)(UnaryBuiltinWrapper(floor)),
):
inscribe(F)
del F # Otherwise Sphinx autodoc will pick it up.
return %s''' % (name, doc, i, o)
+_functions = {}
+
+
def __(*seq):
stack = StackJoyType(23)
for item in seq: stack = item, stack
return stack
-
def stack_effect(*inputs):
-
def _stack_effect(*outputs):
- pass
+ def _apply_to(function):
+ i, o = _functions[function.name] = __(*inputs), __(*outputs)
+ function.__doc__ += (
+ '\nStack effect::\n\n ' # '::' for Sphinx docs.
+ + doc_from_stack_effect(i, o)
+ )
+ return function
+ return _apply_to
+ return _stack_effect
-return _stack_effect
+def ef(*inputs):
+ def _ef(*outputs):
+ return __(*inputs), __(*outputs)
+ return _ef
-_R = range(10)
-A = a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 = map(AnyJoyType, _R)
-B = b0, b1, b2, b3, b4, b5, b6, b7, b8, b9 = map(BooleanJoyType, _R)
-N = n0, n1, n2, n3, n4, n5, n6, n7, n8, n9 = map(NumberJoyType, _R)
-S = s0, s1, s2, s3, s4, s5, s6, s7, s8, s9 = map(StackJoyType, _R)
-F = f0, f1, f2, f3, f4, f5, f6, f7, f8, f9 = map(FloatJoyType, _R)
-I = i0, i1, i2, i3, i4, i5, i6, i7, i8, i9 = map(IntJoyType, _R)
-T = t0, t1, t2, t3, t4, t5, t6, t7, t8, t9 = map(TextJoyType, _R)
-
-
-def defs():
- '''
- Return a dict of named stack effects.
- '''
- at = __(s0, i1), __(a1)
- drop = take = __(s0, i1), __(s1)
- cons = __(a1, s0), __((a1, s0),)
- ccons = compose(cons, cons)
- dup = __(a1,), __(a1, a1)
- dupd = __(a2, a1), __(a2, a2, a1)
- dupdd = __(a3, a2, a1), __(a3, a3, a2, a1)
- first = __((a1, s1),), __(a1,)
- inscribe = __(t1), __()
- over = __(a2, a1), __(a2, a1, a2)
- pop = __(a1), __()
- popd = __(a2, a1,), __(a1)
- popdd = __(a3, a2, a1,), __(a2, a1,)
- popop = __(a2, a1,), __()
- popopd = __(a3, a2, a1,), __(a1)
- popopdd = __(a4, a3, a2, a1,), __(a2, a1)
- rest = __((a1, s0),), __(s0,)
- rolldown = __(a1, a2, a3), __(a2, a3, a1)
- rollup = __(a1, a2, a3), __(a3, a1, a2)
- rrest = compose(rest, rest)
- second = compose(rest, first)
- stack = s0, (s0, s0)
- swaack = (s1, s0), (s0, s1)
- swap = __(a1, a2), __(a2, a1)
- swons = compose(swap, cons)
- third = compose(rest, second)
- tuck = __(a2, a1), __(a1, a2, a1)
- uncons = __((a1, s0),), __(a1, s0)
- unswons = compose(uncons, swap)
- stuncons = compose(stack, uncons)
- stununcons = compose(stack, uncons, uncons)
- unit = __(a1), __((a1, ()))
- of = compose(swap, at)
- clear = s0, s1
-
- eq = ge = gt = le = lt = ne = __(n1, n2), __(b1)
-
- and_ = __(b1, b2), __(b3)
- bool_ = not_ = __(a1), __(b1)
- eh = compose(dup, bool_)
-
- add = div = floordiv = mod = mul = pow_ = sub = truediv = \
- lshift = rshift = __(n1, n2), __(n3,)
- sqr = compose(dup, mul)
- abs_ = floor = sqrt = succ = pred = neg = __(n1,), __(n2,)
- divmod_ = pm = __(n2, n1), __(n4, n3)
-
- first_two = compose(uncons, uncons, pop)
- fourth = compose(rest, third)
- of = compose(swap, at)
-
- _Tree_add_Ee = compose(pop, swap, rolldown, rrest, ccons)
- _Tree_get_E = compose(popop, second)
- _Tree_delete_clear_stuff = compose(rollup, popop, rest)
- _Tree_delete_R0 = compose(over, first, swap, dup)
-
- return {
- name.rstrip('_'): stack_effect
- for name, stack_effect in locals().iteritems()
- }
-
-
-DEFS = defs()
-
-
-def show():
+def show(DEFS):
for name, stack_effect_comment in sorted(DEFS.iteritems()):
t = ' *'[compilable(stack_effect_comment)]
print name, '=', doc_from_stack_effect(*stack_effect_comment), t
-def generate_library_code(f=None):
+def generate_library_code(DEFS, f=None):
if f is None:
import sys
f = sys.stdout
print >> f
-if __name__ == '__main__':
- show()
+##if __name__ == '__main__':
+## show()