scriptreader.cxx

changeset 34
0a9a5902beaa
parent 33
fd35f6cb5f28
child 35
3d3f6ed40171
equal deleted inserted replaced
33:fd35f6cb5f28 34:0a9a5902beaa
45 #include "common.h" 45 #include "common.h"
46 #include "scriptreader.h" 46 #include "scriptreader.h"
47 47
48 ScriptReader::ScriptReader (str path) { 48 ScriptReader::ScriptReader (str path) {
49 token = ""; 49 token = "";
50 prevtoken = "";
51 prevpos = 0;
50 fc = -1; 52 fc = -1;
51 53
52 for (unsigned int u = 0; u < MAX_FILESTACK; u++) 54 for (unsigned int u = 0; u < MAX_FILESTACK; u++)
53 fp[u] = NULL; 55 fp[u] = NULL;
54 56
68 } 70 }
69 71
70 // Opens a file and pushes its pointer to stack 72 // Opens a file and pushes its pointer to stack
71 void ScriptReader::OpenFile (str path) { 73 void ScriptReader::OpenFile (str path) {
72 if (fc+1 >= MAX_FILESTACK) 74 if (fc+1 >= MAX_FILESTACK)
73 ParserError ("supposed to open file `%s` but file stack is full! \ 75 ParserError ("supposed to open file `%s` but file stack is full! do you have recursive `#include` directives?",
74 do you have recursive `#include` directives?",
75 path.chars()); 76 path.chars());
76 77
77 // Save the position first. 78 // Save the position first.
78 if (fc != -1) { 79 if (fc != -1) {
79 savedpos[fc] = ftell (fp[fc]); 80 savedpos[fc] = ftell (fp[fc]);
155 fseek (fp[fc], curpos, SEEK_SET); 156 fseek (fp[fc], curpos, SEEK_SET);
156 157
157 return c[0]; 158 return c[0];
158 } 159 }
159 160
160 // true if was found, false if not. 161 // Read a token from the file buffer. Returns true if token was found, false if not.
161 bool ScriptReader::Next (bool peek) { 162 bool ScriptReader::Next (bool peek) {
163 prevpos = ftell (fp[fc]);
162 str tmp = ""; 164 str tmp = "";
163 // printf ("begin token\n");
164 165
165 while (1) { 166 while (1) {
166 // Check end-of-file 167 // Check end-of-file
167 if (feof (fp[fc])) { 168 if (feof (fp[fc])) {
168 // If we're just peeking, we shouldn't 169 // If we're just peeking, we shouldn't
188 // comment characters, since they will get 189 // comment characters, since they will get
189 // ignored due to comment mode anyway. 190 // ignored due to comment mode anyway.
190 } 191 }
191 192
192 c = ReadChar (); 193 c = ReadChar ();
193 // printf ("add char [%d] `%c`\n", c, c);
194 194
195 // If this is a comment we're reading, check if this character 195 // If this is a comment we're reading, check if this character
196 // gets the comment terminated, otherwise ignore it. 196 // gets the comment terminated, otherwise ignore it.
197 if (commentmode > 0) { 197 if (commentmode > 0) {
198 if (commentmode == 1 && c == '\n') { 198 if (commentmode == 1 && c == '\n') {
234 tmp += c; 234 tmp += c;
235 } 235 }
236 } 236 }
237 237
238 // If we got nothing here, read failed. This should 238 // If we got nothing here, read failed. This should
239 // only hapen in the case of EOF. 239 // only happen in the case of EOF.
240 if (!tmp.len()) { 240 if (!tmp.len()) {
241 token = ""; 241 token = "";
242 return false; 242 return false;
243 } 243 }
244 244
245 pos[fc]++; 245 pos[fc]++;
246 prevtoken = token;
246 token = tmp; 247 token = tmp;
247 return true; 248 return true;
248 } 249 }
249 250
251 void ScriptReader::Prev () {
252 if (!prevpos)
253 error ("ScriptReader::Prev: cannot go back twice!\n");
254
255 fseek (fp[fc], prevpos, SEEK_SET);
256 prevpos = 0;
257 token = prevtoken;
258 }
259
250 // Returns the next token without advancing the cursor. 260 // Returns the next token without advancing the cursor.
251 str ScriptReader::PeekNext () { 261 str ScriptReader::PeekNext (int offset) {
252 // Store current position 262 // Store current information
263 str storedtoken = token;
253 int cpos = ftell (fp[fc]); 264 int cpos = ftell (fp[fc]);
254 265
255 // Advance on the token. 266 // Advance on the token.
256 if (!Next (true)) 267 while (offset >= 0) {
257 return ""; 268 if (!Next (true))
269 return "";
270 offset--;
271 }
258 272
259 str tmp = token; 273 str tmp = token;
260 274
261 // Restore position 275 // Restore position
262 fseek (fp[fc], cpos, SEEK_SET); 276 fseek (fp[fc], cpos, SEEK_SET);
263 pos[fc]--; 277 pos[fc]--;
264 278 token = storedtoken;
265 return tmp; 279 return tmp;
266 } 280 }
267 281
268 void ScriptReader::Seek (unsigned int n, int origin) { 282 void ScriptReader::Seek (unsigned int n, int origin) {
269 switch (origin) { 283 switch (origin) {
288 ParserError ("expected `%s`, reached end of file instead\n", c); 302 ParserError ("expected `%s`, reached end of file instead\n", c);
289 else 303 else
290 ParserError ("expected a token, reached end of file instead\n"); 304 ParserError ("expected a token, reached end of file instead\n");
291 } 305 }
292 306
293 if (strlen (c) && token.compare (c) != 0) { 307 if (strlen (c))
308 MustThis (c);
309 }
310
311 void ScriptReader::MustThis (const char* c) {
312 if (token.compare (c) != 0)
294 ParserError ("expected `%s`, got `%s` instead", c, token.chars()); 313 ParserError ("expected `%s`, got `%s` instead", c, token.chars());
295 }
296 } 314 }
297 315
298 void ScriptReader::ParserError (const char* message, ...) { 316 void ScriptReader::ParserError (const char* message, ...) {
299 PERFORM_FORMAT (message, outmessage); 317 PERFORM_FORMAT (message, outmessage);
300 ParserMessage ("\nError: ", outmessage); 318 ParserMessage ("\nError: ", outmessage);
312 header, filepath[fc], curline[fc], curchar[fc], message); 330 header, filepath[fc], curline[fc], curchar[fc], message);
313 else 331 else
314 fprintf (stderr, "%s%s\n", header, message); 332 fprintf (stderr, "%s%s\n", header, message);
315 } 333 }
316 334
317 void ScriptReader::MustString () { 335 // if gotquote == 1, the current token already holds the quotation mark.
318 MustNext ("\""); 336 void ScriptReader::MustString (bool gotquote) {
337 if (gotquote)
338 MustThis ("\"");
339 else
340 MustNext ("\"");
319 341
320 str string; 342 str string;
321 // Keep reading characters until we find a terminating quote. 343 // Keep reading characters until we find a terminating quote.
322 while (1) { 344 while (1) {
323 // can't end here! 345 // can't end here!

mercurial