Added support for continue-statements

Sat, 25 Aug 2012 04:19:22 +0300

author
Teemu Piippo <crimsondusk64@gmail.com>
date
Sat, 25 Aug 2012 04:19:22 +0300
changeset 59
891b9e6ee139
parent 58
bc9317d1b9c9
child 60
8834e4b6aebd

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;

mercurial