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