[pypy-svn] r44129 - in pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Mon Jun 11 00:37:10 CEST 2007


Author: cfbolz
Date: Mon Jun 11 00:37:09 2007
New Revision: 44129

Modified:
   pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/compiler.py
   pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/engine.py
   pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/interpreter.py
   pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/test/test_compiler.py
   pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/test/test_interpreter.py
Log:
don't even build the Term instances


Modified: pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/compiler.py
==============================================================================
--- pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/compiler.py	(original)
+++ pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/compiler.py	Mon Jun 11 00:37:09 2007
@@ -1,4 +1,4 @@
-from pypy.lang.prolog.interpreter.term import NonVar, Term, Var, Atom
+from pypy.lang.prolog.interpreter.term import NonVar, Term, Var, Atom, Callable
 from pypy.lang.prolog.interpreter.engine import Continuation
 from pypy.lang.prolog.interpreter import helper, error
 from pypy.lang.prolog.interpreter.prologopcode import opcodedesc
@@ -49,7 +49,9 @@
         self.can_contain_cut = False
         result = Code()
         self.activate_vars_later = True
-        self.compile_termbuilding(head)
+        if isinstance(head, Term):
+            for arg in head.args:
+                self.compile_termbuilding(arg)
         result.opcode_head = self.getbytecode()
         if body is not None:
             self.add_localactivations()
@@ -106,8 +108,10 @@
                     self.compile_termbuilding(arg)
             self.emit_opcode(opcodedesc.CALL_BUILTIN, i)
         else:
-            self.compile_termbuilding(body)
-            num = self.getfunction(body.signature)
+            if isinstance(body, Term):
+                for arg in body.args:
+                    self.compile_termbuilding(arg)
+            num = self.getfunction(body)
             self.emit_opcode(opcodedesc.STATIC_CALL, num)
 
     def compile_localvar(self, var):
@@ -160,12 +164,15 @@
             self.constants.append(const)
             return result
 
-    def getfunction(self, signature):
+    def getfunction(self, query):
+        assert isinstance(query, Callable)
+        signature = query.signature
         try:
             return self.functionmap[signature]
         except KeyError:
             result = len(self.functionmap)
             self.functionmap[signature] = result
-            self.functions.append(self.engine.lookup_userfunction(signature))
+            self.functions.append(self.engine.lookup_userfunction(
+                signature, query.get_prolog_signature()))
             return result
 

Modified: pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/engine.py
==============================================================================
--- pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/engine.py	(original)
+++ pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/engine.py	Mon Jun 11 00:37:09 2007
@@ -98,7 +98,9 @@
 
 
 class Function(object):
-    def __init__(self, firstrule=None):
+    def __init__(self, signature, prolog_signature, firstrule=None):
+        self.signature = signature
+        self.prolog_signature = prolog_signature
         if firstrule is None:
             self.rulechain = self.last = None
         else:
@@ -154,7 +156,8 @@
         if function is not None:
             self.signature2function[signature].add_rule(rule, end)
         else:
-            self.signature2function[signature] = Function(rule)
+            self.signature2function[signature] = Function(
+                signature, rule.head.get_prolog_signature(), rule)
 
     def run(self, query, continuation=DONOTHING):
         from pypy.lang.prolog.interpreter.interpreter import dynamic_call_frame
@@ -186,12 +189,13 @@
         #XXX handle choice_point correctly
         return frame.run_directly(continuation, choice_point)
 
-    @purefunction
-    def lookup_userfunction(self, signature):
+    def lookup_userfunction(self, signature, prolog_signature=None):
         signature2function = self.signature2function
         function = signature2function.get(signature, None)
         if function is None:
-            signature2function[signature] = function = Function()
+            assert prolog_signature is not None
+            signature2function[signature] = function = Function(
+                signature, prolog_signature)
         return function
 
     def continue_after_cut(self, continuation, lsc=None):

Modified: pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/interpreter.py
==============================================================================
--- pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/interpreter.py	(original)
+++ pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/interpreter.py	Mon Jun 11 00:37:09 2007
@@ -33,9 +33,9 @@
         self.signature = self.head.signature
         self.engine = engine
 
-    def make_frame(self, head):
+    def make_frame(self, stack):
         f = Frame(self.engine, self.code)
-        f.unify_head(head)
+        f.unify_head(stack)
         return f
 
     def __repr__(self):
@@ -64,16 +64,17 @@
     def getcode(self):
         return hint(hint(self.code, promote=True), deepfreeze=True)
 
-    def unify_head(self, head):
+    def unify_head(self, stack):
         self.run(self.getcode(), True, 0, None)
-        if isinstance(head, Term):
-            result = self.result
-            assert isinstance(result, Term)
+        result = self.result
+        if len(result):
             i = 0
-            m = hint(len(head.args), promote=True)
+            # These should be early constants, really
+            m = hint(len(result), promote=True)
+            startfrom = hint(len(stack) - m, promote=True)
             while i < m:
                 hint(i, concrete=True)
