+ workspace_t tmp = {0};
+ int i, 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;
+ }
+ }
+ }
+ if (n == -1) {
+ VERBOSE (WARNING, fprintf (stdout, "error unknown program (%d)\n", id));
+ return 0;
+ }
+
+ /* store context */
+ tmp.answer = answer;
+ tmp.storage = storage;
+ tmp.storage_size = storage_size;
+
+ /* change context */
+ answer = 0;
+ storage = (programs + n)->storage;
+ storage_size = (programs + n)->storage_size;
+ if (nbops > storage_size) {
+ double *tmp = (double *) callocordie (nbops, sizeof (double));
+ memcpy (tmp, storage, storage_size * sizeof (double));
+ free (storage);
+ (programs + n)->storage = storage = tmp;
+ (programs + n)->storage_size = storage_size = nbops;
+ }
+ for (i = 0; i < nbops; i++) {
+ double val = evaluate_element (ops[i], 0);
+ store (i + 1, val);
+ }
+
+ /* evaluate program */
+ element_t *elements = dupelement ((programs + n)->root);
+ ret = evaluate_element (elements, 0);
+ delelement (elements);
+
+ /* restore context */
+ answer = tmp.answer;
+ storage = tmp.storage;
+ storage_size = tmp.storage_size;
+
+ return ret;