/* * * Gestion de la pile des operandes * */ #include #include "pile.h" #include "exceptions.h" #include "numbers.h" #include "main.h" #include "parser.h" #include "scalaires.h" #include "config.h" #include "fonctions.h" pile_elem pile[PILE_MAX]; pile_elem result_pile[PILE_MAX]; unsigned int pile_ptr = 0; unsigned int result_pile_ptr = 0; /* fonctions basiques sur la pile d operandes */ void push_pile(char *st) { int valid1, valid2, valid3; char valid4 = 0; int i_number; rationnel r_number; polynome poly; char buf[128]; sprintf(buf, _("Calling push_pile(%s)"), st); pushcontext(buf); i_number = char_to_number(st, &valid1); r_number = char_to_rat(st, &valid2); valid3 = is_mute(st); poly = (polynome) NomVarToVar(st, variables, &valid4); if (valid1) { /* il s agit d un entier */ pushcontext(_("it's an integer")); push_pile_poly(ply_constr(rat_constr(i_number, 1), 0)); popcontext(); } else if (valid2) { /* il s agit d un flottant */ pushcontext(_("it's a float")); push_pile_poly(ply_constr(r_number, 0)); popcontext(); } else if (valid3) { /* il s agit de x */ pushcontext(_("it's X")); push_pile_poly(ply_constr(rat_constr(1, 1), 1)); popcontext(); } else if (valid4) { /* il s agit d une variable */ pushcontext(_("it's a variable")); push_pile_poly(ply_copy(poly)); popcontext(); } else { /* il s agit d un nom */ pushcontext(_("it's a name")); if (*st == '\'') { st++; st[strlen(st) - 1] = 0; } push_pile_string(Estrdup(st)); popcontext(); } popcontext(); #ifdef DEBUG fprintf(stderr, "exiting push_pile\n"); #endif } void push_pile_poly(polynome poly) { if (pile_ptr != PILE_MAX) { pile[pile_ptr].type = T_POLY; pile[pile_ptr].poly = poly; pile_ptr++; } else { exception(2, _("push_pile_poly: Stack Overflow")); } } void push_pile_int(int val) { if (pile_ptr != PILE_MAX) { pile[pile_ptr].type = T_INT; pile[pile_ptr].val = val; pile_ptr++; } else { exception(2, _("push_pile_int: Stack Overflow")); } } void push_pile_string(char *st) { if (pile_ptr != PILE_MAX) { pile[pile_ptr].type = T_STRING; pile[pile_ptr].label = Estrdup(st); pile_ptr++; } else { exception(2, _("push_pile_string: Stack Overflow")); } } pile_elem pop_pile(unsigned int count) { char buf[50]; if (((int) (pile_ptr) - (int) count) >= 0) { pile_ptr -= count; } else { sprintf(buf, _("pop_pile: Can't pop %u elements"), count); exception(2, buf); } return pile[pile_ptr]; } void flush_pile(void) { int i; if (pile_ptr) { for (i = 0; i <= pile_ptr - 1; i++) { switch (pile[i].type) { case T_INT: break; case T_STRING: free(pile[i].label); break; case T_POLY: ply_destruct(pile[i].poly); break; } } } pile_ptr=0; } /* fonctions basiques sur la pile de resultats */ void move_to_resultat_pile(void) { pile_elem temp; pushcontext(_("move_to_resultat_pile()")); if (pile_ptr) { temp=pop_pile(1); if (result_pile_ptr!=PILE_MAX) { if (temp.type==T_POLY) { result_pile[result_pile_ptr]=temp; result_pile_ptr++; } else { exception(1, _("move_to_resultat_pile: invalid argument type")); } } else { exception(2, _("move_to_resultat_pile: Stack Overflow")); } } popcontext(); } char * pop_resultat(void) { static char result[BUFSIZ]; pushcontext(_("pop_resultat()")); if (result_pile_ptr) { result_pile_ptr--; sprintf(result,"%s", ply_affichage(result_pile[result_pile_ptr].poly)); } else { exception(2, _("move_to_resultat_pile: empty stack")); } popcontext(); return result; } polynome return_last(int *valid) { if (!result_pile_ptr) { *valid=0; return NULL; } else { *valid=1; return result_pile[result_pile_ptr--].poly; } } int has_resultat(void) { return (result_pile_ptr ? 1 : 0); } /* fonctions avancees sur la pile d operandes */ char *affichage_level_1(void) { char *result = NULL; if (pile_ptr) { switch (pile[pile_ptr - 1].type) { case T_POLY: result = ply_affichage(pile[pile_ptr - 1].poly); break; case T_STRING: result = pile[pile_ptr - 1].label; break; case T_INT: result = (char *) Emalloc(11 * sizeof(char)); sprintf(result, "%10d", pile[pile_ptr - 1].val); break; } } return result; } int is_mute(char *st) { return !(strcmp(st, mute)); } void act_pile(int func) { pile_elem operande1, operande2; pile_elem operande[3]; char buf[50]; char valid; int i, err=0; sprintf(buf, _("Calling act_pile(%i)"), func); pushcontext(buf); #ifdef DEBUG affichage_pile(); #endif switch (func) { case OP_PLUS: #ifdef DEBUG printf("----- OP_PLUS\n"); #endif operande1 = pop_pile(1); operande2 = pop_pile(1); if ((operande1.type == T_POLY) && (operande2.type == T_POLY)) { push_pile_poly(ply_addition(operande1.poly, operande2.poly)); if (operande1.poly) ply_destruct(operande1.poly); if (operande2.poly) ply_destruct(operande2.poly); } else { exception(1, _("act_pile: OP_PLUS invalid arguments")); } break; case OP_MOINS: #ifdef DEBUG printf("----- OP_MOINS\n"); #endif operande2 = pop_pile(1); operande1 = pop_pile(1); if ((operande1.type == T_POLY) && (operande2.type == T_POLY)) { push_pile_poly(ply_soustraction(operande1.poly, operande2.poly)); if (operande1.poly) ply_destruct(operande1.poly); if (operande2.poly) ply_destruct(operande2.poly); } else { exception(1, _("act_pile: OP_MOINS invalid arguments")); } break; case OP_MUL: #ifdef DEBUG printf("----- OP_MUL\n"); #endif operande1 = pop_pile(1); operande2 = pop_pile(1); if ((operande1.type == T_POLY) && (operande2.type == T_POLY)) { push_pile_poly(ply_multiplication(operande1.poly, operande2.poly)); if (operande1.poly) ply_destruct(operande1.poly); if (operande2.poly) ply_destruct(operande2.poly); } else { exception(1, _("act_pile: OP_MUL invalid arguments")); } break; case OP_DIV: #ifdef DEBUG printf("----- OP_DIV\n"); #endif operande2 = pop_pile(1); operande1 = pop_pile(1); if ((operande1.type == T_POLY) && (operande2.type == T_POLY)) { push_pile_poly(ply_division(operande1.poly, operande2.poly)); if (operande1.poly) ply_destruct(operande1.poly); if (operande2.poly) ply_destruct(operande2.poly); } else { exception(1, _("act_pile: OP_DIV invalid arguments")); } break; case OP_MOD: #ifdef DEBUG printf("----- OP_MOD\n"); #endif operande2 = pop_pile(1); operande1 = pop_pile(1); if ((operande1.type == T_POLY) && (operande2.type == T_POLY)) { push_pile_poly(ply_modulo(operande1.poly, operande2.poly)); if (operande1.poly) ply_destruct(operande1.poly); if (operande2.poly) ply_destruct(operande2.poly); } else { exception(1, _("act_pile: OP_MOD invalid arguments")); } break; case OP_EXP: #ifdef DEBUG printf("----- OP_EXP\n"); #endif operande1 = pop_pile(1); operande2 = pop_pile(1); if ((operande1.type == T_POLY) && (operande2.type == T_POLY)) { if (operande1.poly) { if ((operande1.poly->coef.denom == 1) && (operande1.poly->coef.num >= 0)) { push_pile_poly(ply_exposant(operande2.poly, operande1.poly->coef.num)); if (operande2.poly) ply_destruct(operande2.poly); ply_destruct(operande1.poly); } else { exception(1, _("act_pile: OP_EXP invalid power")); } } else { exception(1, _("act_pile: OP_EXP empty polynom")); } } else { exception(1, _("act_pile: OP_EXP invalid arguments")); } break; case OP_ASSIGN: #ifdef DEBUG printf("----- OP_ASSIGN\n"); #endif operande1 = pop_pile(1); operande2 = pop_pile(1); if ((operande1.type == T_POLY) && (operande2.type == T_STRING)) { if (operande2.label) { NomVarToVar(operande2.label, variables, &valid); if (valid) SupprimerDansTab(&variables,operande2.label); InsererVarDansTab(&variables, CreerElement(operande2.label, (void *) operande1.poly)); push_pile(operande2.label); free(operande2.label); } else { exception(1, _("act_pile: OP_ASSIGN empty string")); } } else { exception(1, _("act_pile: OP_ASSIGN invalid arguments")); } break; case OP_PLUS_UNARY: #ifdef DEBUG printf("----- OP_PLUS_UNARY\n"); #endif break; case OP_MOINS_UNARY: #ifdef DEBUG printf("----- OP_MOINS_UNARY\n"); #endif operande1 = pop_pile(1); if (operande1.type == T_POLY) { push_pile_poly(ply_soustraction(ply_constr(rat_constr_zero(), 0), operande1.poly)); if (operande1.poly) ply_destruct(operande1.poly); } else { exception(1, _("act_pile: OP_MOINS_UNARY invalid argument")); } break; case OP_FUNC_CALL: #ifdef DEBUG printf("----- OP_FUNC_CALL\n"); #endif for (i=0;i<3;i++) operande[i].poly=NULL; operande1 = pop_pile(1); if (operande1.type == T_INT) { for(i=0;idegre == 0) { push_pile_poly(ply_constr (rat_constr_from_double (ply_valuation (operande2.poly, rat_to_double(operande[0].poly->coef))), 0)); if (operande[0].poly) ply_destruct(operande[0].poly); ply_destruct(operande2.poly); } else { exception(1, _("act_pile: OP_FUNC_CALL incorrect value for 2nd arg")); } } else { exception(1, _("act_pile: OP_FUNC_CALL arg2 is an empty polynom")); } break; case T_STRING: appel_fonction(operande2.label,operande1.val,operande[0].poly, operande[1].poly, operande[2].poly); break; } } else { exception(1, _("act_pile: OP_FUNC_CALL incorrect argument number")); } break; default: exception(1, _("act_pile: Unknown operator")); } popcontext(); } void affichage_pile(void) { int i; printf(_("\t-- Printing Stack\n")); if (pile_ptr) { for (i = 0; i <= pile_ptr - 1; i++) { switch (pile[i].type) { case T_INT: printf("\t\t%d:I: %d\n", i, pile[i].val); break; case T_STRING: printf("\t\t%d:S: %s\n", i, pile[i].label); break; case T_POLY: printf("\t\t%d:P: %s\n", i, ply_affichage(pile[i].poly)); break; } } } printf(_("\t-- End Printing Stack\n")); }