/** * 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; }
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); } } }