Added support for #include directives, added basic header and statistics printing.

Fri, 13 Jul 2012 18:41:40 +0300

author
Teemu Piippo <crimsondusk64@gmail.com>
date
Fri, 13 Jul 2012 18:41:40 +0300
changeset 1
f0c61c204bc8
parent 0
8dce9696d62d
child 2
bb2c45522eb6

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 ();

mercurial