[pypy-svn] r37656 - in pypy/dist/pypy/lang/prolog: builtin interpreter

cfbolz at codespeak.net cfbolz at codespeak.net
Wed Jan 31 11:39:42 CET 2007


Author: cfbolz
Date: Wed Jan 31 11:39:37 2007
New Revision: 37656

Modified:
   pypy/dist/pypy/lang/prolog/builtin/atomconstruction.py
   pypy/dist/pypy/lang/prolog/builtin/register.py
   pypy/dist/pypy/lang/prolog/interpreter/engine.py
   pypy/dist/pypy/lang/prolog/interpreter/parsing.py
   pypy/dist/pypy/lang/prolog/interpreter/term.py
Log:
some cleanups, caching of atoms and template vars


Modified: pypy/dist/pypy/lang/prolog/builtin/atomconstruction.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/builtin/atomconstruction.py	(original)
+++ pypy/dist/pypy/lang/prolog/builtin/atomconstruction.py	Wed Jan 31 11:39:37 2007
@@ -80,7 +80,7 @@
             try:
                 try:
                     b = s.find(s1, start, stopbefore + len(s1)) # XXX -1?
-                    if b == -1:
+                    if b < 0:
                         break
                     start = b + 1
                     before.unify(term.Number(b), engine.frame)

Modified: pypy/dist/pypy/lang/prolog/builtin/register.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/builtin/register.py	(original)
+++ pypy/dist/pypy/lang/prolog/builtin/register.py	Wed Jan 31 11:39:37 2007
@@ -19,7 +19,7 @@
     code = ["def %s(engine, query, continuation):" % (funcname, )]
     if not translatable:
         code.append("    if we_are_translated():")
-        code.append("        raise error.UncatchableError('does not work in translated version')")
+        code.append("        raise error.UncatchableError('%s does not work in translated version')" % (name, ))
     subargs = ["engine"]
     for i, spec in enumerate(unwrap_spec):
         varname = "var%s" % (i, )

Modified: pypy/dist/pypy/lang/prolog/interpreter/engine.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/interpreter/engine.py	(original)
+++ pypy/dist/pypy/lang/prolog/interpreter/engine.py	Wed Jan 31 11:39:37 2007
@@ -84,7 +84,7 @@
         return self.needed_vars
 
     def newvar(self):
-        result = Var(self.maxvar)
+        result = Var(self.maxvar())
         self.extend(1)
         return result
 

Modified: pypy/dist/pypy/lang/prolog/interpreter/parsing.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/interpreter/parsing.py	(original)
+++ pypy/dist/pypy/lang/prolog/interpreter/parsing.py	Wed Jan 31 11:39:37 2007
@@ -349,7 +349,7 @@
             name = unescape(node.additional_info[1:end])
         else:
             name = node.additional_info
-        return Atom(name)
+        return Atom.make_atom(name)
 
     def visit_VAR(self, node):
         from pypy.lang.prolog.interpreter.term import Var
@@ -399,7 +399,7 @@
         node = node.children[1]
         if len(node.children) == 1:
             l = self.build_list(node)
-            start = Atom("[]")
+            start = Atom.make_atom("[]")
         else:
             l = self.build_list(node.children[0])
             start = self.visit(node.children[2])

Modified: pypy/dist/pypy/lang/prolog/interpreter/term.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/interpreter/term.py	(original)
+++ pypy/dist/pypy/lang/prolog/interpreter/term.py	Wed Jan 31 11:39:37 2007
@@ -48,6 +48,9 @@
     def get_deeper_unify_hash(self, frame=None):
         return [self.get_unify_hash(frame)]
 
+    def basic_unify(self, other, frame):
+        pass
+
     def unify(self, other, frame, occurs_check=False):
         pass
     unify._annspecialcase_ = "specialize:arg(3)"
@@ -66,12 +69,15 @@
         return not (self == other)
 
 
-class Var(PrologObject, UnboxedValue):
+class Var(PrologObject):#, UnboxedValue):
     TAG = 0
     STANDARD_ORDER = 0
 
     __slots__ = ('index', )
 
+    def __init__(self, index):
+        self.index = index
+
     def unify(self, other, frame, occurs_check=False):
         #debug_print("unify", self, other, frame.vars)
         self, val = self.get_last_var_in_chain_and_val(frame)
@@ -150,10 +156,10 @@
     
     def make_template(self, vars_new_indexes):
         if self.index in vars_new_indexes:
-            return TemplateVar(vars_new_indexes[self.index])
+            return TemplateVar.make_templatevar(vars_new_indexes[self.index])
         index = len(vars_new_indexes)
         vars_new_indexes[self.index] = index
-        return TemplateVar(index)
+        return TemplateVar.make_templatevar(index)
 
     def get_unify_hash(self, frame=None):
         if frame is None:
@@ -179,6 +185,7 @@
     TAG = 0
     STANDARD_ORDER = 0
     __slots__ = 'index'
+    cache = []
 
     def __init__(self, index):
         self.index = index
@@ -203,7 +210,7 @@
         return self.index
 
     def clone(self, offset):
-        return TemplateVar(self.index + offset)
+        return TemplateVar.make_template(self.index + offset)
 
     def clone_compress_vars(self, vars_new_indexes, offset):
         raise UncatchableError("TemplateVar in wrong place")
@@ -223,6 +230,14 @@
     def __repr__(self):
         return "TemplateVar(%s)" % (self.index, )
 
