bool isRemainderWhenDevidingByTwo(Expr *expr) { BinaryOperator *binaryOperator = dyn_cast<BinaryOperator>(expr); return binaryOperator && binaryOperator->getOpcode() == BO_Rem && isIntegerLiteral(binaryOperator->getRHS(), 2); }
bool isRemainderEqualsOne(Expr *leftExpr, Expr *rightExpr) { return (isIntegerLiteral(rightExpr, 1) && isRemainderWhenDevidingByTwo(leftExpr)) || (isIntegerLiteral(leftExpr, 1) && isRemainderWhenDevidingByTwo(rightExpr)); }
//find token details and type and update token. May require examining properties of neighbouring tokens void TokenList::findAndSetTokenDetails(Token *token){ //tracersing for a comment body //put comment case the very beginning, is case meet situation like "--and" (in case make comment body be keyword or operator) if(token!=nullptr && token->prev!=nullptr && token->prev->stringRep=="--") { token->setTokenType(T_CommentBody); return; } //use tolower function to convert everything to lower case since VHDL is case-sensitive except literal string str = token->stringRep; int len=(int) str.length(); for(int i=0;i<len;i++){ str[i] = tolower(str[i]);} //first to find Keywords and set boolean type as true const int length_Keyword= 97; //get the length of arrayOfKeywords token->_isKeyword=false; for (int i=0; i<length_Keyword; i++) { if (str == arrayOfKeywords[i]){//compare tableOfKeywords token->_isKeyword=true;} } //traversing for operator //Didnt consider token like "=>, <=, ==" here, this should be done in prepareNextToken for (int i=0; i<28; i++) { if (str == arrayOfOperators[i]){//compare tableOfKeywords token->setTokenType(T_Operator); return;} } //traverse for literal //cases where it has bit vectors "0010101", x"1234ABCD" if ((token->stringRep).find_first_of("\"")!=std::string::npos){ //can find " if (token->details==nullptr) token->details=new tokenDetails; if ((token->stringRep).find_first_of("\"")==0 && (token->stringRep).find_last_of("\"") != (token->stringRep).find_first_of("\"")){// if " starts the first position of token token->details->width=static_cast<int>((token->stringRep).find_last_of("\"")-(token->stringRep).find_first_of("\""))-1; token->details->type="std_logic_vector"; token->setTokenType(T_Literal); return; } if ((token->stringRep).find_first_of("\"")==1){// if " is the second position of token if ((token->stringRep).at(0)=='X'||(token->stringRep).at(0)=='x') { token->details->width=(static_cast<int>((token->stringRep).find_last_of("\"")-(token->stringRep).find_first_of("\""))-1)*4; token->details->type="std_logic_vector"; token->setTokenType(T_Literal); return;} else if ((token->stringRep).at(0)=='B'||(token->stringRep).at(0)=='b') { token->details->width=static_cast<int>((token->stringRep).find_last_of("\"")-(token->stringRep).find_first_of("\""))-1; token->details->type="std_logic_vector"; token->setTokenType(T_Literal); return;} else if ((token->stringRep).at(0)=='O'||(token->stringRep).at(0)=='o') { token->details->width=(static_cast<int>((token->stringRep).find_last_of("\"")-(token->stringRep).find_first_of("\""))-1)*3; token->details->type="std_logic_vector"; token->setTokenType(T_Literal); return;} } } //traverse for std_logic e.g. '0','1' if ((token->stringRep)=="'0'"||(token->stringRep)=="'1'"||(token->stringRep)=="'2'"||(token->stringRep)=="'3'"||(token->stringRep)=="'4'"||(token->stringRep)=="'5'"||(token->stringRep)=="'6'"||(token->stringRep)=="'7'"||(token->stringRep)=="'8'"||(token->stringRep)=="'9'"){ if (token->details == nullptr) token->details=new tokenDetails; token->details->type="std_logic"; token->details->width=1; token->setTokenType(T_Literal); return;} //traverse for boolean literal if (str=="true" || str == "false"){ if (token->details == nullptr) token->details=new tokenDetails; token->setTokenType(T_Literal); token->details->type="boolean"; token->details->width=1; return; } //traverse for integer literal if (isIntegerLiteral(token->stringRep)) { if (token->details ==nullptr) token->details= new tokenDetails; token->setTokenType(T_Literal); token->details->width=0; token->details->type="integer"; return; } //traverse for identifier //all start from letters except operator, comment, and literals should be identifier if((str).find_first_not_of(Letter)!= 0) //as long as the first character in stringRep is in Letter { token->setTokenType(T_Identifier); Token *temp1, *temp = new Token; temp1=head; //first check whether this token already exists or not //traverse the tokenlist (where target token exists) until find same string with target token while (temp1 != nullptr && temp1 != token) { if (temp1->stringRep == token->stringRep){ //FIRST same stringRep means target token already exists token->alreadyExist=true; temp = temp1;} temp1=temp1->getNext();//else if traverse to next token } if (token != nullptr && token->alreadyExist == false) //if this token stringRep shows the first time { if (token->getNext() != nullptr && token->getNext()->getNext() != nullptr && token->getNext()->getStringRep() == ":") //which imply it is a vector { if (token->details==nullptr) //initialize token detail token->details=new tokenDetails; //----------Set detail type--------because VHDL is non-sensitive about capitalization, I try to convert to lower case---// string lowerStringRep = token->getNext()->getNext()->getStringRep(); int len=(int) lowerStringRep.length(); for(int i=0;i<len;i++){ lowerStringRep[i] = tolower(lowerStringRep[i]);} token->details->type = lowerStringRep; if (token->getNext()->getNext()->getNext() != nullptr && token->getNext()->getNext()->getNext()->getStringRep() == "(" &&token->getNext()->getNext()->getNext()->getNext() != nullptr && token->getNext()->getNext()->getNext()->getNext()-> getNext() != nullptr && token->getNext()->getNext()->getNext()->getNext()-> getNext()->getNext() != nullptr){//Find width int length = std::atoi(token->getNext()->getNext()->getNext()->getNext()->getStringRep().c_str()) - std::atoi(token->getNext()->getNext()->getNext()->getNext()->getNext()->getNext()->getStringRep().c_str()); if (length < 0) length = - length; token->details->width = length + 1;} } } else if (token != nullptr && token->alreadyExist == true){// if find this token already exists before if (temp->details != nullptr && token->details != nullptr) { token->details->type= temp->details->type; token->details->width=temp->details->width; } else if(temp->details != nullptr){ token->details = new tokenDetails; token->details->type= temp->details->type; token->details->width=temp->details->width; }} //return; } //traversing for other_type //if token are not be detected as comment, operator, literal or identifier, then it will be categorize as other else { token->setTokenType(T_Other); return; } }