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