[pypy-svn] r45439 - in pypy/dist/pypy/lang/scheme: . test
jlg at codespeak.net
jlg at codespeak.net
Mon Jul 30 17:13:13 CEST 2007
Author: jlg
Date: Mon Jul 30 17:13:13 2007
New Revision: 45439
Modified:
pypy/dist/pypy/lang/scheme/execution.py
pypy/dist/pypy/lang/scheme/object.py
pypy/dist/pypy/lang/scheme/test/test_macro.py
Log:
Letrec, Sete, Define more macro friendly
Modified: pypy/dist/pypy/lang/scheme/execution.py
==============================================================================
--- pypy/dist/pypy/lang/scheme/execution.py (original)
+++ pypy/dist/pypy/lang/scheme/execution.py Mon Jul 30 17:13:13 2007
@@ -111,6 +111,10 @@
raise UnboundVariable(name)
+ def ssete(self, symb, obj):
+ (ctx, name) = self._dispatch(symb)
+ ctx.sete(name, obj)
+
def sete(self, name, obj):
"""update existing location or raise
directly used by (set! <var> <expr>) macro
@@ -153,6 +157,10 @@
else:
self.globalscope[name] = Location(obj)
+ def sbind(self, symb):
+ (ctx, name) = self._dispatch(symb)
+ ctx.bind(name)
+
def bind(self, name):
"""create new empty binding (location)"""
if self.closure:
Modified: pypy/dist/pypy/lang/scheme/object.py
==============================================================================
--- pypy/dist/pypy/lang/scheme/object.py (original)
+++ pypy/dist/pypy/lang/scheme/object.py Mon Jul 30 17:13:13 2007
@@ -605,18 +605,16 @@
ctx.set(w_name.name, w_lambda)
return w_lambda #undefined
else:
- raise WrongArgType(w_first, "Identifier")
+ raise SchemeSyntaxError
class Sete(W_Macro):
def call(self, ctx, lst):
if not isinstance(lst, W_Pair):
raise SchemeSyntaxError
w_identifier = lst.car
- if not isinstance(w_identifier, W_Symbol):
- raise WrongArgType(w_identifier, "Identifier")
w_val = lst.get_cdr_as_pair().car.eval(ctx)
- ctx.sete(w_identifier.name, w_val)
+ ctx.ssete(w_identifier, w_val)
return w_val #undefined
class MacroIf(W_Macro):
@@ -690,12 +688,14 @@
raise SchemeSyntaxError
local_ctx = ctx.copy()
map_name_expr = {}
+ map_name_symb = {}
w_formal = lst.car
while isinstance(w_formal, W_Pair):
w_def = w_formal.get_car_as_pair()
name = w_def.car.to_string()
map_name_expr[name] = w_def.get_cdr_as_pair().car
- local_ctx.bind(name)
+ map_name_symb[name] = w_def.car
+ local_ctx.sbind(w_def.car)
w_formal = w_formal.cdr
map_name_val = {}
@@ -703,7 +703,7 @@
map_name_val[name] = expr.eval(local_ctx)
for (name, w_val) in map_name_val.items():
- local_ctx.sete(name, w_val)
+ local_ctx.ssete(map_name_symb[name], w_val)
return self.eval_body(local_ctx, lst.cdr)
@@ -1001,6 +1001,21 @@
def procedure(self, ctx, lst):
return self.expand_eval(ctx, lst[0])
+class W_DerivedMacro(W_Macro):
+ def __init__(self, name, transformer):
+ self.name = name
+ self.transformer = transformer
+
+ def to_string(self):
+ return "#<derived-macro %s>" % (self.name,)
+
+ def call(self, ctx, lst):
+ return self.transformer.expand_eval(ctx,
+ W_Pair(W_Symbol(self.name), lst))
+
+ def expand(self, ctx, lst):
+ return self.transformer.expand(ctx, lst)
+
class DefineSyntax(W_Macro):
def call(self, ctx, lst):
if not isinstance(lst, W_Pair):
@@ -1019,21 +1034,6 @@
ctx.set(w_def.name, w_macro)
return w_macro #undefined
-class W_DerivedMacro(W_Macro):
- def __init__(self, name, transformer):
- self.name = name
- self.transformer = transformer
-
- def to_string(self):
- return "#<derived-macro %s>" % (self.name,)
-
- def call(self, ctx, lst):
- return self.transformer.expand_eval(ctx,
- W_Pair(W_Symbol(self.name), lst))
-
- def expand(self, ctx, lst):
- return self.transformer.expand(ctx, lst)
-
class LetSyntax(W_Macro):
def call_tr(self, ctx, lst):
#let uses eval_body, so it is tail-recursive aware
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 Mon Jul 30 17:13:13 2007
@@ -178,6 +178,16 @@
eval_(ctx, "(define test 7)")
assert w_transformer.expand_eval(ctx, w_expr).to_number() == 5
+ w_transformer = eval_(ctx, """(syntax-rules ()
+ ((shadow used-arg body)
+ (letrec ((used-arg 5)) body)))""")
+
+ w_expr = parse("(shadow test test)")[0]
+ assert w_transformer.expand_eval(ctx, w_expr).to_number() == 5
+
+ eval_(ctx, "(define test 7)")
+ assert w_transformer.expand_eval(ctx, w_expr).to_number() == 5
+
def test_transformer_eval():
ctx = ExecutionContext()
eval_(ctx, """(define foo (syntax-rules ()
@@ -241,3 +251,12 @@
py.test.raises(UnboundVariable, ctx.get, "foo")
py.test.raises(UnboundVariable, ctx.get, "bar")
+def test_sete():
+ ctx = ExecutionContext()
+ eval_(ctx, "(define a 42)")
+ eval_(ctx, """(let-syntax ((foo (syntax-rules ()
+ ((foo var val) (set! var val)))))
+ (foo a 0))""")
+
+ assert eval_(ctx, "a").to_number() == 0
+
More information about the Pypy-commit
mailing list