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