[pypy-svn] r43500 - in pypy/branch/prolog-jit-experiments/pypy/lang/prolog: builtin interpreter interpreter/test

cfbolz at codespeak.net cfbolz at codespeak.net
Sat May 19 10:38:05 CEST 2007


Author: cfbolz
Date: Sat May 19 10:38:05 2007
New Revision: 43500

Modified:
   pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/allsolution.py
   pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/arithmeticbuiltin.py
   pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/atomconstruction.py
   pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/control.py
   pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/exception.py
   pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/metacall.py
   pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/parseraccess.py
   pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/register.py
   pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/termconstruction.py
   pypy/branch/prolog-jit-experiments/pypy/lang/prolog/interpreter/engine.py
   pypy/branch/prolog-jit-experiments/pypy/lang/prolog/interpreter/helper.py
   pypy/branch/prolog-jit-experiments/pypy/lang/prolog/interpreter/interactive.py
   pypy/branch/prolog-jit-experiments/pypy/lang/prolog/interpreter/test/tool.py
   pypy/branch/prolog-jit-experiments/pypy/lang/prolog/interpreter/translatedmain.py
Log:
intermediate checkin towards using a more classical bytecode interpreter for
Prolog. So far the bytecode is not actually compiled, but produced at runtime.


Modified: pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/allsolution.py
==============================================================================
--- pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/allsolution.py	(original)
+++ pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/allsolution.py	Sat May 19 10:38:05 2007
@@ -10,7 +10,7 @@
         self.found = []
         self.template = template
 
-    def call(self, engine):
+    def _call(self, engine):
         clone = self.template.getvalue(engine.heap)
         self.found.append(clone)
         raise error.UnificationFailed()

Modified: pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/arithmeticbuiltin.py
==============================================================================
--- pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/arithmeticbuiltin.py	(original)
+++ pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/arithmeticbuiltin.py	Sat May 19 10:38:05 2007
@@ -12,16 +12,16 @@
             oldstate = engine.heap.branch()
             try:
                 varorint.unify(term.Number(i), engine.heap)
-                return continuation.call(engine)
+                return continuation.call(engine, choice_point=True)
             except error.UnificationFailed:
                 engine.heap.revert(oldstate)
         varorint.unify(term.Number(upper), engine.heap)
-        return continuation.call(engine)
+        return continuation.call(engine, choice_point=False)
     else:
         integer = helper.unwrap_int(varorint)
         if not (lower <= integer <= upper):
             raise error.UnificationFailed
-    return continuation.call(engine)
+    return continuation.call(engine, choice_point=False)
 expose_builtin(impl_between, "between", unwrap_spec=["int", "int", "obj"],
                handles_continuation=True)
 

Modified: pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/atomconstruction.py
==============================================================================
--- pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/atomconstruction.py	(original)
+++ pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/atomconstruction.py	Sat May 19 10:38:05 2007
@@ -15,7 +15,7 @@
                 try:
                     a1.unify(term.Atom(r[:i]), engine.heap)
                     a2.unify(term.Atom(r[i:]), engine.heap)
-                    return continuation.call(engine)
+                    return continuation.call(engine, choice_point=True)
                 except error.UnificationFailed:
                     engine.heap.revert(oldstate)
             raise error.UnificationFailed()
@@ -39,7 +39,7 @@
         else:
             s2 = helper.convert_to_str(a2)
             result.unify(term.Atom(s1 + s2), engine.heap)
-    return continuation.call(engine)
+    return continuation.call(engine, choice_point=False)
 expose_builtin(impl_atom_concat, "atom_concat",
                unwrap_spec=["obj", "obj", "obj"],
                handles_continuation=True)
@@ -86,7 +86,7 @@
                     before.unify(term.Number(b), engine.heap)
                     after.unify(term.Number(len(s) - len(s1) - b), engine.heap)
                     length.unify(term.Number(len(s1)), engine.heap)
-                    return continuation.call(engine)
+                    return continuation.call(engine, choice_point=True)
                 except:
                     engine.heap.revert(oldstate)
                     raise
@@ -104,7 +104,7 @@
                         after.unify(term.Number(len(s) - l - b), engine.heap)
                         length.unify(term.Number(l), engine.heap)
                         sub.unify(term.Atom(s[b:b + l]), engine.heap)
