diff options
Diffstat (limited to 'table.c')
-rw-r--r-- | table.c | 314 |
1 files changed, 143 insertions, 171 deletions
@@ -3,7 +3,7 @@ | |||
3 | ** Module to control static tables | 3 | ** Module to control static tables |
4 | */ | 4 | */ |
5 | 5 | ||
6 | char *rcs_table="$Id: table.c,v 1.5 1994/04/13 22:10:21 celes Exp celes $"; | 6 | char *rcs_table="$Id: table.c,v 2.1 1994/04/20 22:07:57 celes Exp celes $"; |
7 | 7 | ||
8 | #include <stdlib.h> | 8 | #include <stdlib.h> |
9 | #include <string.h> | 9 | #include <string.h> |
@@ -11,6 +11,7 @@ char *rcs_table="$Id: table.c,v 1.5 1994/04/13 22:10:21 celes Exp celes $"; | |||
11 | #include "mm.h" | 11 | #include "mm.h" |
12 | 12 | ||
13 | #include "opcode.h" | 13 | #include "opcode.h" |
14 | #include "tree.h" | ||
14 | #include "hash.h" | 15 | #include "hash.h" |
15 | #include "inout.h" | 16 | #include "inout.h" |
16 | #include "table.h" | 17 | #include "table.h" |
@@ -18,144 +19,159 @@ char *rcs_table="$Id: table.c,v 1.5 1994/04/13 22:10:21 celes Exp celes $"; | |||
18 | 19 | ||
19 | #define streq(s1,s2) (s1[0]==s2[0]&&strcmp(s1+1,s2+1)==0) | 20 | #define streq(s1,s2) (s1[0]==s2[0]&&strcmp(s1+1,s2+1)==0) |
20 | 21 | ||
21 | #ifndef MAXSYMBOL | 22 | #define BUFFER_BLOCK 256 |
22 | #define MAXSYMBOL 512 | 23 | |
23 | #endif | 24 | Symbol *lua_table; |
24 | static Symbol tablebuffer[MAXSYMBOL] = { | 25 | static Word lua_ntable = 0; |
25 | {"type",{T_CFUNCTION,{lua_type}}}, | 26 | static Word lua_maxsymbol = 0; |
26 | {"tonumber",{T_CFUNCTION,{lua_obj2number}}}, | 27 | |
27 | {"next",{T_CFUNCTION,{lua_next}}}, | 28 | char **lua_constant; |
28 | {"nextvar",{T_CFUNCTION,{lua_nextvar}}}, | 29 | static Word lua_nconstant = 0; |
29 | {"print",{T_CFUNCTION,{lua_print}}}, | 30 | static Word lua_maxconstant = 0; |
30 | {"dofile",{T_CFUNCTION,{lua_internaldofile}}}, | 31 | |
31 | {"dostring",{T_CFUNCTION,{lua_internaldostring}}} | 32 | |
32 | }; | ||
33 | Symbol *lua_table=tablebuffer; | ||
34 | Word lua_ntable=7; | ||
35 | |||
36 | struct List | ||
37 | { | ||
38 | Symbol *s; | ||
39 | struct List *next; | ||
40 | }; | ||
41 | |||
42 | static struct List o6={ tablebuffer+6, 0}; | ||
43 | static struct List o5={ tablebuffer+5, &o6 }; | ||
44 | static struct List o4={ tablebuffer+4, &o5 }; | ||
45 | static struct List o3={ tablebuffer+3, &o4 }; | ||
46 | static struct List o2={ tablebuffer+2, &o3 }; | ||
47 | static struct List o1={ tablebuffer+1, &o2 }; | ||
48 | static struct List o0={ tablebuffer+0, &o1 }; | ||
49 | static struct List *searchlist=&o0; | ||
50 | |||
51 | #ifndef MAXCONSTANT | ||
52 | #define MAXCONSTANT 256 | ||
53 | #endif | ||
54 | /* pre-defined constants need garbage collection extra byte */ | ||
55 | static char tm[] = " mark"; | ||
56 | static char ti[] = " nil"; | ||
57 | static char tn[] = " number"; | ||
58 | static char ts[] = " string"; | ||
59 | static char tt[] = " table"; | ||
60 | static char tf[] = " function"; | ||
61 | static char tc[] = " cfunction"; | ||
62 | static char tu[] = " userdata"; | ||
63 | static char *constantbuffer[MAXCONSTANT] = {tm+1, ti+1, | ||
64 | tn+1, ts+1, | ||
65 | tt+1, tf+1, | ||
66 | tc+1, tu+1 | ||
67 | }; | ||
68 | char **lua_constant = constantbuffer; | ||
69 | Word lua_nconstant=T_USERDATA+1; | ||
70 | |||
71 | #ifndef MAXSTRING | ||
72 | #define MAXSTRING 512 | ||
73 | #endif | ||
74 | static char *stringbuffer[MAXSTRING]; | ||
75 | char **lua_string = stringbuffer; | ||
76 | Word lua_nstring=0; | ||
77 | 33 | ||
78 | #define MAXFILE 20 | 34 | #define MAXFILE 20 |
79 | char *lua_file[MAXFILE]; | 35 | char *lua_file[MAXFILE]; |
80 | int lua_nfile; | 36 | int lua_nfile; |
81 | 37 | ||
38 | /* Variables to controll garbage collection */ | ||
39 | #define GARBAGE_BLOCK 256 | ||
40 | Word lua_block=GARBAGE_BLOCK; /* when garbage collector will be called */ | ||
41 | Word lua_nentity; /* counter of new entities (strings and arrays) */ | ||
82 | 42 | ||
83 | #define markstring(s) (*((s)-1)) | ||
84 | 43 | ||
44 | /* | ||
45 | ** Initialise symbol table with internal functions | ||
46 | */ | ||
47 | static void lua_initsymbol (void) | ||
48 | { | ||
49 | int n; | ||
50 | lua_maxsymbol = BUFFER_BLOCK; | ||
51 | lua_table = (Symbol *) calloc(lua_maxsymbol, sizeof(Symbol)); | ||
52 | if (lua_table == NULL) | ||
53 | { | ||
54 | lua_error ("symbol table: not enough memory"); | ||
55 | return; | ||
56 | } | ||
57 | n = lua_findsymbol("type"); | ||
58 | s_tag(n) = T_CFUNCTION; s_fvalue(n) = lua_type; | ||
59 | n = lua_findsymbol("tonumber"); | ||
60 | s_tag(n) = T_CFUNCTION; s_fvalue(n) = lua_obj2number; | ||
61 | n = lua_findsymbol("next"); | ||
62 | s_tag(n) = T_CFUNCTION; s_fvalue(n) = lua_next; | ||
63 | n = lua_findsymbol("nextvar"); | ||
64 | s_tag(n) = T_CFUNCTION; s_fvalue(n) = lua_nextvar; | ||
65 | n = lua_findsymbol("print"); | ||
66 | s_tag(n) = T_CFUNCTION; s_fvalue(n) = lua_print; | ||
67 | n = lua_findsymbol("dofile"); | ||
68 | s_tag(n) = T_CFUNCTION; s_fvalue(n) = lua_internaldofile; | ||
69 | n = lua_findsymbol("dostring"); | ||
70 | s_tag(n) = T_CFUNCTION; s_fvalue(n) = lua_internaldostring; | ||
71 | } | ||
85 | 72 | ||
86 | /* Variables to controll garbage collection */ | ||
87 | Word lua_block=10; /* to check when garbage collector will be called */ | ||
88 | Word lua_nentity; /* counter of new entities (strings and arrays) */ | ||
89 | 73 | ||
74 | /* | ||
75 | ** Initialise constant table with pre-defined constants | ||
76 | */ | ||
77 | void lua_initconstant (void) | ||
78 | { | ||
79 | lua_maxconstant = BUFFER_BLOCK; | ||
80 | lua_constant = (char **) calloc(lua_maxconstant, sizeof(char *)); | ||
81 | if (lua_constant == NULL) | ||
82 | { | ||
83 | lua_error ("constant table: not enough memory"); | ||
84 | return; | ||
85 | } | ||
86 | lua_findconstant("mark"); | ||
87 | lua_findconstant("nil"); | ||
88 | lua_findconstant("number"); | ||
89 | lua_findconstant("string"); | ||
90 | lua_findconstant("table"); | ||
91 | lua_findconstant("function"); | ||
92 | lua_findconstant("cfunction"); | ||
93 | lua_findconstant("userdata"); | ||
94 | } | ||
90 | 95 | ||
91 | /* | 96 | /* |
92 | ** Given a name, search it at symbol table and return its index. If not | 97 | ** Given a name, search it at symbol table and return its index. If not |
93 | ** found, allocate at end of table, checking oveflow and return its index. | 98 | ** found, allocate it. |
94 | ** On error, return -1. | 99 | ** On error, return -1. |
95 | */ | 100 | */ |
96 | int lua_findsymbol (char *s) | 101 | int lua_findsymbol (char *s) |
97 | { | 102 | { |
98 | struct List *l, *p; | 103 | char *n; |
99 | for (p=NULL, l=searchlist; l!=NULL; p=l, l=l->next) | 104 | if (lua_table == NULL) |
100 | if (streq(s,l->s->name)) | 105 | lua_initsymbol(); |
101 | { | 106 | n = lua_varcreate(s); |
102 | if (p!=NULL) | 107 | if (n == NULL) |
103 | { | ||
104 | p->next = l->next; | ||
105 | l->next = searchlist; | ||
106 | searchlist = l; | ||
107 | } | ||
108 | return (l->s-lua_table); | ||
109 | } | ||
110 | |||
111 | if (lua_ntable >= MAXSYMBOL-1) | ||
112 | { | 108 | { |
113 | lua_error ("symbol table overflow"); | 109 | lua_error ("create symbol: not enough memory"); |
114 | return -1; | 110 | return -1; |
115 | } | 111 | } |
116 | s_name(lua_ntable) = strdup(s); | 112 | if (indexstring(n) == UNMARKED_STRING) |
117 | if (s_name(lua_ntable) == NULL) | ||
118 | { | 113 | { |
119 | lua_error ("not enough memory"); | 114 | if (lua_ntable == lua_maxsymbol) |
120 | return -1; | 115 | { |
116 | lua_maxsymbol *= 2; | ||
117 | if (lua_maxsymbol > MAX_WORD) | ||
118 | { | ||
119 | lua_error("symbol table overflow"); | ||
120 | return -1; | ||
121 | } | ||
122 | lua_table = (Symbol *)realloc(lua_table, lua_maxsymbol*sizeof(Symbol)); | ||
123 | if (lua_table == NULL) | ||
124 | { | ||
125 | lua_error ("symbol table: not enough memory"); | ||
126 | return -1; | ||
127 | } | ||
128 | } | ||
129 | indexstring(n) = lua_ntable; | ||
130 | s_tag(lua_ntable) = T_NIL; | ||
131 | lua_ntable++; | ||
121 | } | 132 | } |
122 | s_tag(lua_ntable) = T_NIL; | 133 | return indexstring(n); |
123 | p = malloc(sizeof(*p)); | ||
124 | p->s = lua_table+lua_ntable; | ||
125 | p->next = searchlist; | ||
126 | searchlist = p; | ||
127 | |||
128 | return lua_ntable++; | ||
129 | } | 134 | } |
130 | 135 | ||
136 | |||
131 | /* | 137 | /* |
132 | ** Given a constant string, search it at constant table and return its index. | 138 | ** Given a name, search it at constant table and return its index. If not |
133 | ** If not found, allocate at end of the table, checking oveflow and return | 139 | ** found, allocate it. |
134 | ** its index. | 140 | ** On error, return -1. |
135 | ** | ||
136 | ** For each allocation, the function allocate a extra char to be used to | ||
137 | ** mark used string (it's necessary to deal with constant and string | ||
138 | ** uniformily). The function store at the table the second position allocated, | ||
139 | ** that represents the beginning of the real string. On error, return -1. | ||
140 | ** | ||
141 | */ | 141 | */ |
142 | int lua_findconstant (char *s) | 142 | int lua_findconstant (char *s) |
143 | { | 143 | { |
144 | int i; | 144 | char *n; |
145 | for (i=0; i<lua_nconstant; i++) | 145 | if (lua_constant == NULL) |
146 | if (streq(s,lua_constant[i])) | 146 | lua_initconstant(); |
147 | return i; | 147 | n = lua_constcreate(s); |
148 | if (lua_nconstant >= MAXCONSTANT-1) | 148 | if (n == NULL) |
149 | { | 149 | { |
150 | lua_error ("lua: constant string table overflow"); | 150 | lua_error ("create constant: not enough memory"); |
151 | return -1; | 151 | return -1; |
152 | } | 152 | } |
153 | if (indexstring(n) == UNMARKED_STRING) | ||
153 | { | 154 | { |
154 | char *c = calloc(strlen(s)+2,sizeof(char)); | 155 | if (lua_nconstant == lua_maxconstant) |
155 | c++; /* create mark space */ | 156 | { |
156 | lua_constant[lua_nconstant++] = strcpy(c,s); | 157 | lua_maxconstant *= 2; |
158 | if (lua_maxconstant > MAX_WORD) | ||
159 | { | ||
160 | lua_error("constant table overflow"); | ||
161 | return -1; | ||
162 | } | ||
163 | lua_constant = (char**)realloc(lua_constant,lua_maxconstant*sizeof(char*)); | ||
164 | if (lua_constant == NULL) | ||
165 | { | ||
166 | lua_error ("constant table: not enough memory"); | ||
167 | return -1; | ||
168 | } | ||
169 | } | ||
170 | indexstring(n) = lua_nconstant; | ||
171 | lua_constant[lua_nconstant] = n; | ||
172 | lua_nconstant++; | ||
157 | } | 173 | } |
158 | return (lua_nconstant-1); | 174 | return indexstring(n); |
159 | } | 175 | } |
160 | 176 | ||
161 | 177 | ||
@@ -175,10 +191,10 @@ void lua_travsymbol (void (*fn)(Object *)) | |||
175 | */ | 191 | */ |
176 | void lua_markobject (Object *o) | 192 | void lua_markobject (Object *o) |
177 | { | 193 | { |
178 | if (tag(o) == T_STRING) | 194 | if (tag(o) == T_STRING && indexstring(svalue(o)) == UNMARKED_STRING) |
179 | markstring (svalue(o)) = 1; | 195 | indexstring(svalue(o)) = MARKED_STRING; |
180 | else if (tag(o) == T_ARRAY) | 196 | else if (tag(o) == T_ARRAY) |
181 | lua_hashmark (avalue(o)); | 197 | lua_hashmark (avalue(o)); |
182 | } | 198 | } |
183 | 199 | ||
184 | 200 | ||
@@ -194,63 +210,27 @@ void lua_pack (void) | |||
194 | /* mark symbol table strings */ | 210 | /* mark symbol table strings */ |
195 | lua_travsymbol(lua_markobject); | 211 | lua_travsymbol(lua_markobject); |
196 | 212 | ||
197 | lua_stringcollector(); | 213 | lua_strcollector(); |
198 | lua_hashcollector(); | 214 | lua_hashcollector(); |
199 | 215 | ||
200 | lua_nentity = 0; /* reset counter */ | 216 | lua_nentity = 0; /* reset counter */ |
201 | } | 217 | } |
202 | 218 | ||
203 | /* | ||
204 | ** Garbage collection to atrings. | ||
205 | ** Delete all unmarked strings | ||
206 | */ | ||
207 | void lua_stringcollector (void) | ||
208 | { | ||
209 | int i, j; | ||
210 | for (i=j=0; i<lua_nstring; i++) | ||
211 | if (markstring(lua_string[i]) == 1) | ||
212 | { | ||
213 | lua_string[j++] = lua_string[i]; | ||
214 | markstring(lua_string[i]) = 0; | ||
215 | } | ||
216 | else | ||
217 | { | ||
218 | free (lua_string[i]-1); | ||
219 | } | ||
220 | lua_nstring = j; | ||
221 | } | ||
222 | 219 | ||
223 | /* | 220 | /* |
224 | ** Allocate a new string at string table. The given string is already | 221 | ** If the string isn't allocated, allocate a new string at string tree. |
225 | ** allocated with mark space and the function puts it at the end of the | ||
226 | ** table, checking overflow, and returns its own pointer, or NULL on error. | ||
227 | */ | 222 | */ |
228 | char *lua_createstring (char *s) | 223 | char *lua_createstring (char *s) |
229 | { | 224 | { |
230 | int i; | ||
231 | if (s == NULL) return NULL; | 225 | if (s == NULL) return NULL; |
232 | 226 | ||
233 | for (i=0; i<lua_nstring; i++) | 227 | if (lua_nentity == lua_block) |
234 | if (streq(s,lua_string[i])) | ||
235 | { | ||
236 | free(s-1); | ||
237 | return lua_string[i]; | ||
238 | } | ||
239 | |||
240 | if (lua_nentity == lua_block || lua_nstring >= MAXSTRING-1) | ||
241 | { | ||
242 | lua_pack (); | 228 | lua_pack (); |
243 | if (lua_nstring >= MAXSTRING-1) | ||
244 | { | ||
245 | lua_error ("string table overflow"); | ||
246 | return NULL; | ||
247 | } | ||
248 | } | ||
249 | lua_string[lua_nstring++] = s; | ||
250 | lua_nentity++; | 229 | lua_nentity++; |
251 | return s; | 230 | return lua_strcreate(s); |
252 | } | 231 | } |
253 | 232 | ||
233 | |||
254 | /* | 234 | /* |
255 | ** Add a file name at file table, checking overflow. This function also set | 235 | ** Add a file name at file table, checking overflow. This function also set |
256 | ** the external variable "lua_filename" with the function filename set. | 236 | ** the external variable "lua_filename" with the function filename set. |
@@ -293,7 +273,7 @@ char *lua_filename (void) | |||
293 | */ | 273 | */ |
294 | void lua_nextvar (void) | 274 | void lua_nextvar (void) |
295 | { | 275 | { |
296 | int index; | 276 | char *varname, *next; |
297 | Object *o = lua_getparam (1); | 277 | Object *o = lua_getparam (1); |
298 | if (o == NULL) | 278 | if (o == NULL) |
299 | { lua_error ("too few arguments to function `nextvar'"); return; } | 279 | { lua_error ("too few arguments to function `nextvar'"); return; } |
@@ -301,7 +281,7 @@ void lua_nextvar (void) | |||
301 | { lua_error ("too many arguments to function `nextvar'"); return; } | 281 | { lua_error ("too many arguments to function `nextvar'"); return; } |
302 | if (tag(o) == T_NIL) | 282 | if (tag(o) == T_NIL) |
303 | { | 283 | { |
304 | index = 0; | 284 | varname = 0; |
305 | } | 285 | } |
306 | else if (tag(o) != T_STRING) | 286 | else if (tag(o) != T_STRING) |
307 | { | 287 | { |
@@ -310,28 +290,20 @@ void lua_nextvar (void) | |||
310 | } | 290 | } |
311 | else | 291 | else |
312 | { | 292 | { |
313 | for (index=0; index<lua_ntable; index++) | 293 | varname = svalue(o); |
314 | if (streq(s_name(index),svalue(o))) break; | 294 | } |
315 | if (index == lua_ntable) | 295 | next = lua_varnext(varname); |
316 | { | 296 | if (next == NULL) |
317 | lua_error ("name not found in function `nextvar'"); | 297 | { |
318 | return; | 298 | lua_pushnil(); |
319 | } | 299 | lua_pushnil(); |
320 | index++; | ||
321 | while (index < lua_ntable && tag(&s_object(index)) == T_NIL) index++; | ||
322 | |||
323 | if (index == lua_ntable) | ||
324 | { | ||
325 | lua_pushnil(); | ||
326 | lua_pushnil(); | ||
327 | return; | ||
328 | } | ||
329 | } | 300 | } |
301 | else | ||
330 | { | 302 | { |
331 | Object name; | 303 | Object name; |
332 | tag(&name) = T_STRING; | 304 | tag(&name) = T_STRING; |
333 | svalue(&name) = lua_createstring(lua_strdup(s_name(index))); | 305 | svalue(&name) = next; |
334 | if (lua_pushobject (&name)) return; | 306 | if (lua_pushobject (&name)) return; |
335 | if (lua_pushobject (&s_object(index))) return; | 307 | if (lua_pushobject (&s_object(indexstring(next)))) return; |
336 | } | 308 | } |
337 | } | 309 | } |