diff options
| -rw-r--r-- | hash.c | 68 |
1 files changed, 53 insertions, 15 deletions
| @@ -3,7 +3,7 @@ | |||
| 3 | ** hash manager for lua | 3 | ** hash manager for lua |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | char *rcs_hash="$Id: hash.c,v 2.5 1994/08/17 15:03:11 celes Exp $"; | 6 | char *rcs_hash="$Id: hash.c,v 2.6 1994/08/17 17:41:23 celes Exp celes $"; |
| 7 | 7 | ||
| 8 | #include <string.h> | 8 | #include <string.h> |
| 9 | #include <stdlib.h> | 9 | #include <stdlib.h> |
| @@ -265,23 +265,61 @@ static void rehash (Hash *t) | |||
| 265 | */ | 265 | */ |
| 266 | Object *lua_hashget (Hash *t, Object *ref) | 266 | Object *lua_hashget (Hash *t, Object *ref) |
| 267 | { | 267 | { |
| 268 | static int count = 1000; | ||
| 268 | static Object nil_obj = {T_NIL, {NULL}}; | 269 | static Object nil_obj = {T_NIL, {NULL}}; |
| 269 | Object parent; | 270 | int h = present(t, ref); |
| 270 | int count = 1000; | 271 | if (h < 0) return NULL; |
| 271 | tag(&parent) = T_STRING; | 272 | if (tag(ref(node(t, h))) != T_NIL) return val(node(t, h)); |
| 272 | svalue(&parent) = "parent"; | 273 | if (--count == 0) |
| 273 | do | ||
| 274 | { | 274 | { |
| 275 | int h = present(t, ref); | 275 | lua_reportbug ("hierarchy too deep (maybe there is an inheritance loop)"); |
| 276 | if (h < 0) return NULL; | 276 | return &nil_obj; |
| 277 | if (tag(ref(node(t, h))) != T_NIL) return val(node(t, h)); | 277 | } |
| 278 | 278 | ||
| 279 | h = present(t, &parent); /* assert(p >= 0); */ | 279 | { /* check "parent" field */ |
| 280 | t = tag(ref(node(t, h))) != T_NIL && tag(val(node(t, h))) == T_ARRAY ? | 280 | Hash *p; |
| 281 | Object parent; | ||
| 282 | tag(&parent) = T_STRING; | ||
| 283 | svalue(&parent) = "parent"; | ||
| 284 | h = present(t, &parent); /* assert(h >= 0); */ | ||
| 285 | p = tag(ref(node(t, h))) != T_NIL && tag(val(node(t, h))) == T_ARRAY ? | ||
| 281 | avalue(val(node(t, h))) : NULL; | 286 | avalue(val(node(t, h))) : NULL; |
| 282 | } while (t != NULL && --count); | 287 | if (p != NULL) |
| 283 | if (count == 0) | 288 | { |
| 284 | lua_reportbug ("hierarchy too deep (maybe there is an inheritance loop)"); | 289 | Object *r = lua_hashget(p, ref); |
| 290 | if (tag(r) != T_NIL) { count++; return r; } | ||
| 291 | } | ||
| 292 | } | ||
| 293 | |||
| 294 | { /* check "parents" field */ | ||
| 295 | Hash *ps; | ||
| 296 | Object parents; | ||
| 297 | tag(&parents) = T_STRING; | ||
| 298 | svalue(&parents) = "parents"; | ||
| 299 | h = present(t, &parents); /* assert(h >= 0); */ | ||
| 300 | ps = tag(ref(node(t, h))) != T_NIL && tag(val(node(t, h))) == T_ARRAY ? | ||
| 301 | avalue(val(node(t, h))) : NULL; | ||
| 302 | if (ps != NULL) | ||
| 303 | { | ||
| 304 | Hash *p; | ||
| 305 | Object index; | ||
| 306 | tag(&index) = T_NUMBER; | ||
| 307 | nvalue(&index) = 1; | ||
| 308 | h = present(ps, &index); | ||
| 309 | p = tag(ref(node(ps, h))) != T_NIL && tag(val(node(ps, h))) == T_ARRAY ? | ||
| 310 | avalue(val(node(ps, h))) : NULL; | ||
| 311 | while (p != NULL) | ||
| 312 | { | ||
| 313 | Object *r = lua_hashget(p, ref); | ||
| 314 | if (tag(r) != T_NIL) { count++; return r; } | ||
| 315 | nvalue(&index)++; | ||
| 316 | h = present(ps, &index); | ||
| 317 | p = tag(ref(node(ps, h))) != T_NIL && tag(val(node(ps, h))) == T_ARRAY ? | ||
| 318 | avalue(val(node(ps, h))) : NULL; | ||
| 319 | } | ||
| 320 | } | ||
| 321 | } | ||
| 322 | count++; | ||
| 285 | return &nil_obj; | 323 | return &nil_obj; |
| 286 | } | 324 | } |
| 287 | 325 | ||
