/* * * Gestion de la pile des operandes * */ #include #include "pile.h" #include "exceptions.h" #include "numbers.h" #include "main.h" #include "parser.h" #ifdef HAVE_CONFIG_H #include "config.h" #else #define _(x) x #endif /* FIXME manque procedure vidage de pile en fin de prog */ 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; double d_number; polynome poly; i_number = char_to_number(st, &valid1); d_number = char_to_double(st, &valid2); valid3 = is_mute(st); poly = (polynome) NomVarToVar(st, variables, &valid4); if (valid1) { /* il s agit d un entier */ push_pile_poly(ply_constr(rat_constr(i_number, 1), 0)); } else if (valid2) { /* il s agit d un flottant */ push_pile_poly(ply_constr(rat_constr_from_double(d_number), 0)); } else if (valid3) { /* il s agit de x */ push_pile_poly(ply_constr(rat_constr(1, 1), 0)); } else if (valid4) { /* il s agit d une variable */ push_pile_poly(ply_copy(poly)); } else { /* il s agit d un nom */ push_pile_string(Estrdup(st)); } } 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 - 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) { /* FIXME: test lowercase / uppercase */ char buf[2]; sprintf(buf, "%c", mute); return strcmp(st, buf); } void act_pile(int func) { pile_elem operande1, operande2; char buf[50]; sprintf(buf, _("Calling act_pile(%i)\n"), func); pushcontext(buf); switch (func) { case OP_PLUS: 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: operande1 = pop_pile(1); operande2 = 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: 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: operande1 = pop_pile(1); operande2 = 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: operande1 = pop_pile(1); operande2 = 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: operande1 = pop_pile(1); operande2 = pop_pile(1); if ((operande1.type == T_POLY) && (operande2.type == T_POLY)) { if (operande2.poly) { if ((operande2.poly->coef.denom == 1) && (operande2.poly->coef.num >= 0)) { push_pile_poly(ply_exposant (operande1.poly, operande2.poly->coef.num)); if (operande1.poly) ply_destruct(operande1.poly); ply_destruct(operande2.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: /* FIXME: sens de l evaluation ? poly label sto ou label poly sto */ 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)); if (operande1.poly) ply_destruct(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: break; case OP_MOINS_UNARY: 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: 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 (operande2.poly->degre == 0) { push_pile_poly(ply_constr (rat_constr_from_double (ply_valuation (operande1.poly, rat_to_double(operande2.poly-> coef))), 1)); 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(); }