-                        return continuation.call(engine)
+                        return continuation.call(engine, choice_point=True)
                     except:
                         engine.heap.revert(oldstate)
                         raise
@@ -123,7 +123,7 @@
                     after.unify(term.Number(a), engine.heap)
                     length.unify(term.Number(l), engine.heap)
                     sub.unify(term.Atom(s[b:b + l]), engine.heap)
-                    return continuation.call(engine)
+                    return continuation.call(engine, choice_point=True)
                     return None
                 except:
                     engine.heap.revert(oldstate)

Modified: pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/control.py
==============================================================================
--- pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/control.py	(original)
+++ pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/control.py	Sat May 19 10:38:05 2007
@@ -11,13 +11,13 @@
 expose_builtin(impl_fail, "fail", unwrap_spec=[])
 
 def impl_true(engine):
-    pass
+    return
 expose_builtin(impl_true, "true", unwrap_spec=[])
 
 def impl_repeat(engine, continuation):
     while 1:
         try:
-            return continuation.call(engine)
+            return continuation.call(engine, choice_point=True)
         except error.UnificationFailed:
             pass
 expose_builtin(impl_repeat, "repeat", unwrap_spec=[], handles_continuation=True)
@@ -32,18 +32,16 @@
         self.next_call = next_call
         self.continuation = continuation
 
-    def call(self, engine):
+    def _call(self, engine):
         next_call = self.next_call.dereference(engine.heap)
-        if isinstance(next_call, term.Var):
-            error.throw_instantiation_error()
         next_call = helper.ensure_callable(next_call)
-        return engine.call(next_call, self.continuation)
+        return engine.call(next_call, self.continuation, choice_point=False)
 
 def impl_and(engine, call1, call2, continuation):
     if not isinstance(call2, term.Var) and not isinstance(call2, term.Callable):
         error.throw_type_error('callable', call2)
     and_continuation = AndContinuation(call2, continuation)
-    return engine.call(call1, and_continuation)
+    return engine.call(call1, and_continuation, choice_point=False)
 expose_builtin(impl_and, ",", unwrap_spec=["callable", "raw"],
                handles_continuation=True)
 
@@ -53,7 +51,7 @@
         return engine.call(call1, continuation)
     except error.UnificationFailed:
         engine.heap.revert(oldstate)
-    return engine.call(call2, continuation)
+    return engine.call(call2, continuation, choice_point=False)
 
 expose_builtin(impl_or, ";", unwrap_spec=["callable", "callable"],
                handles_continuation=True)
@@ -76,7 +74,8 @@
     except error.UnificationFailed:
         engine.heap.revert(oldstate)
         raise
-    return engine.call(helper.ensure_callable(then_clause), continuation)
+    return engine.call(helper.ensure_callable(then_clause), continuation,
+                       choice_point=False)
 expose_builtin(impl_if, "->", unwrap_spec=["callable", "raw"],
                handles_continuation=True)
 

Modified: pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/exception.py
==============================================================================
--- pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/exception.py	(original)
+++ pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/exception.py	Sat May 19 10:38:05 2007
@@ -31,7 +31,7 @@
                 raise error.UserError(exc_term)
             if isinstance(e, error.CatchableError):
                 raise error.CatchableError(exc_term)
-        return engine.call(recover, continuation)
+        return engine.call(recover, continuation, choice_point=False)
 expose_builtin(impl_catch, "catch", unwrap_spec=["callable", "obj", "callable"],
                handles_continuation=True)
 

Modified: pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/metacall.py
==============================================================================
--- pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/metacall.py	(original)
+++ pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/metacall.py	Sat May 19 10:38:05 2007
@@ -9,13 +9,13 @@
     try:
         return engine.call(call, continuation)
     except error.CutException, e:
-        return e.continuation.call(engine)
+        return e.continuation.call(engine, choice_point=False)
 expose_builtin(impl_call, "call", unwrap_spec=["callable"],
                handles_continuation=True)
 
 def impl_once(engine, clause, continuation):
     engine.call(clause)
-    return continuation.call(engine)
+    return continuation.call(engine, choice_point=False)
 expose_builtin(impl_once, "once", unwrap_spec=["callable"],
                handles_continuation=True)
 

