diff options
-rw-r--r-- | lapi.c | 35 | ||||
-rw-r--r-- | lapi.h | 3 | ||||
-rw-r--r-- | lbuiltin.c | 31 | ||||
-rw-r--r-- | lcode.c | 6 | ||||
-rw-r--r-- | lparser.c | 9 | ||||
-rw-r--r-- | ltable.c | 24 | ||||
-rw-r--r-- | ltable.h | 4 | ||||
-rw-r--r-- | lua.h | 7 | ||||
-rw-r--r-- | lvm.c | 32 |
9 files changed, 76 insertions, 75 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lapi.c,v 1.89 2000/08/29 14:52:27 roberto Exp roberto $ | 2 | ** $Id: lapi.c,v 1.90 2000/08/29 20:43:28 roberto Exp roberto $ |
3 | ** Lua API | 3 | ** Lua API |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -327,7 +327,7 @@ int lua_ref (lua_State *L, int lock) { | |||
327 | 327 | ||
328 | 328 | ||
329 | /* | 329 | /* |
330 | ** miscelaneous functions | 330 | ** miscellaneous functions |
331 | */ | 331 | */ |
332 | 332 | ||
333 | 333 | ||
@@ -359,24 +359,21 @@ void lua_unref (lua_State *L, int ref) { | |||
359 | } | 359 | } |
360 | 360 | ||
361 | 361 | ||
362 | int luaA_next (lua_State *L, const Hash *t, int i) { | 362 | int lua_next (lua_State *L) { |
363 | int tsize = t->size; | 363 | const TObject *t = Index(L, -2); |
364 | for (; i<tsize; i++) { | 364 | Node *n; |
365 | Node *n = node(t, i); | ||
366 | if (ttype(val(n)) != TAG_NIL) { | ||
367 | luaA_pushobject(L, key(n)); | ||
368 | luaA_pushobject(L, val(n)); | ||
369 | return i+1; /* index to be used next time */ | ||
370 | } | ||
371 | } | ||
372 | return 0; /* no more elements */ | ||
373 | } | ||
374 | |||
375 | |||
376 | int lua_next (lua_State *L, int index, int i) { | ||
377 | const TObject *t = Index(L, index); | ||
378 | if (ttype(t) != TAG_TABLE) | 365 | if (ttype(t) != TAG_TABLE) |
379 | lua_error(L, "Lua API error - object is not a table in `lua_next'"); | 366 | lua_error(L, "Lua API error - object is not a table in `lua_next'"); |
380 | return luaA_next(L, hvalue(t), i); | 367 | n = luaH_next(L, hvalue(t), Index(L, -1)); |
368 | if (n) { | ||
369 | *(L->top-1) = *key(n); | ||
370 | *L->top = *val(n); | ||
371 | api_incr_top(L); | ||
372 | return 1; | ||
373 | } | ||
374 | else { /* no more elements */ | ||
375 | L->top -= 2; /* remove key and table */ | ||
376 | return 0; | ||
377 | } | ||
381 | } | 378 | } |
382 | 379 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lapi.h,v 1.18 2000/05/08 20:49:05 roberto Exp roberto $ | 2 | ** $Id: lapi.h,v 1.19 2000/08/28 17:57:04 roberto Exp roberto $ |
3 | ** Auxiliary functions from Lua API | 3 | ** Auxiliary functions from Lua API |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -13,6 +13,5 @@ | |||
13 | 13 | ||
14 | TObject *luaA_index (lua_State *L, int index); | 14 | TObject *luaA_index (lua_State *L, int index); |
15 | void luaA_pushobject (lua_State *L, const TObject *o); | 15 | void luaA_pushobject (lua_State *L, const TObject *o); |
16 | int luaA_next (lua_State *L, const Hash *t, int i); | ||
17 | 16 | ||
18 | #endif | 17 | #endif |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lbuiltin.c,v 1.123 2000/08/29 14:33:31 roberto Exp roberto $ | 2 | ** $Id: lbuiltin.c,v 1.124 2000/08/29 14:41:56 roberto Exp roberto $ |
3 | ** Built-in functions | 3 | ** Built-in functions |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -267,6 +267,18 @@ int luaB_type (lua_State *L) { | |||
267 | return 1; | 267 | return 1; |
268 | } | 268 | } |
269 | 269 | ||
270 | |||
271 | int luaB_next (lua_State *L) { | ||
272 | luaL_checktype(L, 1, "table"); | ||
273 | lua_settop(L, 2); /* create a 2nd argument if there isn't one */ | ||
274 | if (lua_next(L)) | ||
275 | return 2; | ||
276 | else { | ||
277 | lua_pushnil(L); | ||
278 | return 1; | ||
279 | } | ||
280 | } | ||
281 | |||
270 | /* }====================================================== */ | 282 | /* }====================================================== */ |
271 | 283 | ||
272 | 284 | ||
@@ -355,23 +367,6 @@ int luaB_call (lua_State *L) { | |||
355 | } | 367 | } |
356 | 368 | ||
357 | 369 | ||
358 | int luaB_next (lua_State *L) { | ||
359 | const Hash *a = gettable(L, 1); | ||
360 | int i; /* `luaA_next' gets first element after `i' */ | ||
361 | if (lua_isnull(L, 2) || lua_isnil(L, 2)) /* no index or nil index? */ | ||
362 | i = 0; /* get first */ | ||
363 | else { | ||
364 | i = luaH_pos(L, a, luaA_index(L, 2))+1; | ||
365 | luaL_arg_check(L, i != 0, 2, "key not found"); | ||
366 | } | ||
367 | if (luaA_next(L, a, i) != 0) | ||
368 | return 2; /* `luaA_next' left them on the stack */ | ||
369 | else { | ||
370 | lua_pushnil(L); | ||
371 | return 1; | ||
372 | } | ||
373 | } | ||
374 | |||
375 | 370 | ||
376 | int luaB_tostring (lua_State *L) { | 371 | int luaB_tostring (lua_State *L) { |
377 | char buff[64]; | 372 | char buff[64]; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lcode.c,v 1.48 2000/08/14 17:46:27 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 1.49 2000/08/15 13:18:28 roberto Exp roberto $ |
3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -693,8 +693,8 @@ const struct OpProperties luaK_opproperties[NUM_OPCODES] = { | |||
693 | {iO, 0, 0}, /* OP_PUSHNILJMP */ | 693 | {iO, 0, 0}, /* OP_PUSHNILJMP */ |
694 | {iS, 0, 0}, /* OP_FORPREP */ | 694 | {iS, 0, 0}, /* OP_FORPREP */ |
695 | {iS, 0, 3}, /* OP_FORLOOP */ | 695 | {iS, 0, 3}, /* OP_FORLOOP */ |
696 | {iS, 3, 0}, /* OP_LFORPREP */ | 696 | {iS, 2, 0}, /* OP_LFORPREP */ |
697 | {iS, 0, 4}, /* OP_LFORLOOP */ | 697 | {iS, 0, 3}, /* OP_LFORLOOP */ |
698 | {iAB, VD, 0} /* OP_CLOSURE */ | 698 | {iAB, VD, 0} /* OP_CLOSURE */ |
699 | }; | 699 | }; |
700 | 700 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.c,v 1.109 2000/08/15 13:18:28 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.110 2000/08/22 17:44:17 roberto Exp roberto $ |
3 | ** LL(1) Parser and code generator for Lua | 3 | ** LL(1) Parser and code generator for Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -877,10 +877,9 @@ static void forlist (LexState *ls, TString *indexname) { | |||
877 | next(ls); /* skip `in' */ | 877 | next(ls); /* skip `in' */ |
878 | exp1(ls); /* table */ | 878 | exp1(ls); /* table */ |
879 | new_localvarstr(ls, "*table*", 0); | 879 | new_localvarstr(ls, "*table*", 0); |
880 | new_localvarstr(ls, "*counter*", 1); | 880 | new_localvar(ls, indexname, 1); |
881 | new_localvar(ls, indexname, 2); | 881 | new_localvar(ls, valname, 2); |
882 | new_localvar(ls, valname, 3); | 882 | forbody(ls, 3, OP_LFORPREP, OP_LFORLOOP); |
883 | forbody(ls, 4, OP_LFORPREP, OP_LFORLOOP); | ||
884 | } | 883 | } |
885 | 884 | ||
886 | 885 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltable.c,v 1.52 2000/08/07 20:21:34 roberto Exp roberto $ | 2 | ** $Id: ltable.c,v 1.53 2000/08/09 19:16:57 roberto Exp roberto $ |
3 | ** Lua tables (hash) | 3 | ** Lua tables (hash) |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -114,12 +114,26 @@ const TObject *luaH_get (lua_State *L, const Hash *t, const TObject *key) { | |||
114 | } | 114 | } |
115 | 115 | ||
116 | 116 | ||
117 | int luaH_pos (lua_State *L, const Hash *t, const TObject *key) { | 117 | Node *luaH_next (lua_State *L, const Hash *t, const TObject *key) { |
118 | const TObject *v = luaH_get(L, t, key); | 118 | int i; |
119 | return (v == &luaO_nilobject) ? -1 : /* key not found */ | 119 | if (ttype(key) == TAG_NIL) |
120 | (int)(((const char *)v - (const char *)(&t->node[0].val))/sizeof(Node)); | 120 | i = 0; /* first iteration */ |
121 | else { | ||
122 | const TObject *v = luaH_get(L, t, key); | ||
123 | if (v == &luaO_nilobject) | ||
124 | lua_error(L, "invalid key for `next'"); | ||
125 | i = (int)(((const char *)v - | ||
126 | (const char *)(&t->node[0].val)) / sizeof(Node)) + 1; | ||
127 | } | ||
128 | for (; i<t->size; i++) { | ||
129 | Node *n = node(t, i); | ||
130 | if (ttype(val(n)) != TAG_NIL) | ||
131 | return n; | ||
132 | } | ||
133 | return NULL; /* no more elements */ | ||
121 | } | 134 | } |
122 | 135 | ||
136 | |||
123 | /* | 137 | /* |
124 | ** try to remove a key without value from a table. To avoid problems with | 138 | ** try to remove a key without value from a table. To avoid problems with |
125 | ** hash, change `key' for a number with the same hash. | 139 | ** hash, change `key' for a number with the same hash. |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltable.h,v 1.22 2000/06/05 20:15:33 roberto Exp roberto $ | 2 | ** $Id: ltable.h,v 1.23 2000/06/06 16:31:41 roberto Exp roberto $ |
3 | ** Lua tables (hash) | 3 | ** Lua tables (hash) |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -21,7 +21,7 @@ const TObject *luaH_getnum (const Hash *t, Number key); | |||
21 | const TObject *luaH_getstr (const Hash *t, TString *key); | 21 | const TObject *luaH_getstr (const Hash *t, TString *key); |
22 | void luaH_remove (Hash *t, TObject *key); | 22 | void luaH_remove (Hash *t, TObject *key); |
23 | TObject *luaH_set (lua_State *L, Hash *t, const TObject *key); | 23 | TObject *luaH_set (lua_State *L, Hash *t, const TObject *key); |
24 | int luaH_pos (lua_State *L, const Hash *t, const TObject *r); | 24 | Node * luaH_next (lua_State *L, const Hash *t, const TObject *r); |
25 | TObject *luaH_setint (lua_State *L, Hash *t, int key); | 25 | TObject *luaH_setint (lua_State *L, Hash *t, int key); |
26 | void luaH_setstrnum (lua_State *L, Hash *t, TString *key, Number val); | 26 | void luaH_setstrnum (lua_State *L, Hash *t, TString *key, Number val); |
27 | unsigned long luaH_hash (lua_State *L, const TObject *key); | 27 | unsigned long luaH_hash (lua_State *L, const TObject *key); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lua.h,v 1.61 2000/08/29 14:33:31 roberto Exp roberto $ | 2 | ** $Id: lua.h,v 1.62 2000/08/29 20:43:28 roberto Exp roberto $ |
3 | ** Lua - An Extensible Extension Language | 3 | ** Lua - An Extensible Extension Language |
4 | ** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil | 4 | ** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil |
5 | ** e-mail: lua@tecgraf.puc-rio.br | 5 | ** e-mail: lua@tecgraf.puc-rio.br |
@@ -29,6 +29,7 @@ | |||
29 | #define LUA_REFNIL (-1) | 29 | #define LUA_REFNIL (-1) |
30 | 30 | ||
31 | #define LUA_ANYTAG (-1) | 31 | #define LUA_ANYTAG (-1) |
32 | #define LUA_NOTAG (-2) | ||
32 | 33 | ||
33 | #define LUA_MULTRET (-1) | 34 | #define LUA_MULTRET (-1) |
34 | 35 | ||
@@ -129,7 +130,7 @@ int lua_dobuffer (lua_State *L, const char *buff, size_t size, | |||
129 | 130 | ||
130 | 131 | ||
131 | /* | 132 | /* |
132 | ** miscelaneous functions | 133 | ** miscellaneous functions |
133 | */ | 134 | */ |
134 | int lua_newtag (lua_State *L); | 135 | int lua_newtag (lua_State *L); |
135 | int lua_copytagmethods (lua_State *L, int tagto, int tagfrom); | 136 | int lua_copytagmethods (lua_State *L, int tagto, int tagfrom); |
@@ -141,7 +142,7 @@ void lua_unref (lua_State *L, int ref); | |||
141 | 142 | ||
142 | long lua_collectgarbage (lua_State *L, long limit); | 143 | long lua_collectgarbage (lua_State *L, long limit); |
143 | 144 | ||
144 | int lua_next (lua_State *L, int index, int i); | 145 | int lua_next (lua_State *L); |
145 | 146 | ||
146 | 147 | ||
147 | 148 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 1.130 2000/08/29 14:41:56 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.131 2000/08/29 14:48:16 roberto Exp roberto $ |
3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -656,34 +656,30 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
656 | break; | 656 | break; |
657 | } | 657 | } |
658 | case OP_LFORPREP: { | 658 | case OP_LFORPREP: { |
659 | Node *node; | ||
659 | if (ttype(top-1) != TAG_TABLE) | 660 | if (ttype(top-1) != TAG_TABLE) |
660 | lua_error(L, "`for' table must be a table"); | 661 | lua_error(L, "`for' table must be a table"); |
661 | top++; /* counter */ | 662 | node = luaH_next(L, hvalue(top-1), &luaO_nilobject); |
662 | L->top = top; | 663 | if (node == NULL) { /* `empty' loop? */ |
663 | ttype(top-1) = TAG_NUMBER; | 664 | top--; /* remove table */ |
664 | nvalue(top-1) = (Number)luaA_next(L, hvalue(top-2), 0); /* counter */ | ||
665 | if (nvalue(top-1) == 0) { /* `empty' loop? */ | ||
666 | top -= 2; /* remove table and counter */ | ||
667 | pc += GETARG_S(i)+1; /* jump to loop end */ | 665 | pc += GETARG_S(i)+1; /* jump to loop end */ |
668 | } | 666 | } |
669 | else { | 667 | else { |
670 | top += 2; /* index,value */ | 668 | top += 2; /* index,value */ |
671 | LUA_ASSERT(top==L->top, "bad top"); | 669 | *(top-2) = *key(node); |
670 | *(top-1) = *val(node); | ||
672 | } | 671 | } |
673 | break; | 672 | break; |
674 | } | 673 | } |
675 | case OP_LFORLOOP: { | 674 | case OP_LFORLOOP: { |
676 | int n; | 675 | Node *node; |
677 | top -= 2; /* remove old index,value */ | 676 | LUA_ASSERT(ttype(top-3) == TAG_TABLE, "invalid table"); |
678 | LUA_ASSERT(ttype(top-2) == TAG_TABLE, "invalid table"); | 677 | node = luaH_next(L, hvalue(top-3), top-2); |
679 | LUA_ASSERT(ttype(top-1) == TAG_NUMBER, "invalid counter"); | 678 | if (node == NULL) /* end loop? */ |
680 | L->top = top; | 679 | top -= 3; /* remove table, key, and value */ |
681 | n = luaA_next(L, hvalue(top-2), (int)nvalue(top-1)); | ||
682 | if (n == 0) /* end loop? */ | ||
683 | top -= 2; /* remove table and counter */ | ||
684 | else { | 680 | else { |
685 | nvalue(top-1) = (Number)n; | 681 | *(top-2) = *key(node); |
686 | top += 2; /* new index,value */ | 682 | *(top-1) = *val(node); |
687 | pc += GETARG_S(i); /* repeat loop */ | 683 | pc += GETARG_S(i); /* repeat loop */ |
688 | } | 684 | } |
689 | break; | 685 | break; |