Commits

Jürgen Bömmels  committed b3e4181

Implement the #\<character name> syntax

  • Participants
  • Parent commits f6d150f

Comments (0)

Files changed (4)

File scheme/object.py

     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 + ">"

File scheme/ssparser.py

         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!<=>_~/$%&:.]*`

File scheme/test/test_object.py

     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)

File scheme/test/test_parser.py

 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):
         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)