Sat, 25 Aug 2012 04:19:22 +0300
Added support for continue-statements
common.h | file | annotate | diff | comparison | revisions | |
parser.cxx | file | annotate | diff | comparison | revisions | |
scriptreader.h | file | annotate | diff | comparison | revisions |
--- a/common.h Sat Aug 25 04:02:37 2012 +0300 +++ b/common.h Sat Aug 25 04:19:22 2012 +0300 @@ -84,6 +84,9 @@ // Plural expression #define PLURAL(n) (n != 1) ? "s" : "" +// Shortcut for zeroing something +#define ZERO(obj) memset (&obj, 0, sizeof (obj)); + void error (const char* text, ...); char* ObjectFileName (str s); bool fexists (char* path);
--- a/parser.cxx Sat Aug 25 04:02:37 2012 +0300 +++ b/parser.cxx Sat Aug 25 04:19:22 2012 +0300 @@ -75,8 +75,8 @@ // of necessary buffering so stuff is written in the correct order. void ScriptReader::ParseBotScript (ObjWriter* w) { // Zero the entire block stack first - for (int i = 0; i < MAX_STRUCTSTACK; i++) - memset (&scopestack[i], 0, sizeof (BlockInformation)); + for (int i = 0; i < MAX_SCOPE; i++) + ZERO(scopestack[i]); while (Next()) { // Check if else is potentically valid @@ -248,7 +248,7 @@ // Don't use PushScope that will reset the scope. g_ScopeCursor++; - if (g_ScopeCursor >= MAX_STRUCTSTACK) + if (g_ScopeCursor >= MAX_SCOPE) ParserError ("too deep scope"); if (SCOPE(0).type != SCOPETYPE_IF) @@ -469,6 +469,34 @@ } // ============================================================ + // Continue + if (!token.compare ("continue")) { + MustNext (";"); + + int curs; + bool found = false; + + // Drop through the scope until we find a loop block + for (curs = g_ScopeCursor; curs > 0 && !found; curs--) { + switch (scopestack[curs].type) { + case SCOPETYPE_FOR: + case SCOPETYPE_WHILE: + case SCOPETYPE_DO: + w->Write<word> (DH_GOTO); + w->AddReference (scopestack[curs].mark1); + found = true; + break; + } + } + + // No loop blocks + if (!found) + ParserError ("`continue`-statement not inside a loop"); + + continue; + } + + // ============================================================ // Label if (!PeekNext().compare (":")) { MUST_NOT_TOPLEVEL @@ -991,10 +1019,10 @@ void ScriptReader::PushScope () { g_ScopeCursor++; - if (g_ScopeCursor >= MAX_STRUCTSTACK) + if (g_ScopeCursor >= MAX_SCOPE) ParserError ("too deep scope"); - BlockInformation* info = &SCOPE(0); + ScopeInfo* info = &SCOPE(0); info->type = 0; info->mark1 = 0; info->mark2 = 0; @@ -1020,7 +1048,7 @@ } void ScriptReader::AddSwitchCase (ObjWriter* w, DataBuffer* b) { - BlockInformation* info = &SCOPE(0); + ScopeInfo* info = &SCOPE(0); info->casecursor++; if (info->casecursor >= MAX_CASE)
--- a/scriptreader.h Sat Aug 25 04:02:37 2012 +0300 +++ b/scriptreader.h Sat Aug 25 04:19:22 2012 +0300 @@ -47,14 +47,14 @@ #include "commands.h" #define MAX_FILESTACK 8 -#define MAX_STRUCTSTACK 32 +#define MAX_SCOPE 32 #define MAX_CASE 64 class ScriptVar; // ============================================================================ // Meta-data about blocks -struct BlockInformation { +struct ScopeInfo { unsigned int mark1; unsigned int mark2; unsigned int type; @@ -91,7 +91,7 @@ unsigned int pos[MAX_FILESTACK]; unsigned int curline[MAX_FILESTACK]; unsigned int curchar[MAX_FILESTACK]; - BlockInformation scopestack[MAX_STRUCTSTACK]; + ScopeInfo scopestack[MAX_SCOPE]; long savedpos[MAX_FILESTACK]; // filepointer cursor position str token; int commentmode;