Fri, 13 Jul 2012 18:41:40 +0300
Added support for #include directives, added basic header and statistics printing.
common.h | 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.cxx | file | annotate | diff | comparison | revisions | |
scriptreader.h | file | annotate | diff | comparison | revisions |
--- a/common.h Fri Jul 13 17:20:51 2012 +0300 +++ b/common.h Fri Jul 13 18:41:40 2012 +0300 @@ -45,14 +45,21 @@ #include "bots.h" #include "str.h" -typedef unsigned long qbyte; +#define APPNAME "botc" +#define VERSION_MAJOR 0 +#define VERSION_MINOR 0 +#define VERSION_REVISION 999 -#define CHECK_FILE(path,action) if (!fp) { \ - fprintf (stderr, "error: couldn't open %s for %s!\n", (char*)path, action); \ - exit (1); \ +typedef unsigned long qbyte; + +#define CHECK_FILE(pointer,path,action) \ + if (!pointer) { \ + error ("couldn't open %s for %s!\n", (char*)path, action); \ + exit (1); \ } -#define PERFORM_FORMAT(in, out) va_list v; \ +#define PERFORM_FORMAT(in, out) \ + va_list v; \ va_start (v, in); \ char* out = vdynformat (in, v, 256); \ va_end (v); @@ -63,4 +70,11 @@ str name; }; +#ifndef __PARSER_CXX__ +extern int g_NumStates; +extern int g_NumEvents; +extern int g_CurMode; +extern str g_CurState; +#endif + #endif // __COMMON_H__ \ No newline at end of file
--- a/main.cxx Fri Jul 13 17:20:51 2012 +0300 +++ b/main.cxx Fri Jul 13 18:41:40 2012 +0300 @@ -57,17 +57,29 @@ 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()); + + // Prepare reader and writer str infile = argv[1]; str outfile = argv[2]; - ScriptReader *r = new ScriptReader (infile); ObjWriter *w = new ObjWriter (outfile); - // Alrite, we're set, begin parsing :) + // We're set, begin parsing :) r->BeginParse (w); + // Clear out the junk afterwards 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 Fri Jul 13 17:20:51 2012 +0300 +++ b/objwriter.cxx Fri Jul 13 18:41:40 2012 +0300 @@ -48,10 +48,8 @@ #include "bots.h" ObjWriter::ObjWriter (str path) { - numstates = 0; - fp = fopen (path, "w"); - CHECK_FILE (path, "writing"); + CHECK_FILE (fp, path, "writing"); } ObjWriter::~ObjWriter () { @@ -69,16 +67,4 @@ void ObjWriter::WriteString (str s) { WriteString (s.chars()); -} - -// Writes a state label -void ObjWriter::WriteState (str name) { - printf ("write state %s\n", (char*)name); - Write (DH_STATENAME); - Write (name.len()); - WriteString (name); - Write (DH_STATEIDX); - Write (numstates); - - numstates++; } \ No newline at end of file
--- a/objwriter.h Fri Jul 13 17:20:51 2012 +0300 +++ b/objwriter.h Fri Jul 13 18:41:40 2012 +0300 @@ -47,15 +47,17 @@ class ObjWriter { public: + // ==================================================================== + // MEMBERS FILE* fp; - int numstates; + // ==================================================================== + // METHODS ObjWriter (str path); ~ObjWriter (); void WriteString (char* s); void WriteString (const char* s); void WriteString (str s); - void WriteState (str name); template <class T> void Write (T stuff) { fwrite (&stuff, sizeof (T), 1, fp);
--- a/parser.cxx Fri Jul 13 17:20:51 2012 +0300 +++ b/parser.cxx Fri Jul 13 18:41:40 2012 +0300 @@ -38,6 +38,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#define __PARSER_CXX__ + #include <stdio.h> #include <stdlib.h> #include "common.h" @@ -47,17 +49,27 @@ #define TOKEN_CHARS token.chars() #define TOKEN_IS(s) !token.compare (s) -#define MUST_TOPLEVEL if (curmode != MODE_TOPLEVEL) \ +#define MUST_TOPLEVEL if (g_CurMode != MODE_TOPLEVEL) \ ParseError ("%ss may only be defined at top level!", token.chars()); +int g_NumStates = 0; +int g_NumEvents = 0; +int g_CurMode = MODE_TOPLEVEL; +str g_CurState = ""; + void ScriptReader::BeginParse (ObjWriter* w) { - // Script starts at top level - curmode = MODE_TOPLEVEL; - curstate = ""; - while (Next()) { - printf ("got token %s\n", (char*)token); - if (TOKEN_IS ("state")) { + // printf ("got token %s\n", token.chars()); + if (TOKEN_IS ("#include")) { + MustNext (); + // First ensure that the file can be opened + FILE* newfile = fopen (token.chars(), "r"); + if (!newfile) + ParseError ("couldn't open included file `%s`!", token.chars()); + fclose (newfile); + ScriptReader* newreader = new ScriptReader (token.chars()); + newreader->BeginParse (w); + } else if (TOKEN_IS ("state")) { MUST_TOPLEVEL MustNext (); @@ -68,12 +80,17 @@ if (statename.first (" ") != statename.len()) ParseError ("state name must be a single word! got `%s`", (char*)statename); - // Must end in a colon MustNext (":"); - w->WriteState (statename); - curstate = statename; + w->Write (DH_STATENAME); + w->Write (statename.len()); + w->WriteString (statename); + w->Write (DH_STATEIDX); + w->Write (g_NumStates); + + g_NumStates++; + g_CurState = statename; } else if (TOKEN_IS ("event")) { MUST_TOPLEVEL @@ -95,18 +112,18 @@ MustNext ("{"); - curmode = MODE_EVENT; + g_CurMode = MODE_EVENT; w->Write (DH_EVENT); // w->Write<long> (u); - numevents++; + g_NumEvents++; } else if (TOKEN_IS ("}")) { // Closing brace.. - switch (curmode) { + switch (g_CurMode) { case MODE_EVENT: // Brace closes event. w->Write (DH_ENDEVENT); - curmode = MODE_TOPLEVEL; + g_CurMode = MODE_TOPLEVEL; break; default: ParseError ("unexpected `}`"); @@ -116,7 +133,7 @@ } } - if (curmode != MODE_TOPLEVEL) + if (g_CurMode != MODE_TOPLEVEL) ParseError ("script did not end at top level! did you forget a `}`?\n"); /*
--- a/scriptreader.cxx Fri Jul 13 17:20:51 2012 +0300 +++ b/scriptreader.cxx Fri Jul 13 18:41:40 2012 +0300 @@ -55,13 +55,17 @@ ScriptReader::ScriptReader (str path) { fp = fopen (path, "r"); - CHECK_FILE (path, "reading"); + CHECK_FILE (fp, path, "reading"); curline = 1; pos = 0; token = ""; } +ScriptReader::~ScriptReader () { + fclose (fp); +} + char ScriptReader::ReadChar () { char* c = (char*)malloc (sizeof (char)); if (!fread (c, sizeof (char), 1, fp))
--- a/scriptreader.h Fri Jul 13 17:20:51 2012 +0300 +++ b/scriptreader.h Fri Jul 13 18:41:40 2012 +0300 @@ -53,18 +53,18 @@ class ScriptReader { public: + // ==================================================================== + // MEMBERS FILE* fp; unsigned int pos; unsigned int curline; str token; bool tokenquoted; - parsermode curmode; - str curstate; - - unsigned int numevents; - + // ==================================================================== + // METHODS ScriptReader (str path); + ~ScriptReader (); char ReadChar (); bool Next (); str PeekNext ();