X-Git-Url: https://secure.softndesign.org/git/?a=blobdiff_plain;f=program.c;h=70ce6c12f943cc5519ba1b2e74d73843d264c5f7;hb=7d32325ab262aaf9cb62151de5a9c889cb5ebfab;hp=c966617c00562beef7d02e191d963ddcb9ff4347;hpb=16a13cbfff44a996b8355cab6fdfee3fae75458d;p=calc.git diff --git a/program.c b/program.c index c966617..70ce6c1 100644 --- a/program.c +++ b/program.c @@ -3,156 +3,128 @@ #include #include "alloc.h" +#include "argument.h" #include "debug.h" #include "parser.h" #include "stack.h" #include "storage.h" #include "tabular.h" +#include "workspace.h" #include "program.h" /* global variables */ -int argument_size = 0; -double *argument = NULL; - -workspace_t *programs = NULL; +workspace_t **programs = NULL; int nb_programs = 0; +/* lookfor program id */ + +int lookfor_program (int id) +{ + int i; + for (i = 0; (programs) && (i < nb_programs); i++) { + if (programs[i]->id == id) { + return i; + } + } + return -1; +} + /* program function */ void prog (int id, element_t *root) { - int i, n = -1; + int n = -1; if (programs == NULL) { /* initial memory allocation */ - programs = (workspace_t *) callocordie (1, sizeof (workspace_t)); - nb_programs = 1; + programs = (workspace_t **) callocordie (1, sizeof (workspace_t *)); n = 0; + nb_programs = 1; + programs[n] = alloc_ws (); } else { /* look for existing program */ - for (i = 0; i < nb_programs; i++) { - if ((programs + i)->id == id) { - n = i; - break; - } - } + n = lookfor_program (id); if (n == -1) { /* new program */ n = nb_programs++; - workspace_t *tmp = (workspace_t *) callocordie (nb_programs, sizeof (workspace_t)); - memcpy (tmp, programs, (nb_programs - 1) * sizeof (workspace_t)); + workspace_t **tmp = (workspace_t **) callocordie (nb_programs, sizeof (workspace_t *)); + memcpy (tmp, programs, (nb_programs - 1) * sizeof (workspace_t *)); free (programs); programs = tmp; + programs[n] = alloc_ws (); + } else { /* clean old program */ - if ((programs + n)->storage) { - free ((programs + n)->storage); - } - if ((programs + n)->stack) { - free_tab ((programs + n)->stack); - } - if ((programs + n)->root) { - delelement ((programs + n)->root); - } - if ((programs + n)->string) { - free ((programs + n)->string); - (programs + n)->string = NULL; - } + clean_ws(programs[n]); } } /* set program */ - (programs + n)->id = id; - (programs + n)->answer = 0; - (programs + n)->storage = NULL; - (programs + n)->storage_size = 0; - (programs + n)->stack = NULL; - (programs + n)->root = dupelement (root); -} - -double arg (int id) -{ - double ret = 0; - if ((id <= 0) || (id > argument_size)) { - VERBOSE (WARNING, fprintf (stdout, "error out of bound (%d/%d)\n", id, argument_size)); - } else { - ret = argument[id - 1]; - } - return ret; + programs[n]->id = id; + programs[n]->root = dupelement (root); } double call (int id, int nbargs, element_t **args) { - workspace_t tmp = {0}; - int i, l, n = -1; + int i; double ret = 0; - if (programs) { + VERBOSE (DEBUG, fprintf (stdout, "new call (%d)\n", id)); - /* look for program */ - for (i = 0; i < nb_programs; i++) { - if ((programs + i)->id == id) { - n = i; - break; - } - } - } + /* look for program */ + int n = lookfor_program (id); if (n == -1) { VERBOSE (WARNING, fprintf (stdout, "error unknown program (%d)\n", id)); return 0; } - /* store context */ - tmp.answer = answer; - tmp.argument = argument; - tmp.argument_size = argument_size; - tmp.storage = storage; - tmp.storage_size = storage_size; - tmp.stack = stack; + /* display debug information */ + VERBOSE (DEBUG, fprintf (stdout, "nbargs: %d\n", nbargs)); + for (i = 0; i < nbargs; i++) { + VERBOSE (DEBUG, fprintf (stdout, "argument %d\n", i + 1); print_element (args[i], 0)); + } + VERBOSE (DEBUG, fprintf (stdout, "program\n"); print_element (programs[n]->root, 0)); - /* change context */ - answer = 0; - storage = (programs + n)->storage; - storage_size = (programs + n)->storage_size; - argument = NULL; - argument_size = 0; - stack = (programs + n)->stack; - if (nbargs > 0) { - argument = (double *) callocordie (nbargs, sizeof (double)); - for (i = 0, l = 0; i < nbargs; l++) { - if (args[l]) { - argument[i++] = evaluate_element (args[l], 0); - } - } - argument_size = nbargs; + /* backup context */ + workspace_t *tmp = backup_ws (alloc_ws ()); + restore_ws (programs[n]); + + /* set arguments */ + VERBOSE (DEBUG, fprintf (stdout, "argument before evaluation (%d)\n", size_tab (argument))); + for (i = 0; i < size_tab (argument); i++) { + VERBOSE (DEBUG, fprintf (stdout, "arg %d value: %g\n", i + 1, get_tab (argument, i + 1))); + } + VERBOSE (DEBUG, fprintf (stdout, "evaluate %d args\n", nbargs)); + tab_t *new_argument = def (nbargs, args); + tab_t *old_argument = argument; + argument = new_argument; + VERBOSE (DEBUG, fprintf (stdout, "argument after evaluation (%d)\n", size_tab (argument))); + for (i = 0; i < size_tab (argument); i++) { + VERBOSE (DEBUG, fprintf (stdout, "arg %d value: %g\n", i + 1, get_tab (argument, i + 1))); } /* evaluate program */ - element_t *elements = dupelement ((programs + n)->root); + answer = 0; + element_t *elements = dupelement (programs[n]->root); ret = evaluate_element (elements, 0); + VERBOSE (DEBUG, fprintf (stdout, "ret; %g\n", ret)); delelement (elements); - (programs + n)->answer = answer; - (programs + n)->storage = storage; - (programs + n)->storage_size = storage_size; - if (argument) { - free (argument); - } - (programs + n)->stack = stack; /* restore context */ - answer = tmp.answer; - storage = tmp.storage; - storage_size = tmp.storage_size; - argument = tmp.argument; - argument_size = tmp.argument_size; - stack = tmp.stack; + backup_ws (programs[n]); + restore_ws (tmp); + free_ws (tmp); + + /* clean arguments */ + free_tab (argument); + argument = old_argument; return ret; } @@ -162,107 +134,59 @@ void list () int i; fprintf (stdout, "programs:"); for (i = 0; i < nb_programs; i++) { - fprintf (stdout, " %d", (programs + i)->id); + fprintf (stdout, " %d", programs[i]->id); } fprintf (stdout, "\n"); } void edit (int id) { - int i, n = -1; - - if (programs) { - - /* look for program */ - for (i = 0; i < nb_programs; i++) { - if ((programs + i)->id == id) { - n = i; - break; - } - } - } + int n = lookfor_program (id); if (n == -1) { VERBOSE (WARNING, fprintf (stdout, "error unknown program (%d)\n", id)); return; } /* set string program */ - fprintf (stdout, "edit: %s\n", (programs + n)->string); + fprintf (stdout, "edit: %s\n", programs[n]->string); } void savestring (int id, char *string) { - int i, n = -1; - - if (programs) { - - /* look for program */ - for (i = 0; i < nb_programs; i++) { - if ((programs + i)->id == id) { - n = i; - break; - } - } - } + int n = lookfor_program (id); /* unnecesary code */ //if (n == -1) { // VERBOSE (WARNING, fprintf (stdout, "error unknown program (%d)\n", id)); // return; //} - //if ((programs + n)->string) { - // free ((programs + n)->string); + //if (programs[n]->string) { + // free (programs[n]->string); //} if (string) { - (programs + n)->string = strdup (string); + programs[n]->string = strdup (string); } } void del (int id) { - int i, j, n = -1; - - if (programs) { - - /* look for program */ - for (i = 0; i < nb_programs; i++) { - if ((programs + i)->id == id) { - n = i; - break; - } - } - } + int n = lookfor_program (id); if (n == -1) { VERBOSE (WARNING, fprintf (stdout, "error unknown program (%d)\n", id)); return; } /* clean program */ - if ((programs + n)->storage) { - free ((programs + n)->storage); - } - if ((programs + n)->stack) { - free_tab ((programs + n)->stack); - } - if ((programs + n)->root) { - delelement ((programs + n)->root); - } - if ((programs + n)->string) { - free ((programs + n)->string); - } + free_ws (programs[n]); /* remove entry */ - workspace_t *tmp = (workspace_t *) callocordie (nb_programs - 1, sizeof (workspace_t)); - for (i = 0, j = 0; i < nb_programs; i++) { - if (i != n) { - memcpy (tmp + j, programs + i, sizeof (workspace_t)); - j++; - } - } + workspace_t **tmp = (workspace_t **) callocordie (nb_programs - 1, sizeof (workspace_t *)); + memcpy (tmp, programs, n * sizeof (workspace_t *)); + memcpy (tmp + n, programs + n + 1, (nb_programs - n - 1) * sizeof (workspace_t *)); + nb_programs--; free (programs); programs = tmp; - nb_programs--; } /* vim: set ts=4 sw=4 et: */