@@ -26,7 +26,7 @@ THE SOFTWARE. */
2626
2727namespace Naggum . Runtime
2828{
29- class Reader
29+ public class Reader
3030 {
3131 /// <summary>
3232 /// Checks if the character is constituent, i.e. not whitespace or list separator.
@@ -45,11 +45,10 @@ public static bool isConstituent(char c)
4545 /// </summary>
4646 /// <param name="stream">stream to read from</param>
4747 /// <returns></returns>
48- private static Object ReadSymbol ( Stream stream )
48+ private static Object ReadSymbol ( StreamReader reader )
4949 {
5050 bool in_symbol = true ;
5151 StringBuilder symbol_name = new StringBuilder ( ) ;
52- StreamReader reader = new StreamReader ( stream ) ;
5352 while ( in_symbol )
5453 {
5554 var ch = reader . Peek ( ) ;
@@ -74,9 +73,8 @@ private static Object ReadSymbol(Stream stream)
7473 /// </summary>
7574 /// <param name="stream">stream to read from</param>
7675 /// <returns></returns>
77- private static Object ReadList ( Stream stream )
76+ private static Object ReadList ( StreamReader reader )
7877 {
79- StreamReader reader = new StreamReader ( stream ) ;
8078 bool in_list = true ;
8179 Cons list = null ;
8280 while ( in_list )
@@ -85,36 +83,89 @@ private static Object ReadList(Stream stream)
8583 if ( ch < 0 ) throw new IOException ( "Unexpected end of stream." ) ;
8684 if ( ( char ) ch != ')' )
8785 {
88- list = new Cons ( Read ( stream ) , list ) ;
86+ list = new Cons ( ReadObject ( reader ) , list ) ;
8987 }
9088 else
9189 {
90+ reader . Read ( ) ; //consume closing paren
9291 in_list = false ;
9392 }
9493 }
9594 return list ;
9695 }
9796
9897 /// <summary>
99- /// Reads an object from input stream.
98+ /// Reads a string from input stream
10099 /// </summary>
101- /// <param name="stream">stream to read from</param>
102- /// <returns></returns>
103- public static Object Read ( Stream stream )
100+ /// <param name="stream">input stream</param>
101+ /// <returns>a string that was read</returns>
102+ private static string ReadString ( StreamReader reader )
103+ {
104+ bool in_string = true ;
105+ bool single_escape = false ;
106+ StringBuilder sbld = new StringBuilder ( ) ;
107+
108+ while ( in_string )
109+ {
110+ var ch = reader . Read ( ) ;
111+ if ( single_escape )
112+ {
113+ single_escape = false ;
114+ switch ( ch )
115+ {
116+ case 'n' : sbld . Append ( '\n ' ) ; break ;
117+ case 'r' : sbld . Append ( '\r ' ) ; break ;
118+ case '\" ' : sbld . Append ( '"' ) ; break ;
119+ case 't' : sbld . Append ( '\t ' ) ; break ;
120+ case '\\ ' : sbld . Append ( '\\ ' ) ; break ;
121+ default : throw new Exception ( "Unknown escape sequence: \\ " + ch ) ;
122+ }
123+ }
124+ else
125+ {
126+ switch ( ch )
127+ {
128+ case '\" ' : in_string = false ; break ;
129+ case '\\ ' : single_escape = true ; break ;
130+ default : sbld . Append ( ( char ) ch ) ; break ;
131+ }
132+ }
133+
134+ }
135+ return sbld . ToString ( ) ;
136+ }
137+
138+ private static Object ReadObject ( StreamReader reader )
104139 {
105- StreamReader reader = new StreamReader ( stream ) ;
106140 while ( Char . IsWhiteSpace ( ( char ) reader . Peek ( ) ) ) reader . Read ( ) ; //consume all leading whitespace
107141 var ch = reader . Peek ( ) ;
108142 if ( ch < 0 ) return null ;
109143 if ( ch == '(' ) //beginning of a list
110144 {
111145 reader . Read ( ) ; //consume opening list delimiter.
112- return ReadList ( stream ) ;
146+ return ReadList ( reader ) ;
147+ }
148+ if ( ch == '\" ' ) //beginning of a string
149+ {
150+ reader . Read ( ) ; //consume opening quote
151+ return ReadString ( reader ) ;
113152 }
114153 if ( isConstituent ( ( char ) ch ) )
115- return ReadSymbol ( stream ) ;
154+ return ReadSymbol ( reader ) ;
116155
117156 throw new IOException ( "Unexpected char: " + ( char ) ch ) ;
118157 }
158+
159+ /// <summary>
160+ /// Reads an object from input stream.
161+ /// </summary>
162+ /// <param name="stream">stream to read from</param>
163+ /// <returns></returns>
164+ public static Object Read ( Stream stream )
165+ {
166+ StreamReader reader = new StreamReader ( stream ) ;
167+ var obj = ReadObject ( reader ) ;
168+ return obj ;
169+ }
119170 }
120171}
0 commit comments