Sat, 14 Jul 2012 04:03:25 +0300
Commands are now read properly.
commands.cxx | file | annotate | diff | comparison | revisions | |
commands.def | file | annotate | diff | comparison | revisions | |
commands.h | file | annotate | diff | comparison | revisions | |
main.cxx | 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 | |
str.cxx | file | annotate | diff | comparison | revisions | |
str.h | file | annotate | diff | comparison | revisions |
--- a/commands.cxx Sat Jul 14 02:16:48 2012 +0300 +++ b/commands.cxx Sat Jul 14 04:03:25 2012 +0300 @@ -48,7 +48,6 @@ CommandDef* g_CommDef; -#define MAX void ReadCommands () { ScriptReader* r = new ScriptReader ((char*)"commands.def"); g_CommDef = NULL; @@ -141,4 +140,17 @@ delete r; printf ("%d command definitions read.\n", numCommDefs); +} + +CommandDef* GetCommandByName (str a) { + a.tolower (); + CommandDef* c; + ITERATE_COMMANDS (c) { + str b = c->name; + b.tolower (); + if (!a.compare (b)) + return c; + } + + return NULL; } \ No newline at end of file
--- a/commands.def Sat Jul 14 02:16:48 2012 +0300 +++ b/commands.def Sat Jul 14 04:03:25 2012 +0300 @@ -1,5 +1,5 @@ -0:changestate:int:1:1 -1:delay:int:1:1 +0:changestate:void:1:1 +1:delay:void:1:1 2:rand:int:2:2 3:StringsAreEqual:bool:0:0 4:LookForPowerups:int:2:2 @@ -11,13 +11,13 @@ 10:LookForSuperArmor:int:2:2 11:LookForPlayerEnemies:int:1:1 12:GetClosestPlayerEnemy:int:0:0 -13:MoveLeft:int:1:1 -14:MoveRight:int:1:1 -15:MoveForward:int:1:1 -16:MoveBackwards:int:1:1 -17:StopMovement:int:0:0 -18:StopForwardMovement:int:0:0 -19:StopSidewaysMovement:int:0:0 +13:MoveLeft:void:1:1 +14:MoveRight:void:1:1 +15:MoveForward:void:1:1 +16:MoveBackwards:void:1:1 +17:StopMovement:void:0:0 +18:StopForwardMovement:void:0:0 +19:StopSidewaysMovement:void:0:0 20:CheckTerrain:int:2:2 21:PathToGoal:int:1:1 22:PathToLastKnownEnemyPosition:int:1:1 @@ -27,42 +27,42 @@ 26:GetDistanceToItem:int:1:1 27:GetItemName:str:1:1 28:IsItemVisible:bool:1:1 -29:SetGoal:int:1:1 -30:BeginAimingAtEnemy:int:0:0 -31:StopAimingAtEnemy:int:0:0 -32:Turn:int:1:1 +29:SetGoal:void:1:1 +30:BeginAimingAtEnemy:void:0:0 +31:StopAimingAtEnemy:void:0:0 +32:Turn:void:1:1 33:GetCurrentAngle:int:0:0 -34:SetEnemy:int:1:1 -35:ClearEnemy:int:0:0 +34:SetEnemy:void:1:1 +35:ClearEnemy:void:0:0 36:IsEnemyAlive:bool:0:0 37:IsEnemyVisible:bool:0:0 38:GetDistanceToEnemy:int:0:0 39:GetPlayerDamagedBy:int:0:0 40:GetEnemyInvulnerabilityTicks:int:0:0 -41:FireWeapon:int:0:0 -42:BeginFiringWeapon:int:0:0 -43:StopFiringWeapon:int:0:0 +41:FireWeapon:void:0:0 +42:BeginFiringWeapon:void:0:0 +43:StopFiringWeapon:void:0:0 44:GetCurrentWeapon:str:0:0 -45:ChangeWeapon:int:0:0 +45:ChangeWeapon:void:0:0 46:GetWeaponFromItem:str:1:1 47:IsWeaponOwned:bool:1:1 48:IsFavoriteWeapon:bool:0:0 -49:Say:int:0:0 -50:SayFromFile:int:0:0 -51:SayFromChatFile:int:0:0 -52:BeginChatting:int:0:0 -53:StopChatting:int:0:0 +49:Say:void:0:0 +50:SayFromFile:void:0:0 +51:SayFromChatFile:void:0:0 +52:BeginChatting:void:0:0 +53:StopChatting:void:0:0 54:ChatSectionExists:bool:0:0 55:ChatSectionExistsInFile:bool:0:0 56:GetLastChatString:str:0:0 57:GetLastChatPlayer:str:0:0 58:GetChatFrequency:int:0:0 -59:Jump:int:0:0 -60:BeginJumping:int:0:0 -61:StopJumping:int:0:0 -62:Taunt:int:0:0 -63:Respawn:int:0:0 -64:TryToJoinGame:int:0:0 +59:Jump:void:0:0 +60:BeginJumping:void:0:0 +61:StopJumping:void:0:0 +62:Taunt:void:0:0 +63:Respawn:void:0:0 +64:TryToJoinGame:void:0:0 65:IsDead:bool:0:0 66:IsSpectating:bool:0:0 67:GetHealth:int:0:0 @@ -76,18 +76,18 @@ 75:GetEvade:int:0:0 76:GetReactionTime:int:0:0 77:GetPerception:int:0:0 -78:SetSkillIncrease:int:1:1 +78:SetSkillIncrease:void:1:1 79:IsSkillIncreased:bool:0:0 -80:SetSkillDecrease:int:1:1 +80:SetSkillDecrease:void:1:1 81:IsSkillDecreased:bool:0:0 82:GetGameMode:int:0:0 83:GetSpread:int:0:0 84:GetLastJoinedPlayer:str:0:0 85:GetPlayerName:str:1:1 86:GetReceivedMedal:int:0:0 -87:ACS_Execute:int:5:5 +87:ACS_Execute:void:5:5 88:GetFavoriteWeapon:str:0:0 -89:SayFromLump:int:0:0 -90:SayFromChatLump:int:0:0 +89:SayFromLump:void:0:0 +90:SayFromChatLump:void:0:0 91:ChatSectionExistsInLump:bool:0:0 92:ChatSectionExistsInChatLump:bool:0:0 \ No newline at end of file
--- a/commands.h Sat Jul 14 02:16:48 2012 +0300 +++ b/commands.h Sat Jul 14 04:03:25 2012 +0300 @@ -57,5 +57,6 @@ }; void ReadCommands (); +CommandDef* GetCommandByName (str a); #endif // __COMMANDS_H__ \ No newline at end of file
--- a/main.cxx Sat Jul 14 02:16:48 2012 +0300 +++ b/main.cxx Sat Jul 14 04:03:25 2012 +0300 @@ -74,6 +74,7 @@ ObjWriter *w = new ObjWriter (argv[2]); // We're set, begin parsing :) + r->extdelimeters = true; r->BeginParse (w); // Clear out the junk afterwards
--- a/parser.cxx Sat Jul 14 02:16:48 2012 +0300 +++ b/parser.cxx Sat Jul 14 04:03:25 2012 +0300 @@ -47,9 +47,8 @@ #include "objwriter.h" #include "scriptreader.h" #include "events.h" +#include "commands.h" -#define TOKEN_CHARS token.chars() -#define TOKEN_IS(s) !token.compare (s) #define MUST_TOPLEVEL if (g_CurMode != MODE_TOPLEVEL) \ ParserError ("%ss may only be defined at top level!", token.chars()); @@ -61,7 +60,7 @@ void ScriptReader::BeginParse (ObjWriter* w) { while (Next()) { // printf ("got token %s\n", token.chars()); - if (TOKEN_IS ("#include")) { + if (!token.compare ("#include")) { MustNext (); // First ensure that the file can be opened FILE* newfile = fopen (token.chars(), "r"); @@ -70,7 +69,7 @@ fclose (newfile); ScriptReader* newreader = new ScriptReader (token.chars()); newreader->BeginParse (w); - } else if (TOKEN_IS ("state")) { + } else if (!token.compare ("state")) { MUST_TOPLEVEL MustNext (); @@ -92,7 +91,7 @@ g_NumStates++; g_CurState = statename; - } else if (TOKEN_IS ("event")) { + } else if (!token.compare ("event")) { MUST_TOPLEVEL // Event definition @@ -109,7 +108,7 @@ w->Write (DH_EVENT); w->Write<long> (e->number); g_NumEvents++; - } else if (TOKEN_IS ("}")) { + } else if (!token.compare ("}")) { // Closing brace.. switch (g_CurMode) { case MODE_EVENT: @@ -121,7 +120,43 @@ ParserError ("unexpected `}`"); } } else { - ParserError ("unknown keyword `%s`!", TOKEN_CHARS); + // Check if it's a command. + CommandDef* comm = GetCommandByName (token); + if (comm) { + w->Write<long> (DH_COMMAND); + w->Write<long> (comm->number); + w->Write<long> (comm->numargs); + MustNext ("("); + int curarg = 0; + while (1) { + if (curarg >= comm->numargs) { + MustNext (")"); + break; + } + + if (!Next ()) + ParserError ("unexpected end-of-file, unterminated command"); + + // If we get a ")" now, the user probably gave too few parameters + if (!token.compare (")")) + ParserError ("unexpected `)`, did you pass too few parameters? (need %d)", comm->numargs); + + // For now, it takes in just numbers. + // Needs to cater for string arguments too... + if (!token.isnumber()) + ParserError ("argument %d (`%s`) is not a number", curarg, token.chars()); + + int i = atoi (token.chars ()); + w->Write<long> (i); + + if (curarg != comm->numargs - 1) + MustNext (","); + + curarg++; + } + MustNext (";"); + } else + ParserError ("unknown keyword `%s`!", token.chars()); } }
--- a/scriptreader.cxx Sat Jul 14 02:16:48 2012 +0300 +++ b/scriptreader.cxx Sat Jul 14 04:03:25 2012 +0300 @@ -45,7 +45,7 @@ #include "common.h" #include "scriptreader.h" -bool IsWhitespace (char c) { +bool IsDelimeter (char c) { // These characters are invisible, thus considered whitespace if (c <= 32 || c == 127 || c == 255) return true; @@ -54,6 +54,7 @@ } ScriptReader::ScriptReader (str path) { + extdelimeters = false; atnewline = false; filepath = path; if (!(fp = fopen (path, "r"))) { @@ -106,7 +107,31 @@ continue; } - if (IsWhitespace (c) && !quote) { + // Extended delimeters: parenthesis, quote marks, braces and brackets. + // These delimeters break the word too. If there was prior data, + // the delimeter pushes the cursor back so that the next character + // will be the same delimeter. If there isn't, the delimeter itself + // is included (and thus becomes a token itself.) + // TODO: quotation marks should be here too.. + bool shouldBreak = false; + if (extdelimeters) { + switch (c) { + case '(': case ')': + case '{': case '}': + case '[': case ']': + // Push the cursor back + if (tmp.len()) + fseek (fp, ftell (fp)-1, SEEK_SET); + else + tmp += c; + shouldBreak = true; + break; + } + } + if (shouldBreak) + break; + + if (IsDelimeter (c) && !quote) { // Don't break if we haven't gathered anything yet. if (tmp.len()) break;
--- a/scriptreader.h Sat Jul 14 02:16:48 2012 +0300 +++ b/scriptreader.h Sat Jul 14 04:03:25 2012 +0300 @@ -62,6 +62,7 @@ str token; bool tokenquoted; bool atnewline; + bool extdelimeters; // ==================================================================== // METHODS
--- a/str.cxx Sat Jul 14 02:16:48 2012 +0300 +++ b/str.cxx Sat Jul 14 04:03:25 2012 +0300 @@ -309,30 +309,22 @@ // ============================================================================ bool str::isnumber () { - return contentcheck (SCCF_NUMBER); + ITERATE_STRING (u) + if (text[u] < '0' || text[u] > '9') + return false; + return true; } // ============================================================================ bool str::isword () { - return contentcheck (SCCF_WORD); -} - -bool str::contentcheck (int flags) { ITERATE_STRING (u) { - if (flags & SCCF_WORD) { - // lowercase letters - if (text[u] >= 'a' || text[u] <= 'z') - continue; - - // uppercase letters - if (text[u] >= 'A' || text[u] <= 'Z') - continue; - } + // lowercase letters + if (text[u] >= 'a' || text[u] <= 'z') + continue; - if (flags & SCCF_NUMBER) { - if (text[u] < '0' || text[u] > '9') - return false; - } + // uppercase letters + if (text[u] >= 'A' || text[u] <= 'Z') + continue; return false; }