Exemplo n.º 1
0
/**
 * Entrée d'une commande (STDIN) et retour d'une réponse appropriée (STDOUT).
 * Retourne -1 lors d'une demande de quitter le programme, ou 0 si on continue.
 *
 * Invite l'utilisateur à entrer des commandes au format postfixe (ex: 3 2 + 5 * =a).
 */
int traitement_commande() {
    printf("> ");
    
    char* entree = entreeDynamique(stdin);
    
    if(entree == NULL) {
        printf("Pas assez de mémoire pour allouer l'entrée.\n");
        return 0;
    }
    
    if(strcmp(entree, "\0") == 0) {
        // Si l'utilisateur quitte ou entre une ligne vide.
        free(entree);
        
        return -1;
    }
    
    // Les différentes parties sont séparées par des espaces.
    char* partie = strtok(entree, " ");
    
    // Pile des commandes entrées, une fois exécutées.
    pile* commandes = malloc(sizeof(pile));
    
    if(commandes == NULL) {
        printf("Entrée invalide. La mémoire maximale a été dépassée.\n");
        free(entree);
        
        return 0;
    }
    
    pile_init(commandes);
    
    do {
        if(strcmp(partie, "+") == 0 || strcmp(partie, "-") == 0 || strcmp(partie, "*") == 0) {
            if(pile_count(commandes) >= 2) {
                num* r;
                
                num* b = pile_pop(commandes);
                num* a = pile_pop(commandes);
                
                if(strcmp(partie, "+") == 0) {
                    r = addition(a, b, a->positif, b->positif);
                } else if(strcmp(partie, "-") == 0) {
                    r = soustraction(a, b, a->positif, b->positif);
                } else if(strcmp(partie, "*") == 0) {
                    r = multiplication(a, b);
                }
                
                if(r == NULL) {
                    printf("Mauvais calcul !\n");
                    
                    superFree(a);
                    superFree(b);
                    
                    free(entree);
                    free(commandes);
                    
                    return 0;
                }
                
                pile_push(commandes, r);
            } else {
                printf("Erreur: il manque une entree pour faire une operation !\n");
                
                free(entree);
                free(commandes);
                
                return 0;
            }
        } else if(partie[0] == '=' && strlen(partie) == 2 && partie[1] >= 'a' && partie[1] <= 'z') {
            // Assignation de variable, on assigne et on continue comme si de rien n'était.
            
            if(pile_count(commandes) > 0) {
                variables[(int) partie[1] % 32] = pile_peek(commandes);
            } else {
                printf("Que voulez-vous assigner ? Il manque quelque chose...\n");
                
                free(entree);
                free(commandes);
                
                return 0;
            }
        } else if(strlen(partie) == 1 && partie[0] >= 'a' && partie[0] <= 'z') {
            // Variable, on met sa valeur dans la pile d'opérations.
            
            if(variables[(int) partie[0] % 32] != NULL) {
                pile_push(commandes, variables[(int) partie[0] % 32]);
            } else {
                printf("La variable '%c' n'est pas encore définie.\n", partie[0]);
                
                free(commandes);
                free(entree);
                
                return 0;
            }
        } else {
            int est_un_nombre = 1;
            int i = 0;
                                    
            while(i < strlen(partie)) {
                if(partie[i] < '0' || partie[i] > '9') {
                    est_un_nombre = 0;
                    
                    break;
                }
                
                i++;
            }
            
            if(est_un_nombre == 1) {
                // Valeur, on la met dans un nombre à précision infinie et on met sa référence dans la pile.
                num* valeur = malloc(sizeof(num));
                
                if(valeur == NULL) {
                    printf("Entrée invalide. La mémoire maximale a été dépassée.\n");
                    
                    free(entree);
                    free(commandes);
                    
                    return 0;
                }
                
                strToBigNum(partie, valeur);
                
                pile_push(commandes, valeur);
            } else {
                // Caractère non-valide.
                printf("Les éléments doivent tous être des variables (a-z, minuscule), des opérateurs ou bien des valeurs positives entières.\n");
                
                return 0;
            }
        }
    } while(partie = strtok(NULL, " "));
    
    if(partie != NULL) {
        free(partie);
    }
   
    if(entree != NULL) {
        free(entree);
    }
    
    if(pile_count(commandes) == 1) {
        printNum(pile_pop(commandes));
    } else {
        printf("Erreur de syntaxe, veuillez completer vos calculs !\n");
    }
        
    free(commandes->data);
    free(commandes);
    
    return 0;
}
Exemplo n.º 2
0
void eval_expr(char *str, File **f, Pile **p)
{
    char buffer[MAX_ENTRY] = "";
    Token token;

    int numberSaved = 0;
    int op_queued = 0;
    int p_size = 0;

    for(unsigned i = 0, j = 0; str[i] != '\0'; i++)
    {
        if(isAnOperator(str[i]))
        {
            p_size = pile_size(*p);

            while(p_size--)
            {
                char p_op = pile_pop(p);
                int p_opId = getOperatorID(p_op);
                int s_opId = getOperatorID(str[i]);

                if((operators[s_opId].associativity == A_LEFT &&
                        operators[s_opId].precedence <= operators[p_opId].precedence) ||
                        (operators[s_opId].associativity == A_RIGHT &&
                         operators[s_opId].precedence < operators[p_opId].precedence))
                {
                    setToken(token, OPERATOR, op, p_opId);
                    file_enqueue(f, token);
                    op_queued = 1;
                }

                if(!op_queued) pile_push(p, p_op);

                op_queued = 0;
            }
            pile_push(p, str[i]);
        }
        else if(str[i] == '(')
        {
            pile_push(p, str[i]);
        }
        else if(str[i] == ')')
        {
            char p_op;
            while((p_op = pile_pop(p)) != '(')
            {
                if(isAnOperator(p_op))
                {
                    setToken(token, OPERATOR, op, getOperatorID(p_op));
                    file_enqueue(f, token);
                }
            }
        }

        else if(isFloat(str[i]))
        {
            buffer[j] = str[i];
            j++;
            numberSaved = 0;
        }

        else if(isblank(str[i]) || (i == strlen(str) - 1))
        {
            if(!numberSaved && j > 0)
            {
                setToken(token, NUMBER, data, atof(buffer));
                file_enqueue(f, token);
                memset(buffer, '\0', j);
                j = 0;
                numberSaved = 1;
            }
        }
    }

    p_size = pile_size(*p);
    while(p_size--)
    {
        char p_op = pile_pop(p);
        if(isAnOperator(p_op))
        {
            setToken(token, OPERATOR, op, getOperatorID(p_op));
            file_enqueue(f, token);
        }
    }

}