[pypy-svn] r45217 - in pypy/dist/pypy/lang/scheme: . test
jlg at codespeak.net
jlg at codespeak.net
Fri Jul 20 18:45:18 CEST 2007
Author: jlg
Date: Fri Jul 20 18:45:17 2007
New Revision: 45217
Added:
pypy/dist/pypy/lang/scheme/test/test_macro.py (contents, props changed)
Modified:
pypy/dist/pypy/lang/scheme/execution.py
pypy/dist/pypy/lang/scheme/object.py
Log:
first attempts for matching in syntax-rules
Modified: pypy/dist/pypy/lang/scheme/execution.py
==============================================================================
--- pypy/dist/pypy/lang/scheme/execution.py (original)
+++ pypy/dist/pypy/lang/scheme/execution.py Fri Jul 20 18:45:17 2007
@@ -52,6 +52,7 @@
'letrec': Letrec,
'quote': Quote,
'quasiquote': QuasiQuote,
+ 'syntax-rules': SyntaxRules,
}
OPERATION_MAP = {}
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 20 18:45:17 2007
@@ -813,3 +813,66 @@
return W_Promise(lst.car, ctx)
+class SyntaxRules(W_Macro):
+ def call(self, ctx, lst):
+ if not isinstance(lst, W_Pair):
+ raise SchemeSyntaxError
+
+ w_literals = lst.car
+ if not isinstance(w_literals, W_List):
+ raise SchemeSyntaxError
+
+ w_syntax_lst = lst.cdr
+ syntax_lst = []
+ while isinstance(w_syntax_lst, W_Pair):
+ w_syntax = w_syntax_lst.car
+ if not isinstance(w_syntax, W_Pair):
+ raise SchemeSyntaxError
+
+ w_pattern = w_syntax.car
+ w_template = w_syntax.get_cdr_as_pair().car
+
+ #do stuff with w_syntax rules
+ syntax_lst.append(SyntaxRule(w_pattern, w_template))
+
+ w_syntax_lst = w_syntax_lst.cdr
+
+ return W_Transformer(syntax_lst)
+
+class SyntaxRule(object):
+ def __init__(self, pattern, template):
+ self.pattern = pattern
+ self.template = template
+
+ def __str__(self):
+ return self.pattern.to_string() + " -> " + self.template.to_string()
+
+ def match(self, w_expr):
+ w_patt = self.pattern
+ while isinstance(w_patt, W_Pair):
+ if w_expr is w_nil:
+ return False
+
+ if isinstance(w_patt, W_Symbol) and not isinstance(w_expr, W_Symbol):
+ return False
+
+ w_patt = w_patt.cdr
+ w_expr = w_expr.cdr
+
+ if w_expr is w_nil:
+ return True
+
+ return False
+
+class W_Transformer(W_Procedure):
+ def __init__(self, syntax_lst, pname=""):
+ self.pname = pname
+ self.syntax_lst = syntax_lst
+
+ def match(self, w_expr):
+ for rule in self.syntax_lst:
+ if rule.match(w_expr):
+ return rule.template
+
+ return False
+
Added: pypy/dist/pypy/lang/scheme/test/test_macro.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/lang/scheme/test/test_macro.py Fri Jul 20 18:45:17 2007
@@ -0,0 +1,32 @@
+import py
+from pypy.lang.scheme.ssparser import parse
+from pypy.lang.scheme.execution import ExecutionContext
+from pypy.lang.scheme.object import *
+
+def eval_expr(ctx, expr):
+ return parse(expr)[0].eval(ctx)
+
+def eval_noctx(expr):
+ return parse(expr)[0].eval(ExecutionContext())
+
+def test_syntax_rules_match():
+ py.test.raises(SchemeSyntaxError, eval_noctx, "(syntax-rules 1)")
+ py.test.raises(SchemeSyntaxError, eval_noctx, "(syntax-rules () 1)")
+
+ w_transformer = eval_noctx("(syntax-rules ())")
+ w_expr = parse("(foo)")[0]
+ assert not w_transformer.match(w_expr)
+
+ w_transformer = eval_noctx("(syntax-rules () ((foo) #t))")
+ w_expr = parse("(bar)")[0]
+ assert w_transformer.match(w_expr)
+ w_expr = parse("(foo bar)")[0]
+ assert not w_transformer.match(w_expr)
+
+ w_transformer = eval_noctx("""(syntax-rules () ((_) #t)
+ ((_ foo) foo))""")
+ w_expr = parse("(foo)")[0]
+ assert w_transformer.match(w_expr).to_boolean()
+ w_expr = parse("(foo bar)")[0]
+ assert w_transformer.match(w_expr).to_string() == "foo"
+
More information about the Pypy-commit
mailing list