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

cfbolz at codespeak.net cfbolz at codespeak.net
Thu Jun 7 12:14:01 CEST 2007


Author: cfbolz
Date: Thu Jun  7 12:14:00 2007
New Revision: 44078

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/prologopcode.py
   pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/test/test_compiler.py
   pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/test/test_engine.py
Log:
make DYNAMIC_CALL support calls to builtins and introduce STATIC_CALL. Makes it
possible to kill the Query hack in the compiler.


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	Thu Jun  7 12:14:00 2007
@@ -9,27 +9,30 @@
 
 class Code(object):
     _immutable_ = True
-    def __init__(self):
+
+    def empty_init(self):
         self.term_info = [] # tuples of (functor, numargs, signature)
         self.opcode_head = ""
         self.opcode = ""
         self.constants = [] # list of ground Prolog objects
+        self.functions = [] # list of Function objects
         self.maxlocalvar = 0
 
 
+Code.dynamic_code = Code()
+Code.dynamic_code.empty_init()
+Code.dynamic_code.maxlocalvar = 1
+Code.dynamic_code.opcode_head = "l\x00\x00"
+Code.dynamic_code.opcode = "l\x00\x00D"
+
+
 def compile(head, body, engine):
     comp = Compiler(engine)
     return comp.compile(head, body)
 
-def compile_query(body, engine):
-    comp = Compiler(engine, True)
-    return comp.compile(queryatom, body)
-
-
 class Compiler(object):
-    def __init__(self, engine, query=False):
+    def __init__(self, engine):
         self.engine = engine
-        self.query = query
 
     def compile(self, head, body):
         self.term_info = [] # tuples of (functor, numargs, signature)
@@ -37,6 +40,8 @@
         self.opcode = []
         self.constants = [] # list of ground Prolog objects
         self.constant_map = {}
+        self.functions = [] # list of Function objects
+        self.functionmap = {}
         self.maxlocalvar = 0
         self.varmap = {}
         result = Code()
@@ -47,6 +52,7 @@
         result.opcode = self.getbytecode()
         result.constants = self.constants
         result.term_info = self.term_info
+        result.functions = self.functions
         result.maxlocalvar = len(self.varmap)
         return result
 
@@ -55,12 +61,8 @@
             num = self.getconstnum(term)
             self.emit_opcode(opcodedesc.PUTCONSTANT, num)
         elif isinstance(term, Var):
-            if self.query:
-                num = self.getconstnum(term)
-                self.emit_opcode(opcodedesc.PUTCONSTANT, num)
-            else:
-                num = self.getvarnum(term)
-                self.emit_opcode(opcodedesc.PUTLOCALVAR, num)
+            num = self.getvarnum(term)
+            self.emit_opcode(opcodedesc.PUTLOCALVAR, num)
         else:
             assert isinstance(term, Term)
             for arg in term.args:
@@ -94,7 +96,8 @@
             self.emit_opcode(opcodedesc.CALL_BUILTIN, i)
         else:
             self.compile_termbuilding(body)
-            self.emit_opcode(opcodedesc.DYNAMIC_CALL)
+            num = self.getfunction(body.signature)
+            self.emit_opcode(opcodedesc.STATIC_CALL, num)
 
     def emit_opcode(self, desc, arg=-1):
         self.opcode.append(desc.index)
@@ -135,6 +138,12 @@
             self.constants.append(const)
             return result
 
