/* * * 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" #ifdef HAVE_CONFIG_H #include "config.h" #else #define _(x) x #endif pile_elem pile[PILE_MAX]; unsigned int pile_ptr = 0; 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")); 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(1, _("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(1, _("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(1, _("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(1, buf); } return pile[pile_ptr]; } 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; char buf[50]; 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 arguments")); } } else { exception(1, _("act_pile: OP_EXP invalid arguments")); } } 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) { InsererVarDansTab(&variables, CreerElement(operande2.label, (void *) operande1.poly)); 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 operande1 = pop_pile(1); if ((operande1.type == T_INT) && (operande1.val == 1)) { operande1 = pop_pile(1); operande2 = pop_pile(1); if ((operande1.type == T_POLY) && (operande2.type == T_POLY)) { if (operande2.poly) { if (operande1.poly->degre == 0) { push_pile_poly(ply_constr (rat_constr_from_double (ply_valuation (operande2.poly, rat_to_double(operande1.poly->coef))), 0)); if (operande1.poly) ply_destruct(operande1.poly); ply_destruct(operande2.poly); } else { exception(1, _("act_pile: OP_FUNC_CALL invalid arguments")); } } else { exception(1, _("act_pile: OP_FUNC_CALL invalid arguments")); } } else { exception(1, _("act_pile: OP_FUNC_CALL invalid arguments")); } } 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")); }