OSDN Git Service

In progress..
authorSimon Forman <sforman@hushmail.com>
Wed, 1 Aug 2018 19:26:50 +0000 (12:26 -0700)
committerSimon Forman <sforman@hushmail.com>
Wed, 1 Aug 2018 19:26:50 +0000 (12:26 -0700)
joy/utils/compiler.py

index 0b2bc91..ba7e4e6 100644 (file)
@@ -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')