| 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; |