[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