fix bracket evaluation
[calc.git] / program.c
CommitLineData
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 18workspace_t **programs = NULL;
a24bd519
LM
19int nb_programs = 0;
20
e952523a
LM
21/* lookfor program id */
22
23int 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
36void 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
74double 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
132void 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
142void 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
159void 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
177void 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: */