24 KiB
24 KiB
In [1]:
from notebook_preamble import D, J, V, defineIn [2]:
V('23 sqr')• 23 sqr 23 • sqr 23 • dup mul 23 23 • mul 529 •
In [3]:
dup, mul = D['dup'], D['mul']In [4]:
def sqr(stack, expression, dictionary):
return mul(*dup(stack, expression, dictionary))In [5]:
old_sqr = D['sqr']
D['sqr'] = sqrIn [6]:
V('23 sqr')• 23 sqr 23 • sqr 529 •
In [7]:
def compile_joy(name, expression):
term, expression = expression
code = term +'(stack, expression, dictionary)'
format_ = '%s(*%s)'
while expression:
term, expression = expression
code = format_ % (term, code)
return '''\
def %s(stack, expression, dictionary):
return %s
''' % (name, code)
def compile_joy_definition(defi):
return compile_joy(defi.name, defi.body)
In [10]:
print(compile_joy_definition(old_sqr))def sqr(stack, expression, dictionary):
return mul(*dup(stack, expression, dictionary))
In [11]:
unit, dip = D['unit'], D['dip']In [12]:
# print compile_joy_definition(D['quoted'])
# raises
# TypeError: can only concatenate tuple (not "str") to tupleIn [13]:
def foo(stack, expression, dictionary):
stack, expression, dictionary = baz(*bar(stack, expression, dictionary))
return barp(*lerp(*baq((99, (23, stack)), expression, dictionary)))In [14]:
from joy.utils.types import compile_, doc_from_stack_effect, infer_string
from joy.library import SimpleFunctionWrapper[0;31m---------------------------------------------------------------------------[0m [0;31mModuleNotFoundError[0m Traceback (most recent call last) [0;32m<ipython-input-14-d5ef3c7560be>[0m in [0;36m<module>[0;34m[0m [0;32m----> 1[0;31m [0;32mfrom[0m [0mjoy[0m[0;34m.[0m[0mutils[0m[0;34m.[0m[0mtypes[0m [0;32mimport[0m [0mcompile_[0m[0;34m,[0m [0mdoc_from_stack_effect[0m[0;34m,[0m [0minfer_string[0m[0;34m[0m[0;34m[0m[0m [0m[1;32m 2[0m [0;32mfrom[0m [0mjoy[0m[0;34m.[0m[0mlibrary[0m [0;32mimport[0m [0mSimpleFunctionWrapper[0m[0;34m[0m[0;34m[0m[0m [0;31mModuleNotFoundError[0m: No module named 'joy.utils.types'
In [ ]:
stack_effects = infer_string('tuck over dup')In [ ]:
for fi, fo in stack_effects:
print doc_from_stack_effect(fi, fo)In [ ]:
source = compile_('foo', stack_effects[0])In [ ]:
print sourceIn [9]:
exec compile(source, '__main__', 'single')
D['foo'] = SimpleFunctionWrapper(foo)[0;36m File [0;32m"<ipython-input-9-1a7e90bf2d7b>"[0;36m, line [0;32m1[0m [0;31m exec compile(source, '__main__', 'single')[0m [0m ^[0m [0;31mSyntaxError[0m[0;31m:[0m invalid syntax
In [ ]:
V('23 18 foo')In [ ]:
from joy.parser import text_to_expressionIn [ ]:
Ein = '[a b c d] e a [f]' # The terms should be reversed here but I don't realize that until later.
Eout = '[a e c d]'
E = '[%s] [%s]' % (Ein, Eout)
print EIn [ ]:
(fi, (fo, _)) = text_to_expression(E)In [ ]:
fi, foIn [ ]:
Ein = '[a1 a2 a3 a4] a5 a6 a7'
Eout = '[a1 a5 a3 a4]'
E = '[%s] [%s]' % (Ein, Eout)
print EIn [ ]:
(fi, (fo, _)) = text_to_expression(E)In [ ]:
fi, foIn [ ]:
def type_vars():
from joy.library import a1, a2, a3, a4, a5, a6, a7, s0, s1
return locals()
tv = type_vars()
tvIn [ ]:
from joy.utils.types import reifyIn [ ]:
stack_effect = reify(tv, (fi, fo))
print doc_from_stack_effect(*stack_effect)In [ ]:
print stack_effectIn [ ]:
stack_effect = eval('(((a1, (a2, (a3, (a4, s1)))), (a5, (a6, (a7, s0)))), ((a1, (a5, (a3, (a4, s1)))), s0))', tv)In [ ]:
print doc_from_stack_effect(*stack_effect)In [ ]:
stack_effect = eval('(((a1, (a2, s1)), (a5, (a6, (a7, s0)))), ((a1, (a5, s1)), s0))', tv)In [ ]:
print doc_from_stack_effect(*stack_effect)In [ ]:
source = compile_('Ee', stack_effect)
print sourceIn [ ]:
stack_effect = eval('((a7, (a6, (a5, ((a1, (a2, s1)), s0)))), ((a1, (a5, s1)), s0))', tv)In [ ]:
print doc_from_stack_effect(*stack_effect)In [ ]:
source = compile_('Ee', stack_effect)
print sourceIn [ ]:
eval(compile(source, '__main__', 'single'))
D['Ee'] = SimpleFunctionWrapper(Ee)In [ ]:
V('[a b c d] 1 2 [f] Ee')In [ ]:
In [ ]:
def dup(stack):
(a1, s23) = stack
return (a1, (a1, s23))
In [ ]:
stack_effects = infer_string('dup mul')
for fi, fo in stack_effects:
print doc_from_stack_effect(fi, fo)In [ ]:
def sqr(stack):
(n1, s23) = stack
n2 = mul(n1, n1)
return (n2, s23)
In [ ]:
In [ ]:
In [ ]:
stack_effects = infer_string('mul mul sub')
for fi, fo in stack_effects:
print doc_from_stack_effect(fi, fo)In [ ]:
def foo(stack):
(n1, (n2, (n3, (n4, s23)))) = stack
n5 = mul(n1, n2)
n6 = mul(n5, n3)
n7 = sub(n6, n4)
return (n7, s23)
# or
def foo(stack):
(n1, (n2, (n3, (n4, s23)))) = stack
n5 = sub(mul(mul(n1, n2), n3), n4)
return (n5, s23)
In [ ]:
In [ ]:
stack_effects = infer_string('tuck')
for fi, fo in stack_effects:
print doc_from_stack_effect(fi, fo)In [ ]:
In [ ]:
from joy.parser import SymbolIn [ ]:
def _names():
n = 0
while True:
yield Symbol('a' + str(n))
n += 1
names = _names().nextIn [ ]:
class Foo(object):
def __init__(self, name):
self.name = name
def __call__(self, stack, expression, code):
in1, (in0, stack) = stack
out = names()
code.append(('call', out, self.name, (in0, in1)))
return (out, stack), expression, codeIn [ ]:
def I(stack, expression, code):
while expression:
term, expression = expression
if callable(term):
stack, expression, _ = term(stack, expression, code)
else:
stack = term, stack
code.append(('pop', term))
s = []
while stack:
term, stack = stack
s.insert(0, term)
if s:
code.append(('push',) + tuple(s))
return codeIn [ ]:
strtup = lambda a, b: '(%s, %s)' % (b, a)
strstk = lambda rest: reduce(strtup, rest, 'stack')
def code_gen(code):
coalesce_pops(code)
lines = []
for t in code:
tag, rest = t[0], t[1:]
if tag == 'pop':
lines.append(strstk(rest) + ' = stack')
elif tag == 'push':
lines.append('stack = ' + strstk(rest))
elif tag == 'call':
#out, name, in_ = rest
lines.append('%s = %s%s' % rest)
else:
raise ValueError(tag)
return '\n'.join(' ' + line for line in lines)
def coalesce_pops(code):
index = [i for i, t in enumerate(code) if t[0] == 'pop']
for start, end in yield_groups(index):
code[start:end] = \
[tuple(['pop'] + [t for _, t in code[start:end][::-1]])]
def yield_groups(index):
'''
Yield slice indices for each group of contiguous ints in the
index list.
'''
k = 0
for i, (a, b) in enumerate(zip(index, index[1:])):
if b - a > 1:
if k != i:
yield index[k], index[i] + 1
k = i + 1
if k < len(index):
yield index[k], index[-1] + 1
def compile_yinyang(name, expression):
return '''\
def %s(stack):
%s
return stack
''' % (name, code_gen(I((), expression, [])))
In [ ]:
mul = Foo('mul')
sub = Foo('sub')In [ ]:
def import_yin():
from joy.utils.generated_library import *
return locals()
yin_dict = {name: SimpleFunctionWrapper(func) for name, func in import_yin().iteritems()}
yin_dict
dup = yin_dict['dup']
#def dup(stack, expression, code):
# n, stack = stack
# return (n, (n, stack)), expressionIn [ ]:
print compile_yinyang('mul_', (names(), (names(), (mul, ()))))In [ ]:
e = (names(), (dup, (mul, ())))
print compile_yinyang('sqr', e)In [ ]:
e = (names(), (dup, (names(), (sub, (mul, ())))))
print compile_yinyang('foo', e)In [ ]:
e = (names(), (names(), (mul, (dup, (sub, (dup, ()))))))
print compile_yinyang('bar', e)In [ ]:
e = (names(), (dup, (dup, (mul, (dup, (mul, (mul, ())))))))
print compile_yinyang('to_the_fifth_power', e)In [ ]:
In [ ]:
In [ ]:
In [ ]: