diff options
| author | Waldemar Celes <celes@tecgraf.puc-rio.br> | 1994-07-19 18:27:18 -0300 |
|---|---|---|
| committer | Waldemar Celes <celes@tecgraf.puc-rio.br> | 1994-07-19 18:27:18 -0300 |
| commit | 493d718b7fe0f1075072a44d7946e38ca7d773d3 (patch) | |
| tree | 3239639a562d742002342166cce005f7d70cc503 /table.c | |
| parent | 1c749a3059051c52c3bc24540e27b0ccbcfff273 (diff) | |
| download | lua-493d718b7fe0f1075072a44d7946e38ca7d773d3.tar.gz lua-493d718b7fe0f1075072a44d7946e38ca7d773d3.tar.bz2 lua-493d718b7fe0f1075072a44d7946e38ca7d773d3.zip | |
Uso de arvores binarias para armazenar nomes e realocacao dinamica
de tabelas (pilhas, hashtable, globais, codigo, etc.)
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 | } |
