summaryrefslogtreecommitdiff
path: root/pile.c
diff options
context:
space:
mode:
Diffstat (limited to 'pile.c')
-rw-r--r--pile.c291
1 files changed, 291 insertions, 0 deletions
diff --git a/pile.c b/pile.c
new file mode 100644
index 0000000..294b402
--- /dev/null
+++ b/pile.c
@@ -0,0 +1,291 @@
+/*
+ *
+ * Gestion de la pile des operandes
+ *
+ */
+
+#include "pile.h"
+#include "exceptions.h"
+#include "numbers.h"
+#include "main.h"
+#include "interface.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, valid4;
+ int i_number;
+ double d_number;
+ polynome poly;
+ char *buf;
+
+ i_number = char_to_number(st, &valid1);
+ d_number = char_to_double(st, &valid2);
+ valid3 = is_mute(st);
+ poly = (polynome) NomVarToVar(st, variables, (char *) 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;
+
+ 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;
+ }
+ }
+}
+
+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();
+}