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 |