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