// ---------------------------------------------------------------- // bool CommandInterpreter::parse( CommandProcessor& cp, const char* command ) { if (!command) return false; if(command[0] == '#') //Comment return true; // Split the command into full command name and parameter list DynArray<string> split; { FOREACH_TOKEN( token, command, "()" ) split.add( token ); } if( split.size() < 1 || split.size() > 2 ) return false; const char* strFullCommandName = "EMPTY"; const char* strParams = "EMPTY"; if(split.size() >= 1) { strFullCommandName = split[0].c_str(); if(split.size() == 2) strParams = split[1].c_str(); } // Request the command CommandRef commandRef = cp.requestCommand( strFullCommandName ); if( commandRef && commandRef->object ) { CommandParameters* cmdParams; parseParams( cp, commandRef, strParams, cmdParams ); // Call the command commandRef->action->call( commandRef->object, *cmdParams ); delete cmdParams; return true; } parseErrors.add("Command not found."); return false; }
// ---------------------------------------------------------------- // bool CommandInterpreter::parseParams( CommandProcessor& cp , CommandCached const * const cmd , const char* strParams , CommandParameters*& out ) { // Now split the parameter list DynArray<const char*> params; { FOREACH_TOKEN( token, strParams, "," ) params.add( token ); } // Make sure the parameter list is the expected size if( params.size() < cmd->input.size() ) { parseErrors.add("Not enough parameters."); return false; } // Loop through the signature and pack all of the parameters into the command parameters class out = new CommandParameters( cmd->getSignatureSize( cp, params ) ); int offset = 0; for( int i=0; i<cmd->input.size(); ++i ) parseAndPack( cp, cmd->input[i], params[i], *out, offset ); return true; }
//taken from http://stackoverflow.com/a/10966395 #define ENUM(X) X, #define STR(X) #X, #define FOREACH_TOKEN(TOKEN) \ TOKEN(END) \ TOKEN(HAT) \ TOKEN(ID) \ TOKEN(ARRAY) \ TOKEN(L) \ TOKEN(R) \ TOKEN(OF) \ TOKEN(INTEGER) \ TOKEN(CHAR) \ TOKEN(NBR) \ TOKEN(DOTDOT) enum token {FOREACH_TOKEN(ENUM)}; static const char *token_str[] = {FOREACH_TOKEN(STR) NULL}; enum token *token; const char *expected = NULL; //part of the error message int match(enum token x) { if (*token == x) { token++; return 1; } else { expected = token_str[x]; return 0; } }