scriptreader.cxx

changeset 38
e4bbd540663b
parent 36
a8838b5f1213
child 50
2e333a3ca49a
equal deleted inserted replaced
37:c349dca807f9 38:e4bbd540663b
43 #include "string.h" 43 #include "string.h"
44 #include "str.h" 44 #include "str.h"
45 #include "common.h" 45 #include "common.h"
46 #include "scriptreader.h" 46 #include "scriptreader.h"
47 47
48 // ============================================================================
48 ScriptReader::ScriptReader (str path) { 49 ScriptReader::ScriptReader (str path) {
49 token = ""; 50 token = "";
50 prevtoken = ""; 51 prevtoken = "";
51 prevpos = 0; 52 prevpos = 0;
52 fc = -1; 53 fc = -1;
56 57
57 OpenFile (path); 58 OpenFile (path);
58 commentmode = 0; 59 commentmode = 0;
59 } 60 }
60 61
62 // ============================================================================
61 ScriptReader::~ScriptReader () { 63 ScriptReader::~ScriptReader () {
62 // If comment mode is 2 by the time the file ended, the 64 // If comment mode is 2 by the time the file ended, the
63 // comment was left unterminated. 1 is no problem, since 65 // comment was left unterminated. 1 is no problem, since
64 // it's terminated by newlines anyway. 66 // it's terminated by newlines anyway.
65 if (commentmode == 2) 67 if (commentmode == 2)
71 CloseFile (u); 73 CloseFile (u);
72 } 74 }
73 } 75 }
74 } 76 }
75 77
78 // ============================================================================
76 // Opens a file and pushes its pointer to stack 79 // Opens a file and pushes its pointer to stack
77 void ScriptReader::OpenFile (str path) { 80 void ScriptReader::OpenFile (str path) {
78 if (fc+1 >= MAX_FILESTACK) 81 if (fc+1 >= MAX_FILESTACK)
79 ParserError ("supposed to open file `%s` but file stack is full! do you have recursive `#include` directives?", 82 ParserError ("supposed to open file `%s` but file stack is full! do you have recursive `#include` directives?",
80 path.chars()); 83 path.chars());
98 curchar[fc] = 1; 101 curchar[fc] = 1;
99 pos[fc] = 0; 102 pos[fc] = 0;
100 atnewline = 0; 103 atnewline = 0;
101 } 104 }
102 105
106 // ============================================================================
107 // Closes the current file
103 void ScriptReader::CloseFile (unsigned int u) { 108 void ScriptReader::CloseFile (unsigned int u) {
104 if (u >= MAX_FILESTACK) 109 if (u >= MAX_FILESTACK)
105 u = fc; 110 u = fc;
106 111
107 if (!fp[u]) 112 if (!fp[u])
108 return; 113 return;
109 114
110 fclose (fp[u]); 115 fclose (fp[u]);
113 118
114 if (fc != -1) 119 if (fc != -1)
115 fseek (fp[fc], savedpos[fc], SEEK_SET); 120 fseek (fp[fc], savedpos[fc], SEEK_SET);
116 } 121 }
117 122
123 // ============================================================================
118 char ScriptReader::ReadChar () { 124 char ScriptReader::ReadChar () {
119 if (feof (fp[fc])) 125 if (feof (fp[fc]))
120 return 0; 126 return 0;
121 127
122 char* c = (char*)malloc (sizeof (char)); 128 char* c = (char*)malloc (sizeof (char));
139 145
140 curchar[fc]++; 146 curchar[fc]++;
141 return c[0]; 147 return c[0];
142 } 148 }
143 149
150 // ============================================================================
151 // Peeks the next character
144 char ScriptReader::PeekChar (int offset) { 152 char ScriptReader::PeekChar (int offset) {
145 // Store current position 153 // Store current position
146 long curpos = ftell (fp[fc]); 154 long curpos = ftell (fp[fc]);
147 155
148 // Forward by offset 156 // Forward by offset
160 fseek (fp[fc], curpos, SEEK_SET); 168 fseek (fp[fc], curpos, SEEK_SET);
161 169
162 return c[0]; 170 return c[0];
163 } 171 }
164 172
173 // ============================================================================
165 // Read a token from the file buffer. Returns true if token was found, false if not. 174 // Read a token from the file buffer. Returns true if token was found, false if not.
166 bool ScriptReader::Next (bool peek) { 175 bool ScriptReader::Next (bool peek) {
167 prevpos = ftell (fp[fc]); 176 prevpos = ftell (fp[fc]);
168 str tmp = ""; 177 str tmp = "";
169 178
250 prevtoken = token; 259 prevtoken = token;
251 token = tmp; 260 token = tmp;
252 return true; 261 return true;
253 } 262 }
254 263
255 void ScriptReader::Prev () { 264 // ============================================================================
256 if (!prevpos)
257 error ("ScriptReader::Prev: cannot go back twice!\n");
258
259 fseek (fp[fc], prevpos, SEEK_SET);
260 prevpos = 0;
261 token = prevtoken;
262 }
263
264 // Returns the next token without advancing the cursor. 265 // Returns the next token without advancing the cursor.
265 str ScriptReader::PeekNext (int offset) { 266 str ScriptReader::PeekNext (int offset) {
266 // Store current information 267 // Store current information
267 str storedtoken = token; 268 str storedtoken = token;
268 int cpos = ftell (fp[fc]); 269 int cpos = ftell (fp[fc]);
281 pos[fc]--; 282 pos[fc]--;
282 token = storedtoken; 283 token = storedtoken;
283 return tmp; 284 return tmp;
284 } 285 }
285 286
287 // ============================================================================
286 void ScriptReader::Seek (unsigned int n, int origin) { 288 void ScriptReader::Seek (unsigned int n, int origin) {
287 switch (origin) { 289 switch (origin) {
288 case SEEK_SET: 290 case SEEK_SET:
289 fseek (fp[fc], 0, SEEK_SET); 291 fseek (fp[fc], 0, SEEK_SET);
290 pos[fc] = 0; 292 pos[fc] = 0;
298 300
299 for (unsigned int i = 0; i < n+1; i++) 301 for (unsigned int i = 0; i < n+1; i++)
300 Next(); 302 Next();
301 } 303 }
302 304
305 // ============================================================================
303 void ScriptReader::MustNext (const char* c) { 306 void ScriptReader::MustNext (const char* c) {
304 if (!Next()) { 307 if (!Next()) {
305 if (strlen (c)) 308 if (strlen (c))
306 ParserError ("expected `%s`, reached end of file instead\n", c); 309 ParserError ("expected `%s`, reached end of file instead\n", c);
307 else 310 else
310 313
311 if (strlen (c)) 314 if (strlen (c))
312 MustThis (c); 315 MustThis (c);
313 } 316 }
314 317
318 // ============================================================================
315 void ScriptReader::MustThis (const char* c) { 319 void ScriptReader::MustThis (const char* c) {
316 if (token.compare (c) != 0) 320 if (token.compare (c) != 0)
317 ParserError ("expected `%s`, got `%s` instead", c, token.chars()); 321 ParserError ("expected `%s`, got `%s` instead", c, token.chars());
318 } 322 }
319 323
324 // ============================================================================
320 void ScriptReader::ParserError (const char* message, ...) { 325 void ScriptReader::ParserError (const char* message, ...) {
321 PERFORM_FORMAT (message, outmessage); 326 PERFORM_FORMAT (message, outmessage);
322 ParserMessage ("\nError: ", outmessage); 327 ParserMessage ("\nError: ", outmessage);
323 exit (1); 328 exit (1);
324 } 329 }
325 330
331 // ============================================================================
326 void ScriptReader::ParserWarning (const char* message, ...) { 332 void ScriptReader::ParserWarning (const char* message, ...) {
327 PERFORM_FORMAT (message, outmessage); 333 PERFORM_FORMAT (message, outmessage);
328 ParserMessage ("Warning: ", outmessage); 334 ParserMessage ("Warning: ", outmessage);
329 } 335 }
330 336
337 // ============================================================================
331 void ScriptReader::ParserMessage (const char* header, char* message) { 338 void ScriptReader::ParserMessage (const char* header, char* message) {
332 if (fc >= 0 && fc < MAX_FILESTACK) 339 if (fc >= 0 && fc < MAX_FILESTACK)
333 fprintf (stderr, "%sIn file %s, at line %u, col %u: %s\n", 340 fprintf (stderr, "%sIn file %s, at line %u, col %u: %s\n",
334 header, filepath[fc], curline[fc], curchar[fc], message); 341 header, filepath[fc], curline[fc], curchar[fc], message);
335 else 342 else
336 fprintf (stderr, "%s%s\n", header, message); 343 fprintf (stderr, "%s%s\n", header, message);
337 } 344 }
338 345
346 // ============================================================================
339 // if gotquote == 1, the current token already holds the quotation mark. 347 // if gotquote == 1, the current token already holds the quotation mark.
340 void ScriptReader::MustString (bool gotquote) { 348 void ScriptReader::MustString (bool gotquote) {
341 if (gotquote) 349 if (gotquote)
342 MustThis ("\""); 350 MustThis ("\"");
343 else 351 else
358 } 366 }
359 367
360 token = string; 368 token = string;
361 } 369 }
362 370
371 // ============================================================================
363 void ScriptReader::MustNumber (bool fromthis) { 372 void ScriptReader::MustNumber (bool fromthis) {
364 str num; 373 str num;
365 if (!fromthis) 374 if (!fromthis)
366 MustNext (); 375 MustNext ();
367 num += token; 376 num += token;
372 if (!token.compare ("-")) { 381 if (!token.compare ("-")) {
373 MustNext (); 382 MustNext ();
374 num += token; 383 num += token;
375 } 384 }
376 385
377 // Result must be a number. 386 // "true" and "false" are valid numbers
378 if (!num.isnumber()) 387 if (!token.icompare ("true"))
379 ParserError ("expected a number, got `%s`", num.chars()); 388 token = "1";
380 389 else if (!token.icompare ("false"))
381 // Save the number into the token. 390 token = "0";
382 token = num; 391 else {
383 } 392 if (!num.isnumber())
384 393 ParserError ("expected a number, got `%s`", num.chars());
385 void ScriptReader::MustBool () { 394 token = num;
386 MustNext(); 395 }
387 if (!token.compare ("0") || !token.compare ("1") || 396 }
388 !token.compare ("true") || !token.compare ("false") ||
389 !token.compare ("yes") || !token.compare ("no")) {
390 return;
391 }
392
393 ParserError ("expected a boolean value, got `%s`", token.chars());
394 }
395
396 bool ScriptReader::BoolValue () {
397 return (!token.compare ("1") || !token.compare ("true") || !token.compare ("yes"));
398 }
399
400 void ScriptReader::MustValue (int type) {
401 switch (type) {
402 case RETURNVAL_INT: MustNumber (); break;
403 case RETURNVAL_STRING: MustString (); break;
404 case RETURNVAL_BOOLEAN: MustBool (); break;
405 }
406 }

mercurial