1 #include "stringparser.hpp" 2 3 #include <algorithm> 4 #include <iterator> 5 6 #include <components/misc/stringops.hpp> 7 8 #include "scanner.hpp" 9 #include "generator.hpp" 10 #include "context.hpp" 11 #include "extensions.hpp" 12 13 namespace Compiler 14 { StringParser(ErrorHandler & errorHandler,const Context & context,Literals & literals)15 StringParser::StringParser (ErrorHandler& errorHandler, const Context& context, Literals& literals) 16 : Parser (errorHandler, context), mLiterals (literals), mState (StartState), mSmashCase (false), mDiscard (false) 17 { 18 19 } 20 parseName(const std::string & name,const TokenLoc & loc,Scanner & scanner)21 bool StringParser::parseName (const std::string& name, const TokenLoc& loc, 22 Scanner& scanner) 23 { 24 if (mState==StartState || mState==CommaState) 25 { 26 start(); 27 mTokenLoc = loc; 28 29 if (!mDiscard) 30 { 31 if (mSmashCase) 32 Generator::pushString (mCode, mLiterals, Misc::StringUtils::lowerCase (name)); 33 else 34 Generator::pushString (mCode, mLiterals, name); 35 } 36 37 return false; 38 } 39 40 return Parser::parseName (name, loc, scanner); 41 } 42 parseKeyword(int keyword,const TokenLoc & loc,Scanner & scanner)43 bool StringParser::parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner) 44 { 45 if (const Extensions *extensions = getContext().getExtensions()) 46 { 47 std::string argumentType; // ignored 48 bool hasExplicit = false; // ignored 49 if (extensions->isInstruction (keyword, argumentType, hasExplicit)) 50 { 51 // pretend this is not a keyword 52 std::string name = loc.mLiteral; 53 if (name.size()>=2 && name[0]=='"' && name[name.size()-1]=='"') 54 name = name.substr (1, name.size()-2); 55 return parseName (name, loc, scanner); 56 } 57 } 58 59 if (keyword==Scanner::K_end || keyword==Scanner::K_begin || 60 keyword==Scanner::K_short || keyword==Scanner::K_long || 61 keyword==Scanner::K_float || keyword==Scanner::K_if || 62 keyword==Scanner::K_endif || keyword==Scanner::K_else || 63 keyword==Scanner::K_elseif || keyword==Scanner::K_while || 64 keyword==Scanner::K_endwhile || keyword==Scanner::K_return || 65 keyword==Scanner::K_messagebox || keyword==Scanner::K_set || 66 keyword==Scanner::K_to || keyword==Scanner::K_getsquareroot) 67 { 68 return parseName (loc.mLiteral, loc, scanner); 69 } 70 71 return Parser::parseKeyword (keyword, loc, scanner); 72 } 73 parseSpecial(int code,const TokenLoc & loc,Scanner & scanner)74 bool StringParser::parseSpecial (int code, const TokenLoc& loc, Scanner& scanner) 75 { 76 if (code==Scanner::S_comma && mState==StartState) 77 { 78 mState = CommaState; 79 return true; 80 } 81 82 return Parser::parseSpecial (code, loc, scanner); 83 } 84 append(std::vector<Interpreter::Type_Code> & code)85 void StringParser::append (std::vector<Interpreter::Type_Code>& code) 86 { 87 std::copy (mCode.begin(), mCode.end(), std::back_inserter (code)); 88 } 89 reset()90 void StringParser::reset() 91 { 92 mState = StartState; 93 mCode.clear(); 94 mSmashCase = false; 95 mTokenLoc = TokenLoc(); 96 mDiscard = false; 97 Parser::reset(); 98 } 99 smashCase()100 void StringParser::smashCase() 101 { 102 mSmashCase = true; 103 } 104 getTokenLoc() const105 const TokenLoc& StringParser::getTokenLoc() const 106 { 107 return mTokenLoc; 108 } 109 discard()110 void StringParser::discard() 111 { 112 mDiscard = true; 113 } 114 } 115