| 66 bool g_stateSpawnDefined = false; |
66 bool g_stateSpawnDefined = false; |
| 67 bool g_GotMainLoop = false; |
67 bool g_GotMainLoop = false; |
| 68 unsigned int g_ScopeCursor = 0; |
68 unsigned int g_ScopeCursor = 0; |
| 69 DataBuffer* g_IfExpression = NULL; |
69 DataBuffer* g_IfExpression = NULL; |
| 70 bool g_CanElse = false; |
70 bool g_CanElse = false; |
| 71 str* g_UnmarkedLabels[MAX_MARKS]; |
71 str* g_UndefinedLabels[MAX_MARKS]; |
| 72 |
72 |
| 73 // ============================================================================ |
73 // ============================================================================ |
| 74 // Main parser code. Begins read of the script file, checks the syntax of it |
74 // Main parser code. Begins read of the script file, checks the syntax of it |
| 75 // and writes the data to the object file via ObjWriter - which also takes care |
75 // and writes the data to the object file via ObjWriter - which also takes care |
| 76 // of necessary buffering so stuff is written in the correct order. |
76 // of necessary buffering so stuff is written in the correct order. |
| 78 // Zero the entire block stack first |
78 // Zero the entire block stack first |
| 79 for (int i = 0; i < MAX_SCOPE; i++) |
79 for (int i = 0; i < MAX_SCOPE; i++) |
| 80 ZERO(scopestack[i]); |
80 ZERO(scopestack[i]); |
| 81 |
81 |
| 82 for (int i = 0; i < MAX_MARKS; i++) |
82 for (int i = 0; i < MAX_MARKS; i++) |
| 83 g_UnmarkedLabels[i] = NULL; |
83 g_UndefinedLabels[i] = NULL; |
| 84 |
84 |
| 85 while (Next()) { |
85 while (Next()) { |
| 86 // Check if else is potentically valid |
86 // Check if else is potentically valid |
| 87 if (!token.compare ("else") && !g_CanElse) |
87 if (!token.compare ("else") && !g_CanElse) |
| 88 ParserError ("else without preceding if"); |
88 ParserError ("else without preceding if"); |
| 204 unsigned int m = w->FindMark (token); |
204 unsigned int m = w->FindMark (token); |
| 205 |
205 |
| 206 // If not set, define it |
206 // If not set, define it |
| 207 if (m == MAX_MARKS) { |
207 if (m == MAX_MARKS) { |
| 208 m = w->AddMark (token); |
208 m = w->AddMark (token); |
| 209 g_UnmarkedLabels[m] = new str (token); |
209 g_UndefinedLabels[m] = new str (token); |
| 210 } |
210 } |
| 211 |
211 |
| 212 // Add a reference to the mark. |
212 // Add a reference to the mark. |
| 213 w->Write<word> (DH_GOTO); |
213 w->Write<word> (DH_GOTO); |
| 214 w->AddReference (m); |
214 w->AddReference (m); |
| 513 if (FindCommand (token)) |
513 if (FindCommand (token)) |
| 514 ParserError ("label name `%s` conflicts with command name\n", token.chars()); |
514 ParserError ("label name `%s` conflicts with command name\n", token.chars()); |
| 515 if (FindGlobalVariable (token)) |
515 if (FindGlobalVariable (token)) |
| 516 ParserError ("label name `%s` conflicts with variable\n", token.chars()); |
516 ParserError ("label name `%s` conflicts with variable\n", token.chars()); |
| 517 |
517 |
| 518 // See if the label is already defined but unmarked |
518 // See if a mark already exists for this label |
| 519 int mark = -1; |
519 int mark = -1; |
| 520 for (int i = 0; i < MAX_MARKS; i++) { |
520 for (int i = 0; i < MAX_MARKS; i++) { |
| 521 if (g_UnmarkedLabels[i] && !g_UnmarkedLabels[i]->compare (token)) { |
521 if (g_UndefinedLabels[i] && !g_UndefinedLabels[i]->compare (token)) { |
| 522 mark = i; |
522 mark = i; |
| 523 w->MoveMark (i); |
523 w->MoveMark (i); |
| 524 |
524 |
| 525 // No longer unmarked |
525 // No longer undefinde |
| 526 delete g_UnmarkedLabels[i]; |
526 delete g_UndefinedLabels[i]; |
| 527 g_UnmarkedLabels[i] = NULL; |
527 g_UndefinedLabels[i] = NULL; |
| 528 } |
528 } |
| 529 } |
529 } |
| 530 |
530 |
| 531 // Not found in unmarked lists, define it now |
531 // Not found in unmarked lists, define it now |
| 532 if (mark == -1) |
532 if (mark == -1) |
| 653 // stateSpawn must be defined! |
653 // stateSpawn must be defined! |
| 654 if (!g_stateSpawnDefined) |
654 if (!g_stateSpawnDefined) |
| 655 ParserError ("script must have a state named `stateSpawn`!"); |
655 ParserError ("script must have a state named `stateSpawn`!"); |
| 656 |
656 |
| 657 for (int i = 0; i < MAX_MARKS; i++) |
657 for (int i = 0; i < MAX_MARKS; i++) |
| 658 if (g_UnmarkedLabels[i]) |
658 if (g_UndefinedLabels[i]) |
| 659 ParserError ("label `%s` is referenced via `goto` but isn't defined\n", g_UnmarkedLabels[i]->chars()); |
659 ParserError ("label `%s` is referenced via `goto` but isn't defined\n", g_UndefinedLabels[i]->chars()); |
| 660 |
660 |
| 661 // Dump the last state's onenter and mainloop |
661 // Dump the last state's onenter and mainloop |
| 662 w->WriteBuffers (); |
662 w->WriteBuffers (); |
| 663 |
663 |
| 664 // String table |
664 // String table |