+    def make_templatevar(index):
+        l = len(TemplateVar.cache)
+        if index >= l:
+            TemplateVar.cache.extend(
+                [TemplateVar(i) for i in range(l, l + index + 1)])
+        return TemplateVar.cache[index]
+    make_templatevar = staticmethod(make_templatevar)
+
 
 class Callable(PrologObject):
     name = ""
@@ -234,6 +249,9 @@
 class Atom(Callable):
     TAG = tag()
     STANDARD_ORDER = 1
+
+    cache = {}
+
     def __init__(self, name):
         self.name = name
         self.signature = self.name + "/0"
@@ -244,15 +262,17 @@
     def __repr__(self):
         return "Atom(%r)" % (self.name,)
 
+    def basic_unify(self, other, frame):
+        if isinstance(other, Atom):
+            if self is other or other.name == self.name:
+                return
+        raise UnificationFailed
+
     def unify(self, other, frame, occurs_check=False):
         #debug_print("unify", self, other, type(other))
         if isinstance(other, Var):
             return other.unify(self, frame, occurs_check)
-        elif isinstance(other, Atom):
-            if other.name != self.name:
-                raise UnificationFailed
-            return
-        raise UnificationFailed
+        return self.basic_unify(other, frame)
     unify._annspecialcase_ = "specialize:arg(3)"
 
     def unify_with_template(self, other, frame, template_frame, to_instantiate):
@@ -260,11 +280,7 @@
             return other.unify_with_template(self, frame, template_frame, to_instantiate)
         elif isinstance(other, TemplateVar):
             return other.unify_with_template(self, frame, template_frame, to_instantiate)
-        elif isinstance(other, Atom):
-            if other.name != self.name:
-                raise UnificationFailed
-            return
-        raise UnificationFailed
+        return self.basic_unify(other, frame)
 
     def get_unify_hash(self, frame=None):
         return intmask(hash(self.name) << TAGBITS | self.TAG)
@@ -272,21 +288,32 @@
     def get_prolog_signature(self):
         return Term("/", [self, Number(0)])
 
+    def make_atom(name):
+        result = Atom.cache.get(name, None)
+        if result is not None:
+            return result
+        Atom.cache[name] = result = Atom(name)
+        return result
+    make_atom = staticmethod(make_atom)
+
 class Number(PrologObject):
     TAG = tag()
     STANDARD_ORDER = 2
     def __init__(self, num):
         self.num = num
- 
-    def unify(self, other, frame, occurs_check=False):
-        #debug_print("unify", self, other, type(other))
-        if isinstance(other, Var):
-            return other.unify(self, frame, occurs_check)
-        elif isinstance(other, Number):
+
+    def basic_unify(self, other, frame):
+        if isinstance(other, Number):
             if other.num != self.num:
                 raise UnificationFailed
             return
         raise UnificationFailed
+
+    def unify(self, other, frame, occurs_check=False):
+        #debug_print("unify", self, other, type(other))
+        if isinstance(other, Var):
+            return other.unify(self, frame, occurs_check)
+        return self.basic_unify(other, frame)
     unify._annspecialcase_ = "specialize:arg(3)"
 
     def unify_with_template(self, other, frame, template_frame, to_instantiate):
@@ -294,11 +321,7 @@
             return other.unify_with_template(self, frame, template_frame, to_instantiate)
         elif isinstance(other, TemplateVar):
             return other.unify_with_template(self, frame, template_frame, to_instantiate)
-        elif isinstance(other, Number):
-            if other.num != self.num:
-                raise UnificationFailed
-            return
-        raise UnificationFailed
+        return self.basic_unify(other, frame)
 
     def __str__(self):
         return repr(self.num)
@@ -316,14 +339,24 @@
     def __init__(self, num):
         self.num = num
 
-    def unify(self, other, frame, occurs_check=False):
-        if isinstance(other, Var):
-            return other.unify(self, frame, occurs_check)
-        elif isinstance(other, Float):
+    def basic_unify(self, other, frame):
+        if isinstance(other, Float):
+            if other.num != self.num:
+                raise UnificationFailed
+            return
+        raise UnificationFailed
+
+    def basic_unify(self, other, frame):
+        if isinstance(other, Float):
             if other.num != self.num:
                 raise UnificationFailed
             return
         raise UnificationFailed
+
+    def unify(self, other, frame, occurs_check=False):
+        if isinstance(other, Var):
+            return other.unify(self, frame, occurs_check)
+        return self.basic_unify(other, frame)
     unify._annspecialcase_ = "specialize:arg(3)"
 
     def unify_with_template(self, other, frame, template_frame, to_instantiate):
@@ -331,11 +364,7 @@
             return other.unify_with_template(self, frame, template_frame, to_instantiate)
         elif isinstance(other, TemplateVar):
             return other.unify_with_template(self, frame, template_frame, to_instantiate)
-        elif isinstance(other, Float):
-            if other.num != self.num:
-                raise UnificationFailed
-            return
-        raise UnificationFailed
+        return self.basic_unify(other, frame)
 
     def get_unify_hash(self, frame=None):
         #XXX no clue whether this is a good idea...
@@ -456,7 +485,7 @@
         return result
 
     def get_prolog_signature(self):
-        return Term("/", [Atom(self.name), Number(len(self.args))])
+        return Term("/", [Atom.make_atom(self.name), Number(len(self.args))])
     
     def contains_var(self, var, frame):
         for arg in self.args:



More information about the Pypy-commit mailing list