| 73 // Main parser code. Begins read of the script file, checks the syntax of it |
73 // Main parser code. Begins read of the script file, checks the syntax of it |
| 74 // and writes the data to the object file via ObjWriter - which also takes care |
74 // and writes the data to the object file via ObjWriter - which also takes care |
| 75 // of necessary buffering so stuff is written in the correct order. |
75 // of necessary buffering so stuff is written in the correct order. |
| 76 void ScriptReader::ParseBotScript (ObjWriter* w) { |
76 void ScriptReader::ParseBotScript (ObjWriter* w) { |
| 77 // Zero the entire block stack first |
77 // Zero the entire block stack first |
| 78 for (int i = 0; i < MAX_STRUCTSTACK; i++) |
78 for (int i = 0; i < MAX_SCOPE; i++) |
| 79 memset (&scopestack[i], 0, sizeof (BlockInformation)); |
79 ZERO(scopestack[i]); |
| 80 |
80 |
| 81 while (Next()) { |
81 while (Next()) { |
| 82 // Check if else is potentically valid |
82 // Check if else is potentically valid |
| 83 if (!token.compare ("else") && !g_CanElse) |
83 if (!token.compare ("else") && !g_CanElse) |
| 84 ParserError ("else without preceding if"); |
84 ParserError ("else without preceding if"); |
| 246 MUST_NOT_TOPLEVEL |
246 MUST_NOT_TOPLEVEL |
| 247 MustNext ("{"); |
247 MustNext ("{"); |
| 248 |
248 |
| 249 // Don't use PushScope that will reset the scope. |
249 // Don't use PushScope that will reset the scope. |
| 250 g_ScopeCursor++; |
250 g_ScopeCursor++; |
| 251 if (g_ScopeCursor >= MAX_STRUCTSTACK) |
251 if (g_ScopeCursor >= MAX_SCOPE) |
| 252 ParserError ("too deep scope"); |
252 ParserError ("too deep scope"); |
| 253 |
253 |
| 254 if (SCOPE(0).type != SCOPETYPE_IF) |
254 if (SCOPE(0).type != SCOPETYPE_IF) |
| 255 ParserError ("else without preceding if"); |
255 ParserError ("else without preceding if"); |
| 256 |
256 |
| 463 ParserError ("unexpected `break`"); |
463 ParserError ("unexpected `break`"); |
| 464 break; |
464 break; |
| 465 } |
465 } |
| 466 |
466 |
| 467 MustNext (";"); |
467 MustNext (";"); |
| |
468 continue; |
| |
469 } |
| |
470 |
| |
471 // ============================================================ |
| |
472 // Continue |
| |
473 if (!token.compare ("continue")) { |
| |
474 MustNext (";"); |
| |
475 |
| |
476 int curs; |
| |
477 bool found = false; |
| |
478 |
| |
479 // Drop through the scope until we find a loop block |
| |
480 for (curs = g_ScopeCursor; curs > 0 && !found; curs--) { |
| |
481 switch (scopestack[curs].type) { |
| |
482 case SCOPETYPE_FOR: |
| |
483 case SCOPETYPE_WHILE: |
| |
484 case SCOPETYPE_DO: |
| |
485 w->Write<word> (DH_GOTO); |
| |
486 w->AddReference (scopestack[curs].mark1); |
| |
487 found = true; |
| |
488 break; |
| |
489 } |
| |
490 } |
| |
491 |
| |
492 // No loop blocks |
| |
493 if (!found) |
| |
494 ParserError ("`continue`-statement not inside a loop"); |
| |
495 |
| 468 continue; |
496 continue; |
| 469 } |
497 } |
| 470 |
498 |
| 471 // ============================================================ |
499 // ============================================================ |
| 472 // Label |
500 // Label |
| 989 return retbuf; |
1017 return retbuf; |
| 990 } |
1018 } |
| 991 |
1019 |
| 992 void ScriptReader::PushScope () { |
1020 void ScriptReader::PushScope () { |
| 993 g_ScopeCursor++; |
1021 g_ScopeCursor++; |
| 994 if (g_ScopeCursor >= MAX_STRUCTSTACK) |
1022 if (g_ScopeCursor >= MAX_SCOPE) |
| 995 ParserError ("too deep scope"); |
1023 ParserError ("too deep scope"); |
| 996 |
1024 |
| 997 BlockInformation* info = &SCOPE(0); |
1025 ScopeInfo* info = &SCOPE(0); |
| 998 info->type = 0; |
1026 info->type = 0; |
| 999 info->mark1 = 0; |
1027 info->mark1 = 0; |
| 1000 info->mark2 = 0; |
1028 info->mark2 = 0; |
| 1001 info->buffer1 = NULL; |
1029 info->buffer1 = NULL; |
| 1002 info->casecursor = -1; |
1030 info->casecursor = -1; |
| 1018 DataBuffer* b = ParseExpression (TYPE_VOID); |
1046 DataBuffer* b = ParseExpression (TYPE_VOID); |
| 1019 return b; |
1047 return b; |
| 1020 } |
1048 } |
| 1021 |
1049 |
| 1022 void ScriptReader::AddSwitchCase (ObjWriter* w, DataBuffer* b) { |
1050 void ScriptReader::AddSwitchCase (ObjWriter* w, DataBuffer* b) { |
| 1023 BlockInformation* info = &SCOPE(0); |
1051 ScopeInfo* info = &SCOPE(0); |
| 1024 |
1052 |
| 1025 info->casecursor++; |
1053 info->casecursor++; |
| 1026 if (info->casecursor >= MAX_CASE) |
1054 if (info->casecursor >= MAX_CASE) |
| 1027 ParserError ("too many cases in one switch"); |
1055 ParserError ("too many cases in one switch"); |
| 1028 |
1056 |