Author: Juergen Boemmels <[email protected]>
Branch: 
Changeset: r21:b3e418138833
Date: 2011-11-29 21:46 +0100
http://bitbucket.org/pypy/lang-scheme/changeset/b3e418138833/

Log:    Implement the #\<character name> syntax

diff --git a/scheme/object.py b/scheme/object.py
--- a/scheme/object.py
+++ b/scheme/object.py
@@ -143,15 +143,30 @@
     def __repr__(self):
         return "<W_String \"" + self.strval + "\">"
 
+_charname_to_char = {
+    'space': ' ',
+    'newline': '\n',
+}
+
+_char_to_charname = dict((v, k) for k, v in _charname_to_char.items())
+
 class W_Character(W_Root):
     def __init__(self, val):
+        if len(val) != 1:
+            val = _charname_to_char.get(val.lower(), None)
+            if val is None:
+                raise SchemeSyntaxError
         self.chrval = val
 
     def to_string(self):
         return self.chrval
 
     def to_repr(self):
-        return "#\\" + self.chrval
+        charname = _char_to_charname.get(self.chrval, None)
+        if charname is None:
+            return "#\\" + self.chrval
+        else:
+            return "#\\" + charname
 
     def __repr__(self):
         return "<W_Character #\\" + self.chrval + ">"
diff --git a/scheme/ssparser.py b/scheme/ssparser.py
--- a/scheme/ssparser.py
+++ b/scheme/ssparser.py
@@ -32,9 +32,9 @@
         return {W_String(str_unquote(c))};
 
     CHARACTER:
-        c = `#\\.`
+        c = `#\\(.|[A-Za-z]+)`
         IGNORE*
-        return {W_Character(c[2])};
+        return {W_Character(c[2:])};
 
     SYMBOL:
         c = `[\+\-\*\^\?a-zA-Z!<=>_~/$%&:][\+\-\*\^\?a-zA-Z0-9!<=>_~/$%&:.]*`
diff --git a/scheme/test/test_object.py b/scheme/test/test_object.py
--- a/scheme/test/test_object.py
+++ b/scheme/test/test_object.py
@@ -24,7 +24,19 @@
     w_str = W_String(str)
     assert str == w_str.to_string()
     assert w_str.to_repr() == r'''"\\ \\\\ \\' \" \\\""'''
-    
+
+def test_char():
+    c = 'x'
+    w_char = W_Character(c)
+    assert w_char.to_boolean() is True
+    assert w_char.to_string() == 'x'
+    assert w_char.to_repr() == r'#\x'
+    c = ' '
+    w_char = W_Character(c)
+    assert w_char.to_boolean() is True
+    assert w_char.to_string() == ' '
+    assert w_char.to_repr() == r'#\space'
+
 def test_fixnum():
     num = 12345
     w_num = W_Integer(num)
diff --git a/scheme/test/test_parser.py b/scheme/test/test_parser.py
--- a/scheme/test/test_parser.py
+++ b/scheme/test/test_parser.py
@@ -2,6 +2,7 @@
 from scheme.ssparser import parse
 from scheme.object import W_Boolean, W_Real, W_Integer, W_String
 from scheme.object import W_Pair, W_Nil, W_Symbol, W_Character, W_Vector
+from scheme.object import SchemeSyntaxError
 from pypy.rlib.parsing.makepackrat import BacktrackException
 
 def parse_sexpr(expr):
@@ -76,6 +77,29 @@
         assert isinstance(w_string, W_String)
         assert unwrap(w_string) == contents
 
+def test_character():
+    w_char = parse_sexpr(r'#\c')
+    assert isinstance(w_char, W_Character)
+    assert unwrap(w_char) == 'c'
+
+    more_chars = [(r'#\Z', 'Z'),
+                  (r'#\,', ','),
+                  (r'#\;', ';'),
+                  (r'#\)', ')'),
+                  (r'#\(', '('),
+                  (r'#\#', '#'),
+                  (r'#\ ', ' '),
+                  (r'#\space', ' '),
+                  (r'#\newline', '\n'),
+                 ]
+     
+    for code, result in more_chars:
+        w_char = parse_sexpr(code)
+        assert isinstance(w_char, W_Character)
+        assert unwrap(w_char) == result
+
+    py.test.raises(SchemeSyntaxError, parse_sexpr, r'#\foobar')
+
 def test_objects():
     w_fixnum = parse_sexpr('-12345')
     assert isinstance(w_fixnum, W_Integer)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to