-                result.args[i].unify(head.args[i], self.heap)
+                result[i].unify(stack[startfrom + i], self.heap)
                 i += 1
         self.result = None
 
@@ -162,7 +163,7 @@
                     else:
                         continuation = continuation._call(self.engine)
         if head:
-            self.result = stack[0]
+            self.result = stack
         return continuation
 
     def _run(self, codeobject, head, pc, continuation):
@@ -204,7 +205,7 @@
                     else:
                         continuation = continuation._call(self.engine)
         if head:
-            self.result = stack[0]
+            self.result = stack
         return continuation
 
 
@@ -278,9 +279,8 @@
         raise error.CutException(continuation)
     
     def STATIC_CALL(self, stack, number, continuation):
-        query = stack.pop()
         function = self.getcode().functions[number]
-        return self.user_call(function, query, continuation)
+        return self.user_call(function, stack, continuation)
 
     def DYNAMIC_CALL(self, stack, continuation):
         query = stack.pop()
@@ -294,8 +294,13 @@
             else:
                 args = None
             return builtin.call(self.engine, args, continuation)
-        function = self.engine.lookup_userfunction(signature)
-        return self.user_call(function, query, continuation)
+        function = self.engine.lookup_userfunction(
+            signature, query.get_prolog_signature())
+        if isinstance(query, Term):
+            args = query.args
+        else:
+            args = None
+        return self.user_call(function, args, continuation)
 
     def CLEAR_LOCAL(self, stack, number):
         self.localvarcache[number] = None
@@ -303,13 +308,12 @@
     def UNIFY(self, stack):
         stack.pop().unify(stack.pop(), self.heap)
 
-    def user_call(self, function, query, continuation):
-        assert isinstance(query, Callable)
+    def user_call(self, function, args, continuation):
         rulechain = function.rulechain
         rulechain = hint(rulechain, promote=True)
         if rulechain is None:
             error.throw_existence_error(
-                "procedure", query.get_prolog_signature())
+                "procedure", function.prolog_signature)
         oldstate = self.heap.branch()
         while rulechain is not None:
             rule = rulechain.rule
@@ -318,7 +322,7 @@
             if rule.code.can_contain_cut:
                 continuation = LimitedScopeContinuation(continuation)
                 try:
-                    frame = rule.make_frame(query)
+                    frame = rule.make_frame(args)
                     result = frame.run_directly(continuation)
                     return result
                 except error.UnificationFailed:
@@ -330,7 +334,7 @@
                     raise
             else:
                 try:
-                    frame = rule.make_frame(query)
+                    frame = rule.make_frame(args)
                     result = frame.run_directly(continuation, choice_point)
                     return result
                 except error.UnificationFailed:

Modified: pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/test/test_compiler.py
==============================================================================
--- pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/test/test_compiler.py	(original)
+++ pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/test/test_compiler.py	Mon Jun 11 00:37:09 2007
@@ -7,8 +7,8 @@
     foo = Atom("foo")
     code = compile(foo, None, e)
     assert not code.opcode
-    assert code.opcode_head == "c\x00\x00"
-    assert code.constants == [foo]
+    assert code.opcode_head == ""
+    assert code.constants == []
     assert not code.can_contain_cut
 
 def test_simple_withbody():
@@ -16,37 +16,37 @@
     foo = Atom("foo")
     bar = Atom("bar")
     code = compile(foo, bar, e)
-    assert code.opcode_head == "c\x00\x00"
-    assert code.opcode == "c\x00\x01s\x00\x00"
-    assert code.constants == [foo, bar]
+    assert code.opcode_head == ""
+    assert code.opcode == "s\x00\x00"
+    assert code.constants == []
     assert not code.can_contain_cut
 
 def test_simple_withargs():
     e = get_engine("")
     head, body = get_query_and_vars("f(X) :- g(X).")[0].args
     code = compile(head, body, e)
-    assert code.opcode_head == "m\x00\x00t\x00\x00"
-    assert code.opcode == "a\x00\x00l\x00\x00t\x00\x01s\x00\x00"
+    assert code.opcode_head == "m\x00\x00"
+    assert code.opcode == "a\x00\x00l\x00\x00s\x00\x00"
     assert code.constants == []
-    assert code.term_info == [("f", 1, "f/1"), ("g", 1, "g/1")]
+    assert code.term_info == []
     assert not code.can_contain_cut
 
 def test_simple_and():
     e = get_engine("")
     head, body = get_query_and_vars("f(X, Y) :- g(X), h(Y).")[0].args
     code = compile(head, body, e)
-    assert code.opcode_head == "m\x00\x00m\x00\x01t\x00\x00"
-    assert code.opcode == "a\x00\x00a\x00\x01l\x00\x00t\x00\x01s\x00\x00l\x00\x01t\x00\x02s\x00\x01"
+    assert code.opcode_head == "m\x00\x00m\x00\x01"
+    assert code.opcode == "a\x00\x00a\x00\x01l\x00\x00s\x00\x00l\x00\x01s\x00\x01"
     assert code.constants == []
