diff options
author | The Lua team <lua@tecgraf.puc-rio.br> | 1993-07-28 10:18:00 -0300 |
---|---|---|
committer | The Lua team <lua@tecgraf.puc-rio.br> | 1993-07-28 10:18:00 -0300 |
commit | cd05d9c5cb69020c069f037ba7f243f705d0a48a (patch) | |
tree | cb7f08c0684c10970a528984741047fb3babadd3 /table.c | |
download | lua-cd05d9c5cb69020c069f037ba7f243f705d0a48a.tar.gz lua-cd05d9c5cb69020c069f037ba7f243f705d0a48a.tar.bz2 lua-cd05d9c5cb69020c069f037ba7f243f705d0a48a.zip |
oldest known commit
Diffstat (limited to 'table.c')
-rw-r--r-- | table.c | 351 |
1 files changed, 351 insertions, 0 deletions
diff --git a/table.c b/table.c new file mode 100644 index 00000000..3bae7ebd --- /dev/null +++ b/table.c | |||
@@ -0,0 +1,351 @@ | |||
1 | /* | ||
2 | ** table.c | ||
3 | ** Module to control static tables | ||
4 | ** TeCGraf - PUC-Rio | ||
5 | ** 11 May 93 | ||
6 | */ | ||
7 | |||
8 | #include <stdlib.h> | ||
9 | #include <string.h> | ||
10 | |||
11 | #include "opcode.h" | ||
12 | #include "hash.h" | ||
13 | #include "inout.h" | ||
14 | #include "table.h" | ||
15 | #include "lua.h" | ||
16 | |||
17 | #define streq(s1,s2) (strcmp(s1,s2)==0) | ||
18 | |||
19 | #ifndef MAXSYMBOL | ||
20 | #define MAXSYMBOL 512 | ||
21 | #endif | ||
22 | static Symbol tablebuffer[MAXSYMBOL] = { | ||
23 | {"type",{T_CFUNCTION,{lua_type}}}, | ||
24 | {"tonumber",{T_CFUNCTION,{lua_obj2number}}}, | ||
25 | {"next",{T_CFUNCTION,{lua_next}}}, | ||
26 | {"nextvar",{T_CFUNCTION,{lua_nextvar}}}, | ||
27 | {"print",{T_CFUNCTION,{lua_print}}} | ||
28 | }; | ||
29 | Symbol *lua_table=tablebuffer; | ||
30 | Word lua_ntable=5; | ||
31 | |||
32 | #ifndef MAXCONSTANT | ||
33 | #define MAXCONSTANT 256 | ||
34 | #endif | ||
35 | static char *constantbuffer[MAXCONSTANT] = {"mark","nil","number", | ||
36 | "string","table", | ||
37 | "function","cfunction" | ||
38 | }; | ||
39 | char **lua_constant = constantbuffer; | ||
40 | Word lua_nconstant=T_CFUNCTION+1; | ||
41 | |||
42 | #ifndef MAXSTRING | ||
43 | #define MAXSTRING 512 | ||
44 | #endif | ||
45 | static char *stringbuffer[MAXSTRING]; | ||
46 | char **lua_string = stringbuffer; | ||
47 | Word lua_nstring=0; | ||
48 | |||
49 | #ifndef MAXARRAY | ||
50 | #define MAXARRAY 512 | ||
51 | #endif | ||
52 | static Hash *arraybuffer[MAXARRAY]; | ||
53 | Hash **lua_array = arraybuffer; | ||
54 | Word lua_narray=0; | ||
55 | |||
56 | #define MAXFILE 20 | ||
57 | char *lua_file[MAXFILE]; | ||
58 | int lua_nfile; | ||
59 | |||
60 | |||
61 | /* | ||
62 | ** Given a name, search it at symbol table and return its index. If not | ||
63 | ** found, allocate at end of table, checking oveflow and return its index. | ||
64 | ** On error, return -1. | ||
65 | */ | ||
66 | int lua_findsymbol (char *s) | ||
67 | { | ||
68 | int i; | ||
69 | for (i=0; i<lua_ntable; i++) | ||
70 | if (streq(s,s_name(i))) | ||
71 | return i; | ||
72 | if (lua_ntable >= MAXSYMBOL-1) | ||
73 | { | ||
74 | lua_error ("symbol table overflow"); | ||
75 | return -1; | ||
76 | } | ||
77 | s_name(lua_ntable) = strdup(s); | ||
78 | if (s_name(lua_ntable) == NULL) | ||
79 | { | ||
80 | lua_error ("not enough memory"); | ||
81 | return -1; | ||
82 | } | ||
83 | s_tag(lua_ntable++) = T_NIL; | ||
84 | |||
85 | return (lua_ntable-1); | ||
86 | } | ||
87 | |||
88 | /* | ||
89 | ** Given a constant string, eliminate its delimeters (" or '), search it at | ||
90 | ** constant table and return its index. If not found, allocate at end of | ||
91 | ** the table, checking oveflow and return its index. | ||
92 | ** | ||
93 | ** For each allocation, the function allocate a extra char to be used to | ||
94 | ** mark used string (it's necessary to deal with constant and string | ||
95 | ** uniformily). The function store at the table the second position allocated, | ||
96 | ** that represents the beginning of the real string. On error, return -1. | ||
97 | ** | ||
98 | */ | ||
99 | int lua_findenclosedconstant (char *s) | ||
100 | { | ||
101 | int i, j, l=strlen(s); | ||
102 | char *c = calloc (l, sizeof(char)); /* make a copy */ | ||
103 | |||
104 | c++; /* create mark space */ | ||
105 | |||
106 | /* introduce scape characters */ | ||
107 | for (i=1,j=0; i<l-1; i++) | ||
108 | { | ||
109 | if (s[i] == '\\') | ||
110 | { | ||
111 | switch (s[++i]) | ||
112 | { | ||
113 | case 'n': c[j++] = '\n'; break; | ||
114 | case 't': c[j++] = '\t'; break; | ||
115 | case 'r': c[j++] = '\r'; break; | ||
116 | default : c[j++] = '\\'; c[j++] = c[i]; break; | ||
117 | } | ||
118 | } | ||
119 | else | ||
120 | c[j++] = s[i]; | ||
121 | } | ||
122 | c[j++] = 0; | ||
123 | |||
124 | for (i=0; i<lua_nconstant; i++) | ||
125 | if (streq(c,lua_constant[i])) | ||
126 | { | ||
127 | free (c-1); | ||
128 | return i; | ||
129 | } | ||
130 | if (lua_nconstant >= MAXCONSTANT-1) | ||
131 | { | ||
132 | lua_error ("lua: constant string table overflow"); | ||
133 | return -1; | ||
134 | } | ||
135 | lua_constant[lua_nconstant++] = c; | ||
136 | return (lua_nconstant-1); | ||
137 | } | ||
138 | |||
139 | /* | ||
140 | ** Given a constant string, search it at constant table and return its index. | ||
141 | ** If not found, allocate at end of the table, checking oveflow and return | ||
142 | ** its index. | ||
143 | ** | ||
144 | ** For each allocation, the function allocate a extra char to be used to | ||
145 | ** mark used string (it's necessary to deal with constant and string | ||
146 | ** uniformily). The function store at the table the second position allocated, | ||
147 | ** that represents the beginning of the real string. On error, return -1. | ||
148 | ** | ||
149 | */ | ||
150 | int lua_findconstant (char *s) | ||
151 | { | ||
152 | int i; | ||
153 | for (i=0; i<lua_nconstant; i++) | ||
154 | if (streq(s,lua_constant[i])) | ||
155 | return i; | ||
156 | if (lua_nconstant >= MAXCONSTANT-1) | ||
157 | { | ||
158 | lua_error ("lua: constant string table overflow"); | ||
159 | return -1; | ||
160 | } | ||
161 | { | ||
162 | char *c = calloc(strlen(s)+2,sizeof(char)); | ||
163 | c++; /* create mark space */ | ||
164 | lua_constant[lua_nconstant++] = strcpy(c,s); | ||
165 | } | ||
166 | return (lua_nconstant-1); | ||
167 | } | ||
168 | |||
169 | |||
170 | /* | ||
171 | ** Mark an object if it is a string or a unmarked array. | ||
172 | */ | ||
173 | void lua_markobject (Object *o) | ||
174 | { | ||
175 | if (tag(o) == T_STRING) | ||
176 | lua_markstring (svalue(o)) = 1; | ||
177 | else if (tag(o) == T_ARRAY && markarray(avalue(o)) == 0) | ||
178 | lua_hashmark (avalue(o)); | ||
179 | } | ||
180 | |||
181 | /* | ||
182 | ** Mark all strings and arrays used by any object stored at symbol table. | ||
183 | */ | ||
184 | static void lua_marktable (void) | ||
185 | { | ||
186 | int i; | ||
187 | for (i=0; i<lua_ntable; i++) | ||
188 | lua_markobject (&s_object(i)); | ||
189 | } | ||
190 | |||
191 | /* | ||
192 | ** Simulate a garbage colection. When string table or array table overflows, | ||
193 | ** this function check if all allocated strings and arrays are in use. If | ||
194 | ** there are unused ones, pack (compress) the tables. | ||
195 | */ | ||
196 | static void lua_pack (void) | ||
197 | { | ||
198 | lua_markstack (); | ||
199 | lua_marktable (); | ||
200 | |||
201 | { /* pack string */ | ||
202 | int i, j; | ||
203 | for (i=j=0; i<lua_nstring; i++) | ||
204 | if (lua_markstring(lua_string[i]) == 1) | ||
205 | { | ||
206 | lua_string[j++] = lua_string[i]; | ||
207 | lua_markstring(lua_string[i]) = 0; | ||
208 | } | ||
209 | else | ||
210 | { | ||
211 | free (lua_string[i]-1); | ||
212 | } | ||
213 | lua_nstring = j; | ||
214 | } | ||
215 | |||
216 | { /* pack array */ | ||
217 | int i, j; | ||
218 | for (i=j=0; i<lua_narray; i++) | ||
219 | if (markarray(lua_array[i]) == 1) | ||
220 | { | ||
221 | lua_array[j++] = lua_array[i]; | ||
222 | markarray(lua_array[i]) = 0; | ||
223 | } | ||
224 | else | ||
225 | { | ||
226 | lua_hashdelete (lua_array[i]); | ||
227 | } | ||
228 | lua_narray = j; | ||
229 | } | ||
230 | } | ||
231 | |||
232 | /* | ||
233 | ** Allocate a new string at string table. The given string is already | ||
234 | ** allocated with mark space and the function puts it at the end of the | ||
235 | ** table, checking overflow, and returns its own pointer, or NULL on error. | ||
236 | */ | ||
237 | char *lua_createstring (char *s) | ||
238 | { | ||
239 | if (s == NULL) return NULL; | ||
240 | |||
241 | if (lua_nstring >= MAXSTRING-1) | ||
242 | { | ||
243 | lua_pack (); | ||
244 | if (lua_nstring >= MAXSTRING-1) | ||
245 | { | ||
246 | lua_error ("string table overflow"); | ||
247 | return NULL; | ||
248 | } | ||
249 | } | ||
250 | lua_string[lua_nstring++] = s; | ||
251 | return s; | ||
252 | } | ||
253 | |||
254 | /* | ||
255 | ** Allocate a new array, already created, at array table. The function puts | ||
256 | ** it at the end of the table, checking overflow, and returns its own pointer, | ||
257 | ** or NULL on error. | ||
258 | */ | ||
259 | void *lua_createarray (void *a) | ||
260 | { | ||
261 | if (a == NULL) return NULL; | ||
262 | |||
263 | if (lua_narray >= MAXARRAY-1) | ||
264 | { | ||
265 | lua_pack (); | ||
266 | if (lua_narray >= MAXARRAY-1) | ||
267 | { | ||
268 | lua_error ("indexed table overflow"); | ||
269 | return NULL; | ||
270 | } | ||
271 | } | ||
272 | lua_array[lua_narray++] = a; | ||
273 | return a; | ||
274 | } | ||
275 | |||
276 | |||
277 | /* | ||
278 | ** Add a file name at file table, checking overflow. This function also set | ||
279 | ** the external variable "lua_filename" with the function filename set. | ||
280 | ** Return 0 on success or 1 on error. | ||
281 | */ | ||
282 | int lua_addfile (char *fn) | ||
283 | { | ||
284 | if (lua_nfile >= MAXFILE-1) | ||
285 | { | ||
286 | lua_error ("too many files"); | ||
287 | return 1; | ||
288 | } | ||
289 | if ((lua_file[lua_nfile++] = strdup (fn)) == NULL) | ||
290 | { | ||
291 | lua_error ("not enough memory"); | ||
292 | return 1; | ||
293 | } | ||
294 | return 0; | ||
295 | } | ||
296 | |||
297 | /* | ||
298 | ** Return the last file name set. | ||
299 | */ | ||
300 | char *lua_filename (void) | ||
301 | { | ||
302 | return lua_file[lua_nfile-1]; | ||
303 | } | ||
304 | |||
305 | /* | ||
306 | ** Internal function: return next global variable | ||
307 | */ | ||
308 | void lua_nextvar (void) | ||
309 | { | ||
310 | int index; | ||
311 | Object *o = lua_getparam (1); | ||
312 | if (o == NULL) | ||
313 | { lua_error ("too few arguments to function `nextvar'"); return; } | ||
314 | if (lua_getparam (2) != NULL) | ||
315 | { lua_error ("too many arguments to function `nextvar'"); return; } | ||
316 | if (tag(o) == T_NIL) | ||
317 | { | ||
318 | index = 0; | ||
319 | } | ||
320 | else if (tag(o) != T_STRING) | ||
321 | { | ||
322 | lua_error ("incorrect argument to function `nextvar'"); | ||
323 | return; | ||
324 | } | ||
325 | else | ||
326 | { | ||
327 | for (index=0; index<lua_ntable; index++) | ||
328 | if (streq(s_name(index),svalue(o))) break; | ||
329 | if (index == lua_ntable) | ||
330 | { | ||
331 | lua_error ("name not found in function `nextvar'"); | ||
332 | return; | ||
333 | } | ||
334 | index++; | ||
335 | while (index < lua_ntable-1 && tag(&s_object(index)) == T_NIL) index++; | ||
336 | |||
337 | if (index == lua_ntable-1) | ||
338 | { | ||
339 | lua_pushnil(); | ||
340 | lua_pushnil(); | ||
341 | return; | ||
342 | } | ||
343 | } | ||
344 | { | ||
345 | Object name; | ||
346 | tag(&name) = T_STRING; | ||
347 | svalue(&name) = lua_createstring(lua_strdup(s_name(index))); | ||
348 | if (lua_pushobject (&name)) return; | ||
349 | if (lua_pushobject (&s_object(index))) return; | ||
350 | } | ||
351 | } | ||