void Dup::execute(QVector<Litterale*> litterals) const {
    Litterale* operande = litterals[0];

    if (operande!=nullptr){
        Litterale* res = operande->clone(); //On a des operandes qui sont des ptr sur des LitteralesNombre -> l'operateur + y est defini -> polymorphisme

        //On empile notre operande et notre resultat
        Pile::getInstance().push(operande);
        Pile::getInstance().push(res);
        Pile::lastOpname = "DUP";
    }
    else {
        this->reChargerOperande(litterals);
    }
}
Example #2
0
/*!
 *  \brief Calcule la littérale résultante de l'expression
 */
Litterale* LitteraleExpression::eval() {
    
    Interpreteur& inter=Interpreteur::getInstance();
    FactoryLitterale& fl=FactoryLitterale::getInstance();
    FactoryOperateur& fo=FactoryOperateur::getInstance();
    
    string s(exp);
    regex e;
    smatch m;

    // Traitement des opérateurs unaires s'appliquant à l'expression
    regex opUnaire("([A-Z](?:[A-Z]|[0-9])*)\\(([^,\\(\\)]+)\\)");
    while (std::regex_search (s,m,opUnaire)) {
        cout<<m[0]<<" "<<m[1]<<" "<<m[2]<<endl;
        // m[1] l'opérateur et m[2] l'argument
        if(inter.isOperateur(m[1])) {
            Litterale* l1 = fl.newLitteraleExpression(m[2])->eval();
            Operateur* op= inter.toOperateur(m[1]);
            return op->applyUnaire(l1);
        }
    }
    
    // Traitement des opérateurs binaires s'appliquant à l'expression
    regex opBinaire("([A-Z](?:[A-Z]|[0-9])*)\\(([^,\\(]+),([^,\\(\\)]+)\\)");
    while (std::regex_search (s,m,opBinaire)) {
        //cout<<m[0]<<" "<<m[1]<<" "<<m[2]<<" "<<m[3]<<endl;
        // m[1] l'opérateur et m[2] l'argument 1 et m[2] l'argument 2
        if(inter.isOperateur(m[1])) {
            Litterale* l1 = fl.newLitteraleExpression(m[2])->eval();
            Litterale* l2 = fl.newLitteraleExpression(m[3])->eval();
            Operateur* op= inter.toOperateur(m[1]);
            return op->applyBinaire(l1,l2);
        }
    }

    // Remplacement des variables par leur contenu
    regex atome("((?:[[:upper:]]{1})(?:[[:upper:]]|[[:digit:]])*)");
    while (regex_search(s,m,atome)) {
        LitteraleAtome* var = LitteraleAtome::getVar(m[1]);
        if(var) {
            Litterale* c = var->getValeur();
            s.replace(s.find(m[0]), m[0].length(), c->toString());
        }
    }
    
    // Traitement des groupes parenthésés
    // Le but est de ne se retrouver qu'avec
    // une suite d'opérations arithmétiques sans parenthèses
    regex paren("\\(([^\\(]*?)\\)");
    while (regex_search(s,m,paren)) {
        //cout<<m[0]<<" va être remplcé par "<<m[1]<<endl;
        Litterale* c = fl.newLitteraleExpression(m[1])->eval();
        //cout<<"av. "<<s<<endl;
        s.replace(s.find(m[0]), m[0].length(), c->toString());
        //cout<<"apr. "<<s<<endl;
    }
    
    // Traitement des + et -
    regex somme("([^\\+]*[1-9])([\\+-])(.+)");
    if (regex_search(s,m,somme)) {
        //cout<<m[1]<<" "<<m[2]<<" "<<m[3]<<endl;
            
        // Conversion en littérale des deux cotés
        Litterale* l1=fl.newLitteraleExpression(m[1])->eval();  // On converti en littérale la partie gauche
        Litterale* l2=fl.newLitteraleExpression(m[3])->eval();  // On converti en littérale la partie droite
        
        // Création de l'opérateur
        OperateurNumerique* op=fo.newOperateurNumerique(m[2]);
        
        // Application du résultat
        Litterale* l3=op->applyBinaire(l1, l2);
        return l3;
    }
    
    // Traitement des * et /
    regex produit("([^\\+]*[1-9])([\\*/])(.+)");
    if (regex_search(s,m,produit)) {
        //cout<<m[1]<<" "<<m[2]<<" "<<m[3]<<endl;
        
        // Conversion en littérale des deux cotés
        Litterale* l1=fl.newLitteraleExpression(m[1])->eval();  // On converti en littérale la partie gauche
        Litterale* l2=fl.newLitteraleExpression(m[3])->eval();  // On converti en littérale la partie droite
        
        // Création de l'opérateur
        OperateurNumerique* op=fo.newOperateurNumerique(m[2]);
        
        // Application du résultat
        Litterale* l3=op->applyBinaire(l1, l2);
        return l3;
    }

    // On vérifie que ce n'est pas tout simplement une littérale
    if(inter.isLitterale(s)) {
        return inter.toLitterale(s);
    }
    
    return nullptr;
}
Litterale* Expression::evaluer() const{
    QString s = value;
    //On vire les '
    s=s.remove(0,1);
    s=s.remove(s.length()-1,s.length());
    QString::iterator it = s.begin();
    //QString contenant le résultat
    QString postfix;

    //Stack d'opérations
    QStack<QString> stack;

    //Map des opérateurs
    const QMap<QString, Operateur*> op_map = OperateurFactory::getMap();

    //Map de tous les symboles
    const QMap<QString,WordIdentifier*>& interpretation_map = Controleur::getInterpretationMap();

    //Traduction de Infix vers Postfix

    QString tmp;
    bool found;

    while(it!=s.end()){
        found=false;

        if(*it==' ' || *it==','){
            it++;
            continue;
        }

        //Verification que ce n'est pas une litterale avec 2 symboles exemple : Expression ou Programme
        if(tmp == "" && interpretation_map.find(*it)!=interpretation_map.end()){
            WordIdentifier *identifier = interpretation_map.find(*it).value();
            WordIdentifier *try1;
            WordIdentifier *try2;

            try1=dynamic_cast<RecursiveEncapsulatorIdentifier*>(identifier);
            try2=dynamic_cast<EncapsulatorIdentifier*>(identifier);
            if(try1 || try2)
            {
                    throw LitteraleException("Litterale "+ QString(*it) +" non permise","Inconnu");
            }
        }

        //On tombe dans le cas ou on a une valeur
        while(it!=s.end() && ((*it<='9' && *it>='0') || (interpretation_map.find(*it)!=interpretation_map.end()))){
              tmp+=*it;
              if(it!=s.end())
                  it++;
        }
        //Pour vider ce qu'on a trouvé
        if(tmp!=""){
            postfix+=tmp+" ";
            tmp.clear();
            found=true;

        }

        //On tombe dans le cas d'un morçeau de texte
        if((*it<='Z' && *it>='A')){
            while(it!=s.end() && ((*it<='Z' && *it>='A') || (*it<='9' && *it>='0'))){
                tmp+=* it;
                if(it!=s.end())
                    it++;
            }
            if(isOperator(tmp)){
                found=true;
                while(!stack.empty() && stack.top() != "(" && CompareOperators(stack.top(),tmp)<=0){
                    postfix += stack.top()+" ";
                    stack.pop();
                }
            stack.push(tmp);
            tmp.clear();
            }
            else if(isVariable(tmp)){
                found=true;
                Litterale* l = VariablesManager::getVariable(tmp);
                if(estdeType<Programme>(l))
                    throw OperateurException("Un programme est dans l'expression !");

                QString rep = l->toString();
                int length_it = s.indexOf(tmp);
                s.replace(tmp,rep);
                it = s.begin();
                for(int i=0; i<length_it;i++,it++);
                tmp.clear();

            }
            else
                throw(LitteraleException("Le mot "+tmp+" est inconnu","Inconnu"));

        }

        if(*it=='('){
            stack.push(*it);
            if(it!=s.end())
                it++;
            found=true;
        }
        if(*it==')'){
            while(stack.top()!="("){
                postfix+= stack.top()+" ";
                stack.pop();
            }
            stack.pop();
            if(it!=s.end())
            it++;
            found=true;
        }
        //On tombe dans le cas d'un opérateur à caractère
        if(!found){
            while(it!=s.end() && !op_map.contains(tmp)){
                tmp+=*it++;
            }
            if(it==s.end() && !op_map.contains(tmp))
                throw LitteraleException("Expression non valide dès "+tmp,"Expression");
            while(!stack.empty() && stack.top() != "(" && CompareOperators(stack.top(),tmp)<=0){
                postfix += stack.top()+" ";
                stack.pop();
            }
        stack.push(tmp);
        tmp.clear();
        }
    }

    while(!stack.empty()){
        postfix+= stack.top() + " ";
        stack.pop();
    }

    MainWindow::getInstanceMainWindow()->getNextCommande(postfix,"INFIX");
    return nullptr;
}