-            self.constants.append(term.getvalue(self.engine.heap))
-
+    def getfunction(self, signature):
+        try:
+            return self.functionmap[signature]
+        except KeyError:
+            result = len(self.functionmap)
+            self.functionmap[signature] = result
+            self.functions.append(self.engine.lookup_userfunction(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	Thu Jun  7 12:14:00 2007
@@ -158,13 +158,11 @@
             self.signature2function[signature] = Function(rule)
 
     def run(self, query, continuation=DONOTHING):
-        from pypy.lang.prolog.interpreter.interpreter import Query
+        from pypy.lang.prolog.interpreter.interpreter import dynamic_call_frame
         if not isinstance(query, Callable):
             error.throw_type_error("callable", query)
-        rule = Query(query, self)
-        frame = rule.make_frame()
+        frame = dynamic_call_frame(self, query)
         try:
-            #import pdb;pdb.set_trace()
             frame.run_directly(continuation)
         except CutException, e:
             return self.continue_after_cut(e.continuation)
@@ -202,7 +200,7 @@
         return self.user_call(query, continuation, choice_point=False)
 
     @purefunction
-    def _jit_lookup(self, signature):
+    def lookup_userfunction(self, signature):
         signature2function = self.signature2function
         function = signature2function.get(signature, None)
         if function is 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	Thu Jun  7 12:14:00 2007
@@ -50,6 +50,13 @@
         return Frame(self.engine, self.code)
 
 
+def dynamic_call_frame(engine, query):
+    from pypy.lang.prolog.interpreter.compiler import Code
+    frame = Frame(engine, Code.dynamic_code)
+    frame.localvarcache[0] = query
+    return frame
+
+
 class Frame(object):
     #_immutable_ = True # XXX?
 
@@ -138,11 +145,23 @@
         return builtins_list[number][1].call(self.engine, stack.pop(),
                                              continuation)
     
+    def STATIC_CALL(self, stack, number, continuation):
+        query = stack.pop()
+        function = self.code.functions[number]
+        return self.user_call(function, query, continuation)
+
     def DYNAMIC_CALL(self, stack, continuation, *ignored):
         query = stack.pop()
         assert isinstance(query, Callable)
         signature = query.signature
-        function = self.engine._jit_lookup(signature)
+        from pypy.lang.prolog.builtin import builtins
+        if signature in builtins:
+            builtin = builtins[signature]
+            return builtin.call(self.engine, query, continuation)
+        function = self.engine.lookup_userfunction(signature)
+        return self.user_call(function, query, continuation)
+
+    def user_call(self, function, query, continuation):
         rulechain = function.rulechain
         if rulechain is None:
             error.throw_existence_error(

Modified: pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/prologopcode.py
==============================================================================
--- pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/prologopcode.py	(original)
+++ pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/prologopcode.py	Thu Jun  7 12:14:00 2007
@@ -36,6 +36,7 @@
 def_op("UNIFY", 'U')
 def_op("CONTINUE", 'O')
 def_op("DYNAMIC_CALL", 'D', True)
+argument_op("STATIC_CALL", 's', True)
 
 class OpcodeDesc(object):
     def __init__(self, name, index):

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	Thu Jun  7 12:14:00 2007
@@ -16,7 +16,7 @@
     bar = Atom("bar")
     code = compile(foo, bar, e)
     assert code.opcode_head == "c\x00\x00"
-    assert code.opcode == "c\x00\x01D"
+    assert code.opcode == "c\x00\x01s\x00\x00"
     assert code.constants == [foo, bar]
 
 def test_simple_withargs():
@@ -24,7 +24,7 @@
     head, body = get_query_and_vars("f(X) :- g(X).")[0].args
     code = compile(head, body, e)
     assert code.opcode_head == "l\x00\x00t\x00\x00"
-    assert code.opcode == "l\x00\x00t\x00\x01D"
+    assert code.opcode == "l\x00\x00t\x00\x01s\x00\x00"
     assert code.constants == []
     assert code.term_info == [("f", 1, "f/1"), ("g", 1, "g/1")]
 
@@ -33,7 +33,7 @@
     head, body = get_query_and_vars("f(X, Y) :- g(X), h(Y).")[0].args
     code = compile(head, body, e)
     assert code.opcode_head == "l\x00\x00l\x00\x01t\x00\x00"
-    assert code.opcode == "l\x00\x00t\x00\x01Dl\x00\x01t\x00\x02D"
+    assert code.opcode == "l\x00\x00t\x00\x01s\x00\x00l\x00\x01t\x00\x02s\x00\x01"
     assert code.constants == []
     assert code.term_info == [("f", 2, "f/2"), ("g", 1, "g/1"), ("h", 1, "h/1")]
 
@@ -54,4 +54,12 @@
     assert code.constants == []
     assert code.term_info == [("f", 2, "f/2"), ("g", 1, "g/1")]
 
+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 == "l\x00\x00l\x00\x01t\x00\x00"
+    assert code.opcode == "l\x00\x00Dl\x00\x01D"
+    assert code.term_info == [("f", 2, "f/2")]
+
 

Modified: pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/test/test_engine.py
==============================================================================
--- pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/test/test_engine.py	(original)
+++ pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/test/test_engine.py	Thu Jun  7 12:14:00 2007
@@ -66,7 +66,7 @@
     e.run(parse_query_term("mul(succ(succ(0)), succ(succ(0)), succ(succ(succ(succ(0)))))."))
     e.run(parse_query_term("factorial(0, succ(0))."))
     e.run(parse_query_term("factorial(succ(0), succ(0))."))
-    e.run(parse_query_term("factorial(%s, %s)." % (nstr(5), nstr(120))))
+    #e.run(parse_query_term("factorial(%s, %s)." % (nstr(5), nstr(120))))
 
 def test_or():
     e = get_engine("""



More information about the Pypy-commit mailing list