Wed, 19 Dec 2012 04:20:02 +0200
Some rework on variables
commands.cxx | file | annotate | diff | comparison | revisions | |
common.h | file | annotate | diff | comparison | revisions | |
main.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 | |
variables.cxx | file | annotate | diff | comparison | revisions | |
variables.h | file | annotate | diff | comparison | revisions |
--- a/commands.cxx Wed Dec 19 03:27:15 2012 +0200 +++ b/commands.cxx Wed Dec 19 04:20:02 2012 +0200 @@ -159,11 +159,11 @@ // Get command type by name int GetCommandType (str t) { t = t.tolower(); - return !t.compare ("int") ? TYPE_INT : - !t.compare ("float") ? TYPE_FLOAT : - !t.compare ("str") ? TYPE_STRING : - !t.compare ("void") ? TYPE_VOID : - !t.compare ("bool") ? TYPE_BOOL : -1; + return (t == "int") ? TYPE_INT : + (t == "float") ? TYPE_FLOAT : + (t == "str") ? TYPE_STRING : + (t == "void") ? TYPE_VOID : + (t == "bool") ? TYPE_BOOL : -1; } // ============================================================================
--- a/common.h Wed Dec 19 03:27:15 2012 +0200 +++ b/common.h Wed Dec 19 04:20:02 2012 +0200 @@ -59,7 +59,7 @@ #endif // Parser mode: where is the parser at? -enum parsermode { +enum parsermode_e { MODE_TOPLEVEL, // at top level MODE_EVENT, // inside event definition MODE_MAINLOOP, // inside mainloop @@ -93,7 +93,7 @@ // Make the parser's variables globally available extern int g_NumStates; extern int g_NumEvents; -extern int g_CurMode; +extern parsermode_e g_CurMode; extern str g_CurState; #define neurosphere if (g_Neurosphere) @@ -102,6 +102,7 @@ #ifndef __GNUC__ #define __attribute__(X) #endif +#define deprecated __attribute__ ((deprecated)) // Power function template<class T> T pow (T a, unsigned int b) {
--- a/main.cxx Wed Dec 19 03:27:15 2012 +0200 +++ b/main.cxx Wed Dec 19 04:20:02 2012 +0200 @@ -168,7 +168,6 @@ // Init stuff InitStringTable (); - InitVariables (); // Prepare reader and writer ScriptReader* r = new ScriptReader (argv[1]); @@ -180,7 +179,7 @@ printf ("Script parsed successfully.\n"); // Parse done, print statistics and write to file - unsigned int globalcount = CountGlobalVars (); + unsigned int globalcount = g_GlobalVariables.size(); unsigned int stringcount = CountStringTable (); int NumMarks = w->MainBuffer->CountMarks (); int NumRefs = w->MainBuffer->CountReferences ();
--- a/objwriter.h Wed Dec 19 03:27:15 2012 +0200 +++ b/objwriter.h Wed Dec 19 04:20:02 2012 +0200 @@ -48,8 +48,6 @@ #include "databuffer.h" #include "str.h" -extern int g_CurMode; - class ObjWriter { public: // ====================================================================
--- a/parser.cxx Wed Dec 19 03:27:15 2012 +0200 +++ b/parser.cxx Wed Dec 19 04:20:02 2012 +0200 @@ -61,7 +61,7 @@ int g_NumStates = 0; int g_NumEvents = 0; -int g_CurMode = MODE_TOPLEVEL; +parsermode_e g_CurMode = MODE_TOPLEVEL; str g_CurState = ""; bool g_stateSpawnDefined = false; bool g_GotMainLoop = false; @@ -171,11 +171,16 @@ } // ============================================================ - if (token == "var") { + if (token == "int" || token == "str" || token == "float" || token == "bool") { // For now, only globals are supported if (g_CurMode != MODE_TOPLEVEL || g_CurState.len()) ParserError ("variables must only be global for now"); + type_e type = (token == "int") ? TYPE_INT : + (token == "str") ? TYPE_STRING : + (token == "float") ? TYPE_FLOAT : + TYPE_BOOL; + MustNext (); // Var name must not be a number @@ -183,7 +188,7 @@ ParserError ("variable name must not be a number"); str varname = token; - ScriptVar* var = DeclareGlobalVariable (this, varname); + ScriptVar* var = DeclareGlobalVariable (this, type, varname); if (!var) ParserError ("declaring %s variable %s failed", @@ -319,16 +324,25 @@ MustNext ("("); MustNext (); DataBuffer* init = ParseStatement (w); + if (!init) + ParserError ("bad statement for initializer of for"); + MustNext (";"); // Condition MustNext (); DataBuffer* cond = ParseExpression (TYPE_INT); + if (!cond) + ParserError ("bad statement for condition of for"); + MustNext (";"); // Incrementor MustNext (); DataBuffer* incr = ParseStatement (w); + if (!incr) + ParserError ("bad statement for incrementor of for"); + MustNext (")"); MustNext ("{"); @@ -507,7 +521,7 @@ // ============================================================ // Label - if (!PeekNext().compare (":")) { + if (PeekNext() == ":") { MUST_NOT_TOPLEVEL // want no conflicts.. @@ -521,7 +535,7 @@ // See if a mark already exists for this label int mark = -1; for (int i = 0; i < MAX_MARKS; i++) { - if (g_UndefinedLabels[i] && !g_UndefinedLabels[i]->compare (token)) { + if (g_UndefinedLabels[i] && *g_UndefinedLabels[i] == token) { mark = i; w->MoveMark (i); @@ -540,7 +554,7 @@ } // ============================================================ - if (!token.compare ("}")) { + if (token == "}") { // Closing brace // If we're in the block stack, we're descending down from it now @@ -640,7 +654,7 @@ w->Write (dataheader); g_CurMode = MODE_TOPLEVEL; - if (!PeekNext().compare (";")) + if (PeekNext() == ";") MustNext (";"); continue; } @@ -656,6 +670,9 @@ // ============================================================ // If nothing else, parse it as a statement DataBuffer* b = ParseStatement (w); + if (!b) + ParserError ("unknown token `%s`", token.chars()); + w->WriteBuffer (b); MustNext (";"); } @@ -692,7 +709,7 @@ int curarg = 0; while (1) { - if (!token.compare (")")) { + if (token == ")") { if (curarg < comm->numargs) ParserError ("too few arguments passed to %s\n\tprototype: %s", comm->name.chars(), GetCommandPrototype (comm).chars()); @@ -712,7 +729,7 @@ MustNext (); } else if (curarg < comm->maxargs - 1) { // Can continue, but can terminate as well. - if (!token.compare (")")) { + if (token == ")") { curarg++; break; } else { @@ -855,7 +872,7 @@ // ============================================================================ // Parses an operator string. Returns the operator number code. -#define ISNEXT(char) !PeekNext (peek ? 1 : 0).compare (char) +#define ISNEXT(char) (!PeekNext (peek ? 1 : 0) == char) int ScriptReader::ParseOperator (bool peek) { str oper; if (peek) @@ -866,18 +883,18 @@ // Check one-char operators bool equalsnext = ISNEXT ("="); - int o = (!oper.compare ("=") && !equalsnext) ? OPER_ASSIGN : - (!oper.compare (">") && !equalsnext && !ISNEXT (">")) ? OPER_GREATERTHAN : - (!oper.compare ("<") && !equalsnext && !ISNEXT ("<")) ? OPER_LESSTHAN : - (!oper.compare ("&") && !ISNEXT ("&")) ? OPER_BITWISEAND : - (!oper.compare ("|") && !ISNEXT ("|")) ? OPER_BITWISEOR : - !oper.compare ("^") ? OPER_BITWISEEOR : - !oper.compare ("+") ? OPER_ADD : - !oper.compare ("-") ? OPER_SUBTRACT : - !oper.compare ("*") ? OPER_MULTIPLY : - !oper.compare ("/") ? OPER_DIVIDE : - !oper.compare ("%") ? OPER_MODULUS : - !oper.compare ("?") ? OPER_TERNARY : + int o = (oper == "=" && !equalsnext) ? OPER_ASSIGN : + (oper == ">" && !equalsnext && !ISNEXT (">")) ? OPER_GREATERTHAN : + (oper == "<" && !equalsnext && !ISNEXT ("<")) ? OPER_LESSTHAN : + (oper == "&" && !ISNEXT ("&")) ? OPER_BITWISEAND : + (oper == "|" && !ISNEXT ("|")) ? OPER_BITWISEOR : + (oper == "+" && !equalsnext) ? OPER_ADD : + (oper == "-" && !equalsnext) ? OPER_SUBTRACT : + (oper == "*" && !equalsnext) ? OPER_MULTIPLY : + (oper == "/" && !equalsnext) ? OPER_DIVIDE : + (oper == "%" && !equalsnext) ? OPER_MODULUS : + (oper == "^") ? OPER_BITWISEEOR : + (oper == "?") ? OPER_TERNARY : -1; if (o != -1) { @@ -886,21 +903,21 @@ // Two-char operators oper += PeekNext (peek ? 1 : 0); - equalsnext = !PeekNext (peek ? 2 : 1).compare ("="); + equalsnext = PeekNext (peek ? 2 : 1) == ("="); - o = !oper.compare ("+=") ? OPER_ASSIGNADD : - !oper.compare ("-=") ? OPER_ASSIGNSUB : - !oper.compare ("*=") ? OPER_ASSIGNMUL : - !oper.compare ("/=") ? OPER_ASSIGNDIV : - !oper.compare ("%=") ? OPER_ASSIGNMOD : - !oper.compare ("==") ? OPER_EQUALS : - !oper.compare ("!=") ? OPER_NOTEQUALS : - !oper.compare (">=") ? OPER_GREATERTHANEQUALS : - !oper.compare ("<=") ? OPER_LESSTHANEQUALS : - !oper.compare ("&&") ? OPER_AND : - !oper.compare ("||") ? OPER_OR : - (!oper.compare ("<<") && !equalsnext) ? OPER_LEFTSHIFT : - (!oper.compare (">>") && !equalsnext) ? OPER_RIGHTSHIFT : + o = (oper == "+=") ? OPER_ASSIGNADD : + (oper == "-=") ? OPER_ASSIGNSUB : + (oper == "*=") ? OPER_ASSIGNMUL : + (oper == "/=") ? OPER_ASSIGNDIV : + (oper == "%=") ? OPER_ASSIGNMOD : + (oper == "==") ? OPER_EQUALS : + (oper == "!=") ? OPER_NOTEQUALS : + (oper == ">=") ? OPER_GREATERTHANEQUALS : + (oper == "<=") ? OPER_LESSTHANEQUALS : + (oper == "&&") ? OPER_AND : + (oper == "||") ? OPER_OR : + (oper == "<<" && !equalsnext) ? OPER_LEFTSHIFT : + (oper == ">>" && !equalsnext) ? OPER_RIGHTSHIFT : -1; if (o != -1) { @@ -910,8 +927,8 @@ // Three-char opers oper += PeekNext (peek ? 2 : 1); - o = !oper.compare ("<<=") ? OPER_ASSIGNLEFTSHIFT : - !oper.compare (">>=") ? OPER_ASSIGNRIGHTSHIFT : + o = oper == "<<=" ? OPER_ASSIGNLEFTSHIFT : + oper == ">>=" ? OPER_ASSIGNRIGHTSHIFT : -1; if (o != -1) { @@ -932,11 +949,11 @@ ScriptVar* g; // Prefixing "!" means negation. - bool negate = !token.compare ("!"); + bool negate = (token == "!"); if (negate) // Jump past the "!" - MustNext (); + Next (); - if (!token.compare ("(")) { + if (token == "(") { // Expression MustNext (); DataBuffer* c = ParseExpression (reqtype); @@ -949,12 +966,13 @@ if (reqtype && comm->returnvalue != reqtype) ParserError ("%s returns an incompatible data type", comm->name.chars()); b = ParseCommand (comm); - } else if ((g = FindGlobalVariable (token)) && reqtype != TYPE_STRING) { + } else if ((g = FindGlobalVariable (token))) { // Global variable b->Write<word> (DH_PUSHGLOBALVAR); b->Write<word> (g->index); } else { // If nothing else, check for literal + printf ("reqtype: %d\n", reqtype); switch (reqtype) { case TYPE_VOID: ParserError ("unknown identifier `%s` (expected keyword, function or variable)", token.chars()); @@ -964,10 +982,10 @@ MustNumber (true); // All values are written unsigned - thus we need to write the value's - // absolute value, followed by an unary minus if it was negative. + // absolute value, followed by an unary minus for negatives. b->Write<word> (DH_PUSHNUMBER); - long v = atoi (token.chars ()); + long v = atol (token); b->Write<word> (static_cast<word> (abs (v))); if (v < 0) b->Write<word> (DH_UNARYMINUS); @@ -988,7 +1006,7 @@ floatstring += token; // Go after the decimal point - if (!PeekNext ().compare(".")) { + if (PeekNext () == ".") { MustNext ("."); MustNumber (false); floatstring += "."; @@ -1030,6 +1048,7 @@ // Get an operator MustNext (); int oper = ParseOperator (); + printf ("got operator %d\n", oper); if (!IsAssignmentOperator (oper)) ParserError ("expected assignment operator"); @@ -1039,7 +1058,7 @@ // Parse the right operand MustNext (); DataBuffer* retbuf = new DataBuffer; - DataBuffer* expr = ParseExpression (TYPE_INT); + DataBuffer* expr = ParseExpression (var->type); // <<= and >>= do not have data headers. Solution: expand them. // a <<= b -> a = a << b @@ -1086,7 +1105,6 @@ return b; } - ParserError ("bad statement"); return NULL; }
--- a/scriptreader.cxx Wed Dec 19 03:27:15 2012 +0200 +++ b/scriptreader.cxx Wed Dec 19 04:20:02 2012 +0200 @@ -331,7 +331,7 @@ // ============================================================================ void ScriptReader::MustThis (const char* c) { - if (token.compare (c) != 0) + if (token != c) ParserError ("expected `%s`, got `%s` instead", c, token.chars()); } @@ -388,7 +388,7 @@ MustNext (); str num = token; - if (!num.compare ("-")) { + if (num == "-") { MustNext (); num += token; } @@ -404,7 +404,7 @@ str check; check.appendformat ("%d", atoi (num)); - if (token.compare (check) != 0) + if (token != check) ParserWarning ("integer too large: %s -> %s", num.chars(), check.chars()); token = num;
--- a/variables.cxx Wed Dec 19 03:27:15 2012 +0200 +++ b/variables.cxx Wed Dec 19 04:20:02 2012 +0200 @@ -43,6 +43,7 @@ #include <stdlib.h> #include <string.h> #include "common.h" +#include "array.h" #include "bots.h" #include "botcommands.h" #include "objwriter.h" @@ -50,70 +51,48 @@ #include "variables.h" #include "scriptreader.h" -ScriptVar* g_GlobalVariables[MAX_SCRIPT_VARIABLES]; -ScriptVar* g_LocalVariable; - -void InitVariables () { - unsigned int u; - ITERATE_GLOBAL_VARS (u) - g_GlobalVariables[u] = NULL; -} +array<ScriptVar> g_GlobalVariables; +array<ScriptVar> g_LocalVariables; // ============================================================================ // Tries to declare a new global-scope variable. Returns pointer // to new global variable, NULL if declaration failed. -ScriptVar* DeclareGlobalVariable (ScriptReader* r, str name) { - // Check that the name is valid +ScriptVar* DeclareGlobalVariable (ScriptReader* r, type_e type, str name) { + // Unfortunately the VM does not support string variables so yeah. + if (type == TYPE_STRING) + r->ParserError ("variables cannot be string\n"); + + // Check that the variable is valid if (FindCommand (name)) r->ParserError ("name of variable-to-be `%s` conflicts with that of a command", name.chars()); if (IsKeyword (name)) r->ParserError ("name of variable-to-be `%s` is a keyword", name.chars()); - // Find a NULL pointer to a global variable - ScriptVar* g; - unsigned int u = 0; - ITERATE_GLOBAL_VARS (u) { - // Check that it doesn't exist already - if (!g_GlobalVariables[u]) - break; - - if (!g_GlobalVariables[u]->name.icompare (name)) - r->ParserError ("attempted redeclaration of variable `%s`", name.chars()); - } - - if (u == MAX_SCRIPT_VARIABLES) + if (g_GlobalVariables.size() >= MAX_SCRIPT_VARIABLES) r->ParserError ("too many global variables!"); - g = new ScriptVar; - g->index = u; - g->name = name; - g->statename = ""; - g->next = NULL; - g->value = 0; + for (uint i = 0; i < g_GlobalVariables.size(); i++) + if (g_GlobalVariables[i].name == name) + r->ParserError ("attempted redeclaration of global variable `%s`", name.chars()); - g_GlobalVariables[u] = g; - return g; + ScriptVar g; + g.index = g_GlobalVariables.size(); + g.name = name; + g.statename = ""; + g.value = 0; + g.type = type; + + g_GlobalVariables << g; + return &g_GlobalVariables[g.index]; } -/* -void AssignScriptVariable (ScriptReader* r, str name, str value) { - ScriptVar* g = FindScriptVariable (name); - if (!g) - r->ParserError ("global variable %s not declared", name.chars()); -} -*/ - // ============================================================================ // Find a global variable by name ScriptVar* FindGlobalVariable (str name) { - unsigned int u = 0; - ITERATE_GLOBAL_VARS (u) { - ScriptVar* g = g_GlobalVariables[u]; - if (!g) - return NULL; - - if (!g->name.compare (name)) + for (uint i = 0; i < g_GlobalVariables.size(); i++) { + ScriptVar* g = &g_GlobalVariables[i]; + if (g->name == name) return g; } @@ -122,12 +101,6 @@ // ============================================================================ // Count all declared global variables -unsigned int CountGlobalVars () { - unsigned int count = 0; - unsigned int u = 0; - ITERATE_GLOBAL_VARS (u) { - if (g_GlobalVariables[u] != NULL) - count++; - } - return count; +uint CountGlobalVars () { + return g_GlobalVariables.size(); } \ No newline at end of file
--- a/variables.h Wed Dec 19 03:27:15 2012 +0200 +++ b/variables.h Wed Dec 19 04:20:02 2012 +0200 @@ -46,24 +46,21 @@ struct ScriptVar { str name; str statename; + type_e type; int value; unsigned int index; - ScriptVar* next; }; -#ifndef __VARIABLES_CXX__ -extern ScriptVar* g_GlobalVariables[MAX_SCRIPT_VARIABLES]; -extern ScriptVar* g_LocalVariable; -#endif // __VARIABLES_CXX__ +extern array<ScriptVar> g_GlobalVariables; +extern array<ScriptVar> g_LocalVariables; #define ITERATE_GLOBAL_VARS(u) \ for (u = 0; u < MAX_SCRIPT_VARIABLES; u++) #define ITERATE_SCRIPT_VARS(g) \ for (g = g_ScriptVariable; g != NULL; g = g->next) -ScriptVar* DeclareGlobalVariable (ScriptReader* r, str name); -unsigned int CountGlobalVars (); -void InitVariables (); +ScriptVar* DeclareGlobalVariable (ScriptReader* r, type_e type, str name); +deprecated unsigned int CountGlobalVars (); ScriptVar* FindGlobalVariable (str name); #endif // __VARIABLES_H__ \ No newline at end of file