#include <malloc.h>
+#include <stdio.h>
#include <string.h>
#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 ((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)->stack_size = 0;
- (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;
double ret = 0;
- if (programs) {
-
- /* 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;
- tmp.stack_size = stack_size;
-
- /* change context */
- answer = 0;
- storage = (programs + n)->storage;
- storage_size = (programs + n)->storage_size;
+ /* backup context */
+ workspace_t *tmp = backup_ws (alloc_ws ());
+ restore_ws (programs[n]);
+
+ /* set arguments */
+ free_tab (argument);
argument = NULL;
- argument_size = 0;
- stack = (programs + n)->stack;
- stack_size = (programs + n)->stack_size;
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;
+ def (nbargs, args);
}
/* evaluate program */
- element_t *elements = dupelement ((programs + n)->root);
+ answer = 0;
+ element_t *elements = dupelement (programs[n]->root);
ret = evaluate_element (elements, 0);
delelement (elements);
- (programs + n)->answer = answer;
- (programs + n)->storage = storage;
- (programs + n)->storage_size = storage_size;
+
+ /* clean arguments */
if (argument) {
- free (argument);
+ free_tab (argument);
+ }
+ argument = NULL;
+ if (nbargs > 0) {
+ def (nbargs, args);
}
- (programs + n)->stack = stack;
- (programs + n)->stack_size = stack_size;
/* restore context */
- answer = tmp.answer;
- storage = tmp.storage;
- storage_size = tmp.storage_size;
- argument = tmp.argument;
- argument_size = tmp.argument_size;
- stack = tmp.stack;
- stack_size = tmp.stack_size;
+ backup_ws (programs[n]);
+ restore_ws (tmp);
return ret;
}
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 ((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, sizeof (workspace_t *));
+ if (n != 0) {
+ memcpy (tmp, programs, (n - 1) * sizeof (workspace_t));
+ }
+ if (n != nb_programs) {
+ memcpy (tmp + n - 1, programs + n, (nb_programs - n) * sizeof (workspace_t));
}
free (programs);
programs = tmp;
- nb_programs--;
}
/* vim: set ts=4 sw=4 et: */