78 |
79 |
79 // We're at a newline, thus next char read will begin the next line |
80 // We're at a newline, thus next char read will begin the next line |
80 if (atnewline) { |
81 if (atnewline) { |
81 atnewline = false; |
82 atnewline = false; |
82 curline++; |
83 curline++; |
|
84 curchar = 0; // gets incremented to 1 |
83 } |
85 } |
84 |
86 |
85 if (c[0] == '\n') |
87 if (c[0] == '\n') |
86 atnewline = true; |
88 atnewline = true; |
87 |
89 |
|
90 curchar++; |
88 return c[0]; |
91 return c[0]; |
89 } |
92 } |
90 |
93 |
91 // true if was found, false if not. |
94 // true if was found, false if not. |
92 bool ScriptReader::Next () { |
95 bool ScriptReader::Next () { |
93 str tmp = ""; |
96 str tmp = ""; |
94 bool quote = false; |
97 bool dontreadnext = false; |
95 tokenquoted = false; |
|
96 while (!feof (fp)) { |
98 while (!feof (fp)) { |
97 char c = ReadChar (); |
99 c = ReadChar (); |
98 |
100 |
99 // Extended delimeters: parenthesis, quote marks, braces and brackets. |
101 // Extended delimeters: basically any non-alnum characters. |
100 // These delimeters break the word too. If there was prior data, |
102 // These delimeters break the word too. If there was prior data, |
101 // the delimeter pushes the cursor back so that the next character |
103 // the delimeter pushes the cursor back so that the next character |
102 // will be the same delimeter. If there isn't, the delimeter itself |
104 // will be the same delimeter. If there isn't, the delimeter itself |
103 // is included (and thus becomes a token itself.) |
105 // is included (and thus becomes a token itself.) |
104 bool shouldBreak = false; |
106 bool shouldBreak = false; |
105 if (extdelimeters) { |
107 if (extdelimeters) { |
106 switch (c) { |
108 if ((c >= 33 && c <= 47) || |
107 case '(': case ')': |
109 (c >= 58 && c <= 64) || |
108 case '{': case '}': |
110 // underscore isn't a delimeter |
109 case '[': case ']': |
111 (c >= 91 && c <= 96 && c != 95) || |
110 case '"': |
112 (c >= 123 && c <= 126)) { |
111 // Push the cursor back |
|
112 if (tmp.len()) |
113 if (tmp.len()) |
113 fseek (fp, ftell (fp)-1, SEEK_SET); |
114 fseek (fp, ftell (fp) - 1, SEEK_SET); |
114 else |
115 else |
115 tmp += c; |
116 tmp += c; |
116 shouldBreak = true; |
117 shouldBreak = true; |
117 break; |
118 break; |
118 } |
119 } |
119 } |
120 } |
120 if (shouldBreak) |
121 if (shouldBreak) |
121 break; |
122 break; |
122 |
123 |
123 if (IsDelimeter (c) && !quote) { |
124 if (IsDelimeter (c)) { |
124 // Don't break if we haven't gathered anything yet. |
125 // Don't break if we haven't gathered anything yet. |
125 if (tmp.len()) |
126 if (tmp.len()) |
126 break; |
127 break; |
127 } else { |
128 } else { |
128 tmp += c; |
129 tmp += c; |
198 PERFORM_FORMAT (message, outmessage); |
199 PERFORM_FORMAT (message, outmessage); |
199 ParserMessage ("Warning: ", outmessage); |
200 ParserMessage ("Warning: ", outmessage); |
200 } |
201 } |
201 |
202 |
202 void ScriptReader::ParserMessage (const char* header, char* message) { |
203 void ScriptReader::ParserMessage (const char* header, char* message) { |
203 fprintf (stderr, "%sIn file %s, on line %d: %s\n", |
204 fprintf (stderr, "%sIn file %s, at line %u, col %u: %s\n", |
204 header, filepath.chars(), curline, message); |
205 header, filepath.chars(), curline, curchar, message); |
205 } |
206 } |
206 |
207 |
|
208 // I guess this should be a void function putting the return value into token? |
207 str ScriptReader::MustGetString () { |
209 str ScriptReader::MustGetString () { |
208 if (!extdelimeters) |
210 if (!extdelimeters) |
209 ParserError ("MustGetString doesn't work with parsers not using extended delimeters!"); |
211 ParserError ("MustGetString doesn't work with parsers not using extended delimeters!"); |
210 |
212 |
211 MustNext ("\""); |
213 MustNext ("\""); |
224 string += c; |
226 string += c; |
225 } |
227 } |
226 |
228 |
227 return string; |
229 return string; |
228 } |
230 } |
|
231 |
|
232 void ScriptReader::MustNumber () { |
|
233 MustNext (); |
|
234 if (!token.isnumber()) |
|
235 ParserError ("expected a number, got `%s`", token.chars()); |
|
236 } |
|
237 |
|
238 void ScriptReader::MustBool () { |
|
239 MustNext(); |
|
240 if (!token.compare ("0") || !token.compare ("1") || |
|
241 !token.compare ("true") || !token.compare ("false") || |
|
242 !token.compare ("yes") || !token.compare ("no")) { |
|
243 return; |
|
244 } |
|
245 |
|
246 ParserError ("expected a boolean value, got `%s`", token.chars()); |
|
247 } |