[pypy-svn] r44097 - in pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter: . test
cfbolz at codespeak.net
cfbolz at codespeak.net
Thu Jun 7 17:24:26 CEST 2007
Author: cfbolz
Date: Thu Jun 7 17:24:26 2007
New Revision: 44097
Modified:
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/prologopcode.py
pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/term.py
pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/test/test_compiler.py
Log:
prevent trailing for variables in the head again
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 17:24:26 2007
@@ -38,6 +38,7 @@
self.term_info = [] # tuples of (functor, numargs, signature)
self.term_info_map = {}
self.opcode = []
+ self.localactivations = []
self.constants = [] # list of ground Prolog objects
self.constant_map = {}
self.functions = [] # list of Function objects
@@ -49,6 +50,7 @@
self.compile_termbuilding(head)
result.opcode_head = self.getbytecode()
if body is not None:
+ self.add_localactivations()
self.compile_body(body)
result.opcode = self.getbytecode()
result.constants = self.constants
@@ -63,8 +65,7 @@
num = self.getconstnum(term)
self.emit_opcode(opcodedesc.PUTCONSTANT, num)
elif isinstance(term, Var):
- num = self.getvarnum(term)
- self.emit_opcode(opcodedesc.PUTLOCALVAR, num)
+ self.compile_localvar(term)
else:
assert isinstance(term, Term)
for arg in term.args:
@@ -99,32 +100,44 @@
i = builtins_index[body.signature]
self.compile_termbuilding(body)
self.emit_opcode(opcodedesc.CALL_BUILTIN, i)
+ self.add_localactivations()
else:
self.compile_termbuilding(body)
num = self.getfunction(body.signature)
self.emit_opcode(opcodedesc.STATIC_CALL, num)
+ self.add_localactivations()
- def emit_opcode(self, desc, arg=-1):
- self.opcode.append(desc.index)
+ def compile_localvar(self, var):
+ try:
+ num = self.varmap[var]
+ except KeyError:
+ num = self.varmap[var] = len(self.varmap)
+ self.emit_opcode(opcodedesc.MAKELOCALVAR, num)
+ self.emit_opcode(opcodedesc.ACTIVATE_LOCAL, num, True)
+ return
+ self.emit_opcode(opcodedesc.PUTLOCALVAR, num)
+
+ def add_localactivations(self):
+ self.opcode.extend(self.localactivations)
+ self.localactivations = []
+
+ def emit_opcode(self, desc, arg=-1, to_activations=False):
+ if to_activations:
+ opcode = self.localactivations
+ else:
+ opcode = self.opcode
+ opcode.append(desc.index)
if desc.hasargument:
if not 0 <= arg < 65536:
raise error.UncatchableError("too many constants or variables!")
- self.opcode.append(arg >> 8)
- self.opcode.append(arg & 0xff)
+ opcode.append(arg >> 8)
+ opcode.append(arg & 0xff)
def getbytecode(self):
bytecodes = [chr(c) for c in self.opcode]
self.opcode = []
return "".join(bytecodes)
-
- def getvarnum(self, var):
- try:
- return self.varmap[var]
- except KeyError:
- result = self.varmap[var] = len(self.varmap)
- return result
-
def getsignum(self, term):
try:
return self.term_info_map[term.signature]
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 17:24:26 2007
@@ -1,6 +1,7 @@
from pypy.lang.prolog.interpreter import helper
from pypy.lang.prolog.interpreter import error
-from pypy.lang.prolog.interpreter.term import Term, Atom, Var, Callable
+from pypy.lang.prolog.interpreter.term import Term, Atom, Var, Callable, \
+ LocalVar
from pypy.lang.prolog.interpreter.engine import Continuation, \
LimitedScopeContinuation, DONOTHING
from pypy.lang.prolog.interpreter.prologopcode import unrolling_opcode_descs, \
@@ -132,12 +133,21 @@
def PUTCONSTANT(self, stack, number):
stack.append(self.code.constants[number])
+ def MAKELOCALVAR(self, stack, number):
+ result = self.localvarcache[number] = self.engine.heap.newvar()
+ stack.append(result)
+
def PUTLOCALVAR(self, stack, number):
result = self.localvarcache[number]
- if result is None:
- result = self.localvarcache[number] = self.engine.heap.newvar()
+ assert result is not None
stack.append(result)
+ def ACTIVATE_LOCAL(self, stack, number):
+ var = self.localvarcache[number]
+ if isinstance(var, LocalVar):
+ self.localvarcache[number] = var.dereference(self.heap)
+ var.active = True
+
def MAKETERM(self, stack, number):
name, numargs, signature = self.code.term_info[number]
args = [None] * numargs
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 17:24:26 2007
@@ -28,6 +28,8 @@
# term construction
argument_op("PUTCONSTANT", 'c')
argument_op("PUTLOCALVAR", 'l')
+argument_op("MAKELOCALVAR", 'm')
+argument_op("ACTIVATE_LOCAL", 'a')
argument_op("MAKETERM", 't')
# running
Modified: pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/term.py
==============================================================================
--- pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/term.py (original)
+++ pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/term.py Thu Jun 7 17:24:26 2007
@@ -165,6 +165,19 @@
return self.eval_arithmetic(engine)
+class LocalVar(Var):
+ __slots__ = ("binding", "active")
+
+ def __init__(self):
+ self.binding = None
+ self.active = False
+
+ def setvalue(self, value, heap):
+ if self.active:
+ heap.add_trail(self)
+ self.binding = value
+
+
class NonVar(PrologObject):
__slots__ = ()
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 17:24:26 2007
@@ -25,8 +25,8 @@
e = get_engine("")
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\x01s\x00\x00"
+ assert code.opcode_head == "m\x00\x00t\x00\x00"
+ assert code.opcode == "a\x00\x00l\x00\x00t\x00\x01s\x00\x00"
assert code.constants == []
assert code.term_info == [("f", 1, "f/1"), ("g", 1, "g/1")]
assert not code.can_contain_cut
@@ -35,8 +35,8 @@
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 == "l\x00\x00l\x00\x01t\x00\x00"
- assert code.opcode == "l\x00\x00t\x00\x01s\x00\x00l\x00\x01t\x00\x02s\x00\x01"
+ 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.constants == []
assert code.term_info == [("f", 2, "f/2"), ("g", 1, "g/1"), ("h", 1, "h/1")]
assert not code.can_contain_cut
@@ -45,7 +45,7 @@
e = get_engine("")
head = get_query_and_vars("f(g(X), a).")[0]
code = compile(head, None, e)
- assert code.opcode_head == "l\x00\x00t\x00\x00c\x00\x00t\x00\x01"
+ 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.constants == [Atom("a")]
assert not code.can_contain_cut
@@ -54,8 +54,8 @@
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 == "l\x00\x00l\x00\x01t\x00\x00"
- assert code.opcode == "l\x00\x00t\x00\x01l\x00\x01t\x00\x01U"
+ 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.constants == []
assert code.term_info == [("f", 2, "f/2"), ("g", 1, "g/1")]
assert not code.can_contain_cut
@@ -64,8 +64,8 @@
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.startswith("l\x00\x00Dl\x00\x01t\x00\x01b")
+ 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.can_contain_cut
@@ -73,8 +73,8 @@
e = get_engine("")
head, body = get_query_and_vars("f(X, Y) :- !.")[0].args
code = compile(head, body, e)
- assert code.opcode_head == "l\x00\x00l\x00\x01t\x00\x00"
- assert code.opcode == "C"
+ assert code.opcode_head == "m\x00\x00m\x00\x01t\x00\x00"
+ assert code.opcode == "a\x00\x00a\x00\x01C"
assert code.term_info == [("f", 2, "f/2")]
assert code.can_contain_cut
@@ -83,9 +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 == "l\x00\x00t\x00\x00"
+ assert code.opcode_head == "m\x00\x00t\x00\x00"
assert code.opcode.startswith(
- "l\x00\x01l\x00\x00c\x00\x00t\x00\x01t\x00\x02b")
+ "a\x00\x00m\x00\x01l\x00\x00c\x00\x00t\x00\x01t\x00\x02b\x00\x02"
+ "a\x00\x01")
assert code.constants == [Number(1)]
assert code.term_info == [("f", 1, "f/1"), ("-", 2, "-/2"),
("is", 2, "is/2")]
More information about the pypy-svn
mailing list