Sat, 14 Jul 2012 17:24:21 +0300
Added mainloop/onenter/onexit support, fixed state writing.. this thing can compile the script for the `jumping arghbot` now!
commands.cxx | file | annotate | diff | comparison | revisions | |
events.cxx | file | annotate | diff | comparison | revisions | |
main.cxx | file | annotate | diff | comparison | revisions | |
objwriter.cxx | file | annotate | diff | comparison | revisions | |
objwriter.h | file | annotate | diff | comparison | revisions | |
parser.cxx | file | annotate | diff | comparison | revisions | |
scriptreader.h | file | annotate | diff | comparison | revisions | |
str.cxx | file | annotate | diff | comparison | revisions | |
str.h | file | annotate | diff | comparison | revisions |
--- a/commands.cxx Sat Jul 14 16:31:21 2012 +0300 +++ b/commands.cxx Sat Jul 14 17:24:21 2012 +0300 @@ -50,7 +50,7 @@ CommandDef* g_CommDef; void ReadCommands () { - ScriptReader* r = new ScriptReader ((char*)"commands.def"); + ScriptReader* r = new ScriptReader ("commands.def"); g_CommDef = NULL; CommandDef* curdef = g_CommDef; unsigned int numCommDefs = 0;
--- a/events.cxx Sat Jul 14 16:31:21 2012 +0300 +++ b/events.cxx Sat Jul 14 17:24:21 2012 +0300 @@ -48,7 +48,7 @@ EventDef* g_EventDef; void ReadEvents () { - ScriptReader* r = new ScriptReader ((char*)"events.def"); + ScriptReader* r = new ScriptReader ("events.def"); g_EventDef = NULL; EventDef* curdef = g_EventDef; unsigned int numEventDefs = 0;
--- a/main.cxx Sat Jul 14 16:31:21 2012 +0300 +++ b/main.cxx Sat Jul 14 17:24:21 2012 +0300 @@ -53,19 +53,21 @@ #include "botcommands.h" int main (int argc, char** argv) { + // Print header + str header; + str headerline = "-="; + header.appendformat ("%s version %d.%d.%d", APPNAME, VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION); + headerline.repeat ((header.len()/2)-1); + headerline += '-'; + printf ("%s\n%s\n", header.chars(), headerline.chars()); + if (argc != 3) { fprintf (stderr, "usage: %s: <infile> <outFile>\n", argv[0]); exit (1); } - // Print header - str header; - str headerline = "=-"; - header.appendformat ("%s version %d.%d.%d", APPNAME, VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION); - headerline.repeat ((header.len()/2)-1); - printf ("%s\n%s\n", header.chars(), headerline.chars()); - // Read definitions + printf ("Reading definitions...\n"); ReadEvents (); ReadCommands (); @@ -74,15 +76,17 @@ ObjWriter *w = new ObjWriter (argv[2]); // We're set, begin parsing :) + printf ("Parsing script..\n"); r->BeginParse (w); - // Clear out the junk afterwards + // Parse done, print statistics + printf ("%d states written\n", g_NumStates); + printf ("%d events written\n", g_NumEvents); + printf ("-- %u bytes written to %s\n", w->numWrittenBytes, argv[2]); + + // Clear out the junk delete r; delete w; - - // Print statistics - printf ("%d states written\n", g_NumStates); - printf ("%d events written\n", g_NumEvents); } void error (const char* text, ...) {
--- a/objwriter.cxx Sat Jul 14 16:31:21 2012 +0300 +++ b/objwriter.cxx Sat Jul 14 17:24:21 2012 +0300 @@ -38,6 +38,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#define __OBJWRITER_CXX__ #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -48,6 +49,7 @@ #include "bots.h" ObjWriter::ObjWriter (str path) { + numWrittenBytes = 0; fp = fopen (path, "w"); CHECK_FILE (fp, path, "writing"); }
--- a/objwriter.h Sat Jul 14 16:31:21 2012 +0300 +++ b/objwriter.h Sat Jul 14 17:24:21 2012 +0300 @@ -50,6 +50,7 @@ // ==================================================================== // MEMBERS FILE* fp; + unsigned int numWrittenBytes; // ==================================================================== // METHODS @@ -61,6 +62,7 @@ template <class T> void Write (T stuff) { fwrite (&stuff, sizeof (T), 1, fp); + numWrittenBytes += sizeof (T); } // Cannot use default arguments in function templates..
--- a/parser.cxx Sat Jul 14 16:31:21 2012 +0300 +++ b/parser.cxx Sat Jul 14 17:24:21 2012 +0300 @@ -56,8 +56,10 @@ int g_NumEvents = 0; int g_CurMode = MODE_TOPLEVEL; str g_CurState = ""; +bool g_stateSpawnDefined = false; void ScriptReader::BeginParse (ObjWriter* w) { + bool gotMainLoop = false; while (Next()) { // printf ("got token %s\n", token.chars()); if (!token.compare ("#include")) { @@ -78,18 +80,32 @@ // State name must be a word. if (token.first (" ") != token.len()) ParserError ("state name must be a single word! got `%s`", token.chars()); + str statename = token; + + // stateSpawn is special - it *must* be defined. If we + // encountered it, then mark down that we have it. + if (!token.icompare ("stateSpawn")) + g_stateSpawnDefined = true; // Must end in a colon MustNext (":"); + // If the previous state did not define a mainloop, + // define a dummy one now, since one has to be present. + if (g_CurState.compare ("") != 0 && !gotMainLoop) { + w->Write (DH_MAINLOOP); + w->Write (DH_ENDMAINLOOP); + } + w->Write (DH_STATENAME); - w->Write (token.len()); - w->WriteString (token); + w->Write (statename.len()); + w->WriteString (statename); w->Write (DH_STATEIDX); w->Write (g_NumStates); g_NumStates++; g_CurState = token; + gotMainLoop = false; } else if (!token.compare ("event")) { MUST_TOPLEVEL @@ -107,17 +123,32 @@ w->Write (DH_EVENT); w->Write<long> (e->number); g_NumEvents++; + } else if (!token.compare ("mainloop")) { + MUST_TOPLEVEL + MustNext ("{"); + g_CurMode = MODE_MAINLOOP; + w->Write (DH_MAINLOOP); + gotMainLoop = true; + } else if (!token.compare ("onenter") || !token.compare ("onexit")) { + MUST_TOPLEVEL + bool onenter = !token.compare ("onenter"); + + MustNext ("{"); + g_CurMode = onenter ? MODE_ONENTER : MODE_ONEXIT; + w->Write (onenter ? DH_ONENTER : DH_ONEXIT); } else if (!token.compare ("}")) { + // Closing brace + int dataheader = (g_CurMode == MODE_EVENT) ? DH_ENDEVENT : + (g_CurMode == MODE_MAINLOOP) ? DH_ENDMAINLOOP : + (g_CurMode == MODE_ONENTER) ? DH_ENDONENTER : + (g_CurMode == MODE_ONEXIT) ? DH_ENDONEXIT : -1; + + if (dataheader == -1) + ParserError ("unexpected `}`"); + // Closing brace.. - switch (g_CurMode) { - case MODE_EVENT: - // Brace closes event. - w->Write (DH_ENDEVENT); - g_CurMode = MODE_TOPLEVEL; - break; - default: - ParserError ("unexpected `}`"); - } + w->Write (dataheader); + g_CurMode = MODE_TOPLEVEL; } else { // Check if it's a command. CommandDef* comm = GetCommandByName (token); @@ -129,7 +160,11 @@ } if (g_CurMode != MODE_TOPLEVEL) - ParserError ("script did not end at top level! did you forget a `}`?\n"); + ParserError ("script did not end at top level! did you forget a `}`?"); + + // stateSpawn must be defined! + if (!g_stateSpawnDefined) + ParserError ("script must have a state named `stateSpawn`!"); /* // State @@ -151,6 +186,10 @@ } void ScriptReader::ParseCommand (CommandDef* comm, ObjWriter* w) { + // If this was defined at top-level, we stop right at square one! + if (g_CurMode == MODE_TOPLEVEL) + ParserError ("no commands allowed at top level!"); + w->Write<long> (DH_COMMAND); w->Write<long> (comm->number); w->Write<long> (comm->maxargs);
--- a/scriptreader.h Sat Jul 14 16:31:21 2012 +0300 +++ b/scriptreader.h Sat Jul 14 17:24:21 2012 +0300 @@ -49,7 +49,10 @@ // Where is the parser at? enum parsermode { MODE_TOPLEVEL, // at top level - MODE_EVENT // inside event definition + MODE_EVENT, // inside event definition + MODE_MAINLOOP, // inside mainloop + MODE_ONENTER, // inside onenter + MODE_ONEXIT, // inside onexit }; class ScriptReader {
--- a/str.cxx Sat Jul 14 16:31:21 2012 +0300 +++ b/str.cxx Sat Jul 14 17:24:21 2012 +0300 @@ -340,6 +340,18 @@ return compare (c.chars()); } +int str::icompare (const char* c) { + return icompare (str ((char*)c)); +} + +int str::icompare (str c) { + str a = text; + a.tolower(); + str b = c; + b.tolower(); + return strcmp (a.chars(), b.chars()); +} + // ============================================================================ str str::tolower () { str n = text;
--- a/str.h Sat Jul 14 16:31:21 2012 +0300 +++ b/str.h Sat Jul 14 17:24:21 2012 +0300 @@ -132,8 +132,11 @@ // Convert string to upper case str toupper (); + // Compare this string with another int compare (const char* c); int compare (str c); + int icompare (str c); + int icompare (const char* c); // Counts the amount of substrings in the string unsigned int count (char* s);