-    assert code.term_info == [("f", 2, "f/2"), ("g", 1, "g/1"), ("h", 1, "h/1")]
+    assert code.term_info == []
     assert not code.can_contain_cut
 
 def test_nested_term():
     e = get_engine("")
     head = get_query_and_vars("f(g(X), a).")[0]
     code = compile(head, None, e)
-    assert code.opcode_head == "m\x00\x00t\x00\x00c\x00\x00t\x00\x01"
-    assert code.term_info == [("g", 1, "g/1"), ("f", 2, "f/2")]
+    assert code.opcode_head == "m\x00\x00t\x00\x00c\x00\x00"
+    assert code.term_info == [("g", 1, "g/1")]
     assert code.constants == [Atom("a")]
     assert not code.can_contain_cut
 
@@ -54,28 +54,28 @@
     e = get_engine("")
     head, body = get_query_and_vars("f(X, Y) :- g(X) = g(Y).")[0].args
     code = compile(head, body, e)
-    assert code.opcode_head == "m\x00\x00m\x00\x01t\x00\x00"
-    assert code.opcode == "a\x00\x00a\x00\x01l\x00\x00t\x00\x01l\x00\x01t\x00\x01U"
+    assert code.opcode_head == "m\x00\x00m\x00\x01"
+    assert code.opcode == "a\x00\x00a\x00\x01l\x00\x00t\x00\x00l\x00\x01t\x00\x00U"
     assert code.constants == []
-    assert code.term_info == [("f", 2, "f/2"), ("g", 1, "g/1")]
+    assert code.term_info == [("g", 1, "g/1")]
     assert not code.can_contain_cut
 
 def test_dynamic_call():
     e = get_engine("")
     head, body = get_query_and_vars("f(X, Y) :- X, call(Y).")[0].args
     code = compile(head, body, e)
-    assert code.opcode_head == "m\x00\x00m\x00\x01t\x00\x00"
+    assert code.opcode_head == "m\x00\x00m\x00\x01"
     assert code.opcode.startswith("a\x00\x00a\x00\x01l\x00\x00Dl\x00\x01b")
-    assert code.term_info == [("f", 2, "f/2")]
+    assert code.term_info == []
     assert code.can_contain_cut
 
 def test_cut():
     e = get_engine("")
     head, body = get_query_and_vars("f(X, Y) :- !.")[0].args
     code = compile(head, body, e)
-    assert code.opcode_head == "m\x00\x00m\x00\x01t\x00\x00"
+    assert code.opcode_head == "m\x00\x00m\x00\x01"
     assert code.opcode == "a\x00\x00a\x00\x01C"
-    assert code.term_info == [("f", 2, "f/2")]
+    assert code.term_info == []
     assert code.can_contain_cut
 
 def test_arithmetic():
@@ -83,10 +83,10 @@
     e = get_engine("")
     head, body = get_query_and_vars("f(X) :- Y is X - 1, f(Y).")[0].args
     code = compile(head, body, e)
-    assert code.opcode_head == "m\x00\x00t\x00\x00"
+    assert code.opcode_head == "m\x00\x00"
     assert code.opcode.startswith(
-        "a\x00\x00m\x00\x01a\x00\x01l\x00\x00c\x00\x00t\x00\x01b")
+        "a\x00\x00m\x00\x01a\x00\x01l\x00\x00c\x00\x00t\x00\x00b")
     assert code.constants == [Number(1)]
-    assert code.term_info == [("f", 1, "f/1"), ("-", 2, "-/2")]
+    assert code.term_info == [("-", 2, "-/2")]
     assert not code.can_contain_cut
  

Modified: pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/test/test_interpreter.py
==============================================================================
--- pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/test/test_interpreter.py	(original)
+++ pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/test/test_interpreter.py	Mon Jun 11 00:37:09 2007
@@ -7,14 +7,14 @@
     head, body = get_query_and_vars("f(X) :- X = a.")[0].args
     r = Rule(head, body, e)
     query = get_query_and_vars("f(a).")[0]
-    frame = r.make_frame(query)
+    frame = r.make_frame(query.args)
     assert frame.localvarcache[0].dereference(e.heap).name == "a"
     cont = object()
     c2 = frame.run(frame.code, False, 0, cont)
     assert cont is c2
 
     query, vars = get_query_and_vars("f(X).")
-    frame = r.make_frame(query)
+    frame = r.make_frame(query.args)
     cont = object()
     c2 = frame.run(frame.code, False, 0, cont)
     assert cont is c2
@@ -28,5 +28,5 @@
     frame = Frame(e, r.code)
     frame.run(frame.code, True, 0, None)
     frame.run(frame.code, False, 0, None)
-    assert frame.result.args[0].dereference(e.heap).name == "a"
-    assert frame.result.args[1].dereference(e.heap).name == "b"
+    assert frame.result[0].dereference(e.heap).name == "a"
+    assert frame.result[1].dereference(e.heap).name == "b"



More information about the Pypy-commit mailing list