Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

KodeConditionCreators.cc

Go to the documentation of this file.
00001 #include "Kodu/Parsing/Parser.h"
00002 #include "Shared/Gamepad.h"
00003 
00004 
00005 namespace Kodu {
00006 
00007   KoduConditionHear* Parser::KodeCreator::createHearKode(std::vector<TokenBase*>& mods) {
00008     bool ishear = false;
00009     bool usenot = false;
00010     std::string said = "";
00011     std::string objecttype = ""; 
00012     while (!mods.empty()) {
00013   
00014   
00015       if (mods[0]->isStringToken()) {
00016         std::string word = mods[0]->getStringData();
00017         said = said + word;
00018       }
00019       if (mods[0]->isKeywordToken()) {
00020         std::string keyword = mods[0]->getKeywordData();
00021         if (keyword == "hear") {
00022           ishear = true;
00023         } else if (keyword == "not") {
00024           usenot = true;
00025         } else if (keyword == "robot" || keyword == "kodu" || keyword == "octopus" || keyword == "cycle" || keyword == "turtle") {
00026           objecttype = keyword;
00027         } else if (keyword == "say") {
00028           PARSER_ASSERT((ishear == true), errorMessage << "what are you trying to hear");
00029         } 
00030       } 
00031       GeneralFncs::destroyPtrInVector(mods, 0);
00032     }
00033     return (new KoduConditionHear(usenot, objecttype, "", said));
00034   }  
00035   
00036             
00037   KoduConditionGamepad* Parser::KodeCreator::createGamepadKode(std::vector<TokenBase*>& mods) {
00038     bool isButton = false;
00039     bool isBumper = false;
00040       
00041     float press = -1;
00042     unsigned int input = 0;
00043     while (!mods.empty()) {
00044       // check if the token is a keyword
00045       std::string keyword = mods[0]->getKeywordData();
00046                 
00047       if (mods[0]->isKeywordToken()) {
00048         if (keyword == "button") {
00049           isButton = true;
00050         }
00051         else if (isButton && keyword == "press") {
00052           press = 1;
00053         }
00054         else if (isButton && keyword == "release") {
00055           press = 0;
00056         }
00057         else if (!isButton && keyword == "right") {
00058           isBumper = true;
00059           input = GamepadSrcID::gamepadRightBumperSrcID;
00060         }
00061         else if (!isButton  && keyword == "left") {
00062           isBumper = true;
00063           input = GamepadSrcID::gamepadLeftBumperSrcID;
00064         }
00065         else if (!isBumper && keyword == "bumper") {
00066           PARSER_ASSERT(isBumper,  errorMessage << "Incorrect usage of bumpers");
00067         }
00068         else if (isButton && !isBumper && keyword == "A") {
00069           input = GamepadSrcID::gamepadAButtonSrcID;
00070         } 
00071         else if (isButton && !isBumper && keyword == "B") {
00072           input = GamepadSrcID::gamepadBButtonSrcID;
00073         } 
00074         else if (isButton && !isBumper && keyword == "X") {
00075           input = GamepadSrcID::gamepadXButtonSrcID;
00076         } 
00077         else if (isButton&& !isBumper  && keyword == "Y") {
00078           input = GamepadSrcID::gamepadYButtonSrcID;
00079         } 
00080         else if (keyword == "joystick") {
00081           std::cout << "Joystick parsed\n";
00082         }
00083         else if (keyword == "L-stick") {          
00084           input = GamepadSrcID::gamepadLeftJoyXSrcID;
00085         }
00086         else
00087           input = -1;
00088       }
00089       // the user specified the wrong keyword
00090       else {
00091         // ASSERTION: The user entered a wrong keyword
00092         PARSER_ASSERT((ERROR),
00093                       errorMessage << "The keyword \"" << keyword << "\" cannot be used with the "  << "Gamepad condition.");
00094       }
00095       // bookkeeping
00096       GeneralFncs::destroyPtrInVector(mods, 0);
00097     }
00098     return (new KoduConditionGamepad(input, press));
00099   }
00100   
00101   KoduConditionBump* Parser::KodeCreator::createBumpKode(std::vector<TokenBase*>& mods) {
00102     // mandatory modifiers
00103     std::string objectType;
00104     std::string objectColor;
00105 
00106     // optional modifiers
00107     SearchLocation_t leftRight = SL_UNRESTRICTED;
00108     SearchLocation_t frontBack = SL_UNRESTRICTED;
00109     bool notEnabled = false;
00110         
00111     // checkers
00112     int tokenCount = 1;
00113 
00114 
00115     // parsing loop
00116     while (!mods.empty()) {
00117       // check if the token is a keyword
00118       if (mods[0]->isKeywordToken()) {
00119         std::string keyword = mods[0]->getKeywordData();
00120         // check if keyword is an object type
00121         if (keyword == "apple" || keyword == "rock" || keyword == "tree" 
00122             || keyword == "robot" || keyword == "kodu" || keyword == "octopus" || keyword == "cycle" || keyword == "turtle") {
00123           // ASSERTION: The object type was not already specified
00124           PARSER_ASSERT((objectType.empty()),
00125                         errorMessage << "The bump condition only accepts one object type.\n"
00126                         << "Previous object found: " << objectType);
00127           objectType = keyword;
00128         }
00129         // check if the keyword is a color
00130         else if (Parser::isValidColor(keyword)) {
00131           // ASSERTION: The color was not already specified
00132           PARSER_ASSERT((objectColor.empty()),
00133                         errorMessage << "The bump condition only accepts one color.\n"
00134                         << "Previous color found: " << objectColor);
00135           objectColor = keyword;
00136         }
00137         // check if the keyword is a regional specifier
00138         else if (keyword == "in_front" || keyword == "behind") {
00139           // ASSERTION: The front/back region was not specified
00140           PARSER_ASSERT((frontBack == 0),
00141                         errorMessage << "A front/back regional specifier was already specified.\n"
00142                         <<  "Second instance found: " << keyword);
00143           if (keyword == "in_front")
00144             frontBack = SL_IN_FRONT;
00145           else
00146             frontBack = SL_BEHIND;
00147         }
00148         // check if the keyword is a regional specifier
00149         else if
00150           (keyword == "to_left" || keyword == "to_right") {
00151           // ASSERTION: The front/back region was not specified
00152           PARSER_ASSERT((leftRight == 0),
00153                         errorMessage << "A front/back regional specifier was already specified.\n"
00154                         <<  "Second instance found: " << keyword);
00155           if (keyword == "to_left")
00156             leftRight = SL_TO_LEFT
00157               ;
00158           else
00159             leftRight = SL_TO_RIGHT;
00160         }
00161         // check if the keyword is the "not" modifier
00162         else if (keyword == "not") {
00163           // ASSERTION: The "not" modifier has not been specified before in this condition
00164           PARSER_ASSERT((notEnabled == false),
00165                         errorMessage << "The \"not\" modifier was already used in this rule. It can " << 
00166                         "only be used once per rule.");
00167           notEnabled = true;
00168         }
00169         // the user specified the wrong keyword
00170         else {
00171           // ASSERTION: The user entered a wrong keyword
00172           PARSER_ASSERT((ERROR),
00173                         errorMessage << "The keyword \"" << keyword << "\" cannot be used with the "  << "Bump condition.");
00174         }
00175         // bookkeeping
00176         GeneralFncs::destroyPtrInVector(mods, 0);
00177       }
00178       // the user something other than a keyword and is therefore illegal
00179       else {
00180         PARSER_ASSERT((ERROR),
00181                       errorMessage << "Token " << tokenCount << " cannot be used with the Bump condition.");
00182       }
00183       // increment the token counter
00184       tokenCount++;
00185     }
00186     // ASSERTION: the user specified a object type
00187     PARSER_ASSERT((!objectType.empty()),
00188                   errorMessage << "An object type must be specified (e.g. tree, apple, or rock).");
00189 
00190     // ASSERTION: the user specified a object color
00191     /*
00192       PARSER_ASSERT((!objectColor.empty()),
00193       errorMessage << "An object color must be specified (e.g. red, green, blue).");*/
00194 
00195     // create the condition
00196     return (new KoduConditionBump(notEnabled, objectType, objectColor, (frontBack | leftRight))); //TODO modify bump to not include color
00197   }
00198 
00199   KoduConditionGot* Parser::KodeCreator::createGotKode(std::vector<TokenBase*>& mods) {
00200     // mandatory modifiers
00201     std::string objectType;
00202     std::string objectColor;
00203 
00204     // optional modifiers
00205     bool notEnabled = false;
00206         
00207     // checkers
00208     int tokenCount = 1;
00209         
00210     // parsing loop
00211     while (!mods.empty()) {
00212       // check if the token is a keyword
00213       if (mods[0]->isKeywordToken()) {
00214         std::string keyword = mods[0]->getKeywordData();
00215         // check if keyword is an object type
00216         if (keyword == "apple" || keyword == "rock" || keyword == "tree") {
00217           // ASSERTION: The object type was not already specifieds
00218           PARSER_ASSERT((objectType.empty()),
00219                         errorMessage << "The Got condition only accepts one object type.\n"
00220                         << "Previous object found: " << objectType);
00221           objectType = keyword;
00222         }
00223         // check if the keyword is a color
00224         else if (Parser::isValidColor(keyword)) {
00225           // ASSERTION: The color was not already specified
00226           PARSER_ASSERT((objectColor.empty()),
00227                         errorMessage << "The Got condition only accepts one color.\n"
00228                         << "Previous color found: " << objectColor);
00229           objectColor = keyword;
00230         }
00231         // check if the keyword is the "not" modifier
00232         else if (keyword == "not") {
00233           // ASSERTION: The "not" modifier has not been specified before in this condition
00234           PARSER_ASSERT((notEnabled == false),
00235                         errorMessage << "The \"not\" modifier was already used in this rule. It can " << 
00236                         "only be used once per rule.");
00237           notEnabled = true;
00238         }
00239         // the user specified the wrong keyword
00240         else {
00241           // ASSERTION: The user entered a wrong keyword
00242           PARSER_ASSERT((ERROR),
00243                         errorMessage << "The keyword \"" << keyword << "\" cannot be used with the "
00244                         << "Got condition.");
00245         }
00246         // bookkeeping
00247         GeneralFncs::destroyPtrInVector(mods, 0);
00248       }
00249       // the user something other than a keyword and is therefore illegal
00250       else {
00251         PARSER_ASSERT((ERROR),
00252                       errorMessage << "Token " << tokenCount << " cannot be used with the Got condition.");
00253       }
00254       // increment the token counter
00255       tokenCount++;
00256     }
00257     // ASSERTION: the user specified a object type
00258     PARSER_ASSERT((!objectType.empty()),
00259                   errorMessage << "An object type must be specified (e.g. tree, apple, or rock).");
00260 
00261     // ASSERTION: the user specified a object color
00262     /*PARSER_ASSERT((!objectColor.empty()),
00263       errorMessage << "An object color must be specified (e.g. red, green, blue).");*/
00264 
00265     // create the condition
00266     return (new KoduConditionGot(notEnabled, objectType, objectColor)); 
00267   }
00268 
00269   KoduConditionSee* Parser::KodeCreator::createSeeKode(std::vector<TokenBase*>& mods) {
00270     // mandatory modifiers
00271     std::string objectType;
00272     std::string objectColor;
00273 
00274     // optional modifiers
00275     bool notEnabled = false;
00276     SearchLocation_t leftRight = SL_UNRESTRICTED;
00277     SearchLocation_t frontBack = SL_UNRESTRICTED;
00278     SearchLocation_t closeFar = SL_UNRESTRICTED;
00279 
00280     // checkers
00281     int tokenCount = 1;
00282         
00283     // parsing loop
00284     while (!mods.empty()) {
00285       // check if the token is a keyword
00286       if (mods[0]->isKeywordToken()) {
00287         std::string keyword = mods[0]->getKeywordData();
00288         // check if keyword is an object type
00289         if (keyword == "apple" || keyword == "rock" || keyword == "tree" 
00290             || keyword == "robot" ||  keyword == "kodu" || keyword == "octopus" || keyword == "cycle" || keyword == "turtle") {
00291           // ASSERTION: The object type was not already specifieds
00292           PARSER_ASSERT((objectType.empty()),
00293                         errorMessage << "The see condition only accepts one object type.\n"
00294                         << "Previous object found: " << objectType);
00295           objectType = keyword;
00296         }
00297         // check if the keyword is a color
00298         else if (Parser::isValidColor(keyword)) {
00299           // ASSERTION: The color was not already specified
00300           PARSER_ASSERT((objectColor.empty()),
00301                         errorMessage << "The see condition only accepts one color.\n"
00302                         << "Previous color found: " << objectColor);
00303           objectColor = keyword;
00304         }
00305         // check if the keyword is a regional specifier
00306         else if (keyword == "in_front" || keyword == "behind") {
00307           // ASSERTION: The front/back location was not specified
00308           PARSER_ASSERT((frontBack == SL_UNRESTRICTED),
00309                         errorMessage << "A front/back location specifier was already specified.\n"
00310                         <<  "Second instance found: " << keyword);
00311           if (keyword == "in_front")
00312             frontBack = SL_IN_FRONT;
00313           else
00314             frontBack = SL_BEHIND;
00315         }
00316         // check if the keyword is a regional specifier
00317         else if (keyword == "to_left" || keyword == "to_right") {
00318           // ASSERTION: The left/right location was not specified
00319           PARSER_ASSERT((leftRight == SL_UNRESTRICTED),
00320                         errorMessage << "A froSeeKodent/back location specifier was already specified.\n"
00321                         <<  "Second instance found: " << keyword);
00322           if (keyword == "to_left")
00323             leftRight = SL_TO_LEFT;
00324           else
00325             leftRight = SL_TO_RIGHT;
00326         }
00327         // check if the keyword is a spatial specifier
00328         else if (keyword == "close_by" || keyword == "far_away") {
00329           // ASSERTION: The close/far location was not specified
00330           PARSER_ASSERT((closeFar == SL_UNRESTRICTED),
00331                         errorMessage << "A close_by/far_away location specifier was already specified.\n"
00332                         <<  "Second instance found: " << keyword);
00333           if (keyword == "close_by")
00334             closeFar = SL_CLOSE_BY;
00335           else
00336             closeFar = SL_FAR_AWAY;
00337         }
00338         // check if the keyword is the "not" modifier
00339         else if (keyword == "not") {
00340           // ASSERTION: The "not" modifier has not been specified before in this condition
00341           PARSER_ASSERT((notEnabled == false),
00342                         errorMessage << "The \"not\" modifier was already used in this rule. It can " << 
00343                         "only be used once per rule.");
00344           notEnabled = true;
00345         }
00346         // the user specified the wrong keyword
00347         else {
00348           // ASSERTION: The user entered a wrong keyword
00349           PARSER_ASSERT((ERROR),
00350                         errorMessage << "The keyword \"" << keyword << "\" cannot be used with the "
00351                         << "See condition.");
00352         }
00353         // bookkeeping
00354         GeneralFncs::destroyPtrInVector(mods, 0);
00355       }
00356       // the user something other than a keyword and is therefore illegal
00357       else {
00358         PARSER_ASSERT((ERROR),
00359                       errorMessage << "Token " << tokenCount << " cannot be used with the See condition.");
00360       }
00361       // increment the token counter
00362       tokenCount++;
00363     }
00364     // ASSERTION: the user specified a object type
00365     PARSER_ASSERT((!objectType.empty()),
00366                   errorMessage << "An object type must be specified (e.g. tree, apple, or rock).");
00367 
00368     // ASSERTION: the user specified a object color (THIS IS NOW REMOVED BECAUSE WE DONT WANT THIS)
00369     /*
00370      *PARSER_ASSERT((!objectColor.empty()),
00371      *   errorMessage << "An object color must be specified (e.g. red, green, blue).");
00372      */
00373     // create the condition
00374       
00375     return (new KoduConditionSee(notEnabled, objectType, objectColor, (frontBack | leftRight | closeFar))); //TODO adjust primitive so this executes
00376        
00377   }
00378     
00379   KoduConditionScored* Parser::KodeCreator::createScoredKode(std::vector<TokenBase*>& mods) {
00380     // optional modifiers
00381     NumericGenerator tempNumReq(0, 0);
00382     bool notEnabled = false;
00383     KoduConditionScored::CompareType_t comparisonType(KoduConditionScored::INVALID);
00384     bool comparisonOperatorSet = false;
00385     std::string scoreDesignator;
00386 
00387     // checkers
00388     int tokenCount = 1;
00389     bool handledNumerics = false;
00390 
00391     // parsing loop
00392     while (!mods.empty()) {
00393       // check if the token is an inequality operator
00394       if (isComparisonOperator(mods[0])) {
00395         // ASSERTION: A number was not specified before an inequality sign
00396         PARSER_ASSERT((handledNumerics == false),
00397                       errorMessage << "A numeric value cannot be specified before an "
00398                       << "inequality operator.");
00399         // ASSERTION: The comparison type was not set
00400         PARSER_ASSERT((comparisonOperatorSet == false),
00401                       errorMessage << "The comparison type was already set.");
00402         std::string keyword = mods[0]->getKeywordData();
00403         // get the comparison type
00404         if (keyword == "equals")
00405           comparisonType = KoduConditionScored::CT_EQUALS;
00406         else if (keyword == "above")
00407           comparisonType = KoduConditionScored::CT_ABOVE;
00408         else if (keyword == "below")
00409           comparisonType = KoduConditionScored::CT_BELOW;
00410         else if (keyword == "not_equals")
00411           comparisonType = KoduConditionScored::CT_NOT_EQUALS;
00412         else if (keyword == ">=")
00413           comparisonType = KoduConditionScored::CT_GT_EQUAL;
00414         else if (keyword == "<=")
00415           comparisonType = KoduConditionScored::CT_LT_EQUAL;
00416         comparisonOperatorSet = true;
00417         // bookkeeping
00418         GeneralFncs::destroyPtrInVector(mods, 0);
00419       }
00420       // check if the token is numeric
00421       else if (isNumericSpecifier(mods[0])) {
00422         // ASSERTION: The numeric/random number parser has not been called for this "phrase"
00423         PARSER_ASSERT((handledNumerics == false),
00424                       errorMessage << "Token " << tokenCount << " is illegal. A numeric "
00425                       << "specifier (number and/or random modifiers) was already specified.");
00426         // get the numeric request
00427         // ASSERTION: The numeric/random number parser did not fail
00428         PARSER_ASSERT((numericGenParser(mods, tempNumReq) == true),
00429                       errorMessage << "An error occurred while parsing the numeric/random token(s).");
00430         // note that numbers have been handled
00431         handledNumerics = true;
00432         continue;
00433       }
00434       // check if it is a color or letter
00435       else if (isScoreDesignator(mods[0])) {
00436         std::string keyword = mods[0]->getKeywordData();
00437         // ASSERTION: the scoring letter was not already specified
00438         PARSER_ASSERT((scoreDesignator.empty()),
00439                       errorMessage << "The scored condition cannot have more than one designator. "
00440                       << "Second designator: " << keyword << ".");
00441         // assign the designator
00442         scoreDesignator = keyword;
00443       }
00444       // check if the token is a keyword
00445       else if (mods[0]->isKeywordToken()) {
00446         // get the keyword
00447         std::string keyword = mods[0]->getKeywordData();
00448         // check if the keyword is "not"
00449         if (keyword == "not") {
00450           // ASSERTION: This is the first occurrence of the "not" modifier
00451           PARSER_ASSERT((notEnabled == false),
00452                         errorMessage << "The \"not\" modifier can only be used once.");
00453           notEnabled = true;
00454         }
00455         // the keyword is illegal
00456         else {
00457           // ASSERTION: This keyword token is illegal
00458           PARSER_ASSERT((ERROR),
00459                         errorMessage << "The keyword \"" << keyword << "\" cannot be used "
00460                         << "with the Scored condition.");
00461         }
00462         // bookkeeping
00463         GeneralFncs::destroyPtrInVector(mods, 0);
00464       }
00465       // the token is illegal
00466       else {
00467         // ASSERTION: The user added an illegal token
00468         PARSER_ASSERT((ERROR),
00469                       errorMessage << "Token " << tokenCount << " cannot be used with the Scored condition.");
00470       }
00471       tokenCount++;
00472     }
00473     // comparison type defaults to equal
00474     if ( comparisonType == KoduConditionScored::INVALID )
00475       comparisonType = KoduConditionScored::CT_EQUALS;
00476     // if a score designator was not assigned, assign it the default color
00477     if (scoreDesignator.empty())
00478       scoreDesignator = Parser::koduDefaultDesignator;
00479     // return the condition
00480     return (new KoduConditionScored(notEnabled, comparisonType, tempNumReq, scoreDesignator, handledNumerics));
00481   }
00482 
00483   KoduConditionTimer* Parser::KodeCreator::createTimerKode(std::vector<TokenBase*>& mods) {
00484     // ASSERTION: There are 0 - 6 modifiers
00485     PARSER_ASSERT((0 <= mods.size() && mods.size() <= 6),
00486                   errorMessage << "The Timer condition should have 0 - 6 modifiers.");
00487 
00488     // mandatory modifiers
00489     NumericGenerator tempNumReq(0.25, 0);
00490 
00491     // optional modifiers
00492     bool notEnabled = false;
00493         
00494     // checkers
00495     int tokenCount = 1;
00496     bool handledNumerics = false;
00497 
00498     // parsing loop
00499     while (!mods.empty()) {
00500       // check if the token is numeric
00501       if (isNumericSpecifier(mods[0])) {
00502         // ASSERTION: The numeric/random number parser has not been called for this "phrase"
00503         PARSER_ASSERT((handledNumerics == false),
00504                       errorMessage << "Numeric specifiers for this action were already handled. "
00505                       << "Token " << tokenCount << " is illegal.");
00506         // get the numeric request
00507         // ASSERTION: The numeric/random number parser did not fail
00508         PARSER_ASSERT((numericGenParser(mods, tempNumReq) == true),
00509                       errorMessage << "An error occurred while parsing the numeric specifier token(s) "
00510                       << "See above.");
00511         // note that numbers have been handled
00512         handledNumerics = true;
00513       }
00514       // check if the token is a keyword
00515       else if (mods[0]->isKeywordToken()) {
00516         // get the keyword
00517         std::string keyword = mods[0]->getKeywordData();
00518         // check if the keyword is "not"
00519         if (keyword == "not") {
00520           // ASSERTION: This is the first occurrence of the "not" modifier
00521           PARSER_ASSERT((notEnabled == false),
00522                         errorMessage << "The \"not\" modifier can only be used once.");
00523           notEnabled = true;
00524         }
00525         // something is WRONG!
00526         else {
00527           // ASSERTION: This keyword token is illegal
00528           PARSER_ASSERT((ERROR),
00529                         errorMessage << "The keyword \"" << keyword << "\" cannot be used "
00530                         << "with the Timer condition.");
00531         }
00532         // bookkeeping
00533         GeneralFncs::destroyPtrInVector(mods, 0);
00534       }
00535       // the token is illegal
00536       else {
00537         // ASSERTION: The user added an illegal token
00538         PARSER_ASSERT((ERROR),
00539                       errorMessage << "Token " << tokenCount << " cannot be used with the Timer condition.");
00540       }
00541       tokenCount++;
00542     }
00543     // create the condition
00544     return (new KoduConditionTimer(notEnabled, tempNumReq));
00545   }
00546 }

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:42 2016 by Doxygen 1.6.3