[pypy-svn] r45009 - in pypy/dist/pypy/lang/scheme: . test
jlg at codespeak.net
jlg at codespeak.net
Fri Jul 13 13:05:39 CEST 2007
Author: jlg
Date: Fri Jul 13 13:05:38 2007
New Revision: 45009
Modified:
pypy/dist/pypy/lang/scheme/TODO.txt
pypy/dist/pypy/lang/scheme/object.py
pypy/dist/pypy/lang/scheme/test/ex.ss
pypy/dist/pypy/lang/scheme/test/test_eval.py
Log:
ListOper subclasses generated dynamically; Div added; porcedure/macro with <body> refactored
Modified: pypy/dist/pypy/lang/scheme/TODO.txt
==============================================================================
--- pypy/dist/pypy/lang/scheme/TODO.txt (original)
+++ pypy/dist/pypy/lang/scheme/TODO.txt Fri Jul 13 13:05:38 2007
@@ -19,6 +19,7 @@
- comparison: < > eq? eqv?
- rational, complex number types
+ - exact/inexact
Do in some future
-----------------
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 13 13:05:38 2007
@@ -1,4 +1,4 @@
-import autopath
+import py
class SchemeException(Exception):
pass
@@ -142,6 +142,15 @@
def call(self, ctx, lst):
raise NotImplementedError
+ def eval_body(self, ctx, body):
+ body_expression = body
+ body_result = None
+ while not isinstance(body_expression, W_Nil):
+ body_result = body_expression.car.eval(ctx)
+ body_expression = body_expression.cdr
+
+ return body_result
+
class W_Procedure(W_Callable):
def __init__(self, pname=""):
self.pname = pname
@@ -211,13 +220,7 @@
else:
local_ctx.put(formal.name, lst[idx])
- body_expression = self.body
- body_result = None
- while not isinstance(body_expression, W_Nil):
- body_result = body_expression.car.eval(local_ctx)
- body_expression = body_expression.cdr
-
- return body_result # self.body.eval(local_ctx)
+ return self.eval_body(local_ctx, self.body)
def plst2lst(plst):
"""coverts python list() of W_Root into W_Pair scheme list"""
@@ -233,6 +236,9 @@
##
class ListOper(W_Procedure):
def procedure(self, ctx, lst):
+ if len(lst) == 1:
+ return self.unary_oper(lst[0].eval(ctx))
+
acc = None
for arg in lst:
if acc is None:
@@ -242,38 +248,50 @@
return acc
+ def unary_oper(self, x):
+ if isinstance(x, W_Float):
+ return W_Float(self.do_unary_oper_float(x.to_float()))
+ else:
+ return W_Fixnum(self.do_unary_oper_int(x.to_fixnum()))
+
def oper(self, x, y):
if isinstance(x, W_Float) or isinstance(y, W_Float):
return W_Float(self.do_oper_float(x.to_float(), y.to_float()))
else:
return W_Fixnum(self.do_oper_int(x.to_fixnum(), y.to_fixnum()))
-class Add(ListOper):
- def do_oper_int(self, x, y):
- return x + y
-
- def do_oper_float(self, x, y):
- return x + y
-
-class Sub(ListOper):
- def procedure(self, ctx, lst):
- if len(lst) == 1:
- return ListOper.procedure(self, ctx, [W_Fixnum(0), lst[0]])
- else:
- return ListOper.procedure(self, ctx, lst)
-
- def do_oper_int(self, x, y):
- return x - y
-
- def do_oper_float(self, x, y):
- return x - y
-
-class Mul(ListOper):
- def do_oper_int(self, x, y):
- return x * y
-
- def do_oper_float(self, x, y):
- return x * y
+def create_op_class(oper, unary_oper):
+ class Op(ListOper):
+ pass
+
+ local_locals = {}
+ for name in ["int", "float"]:
+
+ attr_name = "do_oper_%s" % (name, )
+
+ code = py.code.Source("""
+ def %s(self, x, y):
+ return x %s y
+ """ % (attr_name, oper))
+
+ exec code.compile() in local_locals
+ setattr(Op, attr_name, local_locals[attr_name])
+
+ attr_name = "do_unary_oper_%s" % (name, )
+ code = py.code.Source("""
+ def %s(self, x):
+ return %s x
+ """ % (attr_name, unary_oper))
+
+ exec code.compile() in local_locals
+ setattr(Op, attr_name, local_locals[attr_name])
+
+ return Op
+
+Add = create_op_class('+', '')
+Sub = create_op_class('-', '-')
+Mul = create_op_class('*', '')
+Div = create_op_class('/', '1 /')
class List(W_Procedure):
def procedure(self, ctx, lst):
@@ -356,13 +374,7 @@
local_ctx.put(name, val)
w_formal = w_formal.cdr
- body_expression = lst.cdr
- body_result = None
- while not isinstance(body_expression, W_Nil):
- body_result = body_expression.car.eval(local_ctx)
- body_expression = body_expression.cdr
-
- return body_result
+ return self.eval_body(local_ctx, lst.cdr)
class Letrec(W_Macro):
def call(self, ctx, lst):
@@ -383,13 +395,7 @@
local_ctx.set(name, val)
w_formal = w_formal.cdr
- body_expression = lst.cdr
- body_result = None
- while not isinstance(body_expression, W_Nil):
- body_result = body_expression.car.eval(local_ctx)
- body_expression = body_expression.cdr
-
- return body_result
+ return self.eval_body(local_ctx, lst.cdr)
def Literal(sexpr):
return W_Pair(W_Identifier('quote'), W_Pair(sexpr, W_Nil()))
@@ -417,6 +423,7 @@
'+': Add,
'-': Sub,
'*': Mul,
+ '/': Div,
#list operations
'cons': Cons,
'car': Car,
Modified: pypy/dist/pypy/lang/scheme/test/ex.ss
==============================================================================
--- pypy/dist/pypy/lang/scheme/test/ex.ss (original)
+++ pypy/dist/pypy/lang/scheme/test/ex.ss Fri Jul 13 13:05:38 2007
@@ -21,6 +21,13 @@
(even? 12))
(+ 1 2 3)
-(+ 1 2.9 2)
-(quit)
+(- 2)
+(- 1 2.9 2)
+(* 1 2 2)
+(/ 1 2.9 2)
+(/ 1)
+(/ 2 1)
+(/ 2 1 7)
+(/ 2)
+;(quit)
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 Fri Jul 13 13:05:38 2007
@@ -28,6 +28,13 @@
w_num = eval_noctx("(* 4 -5 6.1)")
assert w_num.to_number() == (4 * -5 * 6.1)
+ w_num = eval_noctx("(/ 4)")
+ assert w_num.to_number() == 1 / 4
+ w_num = eval_noctx("(/ 4 -5)")
+ assert w_num.to_number() == 4 / -5
+ w_num = eval_noctx("(/ 4 -5 6.1)")
+ assert w_num.to_number() == (4 / -5 / 6.1)
+
w_num = eval_noctx("(- 4)")
assert w_num.to_number() == -4
w_num = eval_noctx("(- 4 5)")
More information about the Pypy-commit
mailing list