[pypy-svn] r45159 - in pypy/dist/pypy/lang/scheme: . test
jlg at codespeak.net
jlg at codespeak.net
Tue Jul 17 15:31:02 CEST 2007
Author: jlg
Date: Tue Jul 17 15:31:01 2007
New Revision: 45159
Modified:
pypy/dist/pypy/lang/scheme/TODO.txt
pypy/dist/pypy/lang/scheme/object.py
pypy/dist/pypy/lang/scheme/test/test_eval.py
pypy/dist/pypy/lang/scheme/test/test_object.py
Log:
(let* ...) added; Letrec = Let in our case; ExecutionContex.get() raises UnboundVariable instead of returning None
Modified: pypy/dist/pypy/lang/scheme/TODO.txt
==============================================================================
--- pypy/dist/pypy/lang/scheme/TODO.txt (original)
+++ pypy/dist/pypy/lang/scheme/TODO.txt Tue Jul 17 15:31:01 2007
@@ -6,8 +6,6 @@
Do next
-------
-- definitions: let*
-
- symbols vs identifier, which name is better
- global dict for symbols _obarray_
Modified: pypy/dist/pypy/lang/scheme/object.py
==============================================================================
--- pypy/dist/pypy/lang/scheme/object.py (original)
+++ pypy/dist/pypy/lang/scheme/object.py Tue Jul 17 15:31:01 2007
@@ -74,12 +74,7 @@
def eval_tr(self, ctx):
w_obj = ctx.get(self.name)
- if w_obj is not None:
- return (w_obj, None)
- else:
- #reference to undefined identifier
- #unbound
- raise UnboundVariable(self.name)
+ return (w_obj, None)
class W_Boolean(W_Root):
def __init__(self, val):
@@ -606,39 +601,35 @@
raise SchemeSyntaxError
local_ctx = ctx.copy()
w_formal = lst.car
- while not isinstance(w_formal, W_Nil) and isinstance(w_formal, W_Pair):
- name = w_formal.get_car_as_pair().car.to_string()
+ while isinstance(w_formal, W_Pair):
+ w_def = w_formal.get_car_as_pair()
+ name = w_def.car.to_string()
#evaluate the values in caller ctx
- val = w_formal.get_car_as_pair().get_cdr_as_pair().car.eval(ctx)
- local_ctx.put(name, val)
+ w_val = w_def.get_cdr_as_pair().car.eval(ctx)
+ local_ctx.put(name, w_val)
w_formal = w_formal.cdr
return self.eval_body(local_ctx, lst.cdr)
-class Letrec(W_Macro):
+class LetStar(W_Macro):
def call_tr(self, ctx, lst):
- """letrec uses eval_body, so it is tail-recursive aware"""
+ """let* uses eval_body, so it is tail-recursive aware"""
if not isinstance(lst, W_Pair):
raise SchemeSyntaxError
local_ctx = ctx.copy()
-
- #bound variables
- w_formal = lst.car
- while isinstance(w_formal, W_Pair):
- name = w_formal.get_car_as_pair().car.to_string()
- local_ctx.put(name, W_Nil())
- w_formal = w_formal.cdr
-
- #eval in local_ctx and assign values
w_formal = lst.car
while isinstance(w_formal, W_Pair):
- name = w_formal.get_car_as_pair().car.to_string()
- val = w_formal.get_car_as_pair().get_cdr_as_pair().car.eval(local_ctx)
- local_ctx.set(name, val)
+ w_def = w_formal.get_car_as_pair()
+ name = w_def.car.to_string()
+ #evaluate the values in local ctx
+ w_val = w_def.get_cdr_as_pair().car.eval(local_ctx)
+ local_ctx.put(name, w_val)
w_formal = w_formal.cdr
return self.eval_body(local_ctx, lst.cdr)
+Letrec = Let
+
def literal(sexpr):
return W_Pair(W_Identifier('quote'), W_Pair(sexpr, W_Nil()))
@@ -660,7 +651,7 @@
# Location()
##
class Location(object):
- def __init__(self, w_obj):
+ def __init__(self, w_obj=None):
self.obj = w_obj
##
@@ -704,6 +695,7 @@
'if': MacroIf,
'lambda': Lambda,
'let': Let,
+ 'let*': LetStar,
'letrec': Letrec,
'quote': Quote,
}
@@ -742,7 +734,7 @@
if loc is not None:
return loc.obj
- return None
+ raise UnboundVariable(name)
def sete(self, name, obj):
"""update existing location or raise
Modified: pypy/dist/pypy/lang/scheme/test/test_eval.py
==============================================================================
--- pypy/dist/pypy/lang/scheme/test/test_eval.py (original)
+++ pypy/dist/pypy/lang/scheme/test/test_eval.py Tue Jul 17 15:31:01 2007
@@ -274,7 +274,7 @@
eval_expr(ctx, """(define long_body (lambda () (define x 42) (+ x 1)))""")
w_result = eval_expr(ctx, "(long_body)")
assert w_result.to_number() == 43
- assert ctx.get("x") is None
+ py.test.raises(UnboundVariable, ctx.get, "x")
def test_lambda_lstarg():
ctx = ExecutionContext()
@@ -394,6 +394,8 @@
assert w_result.to_number() == 44
assert ctx.get("var") is w_global
+ py.test.raises(UnboundVariable, eval_noctx, "(let ((y 0) (x y)) x)")
+
def test_letrec():
ctx = ExecutionContext()
w_result = eval_expr(ctx, """
@@ -410,6 +412,19 @@
(even? 2000))""")
assert w_result.to_boolean() is True
+ py.test.raises(UnboundVariable, eval_noctx, "(letrec ((y 0) (x y)) x)")
+
+def test_letstar():
+ #test for (let* ...)
+ w_result = eval_noctx("""
+ (let* ((x 42)
+ (y (- x 42))
+ (z (+ x y)))
+ z)""")
+ assert w_result.to_number() == 42
+
+ py.test.raises(UnboundVariable, eval_noctx, "(let* ((x (+ 1 y)) (y 0)) x)")
+
def test_quit():
py.test.raises(SchemeQuit, eval_noctx, "(quit)")
Modified: pypy/dist/pypy/lang/scheme/test/test_object.py
==============================================================================
--- pypy/dist/pypy/lang/scheme/test/test_object.py (original)
+++ pypy/dist/pypy/lang/scheme/test/test_object.py Tue Jul 17 15:31:01 2007
@@ -64,7 +64,7 @@
assert w_symb is ctx.get("symb")
assert w_fnum is ctx.get("v1")
- assert ctx.get("no_such_key") is None
+ py.test.raises(UnboundVariable, ctx.get, "no_such_key")
def test_location():
w_fnum = W_Integer(42)
More information about the Pypy-commit
mailing list