[pypy-svn] r45401 - in pypy/dist/pypy/lang/scheme: . test
jlg at codespeak.net
jlg at codespeak.net
Fri Jul 27 14:49:49 CEST 2007
Author: jlg
Date: Fri Jul 27 14:49:48 2007
New Revision: 45401
Modified:
pypy/dist/pypy/lang/scheme/object.py
pypy/dist/pypy/lang/scheme/test/test_macro.py
Log:
W_Transformer.match_dict is no more, now it is returned by match function and passed to substitute; removed bug with Closuring already Closured symbol
Modified: pypy/dist/pypy/lang/scheme/object.py
==============================================================================
--- pypy/dist/pypy/lang/scheme/object.py (original)
+++ pypy/dist/pypy/lang/scheme/object.py Fri Jul 27 14:49:48 2007
@@ -922,47 +922,52 @@
def __init__(self, syntax_lst, ctx, pname=""):
self.pname = pname
self.syntax_lst = syntax_lst
- self.match_dict = {}
self.closure = ctx
def match(self, ctx, w_expr):
for rule in self.syntax_lst:
- (matched, temp_dict) = rule.match(ctx, w_expr)
+ (matched, match_dict) = rule.match(ctx, w_expr)
if matched:
- self.match_dict = temp_dict
- return rule.template
+ return (rule.template, match_dict)
- self.match_dict = {}
- return None
+ return (None, {})
def expand(self, ctx, w_expr):
- template = self.match(ctx, w_expr)
+ (template, match_dict) = self.match(ctx, w_expr)
if template is None :
raise SchemeSyntaxError
- return self.substitute(ctx, template)
+ return self.substitute(ctx, template, match_dict)
- def substitute(self, ctx, sexpr):
+ def substitute(self, ctx, sexpr, match_dict):
if isinstance(sexpr, W_Symbol):
- w_sub = self.match_dict.get(sexpr.name, None)
+ w_sub = match_dict.get(sexpr.name, None)
if w_sub is not None:
# Hygenic macros close their input forms in the syntactic
# enviroment at the point of use
#not always needed, because w_sub can have no W_Symbols inside
+
+ #already is a SyntacticClosure
+ if isinstance(w_sub, SyntacticClosure):
+ assert w_sub.closure is ctx
+
+ return w_sub
+
return SyntacticClosure(ctx, w_sub)
return sexpr
elif isinstance(sexpr, W_Pair):
- w_pair = W_Pair(self.substitute(ctx, sexpr.car),
- self.substitute(ctx, sexpr.cdr))
+ w_pair = W_Pair(self.substitute(ctx, sexpr.car, match_dict),
+ self.substitute(ctx, sexpr.cdr, match_dict))
w_paircar = w_pair.car
if isinstance(w_paircar, W_Symbol):
try:
w_macro = ctx.get(w_paircar.name)
+
# recursive macro expansion
if isinstance(w_macro, W_DerivedMacro):
return w_macro.expand(ctx, w_pair)
@@ -978,6 +983,7 @@
# recursive macro expansion
if isinstance(w_macro, W_DerivedMacro):
return w_macro.expand(ctx, w_pair)
+
except UnboundVariable:
pass
Modified: pypy/dist/pypy/lang/scheme/test/test_macro.py
==============================================================================
--- pypy/dist/pypy/lang/scheme/test/test_macro.py (original)
+++ pypy/dist/pypy/lang/scheme/test/test_macro.py Fri Jul 27 14:49:48 2007
@@ -16,32 +16,35 @@
w_transformer = eval_noctx("(syntax-rules ())")
w_expr = parse("(foo)")[0]
- assert not w_transformer.match(ctx, w_expr)
+ assert not w_transformer.match(ctx, w_expr)[0]
w_transformer = eval_noctx("(syntax-rules () ((foo) #t))")
w_expr = parse("(bar)")[0]
- assert w_transformer.match(ctx, w_expr)
+ assert w_transformer.match(ctx, w_expr)[0]
w_expr = parse("(foo bar)")[0]
- assert not w_transformer.match(ctx, w_expr)
+ assert not w_transformer.match(ctx, w_expr)[0]
w_transformer = eval_noctx("""(syntax-rules () ((_) #t)
((_ foo) foo))""")
w_expr = parse("(foo)")[0]
- assert w_transformer.match(ctx, w_expr).to_boolean()
+ assert w_transformer.match(ctx, w_expr)[0].to_boolean()
w_expr = parse("(foo bar)")[0]
- assert w_transformer.match(ctx, w_expr).to_string() == "foo"
- assert w_transformer.match_dict["foo"].to_string() == "bar"
+ (template, match_dict) = w_transformer.match(ctx, w_expr)
+ assert template.to_string() == "foo"
+ assert match_dict["foo"].to_string() == "bar"
w_expr = parse("(foo bar boo)")[0]
- assert not w_transformer.match(ctx, w_expr)
- assert w_transformer.match_dict == {}
+ (template, match_dict) = w_transformer.match(ctx, w_expr)
+ assert not template
+ assert match_dict == {}
w_transformer = eval_noctx("(syntax-rules () ((foo (bar)) bar))")
w_expr = parse("(_ fuzz)")[0]
- assert not w_transformer.match(ctx, w_expr)
+ assert not w_transformer.match(ctx, w_expr)[0]
w_expr = parse("(_ (fuzz))")[0]
- assert w_transformer.match(ctx, w_expr)
- assert w_transformer.match_dict["bar"].to_string() == "fuzz"
+ (template, match_dict) = w_transformer.match(ctx, w_expr)
+ assert template
+ assert match_dict["bar"].to_string() == "fuzz"
def test_syntax_rules_literals():
ctx = ExecutionContext()
@@ -51,13 +54,13 @@
w_transformer = eval_(ctx, "(syntax-rules (=>) ((foo => bar) #t))")
w_expr = parse("(foo bar boo)")[0]
- assert not w_transformer.match(ctx, w_expr)
+ assert not w_transformer.match(ctx, w_expr)[0]
# exact match
w_expr = parse("(foo => boo)")[0]
# within the same context
- assert w_transformer.match(ctx, w_expr)
+ assert w_transformer.match(ctx, w_expr)[0]
w_42 = W_Number(42)
@@ -65,19 +68,19 @@
closure = ctx.copy()
closure.put("=>", w_42)
w_transformer = eval_(ctx, "(syntax-rules (=>) ((foo => bar) #t))")
- assert not w_transformer.match(closure, w_expr)
+ assert not w_transformer.match(closure, w_expr)[0]
# different lexical scope, not the same bindings for => in ctx and closure
ctx.put("=>", W_Number(12))
assert ctx.get("=>") is not closure.get("=>")
w_transformer = eval_(ctx, "(syntax-rules (=>) ((foo => bar) #t))")
- assert not w_transformer.match(closure, w_expr)
+ assert not w_transformer.match(closure, w_expr)[0]
# the same binding for => in ctx and closure
ctx.put("=>", w_42)
assert ctx.get("=>") is closure.get("=>")
w_transformer = eval_(ctx, "(syntax-rules (=>) ((foo => bar) #t))")
- assert w_transformer.match(closure, w_expr)
+ assert w_transformer.match(closure, w_expr)[0]
def test_syntax_rules_expand_simple():
ctx = ExecutionContext()
@@ -203,15 +206,23 @@
((my-or arg1 arg2)
(if arg1
arg1
- (my-or arg2)))))""")
+ (my-or arg2)))
+ ((my-or arg1 arg2 arg3)
+ (if arg1
+ arg1
+ (my-or arg2 arg3)))))""")
assert eval_(ctx, "(my-or)").to_boolean() is False
assert eval_(ctx, "(my-or 12)").to_number() == 12
- #should expand recursively and after that eval, how to check it?
+ #should expand recursively and after that eval
w_expr = parse("(my-or 12 42)")[0]
assert ctx.get("my-or").expand(ctx, w_expr).to_string() == \
"(if 12 12 42)"
+ w_expr = parse("(my-or 12 42 82)")[0]
+ assert ctx.get("my-or").expand(ctx, w_expr).to_string() == \
+ "(if 12 12 (if 42 42 82))"
assert eval_(ctx, "(my-or 12 42)").to_number() == 12
assert eval_(ctx, "(my-or #f 42)").to_number() == 42
+ assert eval_(ctx, "(my-or #f #f 82)").to_number() == 82
More information about the Pypy-commit
mailing list