Modified: pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/parseraccess.py
==============================================================================
--- pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/parseraccess.py	(original)
+++ pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/parseraccess.py	Sat May 19 10:38:05 2007
@@ -14,7 +14,7 @@
                     precedence.unify(term.Number(prec), engine.heap)
                     typ.unify(term.Atom.newatom(form), engine.heap)
                     name.unify(term.Atom(op), engine.heap)
-                    return continuation.call(engine)
+                    return continuation.call(engine, choice_point=True)
                 except error.UnificationFailed:
                     engine.heap.revert(oldstate)
     raise error.UnificationFailed()

Modified: pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/register.py
==============================================================================
--- pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/register.py	(original)
+++ pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/register.py	Sat May 19 10:38:05 2007
@@ -45,7 +45,7 @@
         elif spec in ("concrete", "list"):
             code.append("    %s = query.args[%s].getvalue(engine.heap)" %
                         (varname, i))
-        if spec in ("callable", "int", "atom", "arithmetic", "list"):
+        if spec in ("int", "atom", "arithmetic", "list"):
             code.append(
                 "    if isinstance(%s, term.Var):" % (varname,))
             code.append(
@@ -77,7 +77,9 @@
     call = "    result = %s(%s)" % (func.func_name, ", ".join(subargs))
     code.append(call)
     if not handles_continuation:
-        code.append("    return continuation.call(engine)")
+        code.append("    return continuation.call(engine, choice_point=False)")
+    else:
+        code.append("    return result")
     miniglobals = globals().copy()
     miniglobals[func.func_name] = func
     exec py.code.Source("\n".join(code)).compile() in miniglobals

Modified: pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/termconstruction.py
==============================================================================
--- pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/termconstruction.py	(original)
+++ pypy/branch/prolog-jit-experiments/pypy/lang/prolog/builtin/termconstruction.py	Sat May 19 10:38:05 2007
@@ -48,7 +48,7 @@
             try:
                 third.unify(arg, engine.heap)
                 first.unify(term.Number(i + 1), engine.heap)
-                return continuation.call(engine)
+                return continuation.call(engine, choice_point=True)
             except error.UnificationFailed:
                 engine.heap.revert(oldstate)
         raise error.UnificationFailed()
@@ -64,7 +64,7 @@
         third.unify(arg, engine.heap)
     else:
         error.throw_type_error("integer", first)
-    return continuation.call(engine)
+    return continuation.call(engine, choice_point=False)
 expose_builtin(impl_arg, "arg", unwrap_spec=["obj", "obj", "obj"],
                handles_continuation=True)
 

Modified: pypy/branch/prolog-jit-experiments/pypy/lang/prolog/interpreter/engine.py
==============================================================================
--- pypy/branch/prolog-jit-experiments/pypy/lang/prolog/interpreter/engine.py	(original)
+++ pypy/branch/prolog-jit-experiments/pypy/lang/prolog/interpreter/engine.py	Sat May 19 10:38:05 2007
@@ -8,9 +8,22 @@
 
 DEBUG = False
 
+# bytecodes:
+CALL = chr(0)
+USER_CALL = chr(1)
+TRY_RULE = chr(2)
+CONTINUATION = chr(3)
+DONE = chr(4)
+
+
 class Continuation(object):
-    def call(self, engine):
-        pass
+    def call(self, engine, choice_point=True):
+        if choice_point:
+            return engine.main_loop(CONTINUATION, None, self, None)
+        return (CONTINUATION, None, self, None)
+
+    def _call(self, engine):
+        return (DONE, None, None, None)
 
 DONOTHING = Continuation()
 
@@ -19,9 +32,9 @@
         self.scope_active = True
         self.continuation = continuation
 
-    def call(self, engine):
+    def _call(self, engine):
         self.scope_active = False
-        return self.continuation.call(engine)
+        return self.continuation.call(engine, choice_point=False)
 
 START_NUMBER_OF_VARS = 4096
 
@@ -201,9 +214,9 @@
         vars = query.get_max_var() + 1
         self.heap.clear(vars)
         try:
-            return self.call(query, continuation)
+            return self.call(query, continuation, choice_point=True)
         except CutException, e:
-            self.continue_after_cut(e.continuation)
+            return self.continue_after_cut(e.continuation)
 
     def _build_and_run(self, tree):
         from pypy.lang.prolog.interpreter.parsing import TermBuilder
@@ -219,35 +232,58 @@
         from pypy.lang.prolog.interpreter.parsing import parse_file
         trees = parse_file(s, self.parser, Engine._build_and_run, self)
 
-    def call(self, query, continuation=DONOTHING):
+    def call(self, query, continuation=DONOTHING, choice_point=True,
+             inline=False):
         assert isinstance(query, Callable)
-        if DEBUG:
-            debug_print("calling", query)
+        if not choice_point:
+            return (CALL, query, continuation, None)
+        return self.main_loop(CALL, query, continuation)
+
+    def _call(self, query, continuation):
         signature = query.signature
         # check for builtins
-        if _is_early_constant(signature):
-            for bsig, builtin in unrolling_builtins:
-                if signature == bsig:
-                    #XXX should be:
-                    #return builtin.call(self, query, continuation)
-                    # but then the JIT explodes sometimes for funny reasons
-                    return builtin.function(self, query, continuation)
-            # do a real call
-            return self.user_call(query, continuation)
-        else:
-            return self._opaque_call(signature, query, continuation)
-
-    def _opaque_call(self, signature, query, continuation):
+#        if _is_early_constant(signature):
+#            for bsig, builtin in unrolling_builtins:
+#                if signature == bsig:
+#                    #XXX should be:
+#                    #return builtin.call(self, query, continuation)
+#                    # but then the JIT explodes sometimes for funny reasons
+#                    return builtin.function(self, query, continuation)
+#            # do a real call
+#            return self.user_call(query, continuation, tail_call=True)
+#        else:
+#            return self._opaque_call(signature, query, continuation)
         from pypy.lang.prolog.builtin import builtins
         #builtins = hint(builtins, deepfreeze=True)
         builtin = builtins.get(signature, None)
         if builtin is not None:
-            #XXX should be:
-            #return builtin.call(self, query, continuation)
-            # but then the JIT explodes sometimes for funny reasons
-            return builtin.function(self, query, continuation)
+            return builtin.call(self, query, continuation)
         # do a real call
-        return self.user_call(query, continuation)
+        return self.user_call(query, continuation, choice_point=False)
+
+    def main_loop(self, where, query, continuation, rule=None):
+        from pypy.lang.prolog.builtin.control import AndContinuation
+        from pypy.lang.prolog.interpreter import helper
+        next = (DONE, None, None, None)
+        while 1:
+            #print "  " * self.depth, where, query
+            if where == CALL:
+                next = self._call(query, continuation)
+                assert next is not None
+            elif where == TRY_RULE:
+                next = self._try_rule(rule, query, continuation)
+                assert next is not None
+            elif where == USER_CALL:
+                next = self._user_call(query, continuation)
+                assert next is not None
+            elif where == CONTINUATION:
+                next = continuation._call(self)
+                assert next is not None
+            elif where == DONE:
+                return next
+            else:
+                raise Exception("unknown bytecode")
+            where, query, continuation, rule = next
 
     def _jit_lookup(self, signature):
         signature2function = self.signature2function
@@ -257,8 +293,12 @@
         return function
     _jit_lookup._pure_function_ = True
 
-    def user_call(self, query, continuation):
-        #import pdb; pdb.set_trace()
+    def user_call(self, query, continuation, choice_point=True, inline=False):
+        if not choice_point:
+            return (USER_CALL, query, continuation, None)
+        return self.main_loop(USER_CALL, query, continuation)
+
+    def _user_call(self, query, continuation):
         signature = hint(query.signature, promote=True)
         function = self._jit_lookup(signature)
         startrulechain = function.rulechain
@@ -311,34 +351,30 @@
                 return self.try_rule(rule, query, continuation)
             except CutException, e:
                 if continuation.scope_active:
-                    self.continue_after_cut(e.continuation, continuation)
+                    return self.continue_after_cut(e.continuation, continuation)
                 raise
-        return self.try_rule(rule, query, continuation)
+        return self.try_rule(rule, query, continuation, choice_point=False)
 
-    def try_rule(self, rule, query, continuation=DONOTHING):
-        return self._portal_try_rule(rule, query, continuation)
+    def try_rule(self, rule, query, continuation=DONOTHING, choice_point=True,
+                 inline=False):
+        if not choice_point:
+            return (TRY_RULE, query, continuation, rule)
+        return self.main_loop(TRY_RULE, query, continuation, rule)
 
-    def _portal_try_rule(self, rule, query, continuation=DONOTHING):
-        hint(None, global_merge_point=True)
+    def _try_rule(self, rule, query, continuation):
         rule = hint(rule, deepfreeze=True)
         hint(self, concrete=True)
-        if DEBUG:
-            debug_print("trying rule", rule, query, self.heap.vars[:self.heap.needed_vars])
         # standardizing apart
         nextcall = rule.clone_and_unify_head(self.heap, query)
-        if DEBUG:
-            debug_print("worked", rule, query, self.heap.vars[:self.heap.needed_vars])
         if nextcall is not None:
-            self.call(nextcall, continuation)
-            return "no"
+            return self.call(nextcall, continuation, choice_point=False)
         else:
-            continuation.call(self)
-            return "yes"
+            return continuation.call(self, choice_point=False)
 
     def continue_after_cut(self, continuation, lsc=None):
         while 1:
             try:
-                return continuation.call(self)
+                return continuation.call(self, choice_point=True)
             except CutException, e:
                 if lsc is not None and not lsc.scope_active:
                     raise

Modified: pypy/branch/prolog-jit-experiments/pypy/lang/prolog/interpreter/helper.py
==============================================================================
--- pypy/branch/prolog-jit-experiments/pypy/lang/prolog/interpreter/helper.py	(original)
+++ pypy/branch/prolog-jit-experiments/pypy/lang/prolog/interpreter/helper.py	Sat May 19 10:38:05 2007
@@ -25,9 +25,12 @@
     return isinstance(var, term.Callable)
 
 def ensure_callable(var):
-    if isinstance(var, term.Callable):
+    if isinstance(var, term.Var):
+        error.throw_instantiation_error()
+    elif isinstance(var, term.Callable):
         return var
-    error.throw_type_error("callable", var)
+    else:
+        error.throw_type_error("callable", var)
 
 def unwrap_int(obj):
     if isinstance(obj, term.Number):

Modified: pypy/branch/prolog-jit-experiments/pypy/lang/prolog/interpreter/interactive.py
==============================================================================
--- pypy/branch/prolog-jit-experiments/pypy/lang/prolog/interpreter/interactive.py	(original)
+++ pypy/branch/prolog-jit-experiments/pypy/lang/prolog/interpreter/interactive.py	Sat May 19 10:38:05 2007
@@ -36,7 +36,7 @@
         self.var_to_pos = var_to_pos
         self.write = write
 
-    def call(self, engine):
+    def _call(self, engine):
         self.write("yes\n")
         var_representation(self.var_to_pos, engine, self.write)
         while 1:

Modified: pypy/branch/prolog-jit-experiments/pypy/lang/prolog/interpreter/test/tool.py
==============================================================================
--- pypy/branch/prolog-jit-experiments/pypy/lang/prolog/interpreter/test/tool.py	(original)
+++ pypy/branch/prolog-jit-experiments/pypy/lang/prolog/interpreter/test/tool.py	Sat May 19 10:38:05 2007
@@ -26,7 +26,7 @@
     def __init__(self):
         self.heaps = []
 
-    def call(self, engine):
+    def _call(self, engine):
         f = Heap()
         f.vars = engine.heap.vars[:]
         self.heaps.append(f)

Modified: pypy/branch/prolog-jit-experiments/pypy/lang/prolog/interpreter/translatedmain.py
==============================================================================
--- pypy/branch/prolog-jit-experiments/pypy/lang/prolog/interpreter/translatedmain.py	(original)
+++ pypy/branch/prolog-jit-experiments/pypy/lang/prolog/interpreter/translatedmain.py	Sat May 19 10:38:05 2007
@@ -19,7 +19,7 @@
         self.var_to_pos = var_to_pos
         self.write = write
 
-    def call(self, engine):
+    def _call(self, engine):
         self.write("yes\n")
         var_representation(self.var_to_pos, engine, self.write)
         while 1:



More information about the Pypy-commit mailing list