/* * * 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 /* 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; char buf[128]; sprintf(buf,"appel à push_pile(%s)",st); pushcontext(buf); i_number = char_to_number(st, &valid1); d_number = char_to_double(st, &valid2); valid3 = is_mute(st); poly = (polynome) NomVarToVar(st, variables, &valid4); printf("%p\n", poly); if (valid1) { /* il s agit d un entier */ pushcontext("c est un entier"); push_pile_poly(ply_constr(rat_constr(i_number, 1), 0)); popcontext(); } else if (valid2) { /* il s agit d un flottant */ pushcontext("c est un flottant"); push_pile_poly(ply_constr(rat_constr_from_double(d_number), 0)); popcontext(); } else if (valid3) { /* il s agit de x */ pushcontext("c est X"); push_pile_poly(ply_constr(rat_constr(1, 1), 0)); popcontext(); } else if (valid4) { /* il s agit d une variable */ pushcontext("c est une variable"); push_pile_poly(ply_copy(poly)); popcontext(); } else { /* il s agit d un nom */ pushcontext("c est un nom"); push_pile_string(Estrdup(st)); popcontext(); } popcontext(); fprintf(stderr, "sortie de push_pile\n"); } void push_pile_poly(polynome poly) { pushcontext("entree dans push_pile_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")); } pushcontext("sortie de push_pile_poly"); popcontext(); popcontext(); } void push_pile_int(int val) { pushcontext("appel a push_pile_int"); fprintf(stderr,"%d",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")); } pushcontext("sortie de push-pile_int"); popcontext(); popcontext(); } void push_pile_string(char *st) { pushcontext("appel a push_pile_string"); 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")); } pushcontext("sortie de push_pile_string"); popcontext(); popcontext(); } 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); } fprintf(stderr,"pile_ptr = %d\n", pile_ptr); 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 */ return !(strcmp(st, mute)); } 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: 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: 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 (operande1.poly->degre == 0) { double soja, soja2; rationnel rat; polynome pl; fprintf(stderr,"soja"); soja=rat_to_double(operande1.poly->coef); fprintf(stderr,"%f",soja); soja2=ply_valuation(operande2.poly,soja); fprintf(stderr,"%f", soja2); rat=rat_constr_from_double(soja2); fprintf(stderr,"pl"); pl=ply_constr(rat, 1); /* push_pile_poly(ply_constr(rat_constr_from_double(ply_valuation(operande2.poly,rat_to_double(operande1.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(); }