[pypy-svn] r44127 - in pypy/branch/prolog-bytecode/pypy/lang/prolog: builtin interpreter interpreter/test

cfbolz at codespeak.net cfbolz at codespeak.net
Sun Jun 10 20:37:37 CEST 2007


Author: cfbolz
Date: Sun Jun 10 20:37:37 2007
New Revision: 44127

Modified:
   pypy/branch/prolog-bytecode/pypy/lang/prolog/builtin/register.py
   pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/compiler.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_parsing.py
Log:
don't create the complete Term instance for builtin calls, just build the
arguments (which are usually already there in one form or the other).


Modified: pypy/branch/prolog-bytecode/pypy/lang/prolog/builtin/register.py
==============================================================================
--- pypy/branch/prolog-bytecode/pypy/lang/prolog/builtin/register.py	(original)
+++ pypy/branch/prolog-bytecode/pypy/lang/prolog/builtin/register.py	Sun Jun 10 20:37:37 2007
@@ -15,8 +15,8 @@
         self.signature = signature
         self.handles_continuation = handles_continuation
 
-    def call(self, engine, query, continuation):
-        return self.function(engine, query, continuation)
+    def call(self, engine, args, continuation):
+        return self.function(engine, args, continuation)
         
     def _freeze_(self):
         return True
@@ -31,24 +31,24 @@
     if not name.isalnum():
         name = func.func_name
     funcname = "wrap_%s_%s" % (name, len(unwrap_spec))
-    code = ["def %s(engine, query, continuation):" % (funcname, )]
+    code = ["def %s(engine, stack, continuation):" % (funcname, )]
     if not translatable:
         code.append("    if we_are_translated():")
         code.append("        raise error.UncatchableError('%s does not work in translated version')" % (name, ))
     subargs = ["engine"]
-    if len(unwrap_spec):
-        code.append("    assert isinstance(query, term.Term)")
-    else:
-        code.append("    assert isinstance(query, term.Atom)")
+    if unwrap_spec:
+        code.append("    startpos = len(stack) - %s" % (len(unwrap_spec), ))
     for i, spec in enumerate(unwrap_spec):
+        rawarg = "rawarg%s" % (i, )
+        code.append("    %s = stack[startpos + %s]" % (rawarg, i))
         varname = "var%s" % (i, )
         subargs.append(varname)
         if spec in ("obj", "callable", "int", "atom", "arithmetic"):
-            code.append("    %s = query.args[%s].dereference(engine.heap)" %
-                        (varname, i))
+            code.append("    %s = %s.dereference(engine.heap)" %
+                        (varname, rawarg))
         elif spec in ("concrete", "list"):
-            code.append("    %s = query.args[%s].getvalue(engine.heap)" %
-                        (varname, i))
+            code.append("    %s = %s.getvalue(engine.heap)" %
+                        (varname, rawarg))
         if spec in ("int", "atom", "arithmetic", "list"):
             code.append(
                 "    if isinstance(%s, term.Var):" % (varname,))
@@ -64,7 +64,7 @@
             code.append(
                 "        error.throw_type_error('callable', %s)" % (varname,))
         elif spec == "raw":
-            code.append("    %s = query.args[%s]" % (varname, i))
+            code.append("    %s = %s" % (varname, rawarg))
         elif spec == "int":
             code.append("    %s = helper.unwrap_int(%s)" % (varname, varname))
         elif spec == "atom":

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	Sun Jun 10 20:37:37 2007
@@ -101,7 +101,9 @@
             self.emit_opcode(opcodedesc.CUT)
         elif body.signature in builtins_index:
             i = builtins_index[body.signature]
-            self.compile_termbuilding(body)
+            if isinstance(body, Term):
+                for arg in body.args:
+                    self.compile_termbuilding(arg)
             self.emit_opcode(opcodedesc.CALL_BUILTIN, i)
         else:
             self.compile_termbuilding(body)

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	Sun Jun 10 20:37:37 2007
@@ -257,8 +257,13 @@
 
     def CALL_BUILTIN(self, stack, number, continuation):
         from pypy.lang.prolog.builtin import builtins_list
-        return builtins_list[number][1].call(self.engine, stack.pop(),
-                                             continuation)
+        builtin = builtins_list[number][1]
+        result = builtin.call(self.engine, stack, continuation)
+        i = 0
+        while i < builtin.numargs:
+            hint(i, concrete=True)
+            stack.pop()
+            i += 1
 
     def CUT(self, stack, continuation):
         raise error.CutException(continuation)
@@ -275,7 +280,11 @@
         from pypy.lang.prolog.builtin import builtins
         if signature in builtins:
             builtin = builtins[signature]
-            return builtin.call(self.engine, query, continuation)
+            if isinstance(query, Term):
+                args = query.args
+            else:
+                args = None
+            return builtin.call(self.engine, args, continuation)
         function = self.engine.lookup_userfunction(signature)
         return self.user_call(function, query, continuation)
 

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	Sun Jun 10 20:37:37 2007
@@ -65,8 +65,8 @@
     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.startswith("a\x00\x00a\x00\x01l\x00\x00Dl\x00\x01t\x00\x01b")
-    assert code.term_info == [("f", 2, "f/2"), ("call", 1, "call/1")]
+    assert code.opcode.startswith("a\x00\x00a\x00\x01l\x00\x00Dl\x00\x01b")
+    assert code.term_info == [("f", 2, "f/2")]
     assert code.can_contain_cut
 
 def test_cut():
@@ -85,9 +85,8 @@
     code = compile(head, body, e)
     assert code.opcode_head == "m\x00\x00t\x00\x00"
     assert code.opcode.startswith(
-        "a\x00\x00m\x00\x01a\x00\x01l\x00\x00c\x00\x00t\x00\x01t\x00\x02b")
+        "a\x00\x00m\x00\x01a\x00\x01l\x00\x00c\x00\x00t\x00\x01b")
     assert code.constants == [Number(1)]
-    assert code.term_info == [("f", 1, "f/1"), ("-", 2, "-/2"),
-                              ("is", 2, "is/2")]
+    assert code.term_info == [("f", 1, "f/1"), ("-", 2, "-/2")]
     assert not code.can_contain_cut
  

Modified: pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/test/test_parsing.py
==============================================================================
--- pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/test/test_parsing.py	(original)
+++ pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/test/test_parsing.py	Sun Jun 10 20:37:37 2007
@@ -1,5 +1,6 @@
 from pypy.lang.prolog.interpreter.parsing import parse_file, TermBuilder, OrderTransformer
-from pypy.lang.prolog.interpreter.parsing import parse_query_term
+from pypy.lang.prolog.interpreter.parsing import parse_query_term, \
+    get_query_and_vars
 
 
 def test_simple():
@@ -34,12 +35,10 @@
     four = Term("succ", [Term("succ", [Term("succ",
                 [Term("succ", [Atom("null")])])])])
     e.run(parse_query_term("numeral(succ(succ(null)))."))
-    term = parse_query_term(
+    term, vars = get_query_and_vars(
         """add_numeral(succ(succ(null)), succ(succ(null)), X).""")
     e.run(term)
-    var = Var(0).getvalue(e.heap)
-    print var, e.heap
-    # does not raise
+    var = vars['X'].getvalue(e.heap)
     var.unify(four, e.heap)
     term = parse_query_term(
         """greater_than(succ(succ(succ(null))), succ(succ(null))).""")


More information about the pypy-svn mailing list