parser.cxx

changeset 38
e4bbd540663b
parent 37
c349dca807f9
child 39
07b7ab8080cf
equal deleted inserted replaced
37:c349dca807f9 38:e4bbd540663b
61 int g_NumEvents = 0; 61 int g_NumEvents = 0;
62 int g_CurMode = MODE_TOPLEVEL; 62 int g_CurMode = MODE_TOPLEVEL;
63 str g_CurState = ""; 63 str g_CurState = "";
64 bool g_stateSpawnDefined = false; 64 bool g_stateSpawnDefined = false;
65 bool g_GotMainLoop = false; 65 bool g_GotMainLoop = false;
66 int g_StructStack = 0; 66 unsigned int g_BlockStackCursor = 0;
67 67
68 // ============================================================================ 68 // ============================================================================
69 // Main parser code. Begins read of the script file, checks the syntax of it 69 // Main parser code. Begins read of the script file, checks the syntax of it
70 // and writes the data to the object file via ObjWriter - which also takes care 70 // and writes the data to the object file via ObjWriter - which also takes care
71 // of necessary buffering so stuff is written in the correct order. 71 // of necessary buffering so stuff is written in the correct order.
72 void ScriptReader::BeginParse (ObjWriter* w) { 72 void ScriptReader::BeginParse (ObjWriter* w) {
73 g_StructStack = 0; 73 g_BlockStackCursor = 0;
74 while (Next()) { 74 while (Next()) {
75 printf ("BeginParse: token: `%s`\n", token.chars()); 75 printf ("BeginParse: token: `%s`\n", token.chars());
76 if (!token.icompare ("state")) { 76 if (!token.icompare ("state")) {
77 MUST_TOPLEVEL 77 MUST_TOPLEVEL
78 78
200 w->AddReference (m); 200 w->AddReference (m);
201 MustNext (";"); 201 MustNext (";");
202 continue; 202 continue;
203 } 203 }
204 204
205 // If
206 if (!token.icompare ("if")) {
207 // Condition
208 MustNext ("(");
209
210 // Read the expression and write it.
211 MustNext ();
212 DataBuffer* c = ParseExpression (TYPE_INT);
213 w->WriteBuffer (c);
214 delete c;
215
216 MustNext (")");
217 MustNext ("{");
218
219 // Add a mark - to here temporarily - and add a reference to it.
220 // Upon a closing brace, the mark will be adjusted.
221 unsigned int marknum = w->AddMark (MARKTYPE_IF, "");
222
223 // Use DH_IFNOTGOTO - if the expression is not true, we goto the mark
224 // we just defined - and this mark will be at the end of the block.
225 w->Write<word> (DH_IFNOTGOTO);
226 w->AddReference (marknum);
227
228 // Store it in the block stack
229 blockstack[g_BlockStackCursor] = marknum;
230 g_BlockStackCursor++;
231 continue;
232 }
233
205 if (!token.compare ("}")) { 234 if (!token.compare ("}")) {
206 // If this was done inside the struct stack (i.e. 235 // Closing brace
207 // inside "if" for instance), it does not end the mode. 236
208 if (g_StructStack > 0) { 237 // If we're in the block stack, we're descending down from it now
209 g_StructStack--; 238 if (g_BlockStackCursor > 0) {
239 // Adjust its closing mark so that it's here.
240 unsigned int marknum = blockstack[g_BlockStackCursor];
241 if (marknum != MAX_MARKS) {
242 // printf ("\tblock %d stack mark moved from %d ",
243 g_BlockStackCursor, w->GetCurrentBuffer()->marks[marknum]->pos);
244 w->MoveMark (marknum);
245 // printf ("to %d\n", w->GetCurrentBuffer()->marks[marknum]->pos);
246 }
247
248 g_BlockStackCursor--;
210 continue; 249 continue;
211 } 250 }
212 251
213 // Closing brace
214 int dataheader = (g_CurMode == MODE_EVENT) ? DH_ENDEVENT : 252 int dataheader = (g_CurMode == MODE_EVENT) ? DH_ENDEVENT :
215 (g_CurMode == MODE_MAINLOOP) ? DH_ENDMAINLOOP : 253 (g_CurMode == MODE_MAINLOOP) ? DH_ENDMAINLOOP :
216 (g_CurMode == MODE_ONENTER) ? DH_ENDONENTER : 254 (g_CurMode == MODE_ONENTER) ? DH_ENDONENTER :
217 (g_CurMode == MODE_ONEXIT) ? DH_ENDONEXIT : -1; 255 (g_CurMode == MODE_ONEXIT) ? DH_ENDONEXIT : -1;
218 256
365 case OPER_ADD: return DH_ADD; 403 case OPER_ADD: return DH_ADD;
366 case OPER_SUBTRACT: return DH_SUBTRACT; 404 case OPER_SUBTRACT: return DH_SUBTRACT;
367 case OPER_MULTIPLY: return DH_MULTIPLY; 405 case OPER_MULTIPLY: return DH_MULTIPLY;
368 case OPER_DIVIDE: return DH_DIVIDE; 406 case OPER_DIVIDE: return DH_DIVIDE;
369 case OPER_MODULUS: return DH_MODULUS; 407 case OPER_MODULUS: return DH_MODULUS;
408 case OPER_EQUALS: return DH_EQUALS;
409 case OPER_NOTEQUALS: return DH_NOTEQUALS;
410 case OPER_LESSTHAN: return DH_LESSTHAN;
411 case OPER_GREATERTHAN: return DH_GREATERTHAN;
412 case OPER_LESSTHANEQUALS: return DH_LESSTHANEQUALS;
413 case OPER_GREATERTHANEQUALS: return DH_GREATERTHANEQUALS;
370 } 414 }
371 415
372 error ("DataHeaderByOperator: couldn't find dataheader for operator %d!\n", oper); 416 error ("DataHeaderByOperator: couldn't find dataheader for operator %d!\n", oper);
373 return 0; 417 return 0;
374 } 418 }
429 oper += PeekNext (); 473 oper += PeekNext ();
430 else 474 else
431 oper += token; 475 oper += token;
432 476
433 // Check one-char operators 477 // Check one-char operators
434 int o = !oper.compare ("=") ? OPER_ASSIGN : 478 bool equalsnext = !PeekNext (peek ? 1 : 0).compare ("=");
479 printf ("operator one-char: %s\nequals is%s next (`%s`)\n", oper.chars(),
480 (equalsnext) ? "" : " not", PeekNext (peek ? 1 : 0).chars());
481 int o = (!oper.compare ("=") && !equalsnext) ? OPER_ASSIGN :
482 (!oper.compare (">") && !equalsnext) ? OPER_GREATERTHAN :
483 (!oper.compare ("<") && !equalsnext) ? OPER_LESSTHAN :
435 !oper.compare ("+") ? OPER_ADD : 484 !oper.compare ("+") ? OPER_ADD :
436 !oper.compare ("-") ? OPER_SUBTRACT : 485 !oper.compare ("-") ? OPER_SUBTRACT :
437 !oper.compare ("*") ? OPER_MULTIPLY : 486 !oper.compare ("*") ? OPER_MULTIPLY :
438 !oper.compare ("/") ? OPER_DIVIDE : 487 !oper.compare ("/") ? OPER_DIVIDE :
439 !oper.compare ("%") ? OPER_MODULUS : 488 !oper.compare ("%") ? OPER_MODULUS :
444 } 493 }
445 494
446 // Two-char operators 495 // Two-char operators
447 oper += PeekNext (peek ? 1 : 0); 496 oper += PeekNext (peek ? 1 : 0);
448 497
498 printf ("operator two-char: %s\n", oper.chars());
499
449 o = !oper.compare ("+=") ? OPER_ASSIGNADD : 500 o = !oper.compare ("+=") ? OPER_ASSIGNADD :
450 !oper.compare ("-=") ? OPER_ASSIGNSUB : 501 !oper.compare ("-=") ? OPER_ASSIGNSUB :
451 !oper.compare ("*=") ? OPER_ASSIGNMUL : 502 !oper.compare ("*=") ? OPER_ASSIGNMUL :
452 !oper.compare ("/=") ? OPER_ASSIGNDIV : 503 !oper.compare ("/=") ? OPER_ASSIGNDIV :
453 !oper.compare ("%=") ? OPER_ASSIGNMOD : 504 !oper.compare ("%=") ? OPER_ASSIGNMOD :
505 !oper.compare ("==") ? OPER_EQUALS :
506 !oper.compare ("!=") ? OPER_NOTEQUALS :
507 !oper.compare (">=") ? OPER_GREATERTHANEQUALS :
508 !oper.compare ("<=") ? OPER_LESSTHANEQUALS :
454 -1; 509 -1;
455 510
456 if (o != -1) 511 if (o != -1)
457 MustNext (); 512 MustNext ();
458 513
500 MustNumber (true); 555 MustNumber (true);
501 556
502 // All values are written unsigned - thus we need to write the value's 557 // All values are written unsigned - thus we need to write the value's
503 // absolute value, followed by an unary minus if it was negative. 558 // absolute value, followed by an unary minus if it was negative.
504 b->Write<word> (DH_PUSHNUMBER); 559 b->Write<word> (DH_PUSHNUMBER);
560
505 long v = atoi (token.chars ()); 561 long v = atoi (token.chars ());
506 b->Write<word> (static_cast<word> (abs (v))); 562 b->Write<word> (static_cast<word> (abs (v)));
507 if (v < 0) 563 if (v < 0)
508 b->Write<word> (DH_UNARYMINUS); 564 b->Write<word> (DH_UNARYMINUS);
509 break; 565 break;

mercurial