Commit | Line | Data |
---|---|---|
a24bd519 | 1 | #include <malloc.h> |
7059478f | 2 | #include <stdio.h> |
a24bd519 LM |
3 | #include <string.h> |
4 | ||
5 | #include "alloc.h" | |
c91672f9 | 6 | #include "argument.h" |
a24bd519 LM |
7 | #include "debug.h" |
8 | #include "parser.h" | |
9 | #include "stack.h" | |
10 | #include "storage.h" | |
3559b26c | 11 | #include "tabular.h" |
e952523a | 12 | #include "workspace.h" |
a24bd519 LM |
13 | |
14 | #include "program.h" | |
15 | ||
16 | /* global variables */ | |
17 | ||
e952523a | 18 | workspace_t **programs = NULL; |
a24bd519 LM |
19 | int nb_programs = 0; |
20 | ||
e952523a LM |
21 | /* lookfor program id */ |
22 | ||
23 | int lookfor_program (int id) | |
24 | { | |
25 | int i; | |
26 | for (i = 0; (programs) && (i < nb_programs); i++) { | |
27 | if (programs[i]->id == id) { | |
28 | return i; | |
29 | } | |
30 | } | |
31 | return -1; | |
32 | } | |
33 | ||
a24bd519 LM |
34 | /* program function */ |
35 | ||
36 | void prog (int id, element_t *root) | |
37 | { | |
e952523a | 38 | int n = -1; |
a24bd519 LM |
39 | |
40 | if (programs == NULL) { | |
41 | ||
42 | /* initial memory allocation */ | |
e952523a | 43 | programs = (workspace_t **) callocordie (1, sizeof (workspace_t *)); |
a24bd519 | 44 | n = 0; |
e952523a LM |
45 | nb_programs = 1; |
46 | programs[n] = alloc_ws (); | |
a24bd519 LM |
47 | |
48 | } else { | |
49 | ||
50 | /* look for existing program */ | |
e952523a | 51 | n = lookfor_program (id); |
a24bd519 LM |
52 | if (n == -1) { |
53 | ||
54 | /* new program */ | |
55 | n = nb_programs++; | |
e952523a LM |
56 | workspace_t **tmp = (workspace_t **) callocordie (nb_programs, sizeof (workspace_t *)); |
57 | memcpy (tmp, programs, (nb_programs - 1) * sizeof (workspace_t *)); | |
a24bd519 LM |
58 | free (programs); |
59 | programs = tmp; | |
e952523a LM |
60 | programs[n] = alloc_ws (); |
61 | ||
a24bd519 LM |
62 | } else { |
63 | ||
64 | /* clean old program */ | |
e952523a | 65 | clean_ws(programs[n]); |
a24bd519 LM |
66 | } |
67 | } | |
68 | ||
69 | /* set program */ | |
e952523a LM |
70 | programs[n]->id = id; |
71 | programs[n]->root = dupelement (root); | |
a24bd519 LM |
72 | } |
73 | ||
a24bd519 LM |
74 | double call (int id, int nbargs, element_t **args) |
75 | { | |
2ddb38f0 | 76 | int i; |
a24bd519 LM |
77 | double ret = 0; |
78 | ||
2ddb38f0 LM |
79 | VERBOSE (DEBUG, fprintf (stdout, "new call (%d)\n", id)); |
80 | ||
e952523a LM |
81 | /* look for program */ |
82 | int n = lookfor_program (id); | |
a24bd519 LM |
83 | if (n == -1) { |
84 | VERBOSE (WARNING, fprintf (stdout, "error unknown program (%d)\n", id)); | |
85 | return 0; | |
86 | } | |
87 | ||
2ddb38f0 LM |
88 | /* display debug information */ |
89 | VERBOSE (DEBUG, fprintf (stdout, "nbargs: %d\n", nbargs)); | |
90 | for (i = 0; i < nbargs; i++) { | |
91 | VERBOSE (DEBUG, fprintf (stdout, "argument %d\n", i + 1); print_element (args[i], 0)); | |
92 | } | |
93 | VERBOSE (DEBUG, fprintf (stdout, "program\n"); print_element (programs[n]->root, 0)); | |
a24bd519 | 94 | |
33b4877a LM |
95 | /* backup context */ |
96 | workspace_t *tmp = backup_ws (alloc_ws ()); | |
97 | restore_ws (programs[n]); | |
98 | ||
89a2c19d | 99 | /* set arguments */ |
2ddb38f0 LM |
100 | VERBOSE (DEBUG, fprintf (stdout, "argument before evaluation (%d)\n", size_tab (argument))); |
101 | for (i = 0; i < size_tab (argument); i++) { | |
102 | VERBOSE (DEBUG, fprintf (stdout, "arg %d value: %g\n", i + 1, get_tab (argument, i + 1))); | |
103 | } | |
104 | VERBOSE (DEBUG, fprintf (stdout, "evaluate %d args\n", nbargs)); | |
105 | tab_t *new_argument = def (nbargs, args); | |
106 | tab_t *old_argument = argument; | |
107 | argument = new_argument; | |
108 | VERBOSE (DEBUG, fprintf (stdout, "argument after evaluation (%d)\n", size_tab (argument))); | |
109 | for (i = 0; i < size_tab (argument); i++) { | |
110 | VERBOSE (DEBUG, fprintf (stdout, "arg %d value: %g\n", i + 1, get_tab (argument, i + 1))); | |
111 | } | |
89a2c19d | 112 | |
a24bd519 | 113 | /* evaluate program */ |
e952523a LM |
114 | answer = 0; |
115 | element_t *elements = dupelement (programs[n]->root); | |
a24bd519 | 116 | ret = evaluate_element (elements, 0); |
33b4877a | 117 | VERBOSE (DEBUG, fprintf (stdout, "ret; %g\n", ret)); |
a24bd519 | 118 | delelement (elements); |
c91672f9 | 119 | |
a24bd519 | 120 | /* restore context */ |
e952523a LM |
121 | backup_ws (programs[n]); |
122 | restore_ws (tmp); | |
0361f81a | 123 | free_ws (tmp); |
a24bd519 | 124 | |
89a2c19d LM |
125 | /* clean arguments */ |
126 | free_tab (argument); | |
127 | argument = old_argument; | |
128 | ||
a24bd519 LM |
129 | return ret; |
130 | } | |
131 | ||
132 | void list () | |
133 | { | |
134 | int i; | |
b6311fa2 | 135 | printf ("programs:"); |
a24bd519 | 136 | for (i = 0; i < nb_programs; i++) { |
b6311fa2 | 137 | printf (" %d", programs[i]->id); |
a24bd519 | 138 | } |
b6311fa2 | 139 | printf ("\n"); |
a24bd519 LM |
140 | } |
141 | ||
142 | void edit (int id) | |
143 | { | |
0e1e4e76 | 144 | extern char *edit_line; |
e952523a | 145 | int n = lookfor_program (id); |
a24bd519 LM |
146 | if (n == -1) { |
147 | VERBOSE (WARNING, fprintf (stdout, "error unknown program (%d)\n", id)); | |
148 | return; | |
149 | } | |
150 | ||
151 | /* set string program */ | |
0e1e4e76 LM |
152 | if (edit_line) { |
153 | free (edit_line); | |
154 | } | |
155 | edit_line = strdup (programs[n]->string); | |
b6311fa2 | 156 | //printf ("edit: %s\n", programs[n]->string); |
a24bd519 LM |
157 | } |
158 | ||
159 | void savestring (int id, char *string) | |
160 | { | |
e952523a | 161 | int n = lookfor_program (id); |
a24bd519 LM |
162 | |
163 | /* unnecesary code */ | |
164 | //if (n == -1) { | |
165 | // VERBOSE (WARNING, fprintf (stdout, "error unknown program (%d)\n", id)); | |
166 | // return; | |
167 | //} | |
e952523a LM |
168 | //if (programs[n]->string) { |
169 | // free (programs[n]->string); | |
a24bd519 LM |
170 | //} |
171 | ||
172 | if (string) { | |
e952523a | 173 | programs[n]->string = strdup (string); |
a24bd519 LM |
174 | } |
175 | } | |
176 | ||
177 | void del (int id) | |
178 | { | |
e952523a | 179 | int n = lookfor_program (id); |
a24bd519 LM |
180 | if (n == -1) { |
181 | VERBOSE (WARNING, fprintf (stdout, "error unknown program (%d)\n", id)); | |
182 | return; | |
183 | } | |
184 | ||
185 | /* clean program */ | |
e952523a | 186 | free_ws (programs[n]); |
a24bd519 LM |
187 | |
188 | /* remove entry */ | |
5d50462b LM |
189 | workspace_t **tmp = (workspace_t **) callocordie (nb_programs - 1, sizeof (workspace_t *)); |
190 | memcpy (tmp, programs, n * sizeof (workspace_t *)); | |
191 | memcpy (tmp + n, programs + n + 1, (nb_programs - n - 1) * sizeof (workspace_t *)); | |
192 | nb_programs--; | |
a24bd519 LM |
193 | free (programs); |
194 | programs = tmp; | |
a24bd519 LM |
195 | } |
196 | ||
197 | /* vim: set ts=4 sw=4 et: */ |