Nodes are freed now. Many bugs fixed.
[egate.git] / fml / fmlmem.c
1 /*
2  * FML interpreter. Europagate, 1995
3  *
4  * $Log: fmlmem.c,v $
5  * Revision 1.3  1995/02/09 13:07:15  adam
6  * Nodes are freed now. Many bugs fixed.
7  *
8  * Revision 1.2  1995/02/06  15:23:26  adam
9  * Added some more relational operators (le,ne,ge). Added increment
10  * and decrement operators. Function index changed, so that first
11  * element is 1 - not 0. Function fml_atom_val edited.
12  *
13  * Revision 1.1.1.1  1995/02/06  13:48:10  adam
14  * First version of the FML interpreter. It's slow and memory isn't
15  * freed properly. In particular, the FML nodes aren't released yet.
16  *
17  */
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <assert.h>
22
23 #include "fmlp.h"
24
25 #define FML_ATOM_CHUNK 1024
26 #define FML_NODE_CHUNK 1024
27
28 static int no_nodes = 0;
29 static int no_atoms = 0;
30
31 struct fml_node *fml_node_alloc (Fml fml)
32 {
33     struct fml_node *n;
34
35     if (! fml->node_free_list)
36     {
37         int i;
38
39         n = fml->node_free_list = malloc (sizeof(*n) * FML_NODE_CHUNK);
40         if (!n)
41         {
42             (*fml->err_handle)(FML_ERR_NOMEM);
43             exit (1);
44         }
45         for (i = FML_ATOM_CHUNK-1; --i >= 0; n++)
46             n->p[1] = n+1;
47         n->p[1] = NULL;
48     }
49     n = fml->node_free_list;
50     fml->node_free_list = n->p[1];
51     n->p[0] = n->p[1] = NULL;
52     n->is_atom = 0;
53     no_nodes++;
54     return n;
55 }
56
57 static struct fml_atom *atom_malloc (Fml fml)
58 {
59     struct fml_atom *fa;
60
61     if (! fml->atom_free_list)
62     {
63         int i;
64
65         fa = fml->atom_free_list = malloc (sizeof(*fa) * FML_ATOM_CHUNK);
66         if (!fa)
67         {
68             (*fml->err_handle)(FML_ERR_NOMEM);
69             exit (1);
70         }
71         for (i = FML_ATOM_CHUNK-1; --i >= 0; fa++)
72             fa->next = fa+1;
73         fa->next = NULL;
74     }
75     fa = fml->atom_free_list;
76     fml->atom_free_list = fa->next;
77     no_atoms++;
78     return fa;
79 }
80
81 static void atom_delete (Fml fml, struct fml_atom *a)
82 {
83     a->next = fml->atom_free_list;
84     fml->atom_free_list = a;
85     no_atoms--;
86 }
87
88 static struct fml_atom *atom_copy (Fml fml, struct fml_atom *a)
89 {
90     struct fml_atom *a0, *a1;
91
92     a0 = a1 = atom_malloc (fml);
93     while (a)
94     {
95         memcpy (&a1->buf, &a->buf, FML_ATOM_BUF);
96         if (!a->next)
97             break;
98         a = a->next;
99         a1 = a1->next = atom_malloc (fml);
100     }
101     a1->next = NULL;
102     return a0;
103 }
104
105 struct fml_atom *fml_atom_alloc (Fml fml, char *str)
106 {
107     int soff = 0;
108     struct fml_atom *a, *a0;
109
110     a0 = a = atom_malloc (fml);
111     strncpy (a->buf, str, FML_ATOM_BUF);
112     while (strlen (str+soff) >= FML_ATOM_BUF)
113     {
114         struct fml_atom *an;
115
116         an = atom_malloc (fml);
117         a->next = an;
118         soff += FML_ATOM_BUF;
119         strncpy (an->buf, str+soff, FML_ATOM_BUF);
120         a = an;
121     }
122     a->next = NULL;
123     return a0;
124 }
125
126 struct fml_node *fml_mk_list (Fml fml, struct fml_node *fn)
127 {
128     if (fn->is_atom)
129     {
130         struct fml_node *fn2;
131
132         fn2 = fml_node_alloc (fml);
133         fn2->is_atom = 1;
134         fn2->p[0] = fn->p[0];
135         return fn2;
136     }
137     else
138         return fn->p[0];
139 }
140
141 int fml_atom_str (struct fml_atom *a, char *str)
142 {
143     int len = 0;
144
145     assert (a);
146     while (a->next)
147     {
148         if (str)
149             memcpy (str+len, a->buf, FML_ATOM_BUF);
150         len += FML_ATOM_BUF;
151         a = a->next;
152     }
153     if (str)
154         strcpy (str+len, a->buf);
155     len += strlen(str+len);
156     return len;
157 }
158
159 void fml_atom_strx (struct fml_atom *a, char *str, int max)
160 {
161     int len = 0;
162
163     assert (a);
164     while (a->next && len < max - 2*FML_ATOM_BUF)
165     {
166         memcpy (str+len, a->buf, FML_ATOM_BUF);
167         len += FML_ATOM_BUF;
168         a = a->next;
169     }
170     strncpy (str+len, a->buf, FML_ATOM_BUF-1);
171     str[len+FML_ATOM_BUF-1] = '\0';
172 }
173
174
175 int fml_atom_val (struct fml_atom *a)
176 {
177     static char arg[256];
178     assert (a);
179     if (!a->next)
180         return atoi (a->buf);
181     fml_atom_strx (a, arg, 200);
182     return atoi (arg);
183 }
184
185 void fml_node_delete (Fml fml, struct fml_node *fn)
186 {
187     struct fml_node *f1;
188     while (fn)
189     {
190         if (fn->is_atom)
191             atom_delete (fml, fn->p[0]);
192         else
193             fml_node_delete (fml, fn->p[0]);
194         f1 = fn->p[1];
195         
196         fn->p[1] = fml->node_free_list;
197         fml->node_free_list = fn;
198         no_nodes--;
199
200         fn = f1;
201     }
202 }
203
204 struct fml_node *fml_node_copy (Fml fml, struct fml_node *fn)
205 {
206     struct fml_node *fn0, *fn1;
207
208     if (!fn)
209         return NULL;
210     fn1 = fn0 = fml_node_alloc (fml);
211     while (1)
212     {
213         if (fn->is_atom)
214         {
215             fn1->is_atom = 1;
216             fn1->p[0] = atom_copy (fml, fn->p[0]);
217         }
218         else 
219             fn1->p[0] = fml_node_copy (fml, fn->p[0]);
220         if (!fn->p[1])
221             break;
222         fn = fn->p[1];
223         fn1 = fn1->p[1] = fml_node_alloc (fml);
224     }
225     return fn0;
226 }
227
228 void fml_node_stat (Fml fml)
229 {
230     if (fml->debug & 2)
231         printf ("<<node=%d, atom=%d>>", no_nodes, no_atoms);
232 }