[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