From dae5126bfcd9763dd4f433061568c95b450f5f7f Mon Sep 17 00:00:00 2001 From: Simon Forman Date: Wed, 1 Aug 2018 12:26:50 -0700 Subject: [PATCH] In progress.. --- joy/utils/compiler.py | 75 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 59 insertions(+), 16 deletions(-) diff --git a/joy/utils/compiler.py b/joy/utils/compiler.py index 0b2bc91..ba7e4e6 100644 --- a/joy/utils/compiler.py +++ b/joy/utils/compiler.py @@ -1,17 +1,12 @@ from joy.parser import text_to_expression, Symbol -from joy.utils.stack import iter_stack, list_to_stack -from joy.library import SimpleFunctionWrapper +from joy.utils.stack import concat, iter_stack, list_to_stack +from joy.library import SimpleFunctionWrapper, YIN_STACK_EFFECTS def import_yin(): from joy.utils.generated_library import * return locals() -D = { - name: SimpleFunctionWrapper(func) - for name, func in import_yin().iteritems() - } - def _names(): n = 0 @@ -68,6 +63,7 @@ strstk = lambda rest: reduce(strtup, rest, 'stack') def code_gen(code): + #for p in code: print p coalesce_pops(code) lines = [] emit = lines.append @@ -75,7 +71,7 @@ def code_gen(code): tag, rest = t[0], t[1:] if tag == 'pop': emit(strstk(rest) + ' = stack') elif tag == 'call': emit('%s = %s%s' % rest) - elif tag == 'ret': emit('return ' + strstk(rest)) + elif tag == 'ret': emit('return ' + strstk(rest[::-1])) else: raise ValueError(tag) return '\n'.join(' ' + line for line in lines) @@ -94,14 +90,61 @@ def %s(stack): ''' % (name, code_gen(I(text_to_expression(text)))) +def q(): + memo = {} + def bar(type_var): + try: + res = memo[type_var] + except KeyError: + res = memo[type_var] = InfiniteStack.names() + return res + return bar + + +def type_vars_to_labels(thing, map_): + if not thing: + return thing + if not isinstance(thing, tuple): + return map_(thing) + return tuple(type_vars_to_labels(inner, map_) for inner in thing) + + +def remap_inputs(in_, stack, code): + map_ = q() + while in_: + term, in_ = in_ + arg0, stack = stack + term = type_vars_to_labels(term, map_) + code.append(('call', term, '', arg0)) + return stack, map_ + + +def first_two(stack, expression, code): + in_, out = YIN_STACK_EFFECTS['first_two'] + stack, map_ = remap_inputs(in_, stack, code) + out = type_vars_to_labels(out, map_) + return concat(out, stack), expression, code + + +YIN = import_yin() + + +D = { + name: SimpleFunctionWrapper(func) + for name, func in YIN.iteritems() + } + + D['mul'] = Foo('mul') D['sub'] = Foo('sub') +D['first_two'] = first_two + +print compile_yinyang('mul_', 'mul') +print compile_yinyang('sqr', 'dup mul') +print compile_yinyang('foo', 'dup 23 sub mul') +print compile_yinyang('bar', 'mul mul mul mul') +print compile_yinyang('baz', 'mul dup sub dup') +print compile_yinyang('to_the_fifth_power', 'dup dup mul dup mul mul') +print compile_yinyang('hey', 'dup dup dup') +print compile_yinyang('hey', 'dup first_two mul') -##print compile_yinyang('mul_', 'mul') -##print compile_yinyang('sqr', 'dup mul') -##print compile_yinyang('foo', 'dup 23 sub mul') -##print compile_yinyang('bar', 'mul mul mul mul') -##print compile_yinyang('baz', 'mul dup sub dup') -##print compile_yinyang('to_the_fifth_power', 'dup dup mul dup mul mul') -##print compile_yinyang('hey', 'dup dup dup') -print compile_yinyang('hey', 'first_two')