summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lapi.c432
-rw-r--r--lapi.h5
-rw-r--r--lauxlib.c68
-rw-r--r--lauxlib.h12
-rw-r--r--lbuiltin.c337
-rw-r--r--lbuiltin.h58
-rw-r--r--ldblib.c104
-rw-r--r--ldebug.c40
-rw-r--r--ldo.c87
-rw-r--r--ldo.h3
-rw-r--r--lgc.c42
-rw-r--r--liolib.c196
-rw-r--r--llimits.h8
-rw-r--r--lmathlib.c122
-rw-r--r--lref.c118
-rw-r--r--lref.h27
-rw-r--r--lstate.c8
-rw-r--r--lstate.h35
-rw-r--r--lstrlib.c104
-rw-r--r--ltests.c413
-rw-r--r--lua.c74
-rw-r--r--lua.h251
-rw-r--r--luadebug.h16
-rw-r--r--lundump.c4
24 files changed, 1205 insertions, 1359 deletions
diff --git a/lapi.c b/lapi.c
index 9d7a07ce..86e20807 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 1.86 2000/08/09 19:16:57 roberto Exp roberto $ 2** $Id: lapi.c,v 1.87 2000/08/14 19:10:14 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*/
@@ -16,7 +16,6 @@
16#include "lgc.h" 16#include "lgc.h"
17#include "lmem.h" 17#include "lmem.h"
18#include "lobject.h" 18#include "lobject.h"
19#include "lref.h"
20#include "lstate.h" 19#include "lstate.h"
21#include "lstring.h" 20#include "lstring.h"
22#include "ltable.h" 21#include "ltable.h"
@@ -29,246 +28,148 @@ const char lua_ident[] = "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
29 28
30 29
31 30
32void luaA_checkCargs (lua_State *L, int nargs) { 31#define Index(L,i) ((i) >= 0 ? (L->Cbase+((i)-1)) : (L->top+(i)))
33 if (nargs > L->top-L->Cstack.base)
34 luaL_verror(L, "Lua API error - "
35 "expected at least %d arguments in C2lua stack", nargs);
36}
37
38 32
39lua_Object luaA_putluaObject (lua_State *L, const TObject *o) { 33#define api_incr_top(L) (++L->top)
40 luaD_openstack(L, L->Cstack.base);
41 *L->Cstack.base++ = *o;
42 return L->Cstack.base-1;
43}
44 34
45 35
46static void top2LC (lua_State *L, int n) {
47 /* Put the `n' elements on the top as the Lua2C contents */
48 L->Cstack.base = L->top; /* new base */
49 L->Cstack.lua2C = L->Cstack.base-n; /* position of the new results */
50 L->Cstack.num = n; /* number of results */
51}
52 36
53 37
54lua_Object lua_pop (lua_State *L) { 38TObject *luaA_index (lua_State *L, int index) {
55 luaA_checkCargs(L, 1); 39 return Index(L, index);
56 if (L->Cstack.base != L->top-1) {
57 luaD_openstack(L, L->Cstack.base);
58 *L->Cstack.base = *(--L->top);
59 }
60 return L->Cstack.base++;
61} 40}
62 41
63 42
64void lua_pushglobals (lua_State *L) { 43void luaA_pushobject (lua_State *L, const TObject *o) {
65 hvalue(L->top) = L->gt; 44 *L->top = *o;
66 ttype(L->top) = TAG_TABLE;
67 incr_top; 45 incr_top;
68} 46}
69 47
70 48
71void lua_setglobals (lua_State *L, lua_Object newtable) {
72 if (lua_type(L, newtable)[0] != 't') /* type == "table"? */
73 lua_error(L, "Lua API error - invalid value for global table");
74 L->gt = hvalue(newtable);
75}
76
77 49
78/* 50/*
79** Get a parameter, returning the object handle or LUA_NOOBJECT on error. 51** basic stack manipulation
80** `number' must be 1 to get the first parameter.
81*/ 52*/
82lua_Object lua_lua2C (lua_State *L, int number) {
83 if (number <= 0 || number > L->Cstack.num) return LUA_NOOBJECT;
84 return L->Cstack.lua2C+number-1;
85}
86 53
87 54
88int lua_callfunction (lua_State *L, lua_Object function) { 55int lua_gettop (lua_State *L) {
89 if (function == LUA_NOOBJECT) 56 return (L->top - L->Cbase);
90 return 1;
91 else {
92 luaD_openstack(L, L->Cstack.base);
93 *L->Cstack.base = *function;
94 return luaD_protectedrun(L);
95 }
96} 57}
97 58
98 59
99lua_Object lua_gettagmethod (lua_State *L, int tag, const char *event) { 60void lua_settop (lua_State *L, int index) {
100 return luaA_putluaObject(L, luaT_gettagmethod(L, tag, event)); 61 if (index >= 0)
62 luaD_adjusttop(L, L->Cbase, index);
63 else
64 L->top += index; /* index is negative */
101} 65}
102 66
103 67
104lua_Object lua_settagmethod (lua_State *L, int tag, const char *event) { 68void lua_pushobject (lua_State *L, int index) {
105 TObject *method; 69 *L->top = *Index(L, index);
106 luaA_checkCargs(L, 1); 70 api_incr_top(L);
107 method = L->top-1;
108 if ((ttype(method) != TAG_NIL) && (*lua_type(L, method) != 'f'))
109 lua_error(L, "Lua API error - tag method must be a function or nil");
110 luaT_settagmethod(L, tag, event, method);
111 return lua_pop(L);
112} 71}
113 72
114 73
115lua_Object lua_gettable (lua_State *L) {
116 luaA_checkCargs(L, 2);
117 luaV_gettable(L, L->top--);
118 return lua_pop(L);
119}
120
121 74
122lua_Object lua_rawget (lua_State *L) { 75/*
123 lua_Object res; 76** access functions (stack -> C)
124 luaA_checkCargs(L, 2); 77*/
125 if (ttype(L->top-2) != TAG_TABLE)
126 lua_error(L, "indexed expression not a table");
127 res = luaA_putluaObject(L, luaH_get(L, hvalue(L->top-2), L->top-1));
128 L->top -= 2;
129 return res;
130}
131 78
132 79
133void lua_settable (lua_State *L) { 80#define btest(L,i,value,default) { \
134 StkId top; 81 StkId o; \
135 luaA_checkCargs(L, 3); 82 if ((i) >= 0) { \
136 top = L->top; 83 o = L->Cbase+((i)-1); \
137 luaV_settable(L, top-3, top); 84 if (o >= L->top) return (default); \
138 L->top = top-3; /* pop table, index, and value */ 85 } \
139} 86 else o = L->top+(i); \
87 return (value); }
140 88
141 89
142void lua_rawset (lua_State *L) { 90#define access(L,i,test,default,value) { \
143 luaA_checkCargs(L, 3); 91 StkId o; \
144 if (ttype(L->top-3) != TAG_TABLE) 92 if ((i) >= 0) { \
145 lua_error(L, "indexed expression not a table"); 93 o = L->Cbase+((i)-1); \
146 *luaH_set(L, hvalue(L->top-3), L->top-2) = *(L->top-1); 94 if (o >= L->top) return (default); \
147 L->top -= 3; 95 } \
148} 96 else o = L->top+(i); \
97 return ((test) ? (value) : (default)); }
149 98
150 99
151lua_Object lua_createtable (lua_State *L) { 100const char *lua_type (lua_State *L, int index) {
152 TObject o; 101 btest(L, index, luaO_typename(o), "NO VALUE");
153 luaC_checkGC(L);
154 hvalue(&o) = luaH_new(L, 0);
155 ttype(&o) = TAG_TABLE;
156 return luaA_putluaObject(L, &o);
157} 102}
158 103
159 104int lua_iscfunction (lua_State *L, int index) {
160lua_Object lua_getglobal (lua_State *L, const char *name) { 105 btest(L, index, (ttype(o) == TAG_CCLOSURE), 0);
161 luaV_getglobal(L, luaS_new(L, name), L->top++);
162 return lua_pop(L);
163} 106}
164 107
165 108int lua_isnumber (lua_State *L, int index) {
166void lua_setglobal (lua_State *L, const char *name) { 109 btest(L, index, (tonumber(Index(L, index)) == 0), 0);
167 luaA_checkCargs(L, 1);
168 luaV_setglobal(L, luaS_new(L, name), L->top--);
169} 110}
170 111
171 112int lua_tag (lua_State *L, int index) {
172const char *lua_type (lua_State *L, lua_Object o) { 113 btest(L, index,
173 UNUSED(L); 114 ((ttype(o) == TAG_USERDATA) ? tsvalue(o)->u.d.tag : luaT_effectivetag(L, o)),
174 return (o == LUA_NOOBJECT) ? "NOOBJECT" : luaO_typename(o); 115 -1);
175} 116}
176 117
177int lua_isnil (lua_State *L, lua_Object o) { 118int lua_equal(lua_State *L, int index1, int index2) {
178 UNUSED(L); 119 return luaO_equalObj(Index(L, index1), Index(L, index2));
179 return (o != LUA_NOOBJECT) && (ttype(o) == TAG_NIL);
180} 120}
181 121
182int lua_istable (lua_State *L, lua_Object o) {
183 UNUSED(L);
184 return (o != LUA_NOOBJECT) && (ttype(o) == TAG_TABLE);
185}
186 122
187int lua_isuserdata (lua_State *L, lua_Object o) {
188 UNUSED(L);
189 return (o != LUA_NOOBJECT) && (ttype(o) == TAG_USERDATA);
190}
191 123
192int lua_iscfunction (lua_State *L, lua_Object o) { 124double lua_tonumber (lua_State *L, int index) {
193 UNUSED(L); 125 access(L, index, (tonumber(o) == 0), 0.0, nvalue(o));
194 return (o != LUA_NOOBJECT) && (ttype(o) == TAG_CCLOSURE);
195} 126}
196 127
197int lua_isnumber (lua_State *L, lua_Object o) { 128const char *lua_tostring (lua_State *L, int index) {
198 UNUSED(L); 129 luaC_checkGC(L); /* `tostring' may create a new string */
199 return (o != LUA_NOOBJECT) && (tonumber(o) == 0); 130 access(L, index, (tostring(L, o) == 0), NULL, svalue(o));
200} 131}
201 132
202int lua_isstring (lua_State *L, lua_Object o) { 133size_t lua_strlen (lua_State *L, int index) {
203 UNUSED(L); 134 access(L, index, (tostring(L, o) == 0), 0, tsvalue(o)->u.s.len);
204 return (o != LUA_NOOBJECT && (ttype(o) == TAG_STRING ||
205 ttype(o) == TAG_NUMBER));
206} 135}
207 136
208int lua_isfunction (lua_State *L, lua_Object o) { 137lua_CFunction lua_tocfunction (lua_State *L, int index) {
209 return *lua_type(L, o) == 'f'; 138 access(L, index, (ttype(o) == TAG_CCLOSURE), NULL, clvalue(o)->f.c);
210} 139}
211 140
212int lua_equal(lua_State *L, lua_Object o1, lua_Object o2) { 141void *lua_touserdata (lua_State *L, int index) {
213 UNUSED(L); 142 access(L, index, (ttype(o) == TAG_USERDATA), NULL, tsvalue(o)->u.d.value);
214 if (o1 == LUA_NOOBJECT || o2 == LUA_NOOBJECT)
215 return (o1 == o2);
216 else return luaO_equalObj(o1, o2);
217} 143}
218 144
219 145
220double lua_getnumber (lua_State *L, lua_Object obj) {
221 UNUSED(L);
222 if (obj == LUA_NOOBJECT || tonumber(obj))
223 return 0.0;
224 else return (nvalue(obj));
225}
226 146
227const char *lua_getstring (lua_State *L, lua_Object obj) { 147/*
228 luaC_checkGC(L); /* `tostring' may create a new string */ 148** push functions (C -> stack)
229 if (obj == LUA_NOOBJECT || tostring(L, obj)) 149*/
230 return NULL;
231 else return (svalue(obj));
232}
233
234size_t lua_strlen (lua_State *L, lua_Object obj) {
235 if (obj == LUA_NOOBJECT || tostring(L, obj))
236 return 0L;
237 else return (tsvalue(obj)->u.s.len);
238}
239
240void *lua_getuserdata (lua_State *L, lua_Object obj) {
241 UNUSED(L);
242 if (obj == LUA_NOOBJECT || ttype(obj) != TAG_USERDATA)
243 return NULL;
244 else return tsvalue(obj)->u.d.value;
245}
246
247lua_CFunction lua_getcfunction (lua_State *L, lua_Object obj) {
248 if (!lua_iscfunction(L, obj))
249 return NULL;
250 else return clvalue(obj)->f.c;
251}
252 150
253 151
254void lua_pushnil (lua_State *L) { 152void lua_pushnil (lua_State *L) {
255 ttype(L->top) = TAG_NIL; 153 ttype(L->top) = TAG_NIL;
256 incr_top; 154 api_incr_top(L);
257} 155}
258 156
157
259void lua_pushnumber (lua_State *L, double n) { 158void lua_pushnumber (lua_State *L, double n) {
260 ttype(L->top) = TAG_NUMBER; 159 ttype(L->top) = TAG_NUMBER;
261 nvalue(L->top) = n; 160 nvalue(L->top) = n;
262 incr_top; 161 api_incr_top(L);
263} 162}
264 163
164
265void lua_pushlstring (lua_State *L, const char *s, size_t len) { 165void lua_pushlstring (lua_State *L, const char *s, size_t len) {
166 luaC_checkGC(L);
266 tsvalue(L->top) = luaS_newlstr(L, s, len); 167 tsvalue(L->top) = luaS_newlstr(L, s, len);
267 ttype(L->top) = TAG_STRING; 168 ttype(L->top) = TAG_STRING;
268 incr_top; 169 api_incr_top(L);
269 luaC_checkGC(L);
270} 170}
271 171
172
272void lua_pushstring (lua_State *L, const char *s) { 173void lua_pushstring (lua_State *L, const char *s) {
273 if (s == NULL) 174 if (s == NULL)
274 lua_pushnil(L); 175 lua_pushnil(L);
@@ -276,48 +177,154 @@ void lua_pushstring (lua_State *L, const char *s) {
276 lua_pushlstring(L, s, strlen(s)); 177 lua_pushlstring(L, s, strlen(s));
277} 178}
278 179
180
279void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { 181void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
280 if (fn == NULL)
281 lua_error(L, "Lua API error - attempt to push a NULL Cfunction");
282 luaA_checkCargs(L, n);
283 luaV_Cclosure(L, fn, n);
284 luaC_checkGC(L); 182 luaC_checkGC(L);
183 luaV_Cclosure(L, fn, n);
285} 184}
286 185
186
287void lua_pushusertag (lua_State *L, void *u, int tag) { /* ORDER LUA_T */ 187void lua_pushusertag (lua_State *L, void *u, int tag) { /* ORDER LUA_T */
188 luaC_checkGC(L);
288 if (tag != LUA_ANYTAG && tag != TAG_USERDATA && tag < NUM_TAGS) 189 if (tag != LUA_ANYTAG && tag != TAG_USERDATA && tag < NUM_TAGS)
289 luaL_verror(L, "invalid tag for a userdata (%d)", tag); 190 luaL_verror(L, "invalid tag for a userdata (%d)", tag);
290 tsvalue(L->top) = luaS_createudata(L, u, tag); 191 tsvalue(L->top) = luaS_createudata(L, u, tag);
291 ttype(L->top) = TAG_USERDATA; 192 ttype(L->top) = TAG_USERDATA;
292 incr_top; 193 api_incr_top(L);
293 luaC_checkGC(L);
294} 194}
295 195
296void luaA_pushobject (lua_State *L, const TObject *o) { 196
297 *L->top = *o; 197
298 incr_top; 198/*
199** get functions (Lua -> stack)
200*/
201
202
203void lua_getglobal (lua_State *L, const char *name) {
204 luaV_getglobal(L, luaS_new(L, name), L->top++);
299} 205}
300 206
301void lua_pushobject (lua_State *L, lua_Object o) { 207
302 if (o == LUA_NOOBJECT) 208void lua_gettable (lua_State *L) {
303 lua_error(L, "Lua API error - attempt to push a NOOBJECT"); 209 luaV_gettable(L, L->top--);
304 *L->top = *o;
305 incr_top;
306} 210}
307 211
308 212
309int lua_tag (lua_State *L, lua_Object o) { 213void lua_rawget (lua_State *L) {
310 if (o == LUA_NOOBJECT) 214 if (ttype(L->top - 2) != TAG_TABLE)
311 return TAG_NIL; 215 lua_error(L, "indexed expression not a table");
312 else if (ttype(o) == TAG_USERDATA) /* to allow `old' tags (deprecated) */ 216 *(L->top - 2) = *luaH_get(L, hvalue(L->top - 2), L->top - 1);
313 return tsvalue(o)->u.d.tag; 217 L->top--;
218}
219
220
221void lua_getglobals (lua_State *L) {
222 hvalue(L->top) = L->gt;
223 ttype(L->top) = TAG_TABLE;
224 api_incr_top(L);
225}
226
227
228void lua_gettagmethod (lua_State *L, int tag, const char *event) {
229 *L->top = *luaT_gettagmethod(L, tag, event);
230 api_incr_top(L);
231}
232
233
234int lua_getref (lua_State *L, int ref) {
235 if (ref == LUA_REFNIL)
236 ttype(L->top) = TAG_NIL;
237 else if (0 <= ref && ref < L->refSize &&
238 (L->refArray[ref].st == LOCK || L->refArray[ref].st == HOLD))
239 *L->top = L->refArray[ref].o;
314 else 240 else
315 return luaT_effectivetag(L, o); 241 return 0;
242 api_incr_top(L);
243 return 1;
244}
245
246
247void lua_newtable (lua_State *L) {
248 luaC_checkGC(L);
249 hvalue(L->top) = luaH_new(L, 0);
250 ttype(L->top) = TAG_TABLE;
251 api_incr_top(L);
316} 252}
317 253
318 254
255
256/*
257** set functions (stack -> Lua)
258*/
259
260
261void lua_setglobal (lua_State *L, const char *name) {
262 luaV_setglobal(L, luaS_new(L, name), L->top--);
263}
264
265
266void lua_settable (lua_State *L) {
267 StkId top = L->top;
268 luaV_settable(L, top-3, top);
269 L->top = top-3; /* pop table, index, and value */
270}
271
272
273void lua_rawset (lua_State *L) {
274 if (ttype(L->top-3) != TAG_TABLE)
275 lua_error(L, "indexed expression not a table");
276 *luaH_set(L, hvalue(L->top-3), L->top-2) = *(L->top-1);
277 L->top -= 3;
278}
279
280
281void lua_setglobals (lua_State *L) {
282 TObject *newtable = --L->top;
283 if (ttype(newtable) != TAG_TABLE)
284 lua_error(L, "Lua API error - invalid value for global table");
285 L->gt = hvalue(newtable);
286}
287
288
289void lua_settagmethod (lua_State *L, int tag, const char *event) {
290 TObject *method = L->top - 1;
291 if (ttype(method) != TAG_NIL &&
292 ttype(method) != TAG_CCLOSURE &&
293 ttype(method) != TAG_LCLOSURE)
294 lua_error(L, "Lua API error - tag method must be a function or nil");
295 luaT_settagmethod(L, tag, event, method);
296}
297
298
299int lua_ref (lua_State *L, int lock) {
300 int ref;
301 if (ttype(L->top-1) == TAG_NIL)
302 ref = LUA_REFNIL;
303 else {
304 if (L->refFree != NONEXT) { /* is there a free place? */
305 ref = L->refFree;
306 L->refFree = L->refArray[ref].st;
307 }
308 else { /* no more free places */
309 luaM_growvector(L, L->refArray, L->refSize, 1, struct Ref,
310 "reference table overflow", MAX_INT);
311 ref = L->refSize++;
312 }
313 L->refArray[ref].o = *(L->top-1);
314 L->refArray[ref].st = lock ? LOCK : HOLD;
315 }
316 L->top--;
317 return ref;
318}
319
320
321
322/*
323** miscelaneous functions
324*/
325
326
319void lua_settag (lua_State *L, int tag) { 327void lua_settag (lua_State *L, int tag) {
320 luaA_checkCargs(L, 1);
321 luaT_realtag(L, tag); 328 luaT_realtag(L, tag);
322 switch (ttype(L->top-1)) { 329 switch (ttype(L->top-1)) {
323 case TAG_TABLE: 330 case TAG_TABLE:
@@ -334,6 +341,17 @@ void lua_settag (lua_State *L, int tag) {
334} 341}
335 342
336 343
344void lua_unref (lua_State *L, int ref) {
345 if (ref >= 0) {
346 if (ref >= L->refSize || L->refArray[ref].st >= 0)
347 lua_error(L, "Lua API error - "
348 "invalid argument for function `lua_unref'");
349 L->refArray[ref].st = L->refFree;
350 L->refFree = ref;
351 }
352}
353
354
337int luaA_next (lua_State *L, const Hash *t, int i) { 355int luaA_next (lua_State *L, const Hash *t, int i) {
338 int tsize = t->size; 356 int tsize = t->size;
339 for (; i<tsize; i++) { 357 for (; i<tsize; i++) {
@@ -348,38 +366,10 @@ int luaA_next (lua_State *L, const Hash *t, int i) {
348} 366}
349 367
350 368
351int lua_next (lua_State *L, lua_Object t, int i) { 369int lua_next (lua_State *L, int index, int i) {
370 const TObject *t = Index(L, index);
352 if (ttype(t) != TAG_TABLE) 371 if (ttype(t) != TAG_TABLE)
353 lua_error(L, "Lua API error - object is not a table in `lua_next'"); 372 lua_error(L, "Lua API error - object is not a table in `lua_next'");
354 i = luaA_next(L, hvalue(t), i); 373 return luaA_next(L, hvalue(t), i);
355 top2LC(L, (i==0) ? 0 : 2);
356 return i;
357}
358
359
360
361#if LUA_DEPRECATETFUNCS
362
363/*
364** obsolete functions
365*/
366
367lua_Object lua_rawgetglobal (lua_State *L, const char *name) {
368 lua_pushglobals(L);
369 lua_pushstring(L, name);
370 return lua_rawget(L);
371}
372
373
374void lua_rawsetglobal (lua_State *L, const char *name) {
375 lua_Object value;
376 lua_beginblock(L);
377 value = lua_pop(L);
378 lua_pushglobals(L);
379 lua_pushstring(L, name);
380 lua_pushobject(L, value);
381 lua_rawset(L);
382 lua_endblock(L);
383} 374}
384 375
385#endif
diff --git a/lapi.h b/lapi.h
index 05153d6d..e8c66393 100644
--- a/lapi.h
+++ b/lapi.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.h,v 1.17 2000/05/08 19:32:53 roberto Exp roberto $ 2** $Id: lapi.h,v 1.18 2000/05/08 20:49:05 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*/
@@ -11,9 +11,8 @@
11#include "lobject.h" 11#include "lobject.h"
12 12
13 13
14void luaA_checkCargs (lua_State *L, int nargs); 14TObject *luaA_index (lua_State *L, int index);
15void luaA_pushobject (lua_State *L, const TObject *o); 15void luaA_pushobject (lua_State *L, const TObject *o);
16int luaA_next (lua_State *L, const Hash *t, int i); 16int luaA_next (lua_State *L, const Hash *t, int i);
17lua_Object luaA_putluaObject (lua_State *L, const TObject *o);
18 17
19#endif 18#endif
diff --git a/lauxlib.c b/lauxlib.c
index a657c2c0..2234934b 100644
--- a/lauxlib.c
+++ b/lauxlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lauxlib.c,v 1.29 2000/06/12 13:52:05 roberto Exp roberto $ 2** $Id: lauxlib.c,v 1.30 2000/08/09 19:16:57 roberto Exp roberto $
3** Auxiliary functions for building Lua libraries 3** Auxiliary functions for building Lua libraries
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -41,72 +41,61 @@ void luaL_argerror (lua_State *L, int narg, const char *extramsg) {
41} 41}
42 42
43 43
44static void type_error (lua_State *L, int narg, const char *type_name, 44static void type_error (lua_State *L, int narg, const char *type_name) {
45 lua_Object o) {
46 char buff[100]; 45 char buff[100];
47 const char *otype = (o == LUA_NOOBJECT) ? "no value" : lua_type(L, o); 46 const char *rt = lua_type(L, narg);
48 sprintf(buff, "%.10s expected, got %.10s", type_name, otype); 47 if (*rt == 'N') rt = "no value";
48 sprintf(buff, "%.10s expected, got %.10s", type_name, rt);
49 luaL_argerror(L, narg, buff); 49 luaL_argerror(L, narg, buff);
50} 50}
51 51
52 52
53static const char *checkstr (lua_State *L, lua_Object o, int narg, 53/*
54 size_t *len) { 54** use the 3rd letter of type names for testing:
55 const char *s = lua_getstring(L, o); 55** nuMber, niL, stRing, fuNction, usErdata, taBle, anY
56 if (!s) type_error(L, narg, "string", o); 56*/
57 if (len) *len = lua_strlen(L, o); 57void luaL_checktype(lua_State *L, int narg, const char *tname) {
58 const char *rt = lua_type(L, narg);
59 if (!(*rt != 'N' && (tname[2] == 'y' || tname[2] == rt[2])))
60 type_error(L, narg, tname);
61}
62
63
64static const char *checkstr (lua_State *L, int narg, size_t *len) {
65 const char *s = lua_tostring(L, narg);
66 if (!s) type_error(L, narg, "string");
67 if (len) *len = lua_strlen(L, narg);
58 return s; 68 return s;
59} 69}
60 70
61const char *luaL_check_lstr (lua_State *L, int narg, size_t *len) { 71const char *luaL_check_lstr (lua_State *L, int narg, size_t *len) {
62 return checkstr(L, lua_getparam(L, narg), narg, len); 72 return checkstr(L, narg, len);
63} 73}
64 74
65const char *luaL_opt_lstr (lua_State *L, int narg, const char *def, 75const char *luaL_opt_lstr (lua_State *L, int narg, const char *def,
66 size_t *len) { 76 size_t *len) {
67 lua_Object o = lua_getparam(L, narg); 77 if (lua_isnull(L, narg)) {
68 if (o == LUA_NOOBJECT) {
69 if (len) *len = def ? strlen(def) : 0; 78 if (len) *len = def ? strlen(def) : 0;
70 return def; 79 return def;
71 } 80 }
72 else return checkstr(L, o, narg, len); 81 else return checkstr(L, narg, len);
73} 82}
74 83
75double luaL_check_number (lua_State *L, int narg) { 84double luaL_check_number (lua_State *L, int narg) {
76 lua_Object o = lua_getparam(L, narg); 85 if (!lua_isnumber(L, narg)) type_error(L, narg, "number");
77 if (!lua_isnumber(L, o)) type_error(L, narg, "number", o); 86 return lua_tonumber(L, narg);
78 return lua_getnumber(L, o);
79} 87}
80 88
81 89
82double luaL_opt_number (lua_State *L, int narg, double def) { 90double luaL_opt_number (lua_State *L, int narg, double def) {
83 lua_Object o = lua_getparam(L, narg); 91 if (lua_isnull(L, narg)) return def;
84 if (o == LUA_NOOBJECT) return def;
85 else { 92 else {
86 if (!lua_isnumber(L, o)) type_error(L, narg, "number", o); 93 if (!lua_isnumber(L, narg)) type_error(L, narg, "number");
87 return lua_getnumber(L, o); 94 return lua_tonumber(L, narg);
88 } 95 }
89} 96}
90 97
91 98
92lua_Object luaL_tablearg (lua_State *L, int narg) {
93 lua_Object o = lua_getparam(L, narg);
94 if (!lua_istable(L, o)) type_error(L, narg, "table", o);
95 return o;
96}
97
98lua_Object luaL_functionarg (lua_State *L, int narg) {
99 lua_Object o = lua_getparam(L, narg);
100 if (!lua_isfunction(L, o)) type_error(L, narg, "function", o);
101 return o;
102}
103
104lua_Object luaL_nonnullarg (lua_State *L, int narg) {
105 lua_Object o = lua_getparam(L, narg);
106 luaL_arg_check(L, o != LUA_NOOBJECT, narg, "value expected");
107 return o;
108}
109
110void luaL_openlib (lua_State *L, const struct luaL_reg *l, int n) { 99void luaL_openlib (lua_State *L, const struct luaL_reg *l, int n) {
111 int i; 100 int i;
112 for (i=0; i<n; i++) 101 for (i=0; i<n; i++)
@@ -150,3 +139,4 @@ void luaL_filesource (char *out, const char *filename, int len) {
150 if (filename == NULL) filename = "(stdin)"; 139 if (filename == NULL) filename = "(stdin)";
151 sprintf(out, "@%.*s", len-2, filename); /* -2 for '@' and '\0' */ 140 sprintf(out, "@%.*s", len-2, filename); /* -2 for '@' and '\0' */
152} 141}
142
diff --git a/lauxlib.h b/lauxlib.h
index 1898e95e..25dbc1f9 100644
--- a/lauxlib.h
+++ b/lauxlib.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lauxlib.h,v 1.18 2000/05/24 13:54:49 roberto Exp roberto $ 2** $Id: lauxlib.h,v 1.19 2000/08/09 19:16:57 roberto Exp roberto $
3** Auxiliary functions for building Lua libraries 3** Auxiliary functions for building Lua libraries
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -27,14 +27,15 @@ const char *luaL_opt_lstr (lua_State *L, int numArg, const char *def,
27 size_t *len); 27 size_t *len);
28double luaL_check_number (lua_State *L, int numArg); 28double luaL_check_number (lua_State *L, int numArg);
29double luaL_opt_number (lua_State *L, int numArg, double def); 29double luaL_opt_number (lua_State *L, int numArg, double def);
30lua_Object luaL_functionarg (lua_State *L, int arg); 30
31lua_Object luaL_tablearg (lua_State *L, int arg); 31void luaL_checktype(lua_State *L, int narg, const char *tname);
32lua_Object luaL_nonnullarg (lua_State *L, int numArg); 32
33void luaL_verror (lua_State *L, const char *fmt, ...); 33void luaL_verror (lua_State *L, const char *fmt, ...);
34int luaL_findstring (const char *name, const char *const list[]); 34int luaL_findstring (const char *name, const char *const list[]);
35void luaL_chunkid (char *out, const char *source, int len); 35void luaL_chunkid (char *out, const char *source, int len);
36void luaL_filesource (char *out, const char *filename, int len); 36void luaL_filesource (char *out, const char *filename, int len);
37 37
38
38char *luaL_openspace (lua_State *L, size_t size); 39char *luaL_openspace (lua_State *L, size_t size);
39void luaL_resetbuffer (lua_State *L); 40void luaL_resetbuffer (lua_State *L);
40void luaL_addchar (lua_State *L, int c); 41void luaL_addchar (lua_State *L, int c);
@@ -91,9 +92,6 @@ char *luaL_buffer (lua_State *L);
91 (luaL_opt_lstr)(lua_state,numArg,def,len) 92 (luaL_opt_lstr)(lua_state,numArg,def,len)
92#define luaL_check_number(numArg) (luaL_check_number)(lua_state,numArg) 93#define luaL_check_number(numArg) (luaL_check_number)(lua_state,numArg)
93#define luaL_opt_number(numArg,def) (luaL_opt_number)(lua_state,numArg,def) 94#define luaL_opt_number(numArg,def) (luaL_opt_number)(lua_state,numArg,def)
94#define luaL_functionarg(arg) (luaL_functionarg)(lua_state,arg)
95#define luaL_tablearg(arg) (luaL_tablearg)(lua_state,arg)
96#define luaL_nonnullarg(numArg) (luaL_nonnullarg)(lua_state,numArg)
97#define luaL_openspace(size) (luaL_openspace)(lua_state,size) 95#define luaL_openspace(size) (luaL_openspace)(lua_state,size)
98#define luaL_resetbuffer() (luaL_resetbuffer)(lua_state) 96#define luaL_resetbuffer() (luaL_resetbuffer)(lua_state)
99#define luaL_addchar(c) (luaL_addchar)(lua_state,c) 97#define luaL_addchar(c) (luaL_addchar)(lua_state,c)
diff --git a/lbuiltin.c b/lbuiltin.c
index 6bcfad4b..d7180f2d 100644
--- a/lbuiltin.c
+++ b/lbuiltin.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lbuiltin.c,v 1.120 2000/08/14 19:10:14 roberto Exp roberto $ 2** $Id: lbuiltin.c,v 1.121 2000/08/15 18:28:48 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*/
@@ -50,7 +50,6 @@ void luaB_opentests (lua_State *L);
50** ======================================================= 50** =======================================================
51*/ 51*/
52 52
53
54static Number getsize (const Hash *h) { 53static Number getsize (const Hash *h) {
55 Number max = 0; 54 Number max = 0;
56 int i = h->size; 55 int i = h->size;
@@ -73,7 +72,8 @@ static Number getnarg (lua_State *L, const Hash *a) {
73 72
74 73
75static Hash *gettable (lua_State *L, int arg) { 74static Hash *gettable (lua_State *L, int arg) {
76 return hvalue(luaL_tablearg(L, arg)); 75 luaL_checktype(L, arg, "table");
76 return hvalue(luaA_index(L, arg));
77} 77}
78 78
79/* }====================================================== */ 79/* }====================================================== */
@@ -90,8 +90,9 @@ static Hash *gettable (lua_State *L, int arg) {
90** If your system does not support `stderr', redefine this function, or 90** If your system does not support `stderr', redefine this function, or
91** redefine _ERRORMESSAGE so that it won't need _ALERT. 91** redefine _ERRORMESSAGE so that it won't need _ALERT.
92*/ 92*/
93void luaB__ALERT (lua_State *L) { 93int luaB__ALERT (lua_State *L) {
94 fputs(luaL_check_string(L, 1), stderr); 94 fputs(luaL_check_string(L, 1), stderr);
95 return 0;
95} 96}
96 97
97 98
@@ -99,18 +100,19 @@ void luaB__ALERT (lua_State *L) {
99** Standard implementation of _ERRORMESSAGE. 100** Standard implementation of _ERRORMESSAGE.
100** The library `liolib' redefines _ERRORMESSAGE for better error information. 101** The library `liolib' redefines _ERRORMESSAGE for better error information.
101*/ 102*/
102void luaB__ERRORMESSAGE (lua_State *L) { 103int luaB__ERRORMESSAGE (lua_State *L) {
103 lua_Object al; 104 lua_getglobals(L);
104 lua_pushglobals(L);
105 lua_pushstring(L, LUA_ALERT); 105 lua_pushstring(L, LUA_ALERT);
106 al = lua_rawget(L); 106 lua_rawget(L);
107 if (lua_isfunction(L, al)) { /* avoid error loop if _ALERT is not defined */ 107 if (lua_isfunction(L, -1)) { /* avoid error loop if _ALERT is not defined */
108 const char *s = luaL_check_string(L, 1); 108 const char *s = luaL_check_string(L, 1);
109 char *buff = luaL_openspace(L, strlen(s)+sizeof("error: \n")); 109 char *buff = luaL_openspace(L, strlen(s)+sizeof("error: \n"));
110 strcpy(buff, "error: "); strcat(buff, s); strcat(buff, "\n"); 110 strcpy(buff, "error: "); strcat(buff, s); strcat(buff, "\n");
111 lua_pushobject(L, -1); /* function to be called */
111 lua_pushstring(L, buff); 112 lua_pushstring(L, buff);
112 lua_callfunction(L, al); 113 lua_call(L, 1, 0);
113 } 114 }
115 return 0;
114} 116}
115 117
116 118
@@ -120,36 +122,35 @@ void luaB__ERRORMESSAGE (lua_State *L) {
120** model but changing `fputs' to put the strings at a proper place 122** model but changing `fputs' to put the strings at a proper place
121** (a console window or a log file, for instance). 123** (a console window or a log file, for instance).
122*/ 124*/
123void luaB_print (lua_State *L) { 125int luaB_print (lua_State *L) {
124 lua_Object args[MAXPRINT]; 126 int n = lua_gettop(L); /* number of arguments */
125 lua_Object obj;
126 int n = 0;
127 int i; 127 int i;
128 while ((obj = lua_getparam(L, n+1)) != LUA_NOOBJECT) { 128 lua_getglobal(L, "tostring");
129 luaL_arg_check(L, n < MAXPRINT, n+1, "too many arguments"); 129 for (i=1; i<=n; i++) {
130 args[n++] = obj; 130 const char *s;
131 } 131 lua_pushobject(L, -1); /* function to be called */
132 for (i=0; i<n; i++) { 132 lua_pushobject(L, i);
133 lua_pushobject(L, args[i]); 133 if (lua_call(L, 1, 1) != 0)
134 if (lua_call(L, "tostring"))
135 lua_error(L, "error in `tostring' called by `print'"); 134 lua_error(L, "error in `tostring' called by `print'");
136 obj = lua_getresult(L, 1); 135 s = lua_tostring(L, -1); /* get result */
137 if (!lua_isstring(L, obj)) 136 if (s == NULL)
138 lua_error(L, "`tostring' must return a string to `print'"); 137 lua_error(L, "`tostring' must return a string to `print'");
139 if (i>0) fputs("\t", stdout); 138 if (i>1) fputs("\t", stdout);
140 fputs(lua_getstring(L, obj), stdout); 139 fputs(s, stdout);
140 lua_settop(L, -1); /* pop result */
141 } 141 }
142 fputs("\n", stdout); 142 fputs("\n", stdout);
143 return 0;
143} 144}
144 145
145 146
146void luaB_tonumber (lua_State *L) { 147int luaB_tonumber (lua_State *L) {
147 int base = luaL_opt_int(L, 2, 10); 148 int base = luaL_opt_int(L, 2, 10);
148 if (base == 10) { /* standard conversion */ 149 if (base == 10) { /* standard conversion */
149 lua_Object o = luaL_nonnullarg(L, 1); 150 luaL_checktype(L, 1, "any");
150 if (lua_isnumber(L, o)) { 151 if (lua_isnumber(L, 1)) {
151 lua_pushnumber(L, lua_getnumber(L, o)); 152 lua_pushnumber(L, lua_tonumber(L, 1));
152 return; 153 return 1;
153 } 154 }
154 } 155 }
155 else { 156 else {
@@ -162,94 +163,108 @@ void luaB_tonumber (lua_State *L) {
162 while (isspace((unsigned char)*s2)) s2++; /* skip trailing spaces */ 163 while (isspace((unsigned char)*s2)) s2++; /* skip trailing spaces */
163 if (*s2 == '\0') { /* no invalid trailing characters? */ 164 if (*s2 == '\0') { /* no invalid trailing characters? */
164 lua_pushnumber(L, n); 165 lua_pushnumber(L, n);
165 return; 166 return 1;
166 } 167 }
167 } 168 }
168 } 169 }
169 lua_pushnil(L); /* else not a number */ 170 lua_pushnil(L); /* else not a number */
171 return 1;
170} 172}
171 173
172 174
173void luaB_error (lua_State *L) { 175int luaB_error (lua_State *L) {
174 lua_error(L, luaL_opt_string(L, 1, NULL)); 176 lua_error(L, luaL_opt_string(L, 1, NULL));
177 return 0; /* to avoid errors */
175} 178}
176 179
177void luaB_setglobal (lua_State *L) { 180int luaB_setglobal (lua_State *L) {
178 const char *name = luaL_check_string(L, 1); 181 luaL_checktype(L, 2, "any");
179 lua_Object value = luaL_nonnullarg(L, 2); 182 lua_setglobal(L, luaL_check_string(L, 1));
180 lua_pushobject(L, value); 183 return 0;
181 lua_setglobal(L, name);
182} 184}
183 185
184void luaB_getglobal (lua_State *L) { 186int luaB_getglobal (lua_State *L) {
185 lua_pushobject(L, lua_getglobal(L, luaL_check_string(L, 1))); 187 lua_getglobal(L, luaL_check_string(L, 1));
188 return 1;
186} 189}
187 190
188void luaB_tag (lua_State *L) { 191int luaB_tag (lua_State *L) {
189 lua_pushnumber(L, lua_tag(L, luaL_nonnullarg(L, 1))); 192 luaL_checktype(L, 1, "any");
193 lua_pushnumber(L, lua_tag(L, 1));
194 return 1;
190} 195}
191 196
192void luaB_settag (lua_State *L) { 197int luaB_settag (lua_State *L) {
193 lua_Object o = luaL_tablearg(L, 1); 198 luaL_checktype(L, 1, "table");
194 lua_pushobject(L, o); 199 lua_pushobject(L, 1); /* push table */
195 lua_settag(L, luaL_check_int(L, 2)); 200 lua_settag(L, luaL_check_int(L, 2));
196 lua_pushobject(L, o); /* return first argument */ 201 lua_pushobject(L, 1); /* return first argument */
202 return 1;
197} 203}
198 204
199void luaB_newtag (lua_State *L) { 205int luaB_newtag (lua_State *L) {
200 lua_pushnumber(L, lua_newtag(L)); 206 lua_pushnumber(L, lua_newtag(L));
207 return 1;
201} 208}
202 209
203void luaB_copytagmethods (lua_State *L) { 210int luaB_copytagmethods (lua_State *L) {
204 lua_pushnumber(L, lua_copytagmethods(L, luaL_check_int(L, 1), 211 lua_pushnumber(L, lua_copytagmethods(L, luaL_check_int(L, 1),
205 luaL_check_int(L, 2))); 212 luaL_check_int(L, 2)));
213 return 1;
206} 214}
207 215
208void luaB_globals (lua_State *L) { 216int luaB_globals (lua_State *L) {
209 lua_pushglobals(L); 217 lua_getglobals(L); /* value to be returned */
210 if (lua_getparam(L, 1) != LUA_NOOBJECT) 218 if (!lua_isnull(L, 1)) {
211 lua_setglobals(L, luaL_tablearg(L, 1)); 219 luaL_checktype(L, 1, "table");
220 lua_pushobject(L, 1); /* new table of globals */
221 lua_setglobals(L);
222 }
223 return 1;
212} 224}
213 225
214void luaB_rawget (lua_State *L) { 226int luaB_rawget (lua_State *L) {
215 lua_pushobject(L, luaL_nonnullarg(L, 1)); 227 luaL_checktype(L, 1, "table");
216 lua_pushobject(L, luaL_nonnullarg(L, 2)); 228 luaL_checktype(L, 2, "any");
217 lua_pushobject(L, lua_rawget(L)); 229 lua_rawget(L);
230 return 1;
218} 231}
219 232
220void luaB_rawset (lua_State *L) { 233int luaB_rawset (lua_State *L) {
221 lua_pushobject(L, luaL_nonnullarg(L, 1)); 234 luaL_checktype(L, 1, "table");
222 lua_pushobject(L, luaL_nonnullarg(L, 2)); 235 luaL_checktype(L, 2, "any");
223 lua_pushobject(L, luaL_nonnullarg(L, 3)); 236 luaL_checktype(L, 3, "any");
224 lua_rawset(L); 237 lua_rawset(L);
238 return 1;
225} 239}
226 240
227void luaB_settagmethod (lua_State *L) { 241int luaB_settagmethod (lua_State *L) {
228 int tag = luaL_check_int(L, 1); 242 int tag = (int)luaL_check_int(L, 1);
229 const char *event = luaL_check_string(L, 2); 243 const char *event = luaL_check_string(L, 2);
230 lua_Object nf = luaL_nonnullarg(L, 3); 244 luaL_arg_check(L, lua_isfunction(L, 3) || lua_isnil(L, 3), 3,
231 luaL_arg_check(L, lua_isnil(L, nf) || lua_isfunction(L, nf), 3,
232 "function or nil expected"); 245 "function or nil expected");
233 if (strcmp(event, "gc") == 0 && tag != TAG_NIL) 246 if (strcmp(event, "gc") == 0 && tag != TAG_NIL)
234 lua_error(L, "deprecated use: cannot set the `gc' tag method from Lua"); 247 lua_error(L, "deprecated use: cannot set the `gc' tag method from Lua");
235 lua_pushobject(L, nf); 248 lua_settagmethod(L, tag, event);
236 lua_pushobject(L, lua_settagmethod(L, tag, event)); 249 return 1;
237} 250}
238 251
239void luaB_gettagmethod (lua_State *L) { 252int luaB_gettagmethod (lua_State *L) {
240 lua_pushobject(L, lua_gettagmethod(L, luaL_check_int(L, 1), 253 lua_gettagmethod(L, luaL_check_int(L, 1), luaL_check_string(L, 2));
241 luaL_check_string(L, 2))); 254 return 1;
242} 255}
243 256
244 257
245void luaB_collectgarbage (lua_State *L) { 258int luaB_collectgarbage (lua_State *L) {
246 lua_pushnumber(L, lua_collectgarbage(L, luaL_opt_int(L, 1, 0))); 259 lua_pushnumber(L, lua_collectgarbage(L, luaL_opt_int(L, 1, 0)));
260 return 1;
247} 261}
248 262
249 263
250void luaB_type (lua_State *L) { 264int luaB_type (lua_State *L) {
251 lua_Object o = luaL_nonnullarg(L, 1); 265 luaL_checktype(L, 1, "any");
252 lua_pushstring(L, lua_type(L, o)); 266 lua_pushstring(L, lua_type(L, 1));
267 return 1;
253} 268}
254 269
255/* }====================================================== */ 270/* }====================================================== */
@@ -263,99 +278,115 @@ void luaB_type (lua_State *L) {
263*/ 278*/
264 279
265 280
266static void passresults (lua_State *L) { 281static int passresults (lua_State *L, int status, int oldtop) {
267 L->Cstack.base = L->Cstack.lua2C; /* position of first result */ 282 if (status == 0) {
268 if (L->Cstack.num == 0) 283 int nresults = lua_gettop(L) - oldtop;
269 lua_pushuserdata(L, NULL); /* at least one result to signal no errors */ 284 if (nresults > 0)
285 return nresults; /* results are already on the stack */
286 else {
287 lua_pushuserdata(L, NULL); /* at least one result to signal no errors */
288 return 1;
289 }
290 }
291 else { /* error */
292 lua_pushnil(L);
293 lua_pushnumber(L, status); /* error code */
294 return 2;
295 }
270} 296}
271 297
272void luaB_dostring (lua_State *L) { 298int luaB_dostring (lua_State *L) {
299 int oldtop = lua_gettop(L);
273 size_t l; 300 size_t l;
274 const char *s = luaL_check_lstr(L, 1, &l); 301 const char *s = luaL_check_lstr(L, 1, &l);
275 if (*s == ID_CHUNK) 302 if (*s == ID_CHUNK)
276 lua_error(L, "`dostring' cannot run pre-compiled code"); 303 lua_error(L, "`dostring' cannot run pre-compiled code");
277 if (lua_dobuffer(L, s, l, luaL_opt_string(L, 2, s)) == 0) 304 return passresults(L, lua_dobuffer(L, s, l, luaL_opt_string(L, 2, s)), oldtop);
278 passresults(L);
279 else
280 lua_pushnil(L);
281} 305}
282 306
283 307
284void luaB_dofile (lua_State *L) { 308int luaB_dofile (lua_State *L) {
309 int oldtop = lua_gettop(L);
285 const char *fname = luaL_opt_string(L, 1, NULL); 310 const char *fname = luaL_opt_string(L, 1, NULL);
286 if (lua_dofile(L, fname) == 0) 311 return passresults(L, lua_dofile(L, fname), oldtop);
287 passresults(L);
288 else
289 lua_pushnil(L);
290} 312}
291 313
292 314
293void luaB_call (lua_State *L) { 315int luaB_call (lua_State *L) {
294 lua_Object f = luaL_nonnullarg(L, 1); 316 int oldtop;
295 const Hash *arg = gettable(L, 2); 317 const Hash *arg = gettable(L, 2);
296 const char *options = luaL_opt_string(L, 3, ""); 318 const char *options = luaL_opt_string(L, 3, "");
297 lua_Object err = lua_getparam(L, 4); 319 int err = 0; /* index of old error method */
298 int narg = (int)getnarg(L, arg); 320 int n = (int)getnarg(L, arg);
299 int i, status; 321 int i, status;
300 if (err != LUA_NOOBJECT) { /* set new error method */ 322 if (!lua_isnull(L, 4)) { /* set new error method */
301 lua_Object oldem = lua_getglobal(L, LUA_ERRORMESSAGE); 323 lua_getglobal(L, LUA_ERRORMESSAGE);
302 lua_pushobject(L, err); 324 err = lua_gettop(L); /* get index */
325 lua_pushobject(L, 4);
303 lua_setglobal(L, LUA_ERRORMESSAGE); 326 lua_setglobal(L, LUA_ERRORMESSAGE);
304 err = oldem;
305 } 327 }
328 oldtop = lua_gettop(L); /* top before function-call preparation */
329 /* push function */
330 lua_pushobject(L, 1);
306 /* push arg[1...n] */ 331 /* push arg[1...n] */
307 luaD_checkstack(L, narg); 332 luaD_checkstack(L, n);
308 for (i=0; i<narg; i++) 333 for (i=0; i<n; i++)
309 *(L->top++) = *luaH_getnum(arg, i+1); 334 *(L->top++) = *luaH_getnum(arg, i+1);
310 status = lua_callfunction(L, f); 335 status = lua_call(L, n, LUA_MULTRET);
311 if (err != LUA_NOOBJECT) { /* restore old error method */ 336 n = lua_gettop(L) - oldtop; /* number of results */
337 if (err != 0) { /* restore old error method */
312 lua_pushobject(L, err); 338 lua_pushobject(L, err);
313 lua_setglobal(L, LUA_ERRORMESSAGE); 339 lua_setglobal(L, LUA_ERRORMESSAGE);
314 } 340 }
315 if (status != 0) { /* error in call? */ 341 if (status != 0) { /* error in call? */
316 if (strchr(options, 'x')) { 342 if (strchr(options, 'x'))
317 lua_pushnil(L); 343 lua_pushnil(L); /* return nil to signal the error */
318 return; /* return nil to signal the error */
319 }
320 else 344 else
321 lua_error(L, NULL); /* propagate error without additional messages */ 345 lua_error(L, NULL); /* propagate error without additional messages */
346 return 1;
322 } 347 }
323 else { /* no errors */ 348 else { /* no errors */
324 if (strchr(options, 'p')) { /* pack results? */ 349 if (strchr(options, 'p')) { /* pack results? */
325 luaV_pack(L, L->Cstack.lua2C, L->Cstack.num, L->top); 350 luaV_pack(L, luaA_index(L, oldtop+1), n, L->top);
326 incr_top; 351 incr_top;
352 return 1; /* only table is returned */
327 } 353 }
328 else 354 else
329 L->Cstack.base = L->Cstack.lua2C; /* position of first result */ 355 return n; /* results are already on the stack */
330 } 356 }
331} 357}
332 358
333 359
334void luaB_next (lua_State *L) { 360int luaB_next (lua_State *L) {
335 const Hash *a = gettable(L, 1); 361 const Hash *a = gettable(L, 1);
336 lua_Object k = lua_getparam(L, 2);
337 int i; /* `luaA_next' gets first element after `i' */ 362 int i; /* `luaA_next' gets first element after `i' */
338 if (k == LUA_NOOBJECT || ttype(k) == TAG_NIL) 363 if (lua_isnull(L, 2) || lua_isnil(L, 2)) /* no index or nil index? */
339 i = 0; /* get first */ 364 i = 0; /* get first */
340 else { 365 else {
341 i = luaH_pos(L, a, k)+1; 366 i = luaH_pos(L, a, luaA_index(L, 2))+1;
342 luaL_arg_check(L, i != 0, 2, "key not found"); 367 luaL_arg_check(L, i != 0, 2, "key not found");
343 } 368 }
344 if (luaA_next(L, a, i) == 0) 369 if (luaA_next(L, a, i) != 0)
370 return 2; /* `luaA_next' left them on the stack */
371 else {
345 lua_pushnil(L); 372 lua_pushnil(L);
373 return 1;
374 }
346} 375}
347 376
348 377
349void luaB_tostring (lua_State *L) { 378int luaB_tostring (lua_State *L) {
350 lua_Object o = luaL_nonnullarg(L, 1);
351 char buff[64]; 379 char buff[64];
380 const TObject *o;
381 luaL_checktype(L, 1, "any");
382 o = luaA_index(L, 1);
352 switch (ttype(o)) { 383 switch (ttype(o)) {
353 case TAG_NUMBER: 384 case TAG_NUMBER:
354 lua_pushstring(L, lua_getstring(L, o)); 385 lua_pushstring(L, lua_tostring(L, 1));
355 return; 386 return 1;
356 case TAG_STRING: 387 case TAG_STRING:
357 lua_pushobject(L, o); 388 lua_pushobject(L, 1);
358 return; 389 return 1;
359 case TAG_TABLE: 390 case TAG_TABLE:
360 sprintf(buff, "table: %p", hvalue(o)); 391 sprintf(buff, "table: %p", hvalue(o));
361 break; 392 break;
@@ -368,11 +399,12 @@ void luaB_tostring (lua_State *L) {
368 break; 399 break;
369 case TAG_NIL: 400 case TAG_NIL:
370 lua_pushstring(L, "nil"); 401 lua_pushstring(L, "nil");
371 return; 402 return 1;
372 default: 403 default:
373 LUA_INTERNALERROR("invalid type"); 404 LUA_INTERNALERROR("invalid type");
374 } 405 }
375 lua_pushstring(L, buff); 406 lua_pushstring(L, buff);
407 return 1;
376} 408}
377 409
378/* }====================================================== */ 410/* }====================================================== */
@@ -389,15 +421,17 @@ void luaB_tostring (lua_State *L) {
389** ======================================================= 421** =======================================================
390*/ 422*/
391 423
392void luaB_assert (lua_State *L) { 424int luaB_assert (lua_State *L) {
393 lua_Object p = luaL_nonnullarg(L, 1); 425 luaL_checktype(L, 1, "any");
394 if (lua_isnil(L, p)) 426 if (lua_isnil(L, 1))
395 luaL_verror(L, "assertion failed! %.90s", luaL_opt_string(L, 2, "")); 427 luaL_verror(L, "assertion failed! %.90s", luaL_opt_string(L, 2, ""));
428 return 0;
396} 429}
397 430
398 431
399void luaB_getn (lua_State *L) { 432int luaB_getn (lua_State *L) {
400 lua_pushnumber(L, getnarg(L, gettable(L, 1))); 433 lua_pushnumber(L, getnarg(L, gettable(L, 1)));
434 return 1;
401} 435}
402 436
403 437
@@ -408,72 +442,72 @@ static void t_move (lua_State *L, Hash *t, int from, int to) {
408} 442}
409 443
410 444
411void luaB_tinsert (lua_State *L) { 445int luaB_tinsert (lua_State *L) {
412 Hash *a = gettable(L, 1); 446 Hash *a = gettable(L, 1);
413 lua_Object v = lua_getparam(L, 3);
414 int n = (int)getnarg(L, a); 447 int n = (int)getnarg(L, a);
448 int v = lua_gettop(L); /* last argument: to be inserted */
415 int pos; 449 int pos;
416 if (v != LUA_NOOBJECT) 450 if (v == 2) /* called with only 2 arguments */
417 pos = luaL_check_int(L, 2);
418 else { /* called with only 2 arguments */
419 v = luaL_nonnullarg(L, 2);
420 pos = n+1; 451 pos = n+1;
421 } 452 else
453 pos = luaL_check_int(L, 2); /* 2nd argument is the position */
422 luaH_setstrnum(L, a, luaS_new(L, "n"), n+1); /* a.n = n+1 */ 454 luaH_setstrnum(L, a, luaS_new(L, "n"), n+1); /* a.n = n+1 */
423 for (; n>=pos; n--) 455 for (; n>=pos; n--)
424 t_move(L, a, n, n+1); /* a[n+1] = a[n] */ 456 t_move(L, a, n, n+1); /* a[n+1] = a[n] */
425 *luaH_setint(L, a, pos) = *v; /* a[pos] = v */ 457 *luaH_setint(L, a, pos) = *luaA_index(L, v); /* a[pos] = v */
458 return 0;
426} 459}
427 460
428 461
429void luaB_tremove (lua_State *L) { 462int luaB_tremove (lua_State *L) {
430 Hash *a = gettable(L, 1); 463 Hash *a = gettable(L, 1);
431 int n = (int)getnarg(L, a); 464 int n = (int)getnarg(L, a);
432 int pos = luaL_opt_int(L, 2, n); 465 int pos = luaL_opt_int(L, 2, n);
433 if (n <= 0) return; /* table is "empty" */ 466 if (n <= 0) return 0; /* table is "empty" */
434 luaA_pushobject(L, luaH_getnum(a, pos)); /* result = a[pos] */ 467 luaA_pushobject(L, luaH_getnum(a, pos)); /* result = a[pos] */
435 for ( ;pos<n; pos++) 468 for ( ;pos<n; pos++)
436 t_move(L, a, pos+1, pos); /* a[pos] = a[pos+1] */ 469 t_move(L, a, pos+1, pos); /* a[pos] = a[pos+1] */
437 luaH_setstrnum(L, a, luaS_new(L, "n"), n-1); /* a.n = n-1 */ 470 luaH_setstrnum(L, a, luaS_new(L, "n"), n-1); /* a.n = n-1 */
438 ttype(luaH_setint(L, a, n)) = TAG_NIL; /* a[n] = nil */ 471 ttype(luaH_setint(L, a, n)) = TAG_NIL; /* a[n] = nil */
472 return 1;
439} 473}
440 474
441 475
442static void luaB_foreachi (lua_State *L) { 476static int luaB_foreachi (lua_State *L) {
443 const Hash *t = gettable(L, 1); 477 const Hash *t = gettable(L, 1);
444 int n = (int)getnarg(L, t); 478 int n = (int)getnarg(L, t);
445 int i; 479 int i;
446 lua_Object f = luaL_functionarg(L, 2); 480 luaL_checktype(L, 2, "function");
447 luaD_checkstack(L, 3); /* for f, key, and val */
448 for (i=1; i<=n; i++) { 481 for (i=1; i<=n; i++) {
449 *(L->top++) = *f; 482 lua_pushobject(L, 2);
450 ttype(L->top) = TAG_NUMBER; nvalue(L->top++) = i; 483 ttype(L->top) = TAG_NUMBER; nvalue(L->top++) = i;
451 *(L->top++) = *luaH_getnum(t, i); 484 *(L->top++) = *luaH_getnum(t, i);
452 luaD_call(L, L->top-3, 1); 485 luaD_call(L, L->top-3, 1);
453 if (ttype(L->top-1) != TAG_NIL) 486 if (ttype(L->top-1) != TAG_NIL)
454 return; 487 return 1;
455 L->top--; /* remove nil result */ 488 L->top--; /* remove nil result */
456 } 489 }
490 return 0;
457} 491}
458 492
459 493
460static void luaB_foreach (lua_State *L) { 494static int luaB_foreach (lua_State *L) {
461 const Hash *a = gettable(L, 1); 495 const Hash *a = gettable(L, 1);
462 lua_Object f = luaL_functionarg(L, 2);
463 int i; 496 int i;
464 luaD_checkstack(L, 3); /* for f, key, and val */ 497 luaL_checktype(L, 2, "function");
465 for (i=0; i<a->size; i++) { 498 for (i=0; i<a->size; i++) {
466 const Node *nd = &(a->node[i]); 499 const Node *nd = &(a->node[i]);
467 if (ttype(val(nd)) != TAG_NIL) { 500 if (ttype(val(nd)) != TAG_NIL) {
468 *(L->top++) = *f; 501 lua_pushobject(L, 2);
469 *(L->top++) = *key(nd); 502 *(L->top++) = *key(nd);
470 *(L->top++) = *val(nd); 503 *(L->top++) = *val(nd);
471 luaD_call(L, L->top-3, 1); 504 luaD_call(L, L->top-3, 1);
472 if (ttype(L->top-1) != TAG_NIL) 505 if (ttype(L->top-1) != TAG_NIL)
473 return; 506 return 1;
474 L->top--; /* remove result */ 507 L->top--; /* remove result */
475 } 508 }
476 } 509 }
510 return 0;
477} 511}
478 512
479 513
@@ -492,10 +526,10 @@ static void swap (lua_State *L, Hash *a, int i, int j) {
492 *luaH_setint(L, a, j) = temp; 526 *luaH_setint(L, a, j) = temp;
493} 527}
494 528
495static int sort_comp (lua_State *L, lua_Object f, const TObject *a, 529static int sort_comp (lua_State *L, const TObject *f, const TObject *a,
496 const TObject *b) { 530 const TObject *b) {
497 /* WARNING: the caller (auxsort) must ensure stack space */ 531 /* WARNING: the caller (auxsort) must ensure stack space */
498 if (f != LUA_NOOBJECT) { 532 if (f != NULL) {
499 *(L->top) = *f; 533 *(L->top) = *f;
500 *(L->top+1) = *a; 534 *(L->top+1) = *a;
501 *(L->top+2) = *b; 535 *(L->top+2) = *b;
@@ -508,7 +542,7 @@ static int sort_comp (lua_State *L, lua_Object f, const TObject *a,
508 return luaV_lessthan(L, a, b, L->top); 542 return luaV_lessthan(L, a, b, L->top);
509} 543}
510 544
511static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) { 545static void auxsort (lua_State *L, Hash *a, int l, int u, const TObject *f) {
512 StkId P = L->top++; /* temporary place for pivot */ 546 StkId P = L->top++; /* temporary place for pivot */
513 ttype(P) = TAG_NIL; 547 ttype(P) = TAG_NIL;
514 while (l < u) { /* for tail recursion */ 548 while (l < u) { /* for tail recursion */
@@ -552,14 +586,16 @@ static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) {
552 L->top--; /* remove pivot from stack */ 586 L->top--; /* remove pivot from stack */
553} 587}
554 588
555void luaB_sort (lua_State *L) { 589int luaB_sort (lua_State *L) {
556 Hash *a = gettable(L, 1); 590 Hash *a = gettable(L, 1);
557 int n = (int)getnarg(L, a); 591 int n = (int)getnarg(L, a);
558 lua_Object func = lua_getparam(L, 2); 592 const TObject *func = NULL;
559 luaL_arg_check(L, func == LUA_NOOBJECT || lua_isfunction(L, func), 2, 593 if (!lua_isnull(L, 2)) { /* is there a 2nd argument? */
560 "function expected"); 594 luaL_checktype(L, 2, "function");
561 luaD_checkstack(L, 4); /* for pivot, f, a, b (sort_comp) */ 595 func = luaA_index(L, 2);
596 }
562 auxsort(L, a, 1, n, func); 597 auxsort(L, a, 1, n, func);
598 return 0;
563} 599}
564 600
565/* }====================================================== */ 601/* }====================================================== */
@@ -615,8 +651,9 @@ static void deprecated_funcs (lua_State *L) {
615/* 651/*
616** gives an explicit error in any attempt to call a deprecated function 652** gives an explicit error in any attempt to call a deprecated function
617*/ 653*/
618static void deprecated_func (lua_State *L) { 654static int deprecated_func (lua_State *L) {
619 luaL_verror(L, "function `%.20s' is deprecated", luaL_check_string(L, 1)); 655 luaL_verror(L, "function `%.20s' is deprecated", luaL_check_string(L, 1));
656 return 0; /* to avoid warnings */
620} 657}
621 658
622 659
diff --git a/lbuiltin.h b/lbuiltin.h
index 213f3f3d..7d8a2236 100644
--- a/lbuiltin.h
+++ b/lbuiltin.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lbuiltin.h,v 1.8 2000/05/08 19:32:53 roberto Exp roberto $ 2** $Id: lbuiltin.h,v 1.9 2000/05/26 19:17:57 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*/
@@ -9,34 +9,34 @@
9 9
10#include "lua.h" 10#include "lua.h"
11 11
12void luaB__ALERT (lua_State *L); 12int luaB__ALERT (lua_State *L);
13void luaB__ERRORMESSAGE (lua_State *L); 13int luaB__ERRORMESSAGE (lua_State *L);
14void luaB_assert (lua_State *L); 14int luaB_assert (lua_State *L);
15void luaB_call (lua_State *L); 15int luaB_call (lua_State *L);
16void luaB_collectgarbage (lua_State *L); 16int luaB_collectgarbage (lua_State *L);
17void luaB_copytagmethods (lua_State *L); 17int luaB_copytagmethods (lua_State *L);
18void luaB_dofile (lua_State *L); 18int luaB_dofile (lua_State *L);
19void luaB_dostring (lua_State *L); 19int luaB_dostring (lua_State *L);
20void luaB_error (lua_State *L); 20int luaB_error (lua_State *L);
21void luaB_getglobal (lua_State *L); 21int luaB_getglobal (lua_State *L);
22void luaB_getn (lua_State *L); 22int luaB_getn (lua_State *L);
23void luaB_gettagmethod (lua_State *L); 23int luaB_gettagmethod (lua_State *L);
24void luaB_globals (lua_State *L); 24int luaB_globals (lua_State *L);
25void luaB_newtag (lua_State *L); 25int luaB_newtag (lua_State *L);
26void luaB_next (lua_State *L); 26int luaB_next (lua_State *L);
27void luaB_print (lua_State *L); 27int luaB_print (lua_State *L);
28void luaB_rawget (lua_State *L); 28int luaB_rawget (lua_State *L);
29void luaB_rawset (lua_State *L); 29int luaB_rawset (lua_State *L);
30void luaB_setglobal (lua_State *L); 30int luaB_setglobal (lua_State *L);
31void luaB_settag (lua_State *L); 31int luaB_settag (lua_State *L);
32void luaB_settagmethod (lua_State *L); 32int luaB_settagmethod (lua_State *L);
33void luaB_sort (lua_State *L); 33int luaB_sort (lua_State *L);
34void luaB_tag (lua_State *L); 34int luaB_tag (lua_State *L);
35void luaB_tinsert (lua_State *L); 35int luaB_tinsert (lua_State *L);
36void luaB_tonumber (lua_State *L); 36int luaB_tonumber (lua_State *L);
37void luaB_tostring (lua_State *L); 37int luaB_tostring (lua_State *L);
38void luaB_tremove (lua_State *L); 38int luaB_tremove (lua_State *L);
39void luaB_type (lua_State *L); 39int luaB_type (lua_State *L);
40 40
41void luaB_predefine (lua_State *L); 41void luaB_predefine (lua_State *L);
42 42
diff --git a/ldblib.c b/ldblib.c
index 45edc8c2..17edcda5 100644
--- a/ldblib.c
+++ b/ldblib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldblib.c,v 1.17 2000/06/12 13:52:05 roberto Exp roberto $ 2** $Id: ldblib.c,v 1.18 2000/08/09 19:16:57 roberto Exp roberto $
3** Interface from Lua to its debug API 3** Interface from Lua to its debug API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -17,102 +17,96 @@
17 17
18 18
19 19
20static void settabss (lua_State *L, lua_Object t, const char *i, const char *v) { 20static void settabss (lua_State *L, const char *i, const char *v) {
21 lua_pushobject(L, t); 21 lua_pushobject(L, -1);
22 lua_pushstring(L, i); 22 lua_pushstring(L, i);
23 lua_pushstring(L, v); 23 lua_pushstring(L, v);
24 lua_settable(L); 24 lua_settable(L);
25} 25}
26 26
27 27
28static void settabsi (lua_State *L, lua_Object t, const char *i, int v) { 28static void settabsi (lua_State *L, const char *i, int v) {
29 lua_pushobject(L, t); 29 lua_pushobject(L, -1);
30 lua_pushstring(L, i); 30 lua_pushstring(L, i);
31 lua_pushnumber(L, v); 31 lua_pushnumber(L, v);
32 lua_settable(L); 32 lua_settable(L);
33} 33}
34 34
35 35
36static void settabso (lua_State *L, lua_Object t, const char *i, lua_Object v) { 36static int getinfo (lua_State *L) {
37 lua_pushobject(L, t);
38 lua_pushstring(L, i);
39 lua_pushobject(L, v);
40 lua_settable(L);
41}
42
43
44static void getinfo (lua_State *L) {
45 lua_Debug ar; 37 lua_Debug ar;
46 lua_Object res;
47 lua_Object func = lua_getparam(L, 1);
48 const char *options = luaL_opt_string(L, 2, "flnSu"); 38 const char *options = luaL_opt_string(L, 2, "flnSu");
49 char buff[20]; 39 char buff[20];
50 if (lua_isnumber(L, func)) { 40 if (lua_isnumber(L, 1)) {
51 if (!lua_getstack(L, (int)lua_getnumber(L, func), &ar)) { 41 if (!lua_getstack(L, (int)lua_tonumber(L, 1), &ar)) {
52 lua_pushnil(L); /* level out of range */ 42 lua_pushnil(L); /* level out of range */
53 return; 43 return 1;
54 } 44 }
55 } 45 }
56 else if (lua_isfunction(L, func)) { 46 else if (lua_isfunction(L, 1)) {
57 ar.func = func; 47 lua_pushobject(L, 1);
58 sprintf(buff, ">%.10s", options); 48 sprintf(buff, ">%.10s", options);
59 options = buff; 49 options = buff;
60 } 50 }
61 else 51 else
62 luaL_argerror(L, 1, "function or level expected"); 52 luaL_argerror(L, 1, "function or level expected");
63 res = lua_createtable(L);
64 if (!lua_getinfo(L, options, &ar)) 53 if (!lua_getinfo(L, options, &ar))
65 luaL_argerror(L, 2, "invalid option"); 54 luaL_argerror(L, 2, "invalid option");
55 lua_newtable(L);
66 for (; *options; options++) { 56 for (; *options; options++) {
67 switch (*options) { 57 switch (*options) {
68 case 'S': 58 case 'S':
69 settabss(L, res, "source", ar.source); 59 settabss(L, "source", ar.source);
70 settabsi(L, res, "linedefined", ar.linedefined); 60 settabsi(L, "linedefined", ar.linedefined);
71 settabss(L, res, "what", ar.what); 61 settabss(L, "what", ar.what);
72 break; 62 break;
73 case 'l': 63 case 'l':
74 settabsi(L, res, "currentline", ar.currentline); 64 settabsi(L, "currentline", ar.currentline);
75 break; 65 break;
76 case 'u': 66 case 'u':
77 settabsi(L, res, "nups", ar.nups); 67 settabsi(L, "nups", ar.nups);
78 break; 68 break;
79 case 'n': 69 case 'n':
80 settabss(L, res, "name", ar.name); 70 settabss(L, "name", ar.name);
81 settabss(L, res, "namewhat", ar.namewhat); 71 settabss(L, "namewhat", ar.namewhat);
82 break; 72 break;
83 case 'f': 73 case 'f':
84 settabso(L, res, "func", ar.func); 74 lua_pushobject(L, -1);
75 lua_pushstring(L, "func");
76 lua_pushobject(L, -4);
77 lua_settable(L);
85 break; 78 break;
86 } 79 }
87 } 80 }
88 lua_pushobject(L, res); 81 return 1; /* return table */
89} 82}
90 83
91 84
92static void getlocal (lua_State *L) { 85static int getlocal (lua_State *L) {
93 lua_Debug ar; 86 lua_Debug ar;
94 lua_Localvar lvar; 87 const char *name;
95 if (!lua_getstack(L, luaL_check_int(L, 1), &ar)) /* level out of range? */ 88 if (!lua_getstack(L, luaL_check_int(L, 1), &ar)) /* level out of range? */
96 luaL_argerror(L, 1, "level out of range"); 89 luaL_argerror(L, 1, "level out of range");
97 lvar.index = luaL_check_int(L, 2); 90 name = lua_getlocal(L, &ar, luaL_check_int(L, 2));
98 if (lua_getlocal(L, &ar, &lvar)) { 91 if (name) {
99 lua_pushstring(L, lvar.name); 92 lua_pushstring(L, name);
100 lua_pushobject(L, lvar.value); 93 lua_pushobject(L, -2);
94 return 2;
95 }
96 else {
97 lua_pushnil(L);
98 return 1;
101 } 99 }
102 else lua_pushnil(L);
103} 100}
104 101
105 102
106static void setlocal (lua_State *L) { 103static int setlocal (lua_State *L) {
107 lua_Debug ar; 104 lua_Debug ar;
108 lua_Localvar lvar;
109 if (!lua_getstack(L, luaL_check_int(L, 1), &ar)) /* level out of range? */ 105 if (!lua_getstack(L, luaL_check_int(L, 1), &ar)) /* level out of range? */
110 luaL_argerror(L, 1, "level out of range"); 106 luaL_argerror(L, 1, "level out of range");
111 lvar.index = luaL_check_int(L, 2); 107 luaL_checktype(L, 3, "any");
112 lvar.value = luaL_nonnullarg(L, 3); 108 lua_pushstring(L, lua_setlocal(L, &ar, luaL_check_int(L, 2)));
113 if (lua_setlocal(L, &ar, &lvar)) 109 return 1;
114 lua_pushstring(L, lvar.name);
115 else lua_pushnil(L);
116} 110}
117 111
118 112
@@ -128,47 +122,47 @@ static int callhook = LUA_NOREF; /* Lua reference to call hook function */
128 122
129static void linef (lua_State *L, lua_Debug *ar) { 123static void linef (lua_State *L, lua_Debug *ar) {
130 if (linehook != LUA_NOREF) { 124 if (linehook != LUA_NOREF) {
125 lua_getref(L, linehook);
131 lua_pushnumber(L, ar->currentline); 126 lua_pushnumber(L, ar->currentline);
132 lua_callfunction(L, lua_getref(L, linehook)); 127 lua_call(L, 1, 0);
133 } 128 }
134} 129}
135 130
136 131
137static void callf (lua_State *L, lua_Debug *ar) { 132static void callf (lua_State *L, lua_Debug *ar) {
138 if (callhook != LUA_NOREF) { 133 if (callhook != LUA_NOREF) {
134 lua_getref(L, callhook);
139 lua_pushstring(L, ar->event); 135 lua_pushstring(L, ar->event);
140 lua_callfunction(L, lua_getref(L, callhook)); 136 lua_call(L, 1, 0);
141 } 137 }
142} 138}
143 139
144 140
145static void setcallhook (lua_State *L) { 141static int setcallhook (lua_State *L) {
146 lua_Object f = lua_getparam(L, 1);
147 lua_unref(L, callhook); 142 lua_unref(L, callhook);
148 if (f == LUA_NOOBJECT) { 143 if (lua_isnull(L, 1)) {
149 callhook = LUA_NOREF; 144 callhook = LUA_NOREF;
150 lua_setcallhook(L, NULL); 145 lua_setcallhook(L, NULL);
151 } 146 }
152 else { 147 else {
153 lua_pushobject(L, f);
154 callhook = lua_ref(L, 1); 148 callhook = lua_ref(L, 1);
155 lua_setcallhook(L, callf); 149 lua_setcallhook(L, callf);
156 } 150 }
151 return 0;
157} 152}
158 153
159 154
160static void setlinehook (lua_State *L) { 155static int setlinehook (lua_State *L) {
161 lua_Object f = lua_getparam(L, 1);
162 lua_unref(L, linehook); 156 lua_unref(L, linehook);
163 if (f == LUA_NOOBJECT) { 157 if (lua_isnull(L, 1)) {
164 linehook = LUA_NOREF; 158 linehook = LUA_NOREF;
165 lua_setlinehook(L, NULL); 159 lua_setlinehook(L, NULL);
166 } 160 }
167 else { 161 else {
168 lua_pushobject(L, f);
169 linehook = lua_ref(L, 1); 162 linehook = lua_ref(L, 1);
170 lua_setlinehook(L, linef); 163 lua_setlinehook(L, linef);
171 } 164 }
165 return 0;
172} 166}
173 167
174 168
diff --git a/ldebug.c b/ldebug.c
index 2e851c1b..56bf6ddb 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 1.35 2000/08/14 17:59:20 roberto Exp roberto $ 2** $Id: ldebug.c,v 1.36 2000/08/15 18:28:48 roberto Exp roberto $
3** Debug Interface 3** Debug Interface
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -144,26 +144,28 @@ static Proto *getluaproto (StkId f) {
144} 144}
145 145
146 146
147int lua_getlocal (lua_State *L, const lua_Debug *ar, lua_Localvar *v) { 147const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int localnum) {
148 const char *name;
148 StkId f = ar->_func; 149 StkId f = ar->_func;
149 Proto *fp = getluaproto(f); 150 Proto *fp = getluaproto(f);
150 if (!fp) return 0; /* `f' is not a Lua function? */ 151 if (!fp) return NULL; /* `f' is not a Lua function? */
151 v->name = luaF_getlocalname(fp, v->index, lua_currentpc(f)); 152 name = luaF_getlocalname(fp, localnum, lua_currentpc(f));
152 if (!v->name) return 0; 153 if (!name) return NULL;
153 v->value = luaA_putluaObject(L, (f+1)+(v->index-1)); 154 luaA_pushobject(L, (f+1)+(localnum-1)); /* push value */
154 return 1; 155 return name;
155} 156}
156 157
157 158
158int lua_setlocal (lua_State *L, const lua_Debug *ar, lua_Localvar *v) { 159const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int localnum) {
160 const char *name;
159 StkId f = ar->_func; 161 StkId f = ar->_func;
160 Proto *fp = getluaproto(f); 162 Proto *fp = getluaproto(f);
161 UNUSED(L); 163 UNUSED(L);
162 if (!fp) return 0; /* `f' is not a Lua function? */ 164 if (!fp) return NULL; /* `f' is not a Lua function? */
163 v->name = luaF_getlocalname(fp, v->index, lua_currentpc(f)); 165 name = luaF_getlocalname(fp, localnum, lua_currentpc(f));
164 if (!v->name || v->name[0] == '*') return 0; /* `*' starts private locals */ 166 if (!name || name[0] == '*') return NULL; /* `*' starts private locals */
165 *((f+1)+(v->index-1)) = *v->value; 167 *((f+1)+(localnum-1)) = *(--L->top);
166 return 1; 168 return name;
167} 169}
168 170
169 171
@@ -236,7 +238,7 @@ int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
236 func = ar->_func; 238 func = ar->_func;
237 else { 239 else {
238 what++; /* skip the '>' */ 240 what++; /* skip the '>' */
239 func = ar->func; 241 func = L->top - 1;
240 } 242 }
241 for (; *what; what++) { 243 for (; *what; what++) {
242 switch (*what) { 244 switch (*what) {
@@ -260,13 +262,13 @@ int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
260 } 262 }
261 case 'f': { 263 case 'f': {
262 setnormalized(L->top, func); 264 setnormalized(L->top, func);
263 incr_top; 265 incr_top; /* push function */
264 ar->func = lua_pop(L);
265 break; 266 break;
266 } 267 }
267 default: return 0; /* invalid option */ 268 default: return 0; /* invalid option */
268 } 269 }
269 } 270 }
271 if (!isactive) L->top--; /* pop function */
270 return 1; 272 return 1;
271} 273}
272 274
@@ -420,7 +422,7 @@ static const char *getfuncname (lua_State *L, StkId f, const char **name) {
420void luaG_typeerror (lua_State *L, StkId o, const char *op) { 422void luaG_typeerror (lua_State *L, StkId o, const char *op) {
421 const char *name; 423 const char *name;
422 const char *kind = getobjname(L, o, &name); 424 const char *kind = getobjname(L, o, &name);
423 const char *t = lua_type(L, o); 425 const char *t = luaO_typename(o);
424 if (kind) 426 if (kind)
425 luaL_verror(L, "attempt to %.30s %.20s `%.40s' (a %.10s value)", 427 luaL_verror(L, "attempt to %.30s %.20s `%.40s' (a %.10s value)",
426 op, kind, name, t); 428 op, kind, name, t);
@@ -437,8 +439,8 @@ void luaG_binerror (lua_State *L, StkId p1, lua_Type t, const char *op) {
437 439
438 440
439void luaG_ordererror (lua_State *L, StkId top) { 441void luaG_ordererror (lua_State *L, StkId top) {
440 const char *t1 = lua_type(L, top-2); 442 const char *t1 = luaO_typename(top-2);
441 const char *t2 = lua_type(L, top-1); 443 const char *t2 = luaO_typename(top-1);
442 if (t1[2] == t2[2]) 444 if (t1[2] == t2[2])
443 luaL_verror(L, "attempt to compare two %.10s values", t1); 445 luaL_verror(L, "attempt to compare two %.10s values", t1);
444 else 446 else
diff --git a/ldo.c b/ldo.c
index 06eb0d2d..074638c3 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 1.84 2000/08/09 19:16:57 roberto Exp roberto $ 2** $Id: ldo.c,v 1.85 2000/08/10 19:50:47 roberto Exp roberto $
3** Stack and Call structure of Lua 3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -41,8 +41,7 @@ void luaD_init (lua_State *L, int stacksize) {
41 L->stack = luaM_newvector(L, stacksize+EXTRA_STACK, TObject); 41 L->stack = luaM_newvector(L, stacksize+EXTRA_STACK, TObject);
42 L->stack_last = L->stack+(stacksize-1); 42 L->stack_last = L->stack+(stacksize-1);
43 L->stacksize = stacksize; 43 L->stacksize = stacksize;
44 L->Cstack.base = L->Cstack.lua2C = L->top = L->stack; 44 L->Cbase = L->top = L->stack;
45 L->Cstack.num = 0;
46} 45}
47 46
48 47
@@ -68,8 +67,8 @@ void luaD_checkstack (lua_State *L, int n) {
68 67
69 68
70static void restore_stack_limit (lua_State *L) { 69static void restore_stack_limit (lua_State *L) {
71 if (L->top-L->stack < L->stacksize-1) 70 if (L->top - L->stack < L->stacksize - 1)
72 L->stack_last = L->stack+(L->stacksize-1); 71 L->stack_last = L->stack + (L->stacksize-1);
73} 72}
74 73
75 74
@@ -103,9 +102,8 @@ void luaD_openstack (lua_State *L, StkId pos) {
103void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook) { 102void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook) {
104 if (L->allowhooks) { 103 if (L->allowhooks) {
105 lua_Debug ar; 104 lua_Debug ar;
106 struct C_Lua_Stack oldCLS = L->Cstack; 105 StkId old_Cbase = L->Cbase;
107 StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->top; 106 StkId old_top = L->Cbase = L->top;
108 L->Cstack.num = 0;
109 ar._func = func; 107 ar._func = func;
110 ar.event = "line"; 108 ar.event = "line";
111 ar.currentline = line; 109 ar.currentline = line;
@@ -113,7 +111,7 @@ void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook) {
113 (*linehook)(L, &ar); 111 (*linehook)(L, &ar);
114 L->allowhooks = 1; 112 L->allowhooks = 1;
115 L->top = old_top; 113 L->top = old_top;
116 L->Cstack = oldCLS; 114 L->Cbase = old_Cbase;
117 } 115 }
118} 116}
119 117
@@ -122,42 +120,36 @@ static void luaD_callHook (lua_State *L, StkId func, lua_Hook callhook,
122 const char *event) { 120 const char *event) {
123 if (L->allowhooks) { 121 if (L->allowhooks) {
124 lua_Debug ar; 122 lua_Debug ar;
125 struct C_Lua_Stack oldCLS = L->Cstack; 123 StkId old_Cbase = L->Cbase;
126 StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->top; 124 StkId old_top = L->Cbase = L->top;
127 L->Cstack.num = 0;
128 ar._func = func; 125 ar._func = func;
129 ar.event = event; 126 ar.event = event;
130 L->allowhooks = 0; /* cannot call hooks inside a hook */ 127 L->allowhooks = 0; /* cannot call hooks inside a hook */
131 callhook(L, &ar); 128 callhook(L, &ar);
132 L->allowhooks = 1; 129 L->allowhooks = 1;
133 L->top = old_top; 130 L->top = old_top;
134 L->Cstack = oldCLS; 131 L->Cbase = old_Cbase;
135 } 132 }
136} 133}
137 134
138 135
139static StkId callCclosure (lua_State *L, const struct Closure *cl, StkId base) { 136static StkId callCclosure (lua_State *L, const struct Closure *cl, StkId base) {
140 int nup = cl->nupvalues; /* number of upvalues */ 137 int nup = cl->nupvalues; /* number of upvalues */
141 int numarg = L->top-base; 138 StkId old_Cbase = L->Cbase;
142 struct C_Lua_Stack oldCLS = L->Cstack; 139 int nres; /* number of results */
143 StkId firstResult;
144 if (nup > 0) { 140 if (nup > 0) {
145 int n = numarg; 141 int n = L->top - base; /* number of arguments */
146 luaD_checkstack(L, nup); 142 luaD_checkstack(L, nup);
147 /* open space for upvalues as extra arguments */ 143 /* open space for upvalues as extra arguments */
148 while (n--) *(base+nup+n) = *(base+n); 144 while (n--) *(base+nup+n) = *(base+n);
149 L->top += nup; 145 L->top += nup;
150 numarg += nup;
151 /* copy upvalues into stack */ 146 /* copy upvalues into stack */
152 while (nup--) *(base+nup) = cl->upvalue[nup]; 147 while (nup--) *(base+nup) = cl->upvalue[nup];
153 } 148 }
154 L->Cstack.num = numarg; 149 L->Cbase = base; /* new base for C function */
155 L->Cstack.lua2C = base; 150 nres = (*cl->f.c)(L); /* do the actual call */
156 L->Cstack.base = L->top; 151 L->Cbase = old_Cbase; /* restore old C base */
157 (*cl->f.c)(L); /* do the actual call */ 152 return L->top - nres; /* return index of first result */
158 firstResult = L->Cstack.base;
159 L->Cstack = oldCLS;
160 return firstResult;
161} 153}
162 154
163 155
@@ -257,42 +249,36 @@ void lua_error (lua_State *L, const char *s) {
257 249
258 250
259static void chain_longjmp (lua_State *L, struct lua_longjmp *lj) { 251static void chain_longjmp (lua_State *L, struct lua_longjmp *lj) {
260 lj->base = L->Cstack.base; 252 lj->status = 0;
261 lj->numCblocks = L->numCblocks; 253 lj->base = L->Cbase;
262 lj->previous = L->errorJmp; 254 lj->previous = L->errorJmp;
263 L->errorJmp = lj; 255 L->errorJmp = lj;
264} 256}
265 257
266 258
267static void restore_longjmp (lua_State *L, struct lua_longjmp *lj) { 259static int restore_longjmp (lua_State *L, struct lua_longjmp *lj) {
268 L->Cstack.num = 0; /* no results */ 260 L->Cbase = lj->base;
269 L->top = L->Cstack.base = L->Cstack.lua2C = lj->base;
270 L->numCblocks = lj->numCblocks;
271 L->errorJmp = lj->previous; 261 L->errorJmp = lj->previous;
262 return lj->status;
272} 263}
273 264
274 265
275/* 266/*
276** Execute a protected call. Assumes that function is at Cstack.base and 267** Execute a protected call.
277** parameters are on top of it.
278*/ 268*/
279int luaD_protectedrun (lua_State *L) { 269int lua_call (lua_State *L, int nargs, int nresults) {
270 StkId func = L->top - (nargs+1); /* function to be called */
280 struct lua_longjmp myErrorJmp; 271 struct lua_longjmp myErrorJmp;
281 chain_longjmp(L, &myErrorJmp); 272 chain_longjmp(L, &myErrorJmp);
273 if (nresults == LUA_MULTRET) nresults = MULT_RET; /* internal code */
282 if (setjmp(myErrorJmp.b) == 0) { 274 if (setjmp(myErrorJmp.b) == 0) {
283 StkId base = L->Cstack.base; 275 luaD_call(L, func, nresults);
284 luaD_call(L, base, MULT_RET);
285 L->Cstack.lua2C = base; /* position of the new results */
286 L->Cstack.num = L->top - base;
287 L->Cstack.base = base + L->Cstack.num; /* incorporate results on stack */
288 L->errorJmp = myErrorJmp.previous;
289 return 0;
290 } 276 }
291 else { /* an error occurred: restore the stack */ 277 else { /* an error occurred: restore the state */
292 restore_longjmp(L, &myErrorJmp); 278 L->top = func; /* remove garbage from the stack */
293 restore_stack_limit(L); 279 restore_stack_limit(L);
294 return myErrorJmp.status;
295 } 280 }
281 return restore_longjmp(L, &myErrorJmp);
296} 282}
297 283
298 284
@@ -302,20 +288,17 @@ int luaD_protectedrun (lua_State *L) {
302static int protectedparser (lua_State *L, ZIO *z, int bin) { 288static int protectedparser (lua_State *L, ZIO *z, int bin) {
303 struct lua_longjmp myErrorJmp; 289 struct lua_longjmp myErrorJmp;
304 chain_longjmp(L, &myErrorJmp); 290 chain_longjmp(L, &myErrorJmp);
305 L->top = L->Cstack.base; /* clear C2Lua */
306 if (setjmp(myErrorJmp.b) == 0) { 291 if (setjmp(myErrorJmp.b) == 0) {
307 Proto *tf = bin ? luaU_undump1(L, z) : luaY_parser(L, z); 292 Proto *tf = bin ? luaU_undump1(L, z) : luaY_parser(L, z);
308 L->errorJmp = myErrorJmp.previous; 293 if (tf == NULL)
309 if (tf == NULL) return -1; /* `natural' end */ 294 myErrorJmp.status = -1; /* `natural' end */
310 luaV_Lclosure(L, tf, 0); 295 luaV_Lclosure(L, tf, 0);
311 return 0;
312 } 296 }
313 else { /* an error occurred */ 297 else { /* an error occurred: correct error code */
314 restore_longjmp(L, &myErrorJmp);
315 if (myErrorJmp.status == LUA_ERRRUN) 298 if (myErrorJmp.status == LUA_ERRRUN)
316 myErrorJmp.status = LUA_ERRSYNTAX; 299 myErrorJmp.status = LUA_ERRSYNTAX;
317 return myErrorJmp.status; /* error code */
318 } 300 }
301 return restore_longjmp(L, &myErrorJmp); /* error code */
319} 302}
320 303
321 304
@@ -331,7 +314,7 @@ static int do_main (lua_State *L, ZIO *z, int bin) {
331 else { 314 else {
332 unsigned long newelems2 = 2*(L->nblocks-old_blocks); 315 unsigned long newelems2 = 2*(L->nblocks-old_blocks);
333 L->GCthreshold += newelems2; 316 L->GCthreshold += newelems2;
334 status = luaD_protectedrun(L); 317 status = lua_call(L, 0, LUA_MULTRET);
335 L->GCthreshold -= newelems2; 318 L->GCthreshold -= newelems2;
336 } 319 }
337 } while (bin && status == 0); 320 } while (bin && status == 0);
diff --git a/ldo.h b/ldo.h
index 0e91c7c8..ba168ccb 100644
--- a/ldo.h
+++ b/ldo.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.h,v 1.21 2000/06/28 20:21:06 roberto Exp roberto $ 2** $Id: ldo.h,v 1.22 2000/08/07 18:39:16 roberto Exp roberto $
3** Stack and Call structure of Lua 3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -26,7 +26,6 @@ void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook);
26void luaD_call (lua_State *L, StkId func, int nResults); 26void luaD_call (lua_State *L, StkId func, int nResults);
27void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults); 27void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults);
28void luaD_breakrun (lua_State *L, int errcode); 28void luaD_breakrun (lua_State *L, int errcode);
29int luaD_protectedrun (lua_State *L);
30void luaD_checkstack (lua_State *L, int n); 29void luaD_checkstack (lua_State *L, int n);
31 30
32 31
diff --git a/lgc.c b/lgc.c
index 1e26ed51..f6768dd2 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 1.62 2000/08/09 19:16:57 roberto Exp roberto $ 2** $Id: lgc.c,v 1.63 2000/08/22 17:44:17 roberto Exp roberto $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -11,7 +11,6 @@
11#include "lgc.h" 11#include "lgc.h"
12#include "lmem.h" 12#include "lmem.h"
13#include "lobject.h" 13#include "lobject.h"
14#include "lref.h"
15#include "lstate.h" 14#include "lstate.h"
16#include "lstring.h" 15#include "lstring.h"
17#include "ltable.h" 16#include "ltable.h"
@@ -145,6 +144,43 @@ static void markall (lua_State *L) {
145} 144}
146 145
147 146
147static int hasmark (const TObject *o) {
148 /* valid only for locked objects */
149 switch (o->ttype) {
150 case TAG_STRING: case TAG_USERDATA:
151 return tsvalue(o)->marked;
152 case TAG_TABLE:
153 return ismarked(hvalue(o));
154 case TAG_LCLOSURE: case TAG_CCLOSURE:
155 return ismarked(clvalue(o)->mark);
156 default: /* number */
157 return 1;
158 }
159}
160
161
162/* macro for internal debugging; check if a link of free refs is valid */
163#define VALIDLINK(L, st,n) (NONEXT <= (st) && (st) < (n))
164
165static void invalidaterefs (lua_State *L) {
166 int n = L->refSize;
167 int i;
168 for (i=0; i<n; i++) {
169 struct Ref *r = &L->refArray[i];
170 if (r->st == HOLD && !hasmark(&r->o))
171 r->st = COLLECTED;
172 LUA_ASSERT((r->st == LOCK && hasmark(&r->o)) ||
173 (r->st == HOLD && hasmark(&r->o)) ||
174 r->st == COLLECTED ||
175 r->st == NONEXT ||
176 (r->st < n && VALIDLINK(L, L->refArray[r->st].st, n)),
177 "inconsistent ref table");
178 }
179 LUA_ASSERT(VALIDLINK(L, L->refFree, n), "inconsistent ref table");
180}
181
182
183
148static void collectproto (lua_State *L) { 184static void collectproto (lua_State *L) {
149 Proto **p = &L->rootproto; 185 Proto **p = &L->rootproto;
150 Proto *next; 186 Proto *next;
@@ -300,7 +336,7 @@ void luaC_collect (lua_State *L, int all) {
300long lua_collectgarbage (lua_State *L, long limit) { 336long lua_collectgarbage (lua_State *L, long limit) {
301 unsigned long recovered = L->nblocks; /* to subtract `nblocks' after gc */ 337 unsigned long recovered = L->nblocks; /* to subtract `nblocks' after gc */
302 markall(L); 338 markall(L);
303 luaR_invalidaterefs(L); 339 invalidaterefs(L);
304 luaC_collect(L, 0); 340 luaC_collect(L, 0);
305 recovered = recovered - L->nblocks; 341 recovered = recovered - L->nblocks;
306 L->GCthreshold = (limit == 0) ? 2*L->nblocks : L->nblocks+limit; 342 L->GCthreshold = (limit == 0) ? 2*L->nblocks : L->nblocks+limit;
diff --git a/liolib.c b/liolib.c
index dc432b40..b73bd359 100644
--- a/liolib.c
+++ b/liolib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: liolib.c,v 1.70 2000/08/14 19:10:14 roberto Exp roberto $ 2** $Id: liolib.c,v 1.71 2000/08/22 17:47:17 roberto Exp roberto $
3** Standard I/O (and system) library 3** Standard I/O (and system) library
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -61,13 +61,16 @@ typedef struct IOCtrl {
61static const char *const filenames[] = {"_INPUT", "_OUTPUT"}; 61static const char *const filenames[] = {"_INPUT", "_OUTPUT"};
62 62
63 63
64static void pushresult (lua_State *L, int i) { 64static int pushresult (lua_State *L, int i) {
65 if (i) 65 if (i) {
66 lua_pushuserdata(L, NULL); 66 lua_pushuserdata(L, NULL);
67 return 1;
68 }
67 else { 69 else {
68 lua_pushnil(L); 70 lua_pushnil(L);
69 lua_pushstring(L, strerror(errno)); 71 lua_pushstring(L, strerror(errno));
70 lua_pushnumber(L, errno); 72 lua_pushnumber(L, errno);
73 return 3;;
71 } 74 }
72} 75}
73 76
@@ -79,8 +82,8 @@ static void pushresult (lua_State *L, int i) {
79*/ 82*/
80 83
81 84
82static FILE *gethandle (lua_State *L, IOCtrl *ctrl, lua_Object f) { 85static FILE *gethandle (lua_State *L, IOCtrl *ctrl, int f) {
83 void *p = lua_getuserdata(L, f); 86 void *p = lua_touserdata(L, f);
84 if (p != NULL) { /* is `f' a userdata ? */ 87 if (p != NULL) { /* is `f' a userdata ? */
85 int ftag = lua_tag(L, f); 88 int ftag = lua_tag(L, f);
86 if (ftag == ctrl->iotag) /* does it have the correct tag? */ 89 if (ftag == ctrl->iotag) /* does it have the correct tag? */
@@ -94,7 +97,7 @@ static FILE *gethandle (lua_State *L, IOCtrl *ctrl, lua_Object f) {
94 97
95 98
96static FILE *getnonullfile (lua_State *L, IOCtrl *ctrl, int arg) { 99static FILE *getnonullfile (lua_State *L, IOCtrl *ctrl, int arg) {
97 FILE *f = gethandle(L, ctrl, lua_getparam(L, arg)); 100 FILE *f = gethandle(L, ctrl, arg);
98 luaL_arg_check(L, f, arg, "invalid file handle"); 101 luaL_arg_check(L, f, arg, "invalid file handle");
99 return f; 102 return f;
100} 103}
@@ -102,9 +105,11 @@ static FILE *getnonullfile (lua_State *L, IOCtrl *ctrl, int arg) {
102 105
103static FILE *getfilebyref (lua_State *L, IOCtrl *ctrl, int inout) { 106static FILE *getfilebyref (lua_State *L, IOCtrl *ctrl, int inout) {
104 FILE *f; 107 FILE *f;
105 lua_pushglobals(L); 108 lua_getglobals(L);
106 lua_pushref(L, ctrl->ref[inout]); 109 lua_getref(L, ctrl->ref[inout]);
107 f = gethandle(L, ctrl, lua_rawget(L)); 110 lua_rawget(L);
111 f = gethandle(L, ctrl, -1);
112 lua_settop(L, -1); /* remove global */
108 if (f == NULL) 113 if (f == NULL)
109 luaL_verror(L, "global variable `%.10s' is not a file handle", 114 luaL_verror(L, "global variable `%.10s' is not a file handle",
110 filenames[inout]); 115 filenames[inout]);
@@ -122,12 +127,13 @@ static void setfilebyname (lua_State *L, IOCtrl *ctrl, FILE *f,
122#define setfile(L,ctrl,f,inout) (setfilebyname(L,ctrl,f,filenames[inout])) 127#define setfile(L,ctrl,f,inout) (setfilebyname(L,ctrl,f,filenames[inout]))
123 128
124 129
125static void setreturn (lua_State *L, IOCtrl *ctrl, FILE *f, int inout) { 130static int setreturn (lua_State *L, IOCtrl *ctrl, FILE *f, int inout) {
126 if (f == NULL) 131 if (f == NULL)
127 pushresult(L, 0); 132 return pushresult(L, 0);
128 else { 133 else {
129 setfile(L, ctrl, f, inout); 134 setfile(L, ctrl, f, inout);
130 lua_pushusertag(L, f, ctrl->iotag); 135 lua_pushusertag(L, f, ctrl->iotag);
136 return 1;
131 } 137 }
132} 138}
133 139
@@ -143,15 +149,15 @@ static int closefile (lua_State *L, IOCtrl *ctrl, FILE *f) {
143} 149}
144 150
145 151
146static void io_close (lua_State *L) { 152static int io_close (lua_State *L) {
147 IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1)); 153 IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1);
148 pushresult(L, closefile(L, ctrl, getnonullfile(L, ctrl, 2))); 154 return pushresult(L, closefile(L, ctrl, getnonullfile(L, ctrl, 2)));
149} 155}
150 156
151 157
152static void file_collect (lua_State *L) { 158static int file_collect (lua_State *L) {
153 IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1)); 159 IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1);
154 if (ctrl == (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 2))) { 160 if (ctrl == (IOCtrl *)lua_touserdata(L, 2)) {
155 /* collectig `ctrl' itself */ 161 /* collectig `ctrl' itself */
156 lua_unref(L, ctrl->ref[INFILE]); 162 lua_unref(L, ctrl->ref[INFILE]);
157 lua_unref(L, ctrl->ref[OUTFILE]); 163 lua_unref(L, ctrl->ref[OUTFILE]);
@@ -162,50 +168,54 @@ static void file_collect (lua_State *L) {
162 if (f != stdin && f != stdout && f != stderr) 168 if (f != stdin && f != stdout && f != stderr)
163 CLOSEFILE(L, f); 169 CLOSEFILE(L, f);
164 } 170 }
171 return 0;
165} 172}
166 173
167 174
168static void io_open (lua_State *L) { 175static int io_open (lua_State *L) {
169 IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1)); 176 IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1);
170 FILE *f = fopen(luaL_check_string(L, 2), luaL_check_string(L, 3)); 177 FILE *f = fopen(luaL_check_string(L, 2), luaL_check_string(L, 3));
171 if (f) lua_pushusertag(L, f, ctrl->iotag); 178 if (f) {
172 else pushresult(L, 0); 179 lua_pushusertag(L, f, ctrl->iotag);
180 return 1;
181 }
182 else
183 return pushresult(L, 0);
173} 184}
174 185
175 186
176 187
177static void io_fromto (lua_State *L, int inout, const char *mode) { 188static int io_fromto (lua_State *L, int inout, const char *mode) {
178 IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1)); 189 IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1);
179 lua_Object f = lua_getparam(L, 2);
180 FILE *current; 190 FILE *current;
181 if (f == LUA_NOOBJECT) { 191 if (lua_isnull(L, 2)) {
182 closefile(L, ctrl, getfilebyref(L, ctrl, inout)); 192 closefile(L, ctrl, getfilebyref(L, ctrl, inout));
183 current = (inout == 0) ? stdin : stdout; 193 current = (inout == 0) ? stdin : stdout;
184 } 194 }
185 else if (lua_tag(L, f) == ctrl->iotag) /* deprecated option */ 195 else if (lua_tag(L, 2) == ctrl->iotag) /* deprecated option */
186 current = (FILE *)lua_getuserdata(L, f); 196 current = (FILE *)lua_touserdata(L, 2);
187 else { 197 else {
188 const char *s = luaL_check_string(L, 2); 198 const char *s = luaL_check_string(L, 2);
189 current = (*s == '|') ? popen(s+1, mode) : fopen(s, mode); 199 current = (*s == '|') ? popen(s+1, mode) : fopen(s, mode);
190 } 200 }
191 setreturn(L, ctrl, current, inout); 201 return setreturn(L, ctrl, current, inout);
192} 202}
193 203
194 204
195static void io_readfrom (lua_State *L) { 205static int io_readfrom (lua_State *L) {
196 io_fromto(L, INFILE, "r"); 206 return io_fromto(L, INFILE, "r");
197} 207}
198 208
199 209
200static void io_writeto (lua_State *L) { 210static int io_writeto (lua_State *L) {
201 io_fromto(L, OUTFILE, "w"); 211 return io_fromto(L, OUTFILE, "w");
202} 212}
203 213
204 214
205static void io_appendto (lua_State *L) { 215static int io_appendto (lua_State *L) {
206 IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1)); 216 IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1);
207 FILE *current = fopen(luaL_check_string(L, 2), "a"); 217 FILE *current = fopen(luaL_check_string(L, 2), "a");
208 setreturn(L, ctrl, current, OUTFILE); 218 return setreturn(L, ctrl, current, OUTFILE);
209} 219}
210 220
211 221
@@ -342,28 +352,29 @@ static int read_chars (lua_State *L, FILE *f, size_t n) {
342} 352}
343 353
344 354
345static void io_read (lua_State *L) { 355static int io_read (lua_State *L) {
346 IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1)); 356 IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1);
347 int arg = 2; 357 int lastarg = lua_gettop(L);
348 lua_Object op; 358 int firstarg = 2;
349 FILE *f = gethandle(L, ctrl, lua_getparam(L, arg)); 359 FILE *f = gethandle(L, ctrl, firstarg);
350 if (f) arg++; 360 int n = 0;
361 if (f) firstarg++;
351 else f = getfilebyref(L, ctrl, INFILE); /* get _INPUT */ 362 else f = getfilebyref(L, ctrl, INFILE); /* get _INPUT */
352 op = lua_getparam(L, arg);
353 do { /* repeat for each part */ 363 do { /* repeat for each part */
354 size_t l; 364 size_t l;
355 int success; 365 int success;
356 luaL_resetbuffer(L); 366 luaL_resetbuffer(L);
357 if (lua_isnumber(L, op)) 367 if (lua_isnumber(L, firstarg+n))
358 success = read_chars(L, f, (size_t)lua_getnumber(L, op)); 368 success = read_chars(L, f, (size_t)lua_tonumber(L, firstarg+n));
359 else { 369 else {
360 const char *p = luaL_opt_string(L, arg, "*l"); 370 const char *p = luaL_opt_string(L, firstarg+n, "*l");
361 if (p[0] != '*') 371 if (p[0] != '*')
362 success = read_pattern(L, f, p); /* deprecated! */ 372 success = read_pattern(L, f, p); /* deprecated! */
363 else { 373 else {
364 switch (p[1]) { 374 switch (p[1]) {
365 case 'n': /* number */ 375 case 'n': /* number */
366 if (!read_number(L, f)) return; /* read fails */ 376 if (!read_number(L, f)) return n; /* read fails */
377 n++;
367 continue; /* number is already pushed; avoid the "pushstring" */ 378 continue; /* number is already pushed; avoid the "pushstring" */
368 case 'l': /* line */ 379 case 'l': /* line */
369 success = read_line(L, f); 380 success = read_line(L, f);
@@ -377,66 +388,69 @@ static void io_read (lua_State *L) {
377 success = 0; /* must read something to succeed */ 388 success = 0; /* must read something to succeed */
378 break; 389 break;
379 default: 390 default:
380 luaL_argerror(L, arg, "invalid format"); 391 luaL_argerror(L, firstarg+n, "invalid format");
381 success = 0; /* to avoid warnings */ 392 success = 0; /* to avoid warnings */
382 } 393 }
383 } 394 }
384 } 395 }
385 l = luaL_getsize(L); 396 l = luaL_getsize(L);
386 if (!success && l==0) return; /* read fails */ 397 if (!success && l==0) return n; /* read fails */
387 lua_pushlstring(L, luaL_buffer(L), l); 398 lua_pushlstring(L, luaL_buffer(L), l);
388 } while ((op = lua_getparam(L, ++arg)) != LUA_NOOBJECT); 399 n++;
400 } while (firstarg+n <= lastarg);
401 return n;
389} 402}
390 403
391/* }====================================================== */ 404/* }====================================================== */
392 405
393 406
394static void io_write (lua_State *L) { 407static int io_write (lua_State *L) {
395 IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1)); 408 int lastarg = lua_gettop(L);
409 IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1);
396 int arg = 2; 410 int arg = 2;
397 int status = 1; 411 int status = 1;
398 lua_Object o; 412 FILE *f = gethandle(L, ctrl, arg);
399 FILE *f = gethandle(L, ctrl, lua_getparam(L, arg));
400 if (f) arg++; 413 if (f) arg++;
401 else f = getfilebyref(L, ctrl, OUTFILE); /* get _OUTPUT */ 414 else f = getfilebyref(L, ctrl, OUTFILE); /* get _OUTPUT */
402 while ((o = lua_getparam(L, arg)) != LUA_NOOBJECT) { 415 for (; arg <= lastarg; arg++) {
403 if (lua_type(L, o)[2] == 'm') { /* nuMber? */ /* LUA_NUMBER */ 416 if (lua_type(L, arg)[2] == 'm') { /* nuMber? */ /* LUA_NUMBER */
404 /* optimization: could be done exactly as for strings */ 417 /* optimization: could be done exactly as for strings */
405 status = status && fprintf(f, "%.16g", lua_getnumber(L, o)) > 0; 418 status = status && fprintf(f, "%.16g", lua_tonumber(L, arg)) > 0;
406 } 419 }
407 else { 420 else {
408 size_t l; 421 size_t l;
409 const char *s = luaL_check_lstr(L, arg, &l); 422 const char *s = luaL_check_lstr(L, arg, &l);
410 status = status && (fwrite(s, sizeof(char), l, f) == l); 423 status = status && (fwrite(s, sizeof(char), l, f) == l);
411 } 424 }
412 arg++;
413 } 425 }
414 pushresult(L, status); 426 pushresult(L, status);
427 return 1;
415} 428}
416 429
417 430
418static void io_seek (lua_State *L) { 431static int io_seek (lua_State *L) {
419 static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; 432 static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
420 static const char *const modenames[] = {"set", "cur", "end", NULL}; 433 static const char *const modenames[] = {"set", "cur", "end", NULL};
421 IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1)); 434 IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1);
422 FILE *f = getnonullfile(L, ctrl, 2); 435 FILE *f = getnonullfile(L, ctrl, 2);
423 int op = luaL_findstring(luaL_opt_string(L, 3, "cur"), modenames); 436 int op = luaL_findstring(luaL_opt_string(L, 3, "cur"), modenames);
424 long offset = luaL_opt_long(L, 4, 0); 437 long offset = luaL_opt_long(L, 4, 0);
425 luaL_arg_check(L, op != -1, 3, "invalid mode"); 438 luaL_arg_check(L, op != -1, 3, "invalid mode");
426 op = fseek(f, offset, mode[op]); 439 op = fseek(f, offset, mode[op]);
427 if (op) 440 if (op)
428 pushresult(L, 0); /* error */ 441 return pushresult(L, 0); /* error */
429 else 442 else {
430 lua_pushnumber(L, ftell(f)); 443 lua_pushnumber(L, ftell(f));
444 return 1;
445 }
431} 446}
432 447
433 448
434static void io_flush (lua_State *L) { 449static int io_flush (lua_State *L) {
435 IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1)); 450 IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1);
436 lua_Object of = lua_getparam(L, 2); 451 FILE *f = gethandle(L, ctrl, 2);
437 FILE *f = gethandle(L, ctrl, of); 452 luaL_arg_check(L, f || lua_isnull(L, 2), 2, "invalid file handle");
438 luaL_arg_check(L, f || of == LUA_NOOBJECT, 2, "invalid file handle"); 453 return pushresult(L, fflush(f) == 0);
439 pushresult(L, fflush(f) == 0);
440} 454}
441 455
442/* }====================================================== */ 456/* }====================================================== */
@@ -448,39 +462,43 @@ static void io_flush (lua_State *L) {
448** ======================================================= 462** =======================================================
449*/ 463*/
450 464
451static void io_execute (lua_State *L) { 465static int io_execute (lua_State *L) {
452 lua_pushnumber(L, system(luaL_check_string(L, 1))); 466 lua_pushnumber(L, system(luaL_check_string(L, 1)));
467 return 1;
453} 468}
454 469
455 470
456static void io_remove (lua_State *L) { 471static int io_remove (lua_State *L) {
457 pushresult(L, remove(luaL_check_string(L, 1)) == 0); 472 return pushresult(L, remove(luaL_check_string(L, 1)) == 0);
458} 473}
459 474
460 475
461static void io_rename (lua_State *L) { 476static int io_rename (lua_State *L) {
462 pushresult(L, rename(luaL_check_string(L, 1), 477 return pushresult(L, rename(luaL_check_string(L, 1),
463 luaL_check_string(L, 2)) == 0); 478 luaL_check_string(L, 2)) == 0);
464} 479}
465 480
466 481
467static void io_tmpname (lua_State *L) { 482static int io_tmpname (lua_State *L) {
468 lua_pushstring(L, tmpnam(NULL)); 483 lua_pushstring(L, tmpnam(NULL));
484 return 1;
469} 485}
470 486
471 487
472 488
473static void io_getenv (lua_State *L) { 489static int io_getenv (lua_State *L) {
474 lua_pushstring(L, getenv(luaL_check_string(L, 1))); /* if NULL push nil */ 490 lua_pushstring(L, getenv(luaL_check_string(L, 1))); /* if NULL push nil */
491 return 1;
475} 492}
476 493
477 494
478static void io_clock (lua_State *L) { 495static int io_clock (lua_State *L) {
479 lua_pushnumber(L, ((double)clock())/CLOCKS_PER_SEC); 496 lua_pushnumber(L, ((double)clock())/CLOCKS_PER_SEC);
497 return 1;
480} 498}
481 499
482 500
483static void io_date (lua_State *L) { 501static int io_date (lua_State *L) {
484 char b[256]; 502 char b[256];
485 const char *s = luaL_opt_string(L, 1, "%c"); 503 const char *s = luaL_opt_string(L, 1, "%c");
486 struct tm *stm; 504 struct tm *stm;
@@ -490,10 +508,11 @@ static void io_date (lua_State *L) {
490 lua_pushstring(L, b); 508 lua_pushstring(L, b);
491 else 509 else
492 lua_error(L, "invalid `date' format"); 510 lua_error(L, "invalid `date' format");
511 return 1;
493} 512}
494 513
495 514
496static void setloc (lua_State *L) { 515static int setloc (lua_State *L) {
497 static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, 516 static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
498 LC_NUMERIC, LC_TIME}; 517 LC_NUMERIC, LC_TIME};
499 static const char *const catnames[] = {"all", "collate", "ctype", "monetary", 518 static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
@@ -501,25 +520,28 @@ static void setloc (lua_State *L) {
501 int op = luaL_findstring(luaL_opt_string(L, 2, "all"), catnames); 520 int op = luaL_findstring(luaL_opt_string(L, 2, "all"), catnames);
502 luaL_arg_check(L, op != -1, 2, "invalid option"); 521 luaL_arg_check(L, op != -1, 2, "invalid option");
503 lua_pushstring(L, setlocale(cat[op], luaL_check_string(L, 1))); 522 lua_pushstring(L, setlocale(cat[op], luaL_check_string(L, 1)));
523 return 1;
504} 524}
505 525
506 526
507static void io_exit (lua_State *L) { 527static int io_exit (lua_State *L) {
508 exit(luaL_opt_int(L, 1, EXIT_SUCCESS)); 528 exit(luaL_opt_int(L, 1, EXIT_SUCCESS));
529 return 0; /* to avoid warnings */
509} 530}
510 531
511/* }====================================================== */ 532/* }====================================================== */
512 533
513 534
514 535
515static void io_debug (lua_State *L) { 536static int io_debug (lua_State *L) {
516 for (;;) { 537 for (;;) {
517 char buffer[250]; 538 char buffer[250];
518 fprintf(stderr, "lua_debug> "); 539 fprintf(stderr, "lua_debug> ");
519 if (fgets(buffer, sizeof(buffer), stdin) == 0 || 540 if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
520 strcmp(buffer, "cont\n") == 0) 541 strcmp(buffer, "cont\n") == 0)
521 return; 542 return 0;
522 lua_dostring(L, buffer); 543 lua_dostring(L, buffer);
544 lua_settop(L, 0); /* remove eventual returns */
523 } 545 }
524} 546}
525 547
@@ -529,12 +551,11 @@ static void io_debug (lua_State *L) {
529#define MAXMESSAGE (MESSAGESIZE*10) 551#define MAXMESSAGE (MESSAGESIZE*10)
530 552
531 553
532static void errorfb (lua_State *L) { 554static int errorfb (lua_State *L) {
533 char buff[MAXMESSAGE]; 555 char buff[MAXMESSAGE];
534 int level = 1; /* skip level 0 (it's this function) */ 556 int level = 1; /* skip level 0 (it's this function) */
535 lua_Debug ar; 557 lua_Debug ar;
536 lua_Object alertfunc; 558 sprintf(buff, "error: %.200s\n", lua_tostring(L, 1));
537 sprintf(buff, "error: %.200s\n", lua_getstring(L, lua_getparam(L, 1)));
538 while (lua_getstack(L, level++, &ar)) { 559 while (lua_getstack(L, level++, &ar)) {
539 char buffchunk[60]; 560 char buffchunk[60];
540 lua_getinfo(L, "Snl", &ar); 561 lua_getinfo(L, "Snl", &ar);
@@ -572,13 +593,14 @@ static void errorfb (lua_State *L) {
572 sprintf(buff+strlen(buff), " [%.70s]", buffchunk); 593 sprintf(buff+strlen(buff), " [%.70s]", buffchunk);
573 strcat(buff, "\n"); 594 strcat(buff, "\n");
574 } 595 }
575 lua_pushglobals(L); 596 lua_getglobals(L);
576 lua_pushstring(L, LUA_ALERT); 597 lua_pushstring(L, LUA_ALERT);
577 alertfunc = lua_rawget(L); 598 lua_rawget(L);
578 if (lua_isfunction(L, alertfunc)) { /* avoid loop if _ALERT is not defined */ 599 if (lua_isfunction(L, -1)) { /* avoid loop if _ALERT is not defined */
579 lua_pushstring(L, buff); 600 lua_pushstring(L, buff);
580 lua_callfunction(L, alertfunc); 601 lua_call(L, 1, 0);
581 } 602 }
603 return 0;
582} 604}
583 605
584 606
diff --git a/llimits.h b/llimits.h
index f7412acf..c716b0dd 100644
--- a/llimits.h
+++ b/llimits.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: llimits.h,v 1.11 2000/06/28 17:03:32 roberto Exp roberto $ 2** $Id: llimits.h,v 1.12 2000/08/15 18:28:48 roberto Exp roberto $
3** Limits, basic types, and some other "installation-dependent" definitions 3** Limits, basic types, and some other "installation-dependent" definitions
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -197,12 +197,6 @@ typedef unsigned long Instruction;
197#define RFIELDS_PER_FLUSH (LFIELDS_PER_FLUSH/2) 197#define RFIELDS_PER_FLUSH (LFIELDS_PER_FLUSH/2)
198 198
199 199
200/* maximum number of values printed in one call to `print' */
201#ifndef MAXPRINT
202#define MAXPRINT 40 /* arbitrary limit */
203#endif
204
205
206/* maximum lookback to find a real constant (for code generation) */ 200/* maximum lookback to find a real constant (for code generation) */
207#ifndef LOOKBACKNUMS 201#ifndef LOOKBACKNUMS
208#define LOOKBACKNUMS 20 /* arbitrary constant */ 202#define LOOKBACKNUMS 20 /* arbitrary constant */
diff --git a/lmathlib.c b/lmathlib.c
index 86850cc9..d6957e76 100644
--- a/lmathlib.c
+++ b/lmathlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lmathlib.c,v 1.25 2000/06/12 13:52:05 roberto Exp roberto $ 2** $Id: lmathlib.c,v 1.26 2000/08/09 19:16:57 roberto Exp roberto $
3** Standard mathematical library 3** Standard mathematical library
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -33,138 +33,169 @@
33#endif 33#endif
34 34
35 35
36static void math_abs (lua_State *L) { 36static int math_abs (lua_State *L) {
37 lua_pushnumber(L, fabs(luaL_check_number(L, 1))); 37 lua_pushnumber(L, fabs(luaL_check_number(L, 1)));
38 return 1;
38} 39}
39 40
40static void math_sin (lua_State *L) { 41static int math_sin (lua_State *L) {
41 lua_pushnumber(L, sin(TORAD(luaL_check_number(L, 1)))); 42 lua_pushnumber(L, sin(TORAD(luaL_check_number(L, 1))));
43 return 1;
42} 44}
43 45
44static void math_cos (lua_State *L) { 46static int math_cos (lua_State *L) {
45 lua_pushnumber(L, cos(TORAD(luaL_check_number(L, 1)))); 47 lua_pushnumber(L, cos(TORAD(luaL_check_number(L, 1))));
48 return 1;
46} 49}
47 50
48static void math_tan (lua_State *L) { 51static int math_tan (lua_State *L) {
49 lua_pushnumber(L, tan(TORAD(luaL_check_number(L, 1)))); 52 lua_pushnumber(L, tan(TORAD(luaL_check_number(L, 1))));
53 return 1;
50} 54}
51 55
52static void math_asin (lua_State *L) { 56static int math_asin (lua_State *L) {
53 lua_pushnumber(L, FROMRAD(asin(luaL_check_number(L, 1)))); 57 lua_pushnumber(L, FROMRAD(asin(luaL_check_number(L, 1))));
58 return 1;
54} 59}
55 60
56static void math_acos (lua_State *L) { 61static int math_acos (lua_State *L) {
57 lua_pushnumber(L, FROMRAD(acos(luaL_check_number(L, 1)))); 62 lua_pushnumber(L, FROMRAD(acos(luaL_check_number(L, 1))));
63 return 1;
58} 64}
59 65
60static void math_atan (lua_State *L) { 66static int math_atan (lua_State *L) {
61 lua_pushnumber(L, FROMRAD(atan(luaL_check_number(L, 1)))); 67 lua_pushnumber(L, FROMRAD(atan(luaL_check_number(L, 1))));
68 return 1;
62} 69}
63 70
64static void math_atan2 (lua_State *L) { 71static int math_atan2 (lua_State *L) {
65 lua_pushnumber(L, FROMRAD(atan2(luaL_check_number(L, 1), luaL_check_number(L, 2)))); 72 lua_pushnumber(L, FROMRAD(atan2(luaL_check_number(L, 1), luaL_check_number(L, 2))));
73 return 1;
66} 74}
67 75
68static void math_ceil (lua_State *L) { 76static int math_ceil (lua_State *L) {
69 lua_pushnumber(L, ceil(luaL_check_number(L, 1))); 77 lua_pushnumber(L, ceil(luaL_check_number(L, 1)));
78 return 1;
70} 79}
71 80
72static void math_floor (lua_State *L) { 81static int math_floor (lua_State *L) {
73 lua_pushnumber(L, floor(luaL_check_number(L, 1))); 82 lua_pushnumber(L, floor(luaL_check_number(L, 1)));
83 return 1;
74} 84}
75 85
76static void math_mod (lua_State *L) { 86static int math_mod (lua_State *L) {
77 lua_pushnumber(L, fmod(luaL_check_number(L, 1), luaL_check_number(L, 2))); 87 lua_pushnumber(L, fmod(luaL_check_number(L, 1), luaL_check_number(L, 2)));
88 return 1;
78} 89}
79 90
80static void math_sqrt (lua_State *L) { 91static int math_sqrt (lua_State *L) {
81 lua_pushnumber(L, sqrt(luaL_check_number(L, 1))); 92 lua_pushnumber(L, sqrt(luaL_check_number(L, 1)));
93 return 1;
82} 94}
83 95
84static void math_pow (lua_State *L) { 96static int math_pow (lua_State *L) {
85 lua_pushnumber(L, pow(luaL_check_number(L, 1), luaL_check_number(L, 2))); 97 lua_pushnumber(L, pow(luaL_check_number(L, 1), luaL_check_number(L, 2)));
98 return 1;
86} 99}
87 100
88static void math_log (lua_State *L) { 101static int math_log (lua_State *L) {
89 lua_pushnumber(L, log(luaL_check_number(L, 1))); 102 lua_pushnumber(L, log(luaL_check_number(L, 1)));
103 return 1;
90} 104}
91 105
92static void math_log10 (lua_State *L) { 106static int math_log10 (lua_State *L) {
93 lua_pushnumber(L, log10(luaL_check_number(L, 1))); 107 lua_pushnumber(L, log10(luaL_check_number(L, 1)));
108 return 1;
94} 109}
95 110
96static void math_exp (lua_State *L) { 111static int math_exp (lua_State *L) {
97 lua_pushnumber(L, exp(luaL_check_number(L, 1))); 112 lua_pushnumber(L, exp(luaL_check_number(L, 1)));
113 return 1;
98} 114}
99 115
100static void math_deg (lua_State *L) { 116static int math_deg (lua_State *L) {
101 lua_pushnumber(L, luaL_check_number(L, 1)/RADIANS_PER_DEGREE); 117 lua_pushnumber(L, luaL_check_number(L, 1)/RADIANS_PER_DEGREE);
118 return 1;
102} 119}
103 120
104static void math_rad (lua_State *L) { 121static int math_rad (lua_State *L) {
105 lua_pushnumber(L, luaL_check_number(L, 1)*RADIANS_PER_DEGREE); 122 lua_pushnumber(L, luaL_check_number(L, 1)*RADIANS_PER_DEGREE);
123 return 1;
106} 124}
107 125
108static void math_frexp (lua_State *L) { 126static int math_frexp (lua_State *L) {
109 int e; 127 int e;
110 lua_pushnumber(L, frexp(luaL_check_number(L, 1), &e)); 128 lua_pushnumber(L, frexp(luaL_check_number(L, 1), &e));
111 lua_pushnumber(L, e); 129 lua_pushnumber(L, e);
130 return 2;
112} 131}
113 132
114static void math_ldexp (lua_State *L) { 133static int math_ldexp (lua_State *L) {
115 lua_pushnumber(L, ldexp(luaL_check_number(L, 1), luaL_check_int(L, 2))); 134 lua_pushnumber(L, ldexp(luaL_check_number(L, 1), luaL_check_int(L, 2)));
135 return 1;
116} 136}
117 137
118 138
119 139
120static void math_min (lua_State *L) { 140static int math_min (lua_State *L) {
121 int i = 1; 141 int n = lua_gettop(L); /* number of arguments */
122 double dmin = luaL_check_number(L, i); 142 double dmin = luaL_check_number(L, 1);
123 while (lua_getparam(L, ++i) != LUA_NOOBJECT) { 143 int i;
144 for (i=2; i<=n; i++) {
124 double d = luaL_check_number(L, i); 145 double d = luaL_check_number(L, i);
125 if (d < dmin) 146 if (d < dmin)
126 dmin = d; 147 dmin = d;
127 } 148 }
128 lua_pushnumber(L, dmin); 149 lua_pushnumber(L, dmin);
150 return 1;
129} 151}
130 152
131 153
132static void math_max (lua_State *L) { 154static int math_max (lua_State *L) {
133 int i = 1; 155 int n = lua_gettop(L); /* number of arguments */
134 double dmax = luaL_check_number(L, i); 156 double dmax = luaL_check_number(L, 1);
135 while (lua_getparam(L, ++i) != LUA_NOOBJECT) { 157 int i;
158 for (i=2; i<=n; i++) {
136 double d = luaL_check_number(L, i); 159 double d = luaL_check_number(L, i);
137 if (d > dmax) 160 if (d > dmax)
138 dmax = d; 161 dmax = d;
139 } 162 }
140 lua_pushnumber(L, dmax); 163 lua_pushnumber(L, dmax);
164 return 1;
141} 165}
142 166
143 167
144static void math_random (lua_State *L) { 168static int math_random (lua_State *L) {
145 /* the '%' avoids the (rare) case of r==1, and is needed also because on 169 /* the '%' avoids the (rare) case of r==1, and is needed also because on
146 some systems (SunOS!) "rand()" may return a value larger than RAND_MAX */ 170 some systems (SunOS!) "rand()" may return a value larger than RAND_MAX */
147 double r = (double)(rand()%RAND_MAX) / (double)RAND_MAX; 171 double r = (double)(rand()%RAND_MAX) / (double)RAND_MAX;
148 if (lua_getparam(L, 1) == LUA_NOOBJECT) /* no arguments? */ 172 switch (lua_gettop(L)) { /* check number of arguments */
149 lua_pushnumber(L, r); /* Number between 0 and 1 */ 173 case 0: { /* no arguments */
150 else { 174 lua_pushnumber(L, r); /* Number between 0 and 1 */
151 int l, u; /* lower & upper limits */ 175 break;
152 if (lua_getparam(L, 2) == LUA_NOOBJECT) { /* only one argument? */
153 l = 1;
154 u = luaL_check_int(L, 1);
155 } 176 }
156 else { /* two arguments */ 177 case 1: { /* only upper limit */
157 l = luaL_check_int(L, 1); 178 int u = luaL_check_int(L, 1);
158 u = luaL_check_int(L, 2); 179 luaL_arg_check(L, 1<=u, 1, "interval is empty");
180 lua_pushnumber(L, (int)(r*u)+1); /* integer between 1 and `u' */
181 break;
159 } 182 }
160 luaL_arg_check(L, l<=u, 1, "interval is empty"); 183 case 2: { /* lower and upper limits */
161 lua_pushnumber(L, (int)(r*(u-l+1))+l); /* integer between `l' and `u' */ 184 int l = luaL_check_int(L, 1);
185 int u = luaL_check_int(L, 2);
186 luaL_arg_check(L, l<=u, 2, "interval is empty");
187 lua_pushnumber(L, (int)(r*(u-l+1))+l); /* integer between `l' and `u' */
188 break;
189 }
190 default: lua_error(L, "wrong number of arguments");
162 } 191 }
192 return 1;
163} 193}
164 194
165 195
166static void math_randomseed (lua_State *L) { 196static int math_randomseed (lua_State *L) {
167 srand(luaL_check_int(L, 1)); 197 srand(luaL_check_int(L, 1));
198 return 0;
168} 199}
169 200
170 201
@@ -199,9 +230,10 @@ static const struct luaL_reg mathlib[] = {
199*/ 230*/
200void lua_mathlibopen (lua_State *L) { 231void lua_mathlibopen (lua_State *L) {
201 luaL_openl(L, mathlib); 232 luaL_openl(L, mathlib);
202 lua_pushcfunction(L, math_pow);
203 lua_pushnumber(L, 0); /* to get its tag */ 233 lua_pushnumber(L, 0); /* to get its tag */
204 lua_settagmethod(L, lua_tag(L, lua_pop(L)), "pow"); 234 lua_pushcfunction(L, math_pow);
235 lua_settagmethod(L, lua_tag(L, -2), "pow");
236 lua_settop(L, -1); /* remove number */
205 lua_pushnumber(L, PI); lua_setglobal(L, "PI"); 237 lua_pushnumber(L, PI); lua_setglobal(L, "PI");
206} 238}
207 239
diff --git a/lref.c b/lref.c
deleted file mode 100644
index c3fc57af..00000000
--- a/lref.c
+++ /dev/null
@@ -1,118 +0,0 @@
1/*
2** $Id: lref.c,v 1.17 2000/08/09 19:16:57 roberto Exp roberto $
3** reference mechanism
4** See Copyright Notice in lua.h
5*/
6
7
8#include "lua.h"
9
10#include "lapi.h"
11#include "ldo.h"
12#include "lmem.h"
13#include "lref.h"
14#include "lstate.h"
15
16
17int lua_ref (lua_State *L, int lock) {
18 int ref;
19 luaA_checkCargs(L, 1);
20 if (ttype(L->top-1) == TAG_NIL)
21 ref = LUA_REFNIL;
22 else {
23 if (L->refFree != NONEXT) { /* is there a free place? */
24 ref = L->refFree;
25 L->refFree = L->refArray[ref].st;
26 }
27 else { /* no more free places */
28 luaM_growvector(L, L->refArray, L->refSize, 1, struct Ref,
29 "reference table overflow", MAX_INT);
30 ref = L->refSize++;
31 }
32 L->refArray[ref].o = *(L->top-1);
33 L->refArray[ref].st = lock ? LOCK : HOLD;
34 }
35 L->top--;
36 return ref;
37}
38
39
40void lua_unref (lua_State *L, int ref) {
41 if (ref >= 0) {
42 if (ref >= L->refSize || L->refArray[ref].st >= 0)
43 lua_error(L, "Lua API error - "
44 "invalid argument for function `lua_unref'");
45 L->refArray[ref].st = L->refFree;
46 L->refFree = ref;
47 }
48}
49
50
51int lua_pushref (lua_State *L, int ref) {
52 if (ref == LUA_REFNIL)
53 ttype(L->top) = TAG_NIL;
54 else if (0 <= ref && ref < L->refSize &&
55 (L->refArray[ref].st == LOCK || L->refArray[ref].st == HOLD))
56 *L->top = L->refArray[ref].o;
57 else
58 return 0;
59 incr_top;
60 return 1;
61}
62
63
64void lua_beginblock (lua_State *L) {
65 luaM_growvector(L, L->Cblocks, L->numCblocks, 1, struct C_Lua_Stack,
66 "too many nested blocks", L->stacksize);
67 L->Cblocks[L->numCblocks] = L->Cstack;
68 L->numCblocks++;
69}
70
71
72void lua_endblock (lua_State *L) {
73 if (L->numCblocks <= 0)
74 lua_error(L, "Lua API error - no block to end");
75 --L->numCblocks;
76 L->Cstack = L->Cblocks[L->numCblocks];
77 L->top = L->Cstack.base;
78}
79
80
81
82
83
84
85static int hasmark (const TObject *o) {
86 /* valid only for locked objects */
87 switch (o->ttype) {
88 case TAG_STRING: case TAG_USERDATA:
89 return tsvalue(o)->marked;
90 case TAG_TABLE:
91 return ismarked(hvalue(o));
92 case TAG_LCLOSURE: case TAG_CCLOSURE:
93 return ismarked(clvalue(o)->mark);
94 default: /* number */
95 return 1;
96 }
97}
98
99
100/* for internal debugging only; check if a link of free refs is valid */
101#define VALIDLINK(L, st,n) (NONEXT <= (st) && (st) < (n))
102
103void luaR_invalidaterefs (lua_State *L) {
104 int n = L->refSize;
105 int i;
106 for (i=0; i<n; i++) {
107 struct Ref *r = &L->refArray[i];
108 if (r->st == HOLD && !hasmark(&r->o))
109 r->st = COLLECTED;
110 LUA_ASSERT((r->st == LOCK && hasmark(&r->o)) ||
111 r->st == COLLECTED ||
112 r->st == NONEXT ||
113 (r->st < n && VALIDLINK(L, L->refArray[r->st].st, n)),
114 "inconsistent ref table");
115 }
116 LUA_ASSERT(VALIDLINK(L, L->refFree, n), "inconsistent ref table");
117}
118
diff --git a/lref.h b/lref.h
deleted file mode 100644
index 4aec948d..00000000
--- a/lref.h
+++ /dev/null
@@ -1,27 +0,0 @@
1/*
2** $Id: lref.h,v 1.5 1999/12/27 17:33:22 roberto Exp roberto $
3** reference mechanism
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lref_h
8#define lref_h
9
10#include "lobject.h"
11
12
13#define NONEXT -1 /* to end the free list */
14#define HOLD -2
15#define COLLECTED -3
16#define LOCK -4
17
18
19struct Ref {
20 TObject o;
21 int st; /* can be LOCK, HOLD, COLLECTED, or next (for free list) */
22};
23
24
25void luaR_invalidaterefs (lua_State *L);
26
27#endif
diff --git a/lstate.c b/lstate.c
index a50252bc..d3d045f0 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.c,v 1.32 2000/08/09 19:16:57 roberto Exp roberto $ 2** $Id: lstate.c,v 1.33 2000/08/14 17:46:07 roberto Exp roberto $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -9,13 +9,11 @@
9 9
10#include "lua.h" 10#include "lua.h"
11 11
12#include "lauxlib.h"
13#include "lbuiltin.h" 12#include "lbuiltin.h"
14#include "ldo.h" 13#include "ldo.h"
15#include "lgc.h" 14#include "lgc.h"
16#include "llex.h" 15#include "llex.h"
17#include "lmem.h" 16#include "lmem.h"
18#include "lref.h"
19#include "lstate.h" 17#include "lstate.h"
20#include "lstring.h" 18#include "lstring.h"
21#include "ltable.h" 19#include "ltable.h"
@@ -35,8 +33,6 @@ lua_State *lua_newstate (int stacksize, int put_builtin) {
35 L->Mbuffbase = 0; 33 L->Mbuffbase = 0;
36 L->Mbuffsize = 0; 34 L->Mbuffsize = 0;
37 L->Mbuffnext = 0; 35 L->Mbuffnext = 0;
38 L->Cblocks = NULL;
39 L->numCblocks = 0;
40 L->rootproto = NULL; 36 L->rootproto = NULL;
41 L->rootcl = NULL; 37 L->rootcl = NULL;
42 L->roottable = NULL; 38 L->roottable = NULL;
@@ -84,8 +80,6 @@ void lua_close (lua_State *L) {
84 luaM_free(L, L->IMtable); 80 luaM_free(L, L->IMtable);
85 luaM_free(L, L->refArray); 81 luaM_free(L, L->refArray);
86 luaM_free(L, L->Mbuffer); 82 luaM_free(L, L->Mbuffer);
87 luaM_free(L, L->Cblocks);
88 LUA_ASSERT(L->numCblocks == 0, "Cblocks still open");
89 LUA_ASSERT(L->nblocks == 0, "wrong count for nblocks"); 83 LUA_ASSERT(L->nblocks == 0, "wrong count for nblocks");
90 luaM_free(L, L); 84 luaM_free(L, L);
91 LUA_ASSERT(L != lua_state || memdebug_numblocks == 0, "memory leak!"); 85 LUA_ASSERT(L != lua_state || memdebug_numblocks == 0, "memory leak!");
diff --git a/lstate.h b/lstate.h
index d177c3a6..65e4c6ef 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.h,v 1.35 2000/08/07 18:39:16 roberto Exp roberto $ 2** $Id: lstate.h,v 1.36 2000/08/08 20:42:07 roberto Exp roberto $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -19,27 +19,28 @@ typedef TObject *StkId; /* index to stack elements */
19 19
20 20
21/* 21/*
22** chain list of long jumps 22** marks for Reference array
23*/ 23*/
24struct lua_longjmp { 24#define NONEXT -1 /* to end the free list */
25 jmp_buf b; 25#define HOLD -2
26 struct lua_longjmp *previous; 26#define COLLECTED -3
27 volatile int status; /* error code */ 27#define LOCK -4
28 StkId base; 28
29 int numCblocks; 29
30struct Ref {
31 TObject o;
32 int st; /* can be LOCK, HOLD, COLLECTED, or next (for free list) */
30}; 33};
31 34
32 35
33/* 36/*
34** stack layout for C point of view: 37** chain list of long jumps
35** [lua2C, lua2C+num) - `array' lua2C
36** [lua2C+num, base) - space for extra lua_Objects (limbo)
37** [base, L->top) - `stack' C2Lua
38*/ 38*/
39struct C_Lua_Stack { 39struct lua_longjmp {
40 jmp_buf b;
41 struct lua_longjmp *previous;
42 volatile int status; /* error code */
40 StkId base; 43 StkId base;
41 StkId lua2C;
42 int num;
43}; 44};
44 45
45 46
@@ -57,14 +58,12 @@ struct lua_State {
57 StkId stack; /* stack base */ 58 StkId stack; /* stack base */
58 StkId stack_last; /* last free slot in the stack */ 59 StkId stack_last; /* last free slot in the stack */
59 int stacksize; 60 int stacksize;
60 struct C_Lua_Stack Cstack; /* C2lua struct */ 61 StkId Cbase; /* base for current C function */
61 struct lua_longjmp *errorJmp; /* current error recover point */ 62 struct lua_longjmp *errorJmp; /* current error recover point */
62 char *Mbuffer; /* global buffer */ 63 char *Mbuffer; /* global buffer */
63 size_t Mbuffbase; /* current first position of Mbuffer */ 64 size_t Mbuffbase; /* current first position of Mbuffer */
64 size_t Mbuffsize; /* size of Mbuffer */ 65 size_t Mbuffsize; /* size of Mbuffer */
65 size_t Mbuffnext; /* next position to fill in Mbuffer */ 66 size_t Mbuffnext; /* next position to fill in Mbuffer */
66 struct C_Lua_Stack *Cblocks;
67 int numCblocks; /* number of nested Cblocks */
68 /* global state */ 67 /* global state */
69 Proto *rootproto; /* list of all prototypes */ 68 Proto *rootproto; /* list of all prototypes */
70 Closure *rootcl; /* list of all closures */ 69 Closure *rootcl; /* list of all closures */
diff --git a/lstrlib.c b/lstrlib.c
index 16066499..c380359b 100644
--- a/lstrlib.c
+++ b/lstrlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstrlib.c,v 1.45 2000/06/12 14:37:18 roberto Exp roberto $ 2** $Id: lstrlib.c,v 1.46 2000/08/09 19:16:57 roberto Exp roberto $
3** Standard library for string operations and pattern-matching 3** Standard library for string operations and pattern-matching
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -25,10 +25,11 @@ static void addnchar (lua_State *L, const char *s, size_t n) {
25} 25}
26 26
27 27
28static void str_len (lua_State *L) { 28static int str_len (lua_State *L) {
29 size_t l; 29 size_t l;
30 luaL_check_lstr(L, 1, &l); 30 luaL_check_lstr(L, 1, &l);
31 lua_pushnumber(L, l); 31 lua_pushnumber(L, l);
32 return 1;
32} 33}
33 34
34 35
@@ -43,7 +44,7 @@ static long posrelat (long pos, size_t len) {
43} 44}
44 45
45 46
46static void str_sub (lua_State *L) { 47static int str_sub (lua_State *L) {
47 size_t l; 48 size_t l;
48 const char *s = luaL_check_lstr(L, 1, &l); 49 const char *s = luaL_check_lstr(L, 1, &l);
49 long start = posrelat(luaL_check_long(L, 2), l); 50 long start = posrelat(luaL_check_long(L, 2), l);
@@ -53,10 +54,11 @@ static void str_sub (lua_State *L) {
53 if (start <= end) 54 if (start <= end)
54 lua_pushlstring(L, s+start-1, end-start+1); 55 lua_pushlstring(L, s+start-1, end-start+1);
55 else lua_pushstring(L, ""); 56 else lua_pushstring(L, "");
57 return 1;
56} 58}
57 59
58 60
59static void str_lower (lua_State *L) { 61static int str_lower (lua_State *L) {
60 size_t l; 62 size_t l;
61 size_t i; 63 size_t i;
62 const char *s = luaL_check_lstr(L, 1, &l); 64 const char *s = luaL_check_lstr(L, 1, &l);
@@ -64,10 +66,11 @@ static void str_lower (lua_State *L) {
64 for (i=0; i<l; i++) 66 for (i=0; i<l; i++)
65 luaL_addchar(L, tolower((unsigned char)(s[i]))); 67 luaL_addchar(L, tolower((unsigned char)(s[i])));
66 closeandpush(L); 68 closeandpush(L);
69 return 1;
67} 70}
68 71
69 72
70static void str_upper (lua_State *L) { 73static int str_upper (lua_State *L) {
71 size_t l; 74 size_t l;
72 size_t i; 75 size_t i;
73 const char *s = luaL_check_lstr(L, 1, &l); 76 const char *s = luaL_check_lstr(L, 1, &l);
@@ -75,9 +78,10 @@ static void str_upper (lua_State *L) {
75 for (i=0; i<l; i++) 78 for (i=0; i<l; i++)
76 luaL_addchar(L, toupper((unsigned char)(s[i]))); 79 luaL_addchar(L, toupper((unsigned char)(s[i])));
77 closeandpush(L); 80 closeandpush(L);
81 return 1;
78} 82}
79 83
80static void str_rep (lua_State *L) { 84static int str_rep (lua_State *L) {
81 size_t l; 85 size_t l;
82 const char *s = luaL_check_lstr(L, 1, &l); 86 const char *s = luaL_check_lstr(L, 1, &l);
83 int n = luaL_check_int(L, 2); 87 int n = luaL_check_int(L, 2);
@@ -85,27 +89,31 @@ static void str_rep (lua_State *L) {
85 while (n-- > 0) 89 while (n-- > 0)
86 addnchar(L, s, l); 90 addnchar(L, s, l);
87 closeandpush(L); 91 closeandpush(L);
92 return 1;
88} 93}
89 94
90 95
91static void str_byte (lua_State *L) { 96static int str_byte (lua_State *L) {
92 size_t l; 97 size_t l;
93 const char *s = luaL_check_lstr(L, 1, &l); 98 const char *s = luaL_check_lstr(L, 1, &l);
94 long pos = posrelat(luaL_opt_long(L, 2, 1), l); 99 long pos = posrelat(luaL_opt_long(L, 2, 1), l);
95 luaL_arg_check(L, 0<pos && (size_t)pos<=l, 2, "out of range"); 100 luaL_arg_check(L, 0<pos && (size_t)pos<=l, 2, "out of range");
96 lua_pushnumber(L, (unsigned char)s[pos-1]); 101 lua_pushnumber(L, (unsigned char)s[pos-1]);
102 return 1;
97} 103}
98 104
99 105
100static void str_char (lua_State *L) { 106static int str_char (lua_State *L) {
101 int i = 0; 107 int n = lua_gettop(L); /* number of arguments */
108 int i;
102 luaL_resetbuffer(L); 109 luaL_resetbuffer(L);
103 while (lua_getparam(L, ++i) != LUA_NOOBJECT) { 110 for (i=1; i<=n; i++) {
104 int c = luaL_check_int(L, i); 111 int c = luaL_check_int(L, i);
105 luaL_arg_check(L, (unsigned char)c == c, i, "invalid value"); 112 luaL_arg_check(L, (unsigned char)c == c, i, "invalid value");
106 luaL_addchar(L, (unsigned char)c); 113 luaL_addchar(L, (unsigned char)c);
107 } 114 }
108 closeandpush(L); 115 closeandpush(L);
116 return 1;
109} 117}
110 118
111 119
@@ -135,16 +143,6 @@ struct Capture {
135#define SPECIALS "^$*+?.([%-" 143#define SPECIALS "^$*+?.([%-"
136 144
137 145
138static void push_captures (lua_State *L, struct Capture *cap) {
139 int i;
140 for (i=0; i<cap->level; i++) {
141 int l = cap->capture[i].len;
142 if (l == -1) lua_error(L, "unfinished capture");
143 lua_pushlstring(L, cap->capture[i].init, l);
144 }
145}
146
147
148static int check_capture (lua_State *L, int l, struct Capture *cap) { 146static int check_capture (lua_State *L, int l, struct Capture *cap) {
149 l -= '1'; 147 l -= '1';
150 if (!(0 <= l && l < cap->level && cap->capture[l].len != -1)) 148 if (!(0 <= l && l < cap->level && cap->capture[l].len != -1))
@@ -400,20 +398,31 @@ static const char *lmemfind (const char *s1, size_t l1,
400} 398}
401 399
402 400
403static void str_find (lua_State *L) { 401static int push_captures (lua_State *L, struct Capture *cap) {
402 int i;
403 for (i=0; i<cap->level; i++) {
404 int l = cap->capture[i].len;
405 if (l == -1) lua_error(L, "unfinished capture");
406 lua_pushlstring(L, cap->capture[i].init, l);
407 }
408 return cap->level; /* number of strings pushed */
409}
410
411
412static int str_find (lua_State *L) {
404 size_t l1, l2; 413 size_t l1, l2;
405 const char *s = luaL_check_lstr(L, 1, &l1); 414 const char *s = luaL_check_lstr(L, 1, &l1);
406 const char *p = luaL_check_lstr(L, 2, &l2); 415 const char *p = luaL_check_lstr(L, 2, &l2);
407 long init = posrelat(luaL_opt_long(L, 3, 1), l1) - 1; 416 long init = posrelat(luaL_opt_long(L, 3, 1), l1) - 1;
408 struct Capture cap; 417 struct Capture cap;
409 luaL_arg_check(L, 0 <= init && (size_t)init <= l1, 3, "out of range"); 418 luaL_arg_check(L, 0 <= init && (size_t)init <= l1, 3, "out of range");
410 if (lua_getparam(L, 4) != LUA_NOOBJECT || 419 if (lua_gettop(L) > 3 || /* extra argument? */
411 strpbrk(p, SPECIALS) == NULL) { /* no special characters? */ 420 strpbrk(p, SPECIALS) == NULL) { /* or no special characters? */
412 const char *s2 = lmemfind(s+init, l1-init, p, l2); 421 const char *s2 = lmemfind(s+init, l1-init, p, l2);
413 if (s2) { 422 if (s2) {
414 lua_pushnumber(L, s2-s+1); 423 lua_pushnumber(L, s2-s+1);
415 lua_pushnumber(L, s2-s+l2); 424 lua_pushnumber(L, s2-s+l2);
416 return; 425 return 2;
417 } 426 }
418 } 427 }
419 else { 428 else {
@@ -426,19 +435,19 @@ static void str_find (lua_State *L) {
426 if ((res=match(L, s1, p, &cap)) != NULL) { 435 if ((res=match(L, s1, p, &cap)) != NULL) {
427 lua_pushnumber(L, s1-s+1); /* start */ 436 lua_pushnumber(L, s1-s+1); /* start */
428 lua_pushnumber(L, res-s); /* end */ 437 lua_pushnumber(L, res-s); /* end */
429 push_captures(L, &cap); 438 return push_captures(L, &cap) + 2;
430 return;
431 } 439 }
432 } while (s1++<cap.src_end && !anchor); 440 } while (s1++<cap.src_end && !anchor);
433 } 441 }
434 lua_pushnil(L); /* not found */ 442 lua_pushnil(L); /* not found */
443 return 1;
435} 444}
436 445
437 446
438static void add_s (lua_State *L, lua_Object newp, struct Capture *cap) { 447static void add_s (lua_State *L, struct Capture *cap) {
439 if (lua_isstring(L, newp)) { 448 if (lua_isstring(L, 3)) {
440 const char *news = lua_getstring(L, newp); 449 const char *news = lua_tostring(L, 3);
441 size_t l = lua_strlen(L, newp); 450 size_t l = lua_strlen(L, 3);
442 size_t i; 451 size_t i;
443 for (i=0; i<l; i++) { 452 for (i=0; i<l; i++) {
444 if (news[i] != ESC) 453 if (news[i] != ESC)
@@ -455,39 +464,38 @@ static void add_s (lua_State *L, lua_Object newp, struct Capture *cap) {
455 } 464 }
456 } 465 }
457 else { /* is a function */ 466 else { /* is a function */
458 lua_Object res;
459 int status; 467 int status;
460 size_t oldbuff; 468 size_t oldbuff;
461 lua_beginblock(L); 469 int n;
462 push_captures(L, cap); 470 const char *s;
471 lua_pushobject(L, 3);
472 n = push_captures(L, cap);
463 /* function may use buffer, so save it and create a new one */ 473 /* function may use buffer, so save it and create a new one */
464 oldbuff = luaL_newbuffer(L, 0); 474 oldbuff = luaL_newbuffer(L, 0);
465 status = lua_callfunction(L, newp); 475 status = lua_call(L, n, 1);
466 /* restore old buffer */ 476 /* restore old buffer */
467 luaL_oldbuffer(L, oldbuff); 477 luaL_oldbuffer(L, oldbuff);
468 if (status != 0) { 478 if (status != 0)
469 lua_endblock(L);
470 lua_error(L, NULL); 479 lua_error(L, NULL);
471 } 480 s = lua_tostring(L, -1);
472 res = lua_getresult(L, 1); 481 if (s)
473 if (lua_isstring(L, res)) 482 addnchar(L, lua_tostring(L, -1), lua_strlen(L, -1));
474 addnchar(L, lua_getstring(L, res), lua_strlen(L, res)); 483 lua_settop(L, -1); /* pop function result */
475 lua_endblock(L);
476 } 484 }
477} 485}
478 486
479 487
480static void str_gsub (lua_State *L) { 488static int str_gsub (lua_State *L) {
481 size_t srcl; 489 size_t srcl;
482 const char *src = luaL_check_lstr(L, 1, &srcl); 490 const char *src = luaL_check_lstr(L, 1, &srcl);
483 const char *p = luaL_check_string(L, 2); 491 const char *p = luaL_check_string(L, 2);
484 lua_Object newp = lua_getparam(L, 3);
485 int max_s = luaL_opt_int(L, 4, srcl+1); 492 int max_s = luaL_opt_int(L, 4, srcl+1);
486 int anchor = (*p == '^') ? (p++, 1) : 0; 493 int anchor = (*p == '^') ? (p++, 1) : 0;
487 int n = 0; 494 int n = 0;
488 struct Capture cap; 495 struct Capture cap;
489 luaL_arg_check(L, lua_isstring(L, newp) || lua_isfunction(L, newp), 3, 496 luaL_arg_check(L,
490 "string or function expected"); 497 lua_gettop(L) >= 3 && (lua_isstring(L, 3) || lua_isfunction(L, 3)),
498 3, "string or function expected");
491 luaL_resetbuffer(L); 499 luaL_resetbuffer(L);
492 cap.src_end = src+srcl; 500 cap.src_end = src+srcl;
493 while (n < max_s) { 501 while (n < max_s) {
@@ -496,7 +504,7 @@ static void str_gsub (lua_State *L) {
496 e = match(L, src, p, &cap); 504 e = match(L, src, p, &cap);
497 if (e) { 505 if (e) {
498 n++; 506 n++;
499 add_s(L, newp, &cap); 507 add_s(L, &cap);
500 } 508 }
501 if (e && e>src) /* non empty match? */ 509 if (e && e>src) /* non empty match? */
502 src = e; /* skip it */ 510 src = e; /* skip it */
@@ -508,6 +516,7 @@ static void str_gsub (lua_State *L) {
508 addnchar(L, src, cap.src_end-src); 516 addnchar(L, src, cap.src_end-src);
509 closeandpush(L); 517 closeandpush(L);
510 lua_pushnumber(L, n); /* number of substitutions */ 518 lua_pushnumber(L, n); /* number of substitutions */
519 return 2;
511} 520}
512 521
513/* }====================================================== */ 522/* }====================================================== */
@@ -534,7 +543,7 @@ static void luaI_addquoted (lua_State *L, int arg) {
534/* maximum size of each format specification (such as '%-099.99d') */ 543/* maximum size of each format specification (such as '%-099.99d') */
535#define MAX_FORMAT 20 /* arbitrary limit */ 544#define MAX_FORMAT 20 /* arbitrary limit */
536 545
537static void str_format (lua_State *L) { 546static int str_format (lua_State *L) {
538 int arg = 1; 547 int arg = 1;
539 const char *strfrmt = luaL_check_string(L, arg); 548 const char *strfrmt = luaL_check_string(L, arg);
540 luaL_resetbuffer(L); 549 luaL_resetbuffer(L);
@@ -597,6 +606,7 @@ static void str_format (lua_State *L) {
597 } 606 }
598 } 607 }
599 closeandpush(L); /* push the result */ 608 closeandpush(L); /* push the result */
609 return 1;
600} 610}
601 611
602 612
diff --git a/ltests.c b/ltests.c
index b0f38e7c..0d83f011 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltests.c,v 1.33 2000/08/09 19:16:57 roberto Exp roberto $ 2** $Id: ltests.c,v 1.34 2000/08/15 20:14:27 roberto Exp roberto $
3** Internal Module for Debugging of the Lua Implementation 3** Internal Module for Debugging of the Lua Implementation
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -10,7 +10,6 @@
10#include <stdlib.h> 10#include <stdlib.h>
11#include <string.h> 11#include <string.h>
12 12
13#define LUA_SINGLESTATE
14 13
15#include "lua.h" 14#include "lua.h"
16 15
@@ -38,11 +37,11 @@ void luaB_opentests (lua_State *L);
38 37
39 38
40 39
41static void setnameval (lua_Object t, const char *name, int val) { 40static void setnameval (lua_State *L, const char *name, int val) {
42 lua_pushobject(t); 41 lua_pushobject(L, -1);
43 lua_pushstring(name); 42 lua_pushstring(L, name);
44 lua_pushnumber(val); 43 lua_pushnumber(L, val);
45 lua_settable(); 44 lua_settable(L);
46} 45}
47 46
48 47
@@ -65,7 +64,7 @@ static const char *const instrname[NUM_OPCODES] = {
65}; 64};
66 65
67 66
68static int pushop (Proto *p, int pc) { 67static int pushop (lua_State *L, Proto *p, int pc) {
69 char buff[100]; 68 char buff[100];
70 Instruction i = p->code[pc]; 69 Instruction i = p->code[pc];
71 OpCode o = GET_OPCODE(i); 70 OpCode o = GET_OPCODE(i);
@@ -85,146 +84,161 @@ static int pushop (Proto *p, int pc) {
85 sprintf(buff+8, "%-12s%4d %4d", name, GETARG_A(i), GETARG_B(i)); 84 sprintf(buff+8, "%-12s%4d %4d", name, GETARG_A(i), GETARG_B(i));
86 break; 85 break;
87 } 86 }
88 lua_pushstring(buff); 87 lua_pushstring(L, buff);
89 return (o != OP_END); 88 return (o != OP_END);
90} 89}
91 90
92 91
93static void listcode (void) { 92static int listcode (lua_State *L) {
94 lua_Object o = luaL_nonnullarg(1);
95 lua_Object t = lua_createtable();
96 int pc; 93 int pc;
97 Proto *p; 94 Proto *p;
98 int res; 95 int res;
99 luaL_arg_check(ttype(o) == TAG_LCLOSURE, 1, "Lua function expected"); 96 luaL_arg_check(L, lua_tag(L, 1) == TAG_LCLOSURE, 1, "Lua function expected");
100 p = clvalue(o)->f.l; 97 p = clvalue(luaA_index(L, 1))->f.l;
101 setnameval(t, "maxstack", p->maxstacksize); 98 lua_newtable(L);
102 setnameval(t, "numparams", p->numparams); 99 setnameval(L, "maxstack", p->maxstacksize);
100 setnameval(L, "numparams", p->numparams);
103 pc = 0; 101 pc = 0;
104 do { 102 do {
105 lua_pushobject(t); 103 lua_pushobject(L, -1);
106 lua_pushnumber(pc+1); 104 lua_pushnumber(L, pc+1);
107 res = pushop(p, pc++); 105 res = pushop(L, p, pc++);
108 lua_settable(); 106 lua_settable(L);
109 } while (res); 107 } while (res);
110 lua_pushobject(t); 108 return 1;
111} 109}
112 110
113 111
114static void liststrings (void) { 112static int liststrings (lua_State *L) {
115 lua_Object o = luaL_nonnullarg(1);
116 lua_Object t = lua_createtable();
117 Proto *p; 113 Proto *p;
118 int i; 114 int i;
119 luaL_arg_check(ttype(o) == TAG_LCLOSURE, 1, "Lua function expected"); 115 luaL_arg_check(L, lua_tag(L, 1) == TAG_LCLOSURE, 1, "Lua function expected");
120 p = clvalue(o)->f.l; 116 p = clvalue(luaA_index(L, 1))->f.l;
117 lua_newtable(L);
121 for (i=0; i<p->nkstr; i++) { 118 for (i=0; i<p->nkstr; i++) {
122 lua_pushobject(t); 119 lua_pushobject(L, -1);
123 lua_pushnumber(i+1); 120 lua_pushnumber(L, i+1);
124 lua_pushstring(p->kstr[i]->str); 121 lua_pushstring(L, p->kstr[i]->str);
125 lua_settable(); 122 lua_settable(L);
126 } 123 }
127 lua_pushobject(t); 124 return 1;
128} 125}
129 126
130 127
131static void listlocals (void) { 128static int listlocals (lua_State *L) {
132 lua_Object o = luaL_nonnullarg(1);
133 Proto *p; 129 Proto *p;
134 int pc = luaL_check_int(2) - 1; 130 int pc = luaL_check_int(L, 2) - 1;
135 int i = 1; 131 int i = 0;
136 const char *name; 132 const char *name;
137 luaL_arg_check(ttype(o) == TAG_LCLOSURE, 1, "Lua function expected"); 133 luaL_arg_check(L, lua_tag(L, 1) == TAG_LCLOSURE, 1, "Lua function expected");
138 p = clvalue(o)->f.l; 134 p = clvalue(luaA_index(L, 1))->f.l;
139 while ((name = luaF_getlocalname(p, i++, pc)) != NULL) 135 while ((name = luaF_getlocalname(p, ++i, pc)) != NULL)
140 lua_pushstring(name); 136 lua_pushstring(L, name);
137 return i-1;
141} 138}
142 139
143/* }====================================================== */ 140/* }====================================================== */
144 141
145 142
146 143
147static void get_limits (void) { 144static int get_limits (lua_State *L) {
148 lua_Object t = lua_createtable(); 145 lua_newtable(L);
149 setnameval(t, "BITS_INT", BITS_INT); 146 setnameval(L, "BITS_INT", BITS_INT);
150 setnameval(t, "LFPF", LFIELDS_PER_FLUSH); 147 setnameval(L, "LFPF", LFIELDS_PER_FLUSH);
151 setnameval(t, "MAXARG_A", MAXARG_A); 148 setnameval(L, "MAXARG_A", MAXARG_A);
152 setnameval(t, "MAXARG_B", MAXARG_B); 149 setnameval(L, "MAXARG_B", MAXARG_B);
153 setnameval(t, "MAXARG_S", MAXARG_S); 150 setnameval(L, "MAXARG_S", MAXARG_S);
154 setnameval(t, "MAXARG_U", MAXARG_U); 151 setnameval(L, "MAXARG_U", MAXARG_U);
155 setnameval(t, "MAXLOCALS", MAXLOCALS); 152 setnameval(L, "MAXLOCALS", MAXLOCALS);
156 setnameval(t, "MAXPARAMS", MAXPARAMS); 153 setnameval(L, "MAXPARAMS", MAXPARAMS);
157 setnameval(t, "MAXSTACK", MAXSTACK); 154 setnameval(L, "MAXSTACK", MAXSTACK);
158 setnameval(t, "MAXUPVALUES", MAXUPVALUES); 155 setnameval(L, "MAXUPVALUES", MAXUPVALUES);
159 setnameval(t, "MAXVARSLH", MAXVARSLH); 156 setnameval(L, "MAXVARSLH", MAXVARSLH);
160 setnameval(t, "RFPF", RFIELDS_PER_FLUSH); 157 setnameval(L, "RFPF", RFIELDS_PER_FLUSH);
161 setnameval(t, "SIZE_A", SIZE_A); 158 setnameval(L, "SIZE_A", SIZE_A);
162 setnameval(t, "SIZE_B", SIZE_B); 159 setnameval(L, "SIZE_B", SIZE_B);
163 setnameval(t, "SIZE_OP", SIZE_OP); 160 setnameval(L, "SIZE_OP", SIZE_OP);
164 setnameval(t, "SIZE_U", SIZE_U); 161 setnameval(L, "SIZE_U", SIZE_U);
165 lua_pushobject(t); 162 return 1;
166} 163}
167 164
168 165
169static void mem_query (void) { 166static int mem_query (lua_State *L) {
170 lua_Object arg = lua_getparam(1); 167 if (lua_isnull(L, 1)) {
171 if (arg == LUA_NOOBJECT) { 168 lua_pushnumber(L, memdebug_total);
172 lua_pushnumber(memdebug_total); 169 lua_pushnumber(L, memdebug_numblocks);
173 lua_pushnumber(memdebug_numblocks); 170 lua_pushnumber(L, memdebug_maxmem);
174 lua_pushnumber(memdebug_maxmem); 171 return 3;
172 }
173 else {
174 memdebug_memlimit = luaL_check_int(L, 1);
175 return 0;
175 } 176 }
176 else
177 memdebug_memlimit = luaL_check_int(1);
178} 177}
179 178
180 179
181static void hash_query (void) { 180static int hash_query (lua_State *L) {
182 lua_Object o = luaL_nonnullarg(1); 181 if (lua_isnull(L, 2)) {
183 if (lua_getparam(2) == LUA_NOOBJECT) { 182 luaL_arg_check(L, lua_tag(L, 1) == TAG_STRING, 1, "string expected");
184 luaL_arg_check(ttype(o) == TAG_STRING, 1, "string expected"); 183 lua_pushnumber(L, tsvalue(luaA_index(L, 1))->u.s.hash);
185 lua_pushnumber(tsvalue(o)->u.s.hash);
186 } 184 }
187 else { 185 else {
188 const Hash *t = hvalue(luaL_tablearg(2)); 186 Hash *t;
189 lua_pushnumber(luaH_mainposition(t, o) - t->node); 187 luaL_checktype(L, 2, "table");
188 t = hvalue(luaA_index(L, 2));
189 lua_pushnumber(L, luaH_mainposition(t, luaA_index(L, 1)) - t->node);
190 } 190 }
191 return 1;
191} 192}
192 193
193 194
194static void table_query (void) { 195static int table_query (lua_State *L) {
195 const Hash *t = hvalue(luaL_tablearg(1)); 196 const Hash *t;
196 int i = luaL_opt_int(2, -1); 197 int i = luaL_opt_int(L, 2, -1);
198 luaL_checktype(L, 1, "table");
199 t = hvalue(luaA_index(L, 1));
197 if (i == -1) { 200 if (i == -1) {
198 lua_pushnumber(t->size); 201 lua_pushnumber(L, t->size);
199 lua_pushnumber(t->firstfree - t->node); 202 lua_pushnumber(L, t->firstfree - t->node);
203 return 2;
200 } 204 }
201 else if (i < t->size) { 205 else if (i < t->size) {
202 luaA_pushobject(lua_state, &t->node[i].key); 206 luaA_pushobject(L, &t->node[i].key);
203 luaA_pushobject(lua_state, &t->node[i].val); 207 luaA_pushobject(L, &t->node[i].val);
204 if (t->node[i].next) 208 if (t->node[i].next) {
205 lua_pushnumber(t->node[i].next - t->node); 209 lua_pushnumber(L, t->node[i].next - t->node);
210 return 3;
211 }
212 else
213 return 2;
206 } 214 }
215 return 0;
207} 216}
208 217
209 218
210static void string_query (void) { 219static int string_query (lua_State *L) {
211 lua_State *L = lua_state; 220 stringtable *tb = (*luaL_check_string(L, 1) == 's') ? &L->strt : &L->udt;
212 stringtable *tb = (*luaL_check_string(1) == 's') ? &L->strt : &L->udt; 221 int s = luaL_opt_int(L, 2, 0) - 1;
213 int s = luaL_opt_int(2, 0) - 1;
214 if (s==-1) { 222 if (s==-1) {
215 lua_pushnumber(tb->nuse); 223 lua_pushnumber(L ,tb->nuse);
216 lua_pushnumber(tb->size); 224 lua_pushnumber(L ,tb->size);
225 return 2;
217 } 226 }
218 else if (s < tb->size) { 227 else if (s < tb->size) {
219 TString *ts; 228 TString *ts;
229 int n = 0;
220 for (ts = tb->hash[s]; ts; ts = ts->nexthash) { 230 for (ts = tb->hash[s]; ts; ts = ts->nexthash) {
221 ttype(L->top) = TAG_STRING; 231 ttype(L->top) = TAG_STRING;
222 tsvalue(L->top) = ts; 232 tsvalue(L->top) = ts;
223 incr_top; 233 incr_top;
234 n++;
224 } 235 }
236 return n;
225 } 237 }
238 return 0;
226} 239}
227 240
241
228/* 242/*
229** {====================================================== 243** {======================================================
230** function to test the API with C. It interprets a kind of "assembler" 244** function to test the API with C. It interprets a kind of "assembler"
@@ -238,21 +252,33 @@ static void skip (const char **pc) {
238 while (**pc != '\0' && strchr(delimits, **pc)) (*pc)++; 252 while (**pc != '\0' && strchr(delimits, **pc)) (*pc)++;
239} 253}
240 254
241static int getnum (const char **pc) { 255static int getnum (const char **pc, int *reg) {
242 int res = 0; 256 int res = 0;
257 int sig = 1;
258 int ref = 0;
243 skip(pc); 259 skip(pc);
260 if (**pc == 'r') {
261 ref = 1;
262 (*pc)++;
263 }
264 else if (**pc == '-') {
265 sig = -1;
266 (*pc)++;
267 }
244 while (isdigit(**pc)) res = res*10 + (*(*pc)++) - '0'; 268 while (isdigit(**pc)) res = res*10 + (*(*pc)++) - '0';
245 return res; 269 if (!ref)
270 return sig*res;
271 else
272 return reg[res];
246} 273}
247 274
248static int getreg (const char **pc) { 275static int getreg (const char **pc) {
249 skip(pc); 276 skip(pc);
250 if (*(*pc)++ != 'r') lua_error("`testC' expecting a register"); 277 (*pc)++; /* skip the `r' */
251 return getnum(pc); 278 return getnum(pc, NULL);
252} 279}
253 280
254static const char *getname (const char **pc) { 281static const char *getname (char *buff, const char **pc) {
255 static char buff[30];
256 int i = 0; 282 int i = 0;
257 skip(pc); 283 skip(pc);
258 while (**pc != '\0' && !strchr(delimits, **pc)) 284 while (**pc != '\0' && !strchr(delimits, **pc))
@@ -264,159 +290,148 @@ static const char *getname (const char **pc) {
264 290
265#define EQ(s1) (strcmp(s1, inst) == 0) 291#define EQ(s1) (strcmp(s1, inst) == 0)
266 292
293#define getnum ((getnum)(&pc, reg))
294#define getreg ((getreg)(&pc))
295#define getname ((getname)(buff, &pc))
296
267 297
268static void testC (void) { 298static int testC (lua_State *L) {
269 lua_Object reg[10]; 299 char buff[30];
270 const char *pc = luaL_check_string(1); 300 int reg[10];
301 const char *pc = luaL_check_string(L, 1);
271 for (;;) { 302 for (;;) {
272 const char *inst = getname(&pc); 303 const char *inst = getname;
273 if EQ("") return; 304 if EQ("") return 0;
305 else if EQ("return") {
306 return getnum;
307 }
308 else if EQ("retall") {
309 return lua_gettop(L) - 1;
310 }
311 else if EQ("gettop") {
312 reg[getreg] = lua_gettop(L);
313 }
314 else if EQ("settop") {
315 lua_settop(L, getnum);
316 }
317 else if EQ("setreg") {
318 int n = getreg;
319 reg[n] = lua_tonumber(L, getnum);
320 }
274 else if EQ("pushnum") { 321 else if EQ("pushnum") {
275 lua_pushnumber(getnum(&pc)); 322 lua_pushnumber(L, getnum);
276 } 323 }
277 else if EQ("createtable") { 324 else if EQ("newtable") {
278 reg[getreg(&pc)] = lua_createtable(); 325 lua_newtable(L);
279 } 326 }
280 else if EQ("closure") { 327 else if EQ("closure") {
281 lua_CFunction f = lua_getcfunction(lua_getglobal(getname(&pc))); 328 lua_CFunction f;
282 lua_pushcclosure(f, getnum(&pc)); 329 lua_getglobal(L, getname);
330 f = lua_tocfunction(L, -1);
331 lua_settop(L, -1);
332 lua_pushcclosure(L, f, getnum);
283 } 333 }
284 else if EQ("pop") { 334 else if EQ("pushobject") {
285 reg[getreg(&pc)] = lua_pop(); 335 lua_pushobject(L, getnum);
286 } 336 }
287 else if EQ("getglobal") { 337 else if EQ("getglobal") {
288 int n = getreg(&pc); 338 lua_getglobal(L, getname);
289 reg[n] = lua_getglobal(getname(&pc));
290 } 339 }
291 else if EQ("ref") { 340 else if EQ("ref") {
292 lua_pushnumber(lua_ref(0)); 341 reg[getreg] = lua_ref(L, 0);
293 reg[getreg(&pc)] = lua_pop();
294 } 342 }
295 else if EQ("reflock") { 343 else if EQ("reflock") {
296 lua_pushnumber(lua_ref(1)); 344 reg[getreg] = lua_ref(L, 1);
297 reg[getreg(&pc)] = lua_pop();
298 } 345 }
299 else if EQ("getref") { 346 else if EQ("getref") {
300 int n = getreg(&pc); 347 int n = getreg;
301 reg[n] = lua_getref((int)lua_getnumber(reg[getreg(&pc)])); 348 reg[n] = lua_getref(L, getnum);
302 } 349 }
303 else if EQ("unref") { 350 else if EQ("unref") {
304 lua_unref((int)lua_getnumber(reg[getreg(&pc)])); 351 lua_unref(L, getnum);
305 }
306 else if EQ("getparam") {
307 int n = getreg(&pc);
308 reg[n] = lua_getparam(getnum(&pc)+1); /* skips the command itself */
309 }
310 else if EQ("getresult") {
311 int n = getreg(&pc);
312 reg[n] = lua_getparam(getnum(&pc));
313 } 352 }
314 else if EQ("setglobal") { 353 else if EQ("setglobal") {
315 lua_setglobal(getname(&pc)); 354 lua_setglobal(L, getname);
316 }
317 else if EQ("pushglobals") {
318 lua_pushglobals();
319 } 355 }
320 else if EQ("pushstring") { 356 else if EQ("pushstring") {
321 lua_pushstring(getname(&pc)); 357 lua_pushstring(L, getname);
322 }
323 else if EQ("pushreg") {
324 lua_pushobject(reg[getreg(&pc)]);
325 } 358 }
326 else if EQ("call") { 359 else if EQ("call") {
327 if (lua_call(getname(&pc))) lua_error(NULL); 360 int narg = getnum;
361 int nres = getnum;
362 if (lua_call(L, narg, nres)) lua_error(L, NULL);
328 } 363 }
329 else if EQ("gettable") { 364 else if EQ("gettable") {
330 reg[getreg(&pc)] = lua_gettable(); 365 lua_gettable(L);
331 } 366 }
332 else if EQ("rawget") { 367 else if EQ("rawget") {
333 reg[getreg(&pc)] = lua_rawget(); 368 lua_rawget(L);
334 } 369 }
335 else if EQ("settable") { 370 else if EQ("settable") {
336 lua_settable(); 371 lua_settable(L);
337 } 372 }
338 else if EQ("rawset") { 373 else if EQ("rawset") {
339 lua_rawset(); 374 lua_rawset(L);
340 } 375 }
341 else if EQ("tag") { 376 else if EQ("tag") {
342 lua_pushnumber(lua_tag(reg[getreg(&pc)])); 377 int n = getreg;
378 reg[n] = lua_tag(L, getnum);
343 } 379 }
344 else if EQ("type") { 380 else if EQ("type") {
345 lua_pushstring(lua_type(reg[getreg(&pc)])); 381 lua_pushstring(L, lua_type(L, getnum));
346 }
347 else if EQ("next") {
348 int n = getreg(&pc);
349 n = lua_next(reg[n], (int)lua_getnumber(reg[getreg(&pc)]));
350 lua_pushnumber(n);
351 } 382 }
352 else if EQ("equal") { 383 else if EQ("equal") {
353 int n1 = getreg(&pc); 384 int n1 = getreg;
354 int n2 = getreg(&pc); 385 int n2 = getnum;
355 lua_pushnumber(lua_equal(reg[n1], reg[n2])); 386 int n3 = getnum;
387 reg[n1] = lua_equal(L, n2, n3);
356 } 388 }
357 else if EQ("pushusertag") { 389 else if EQ("pushusertag") {
358 int val = getreg(&pc); 390 int val = getnum;
359 int tag = getreg(&pc); 391 int tag = getnum;
360 lua_pushusertag((void *)(int)lua_getnumber(reg[val]), 392 lua_pushusertag(L, (void *)val, tag);
361 (int)lua_getnumber(reg[tag]));
362 } 393 }
363 else if EQ("udataval") { 394 else if EQ("udataval") {
364 int n = getreg(&pc); 395 int n = getreg;
365 lua_pushnumber((int)lua_getuserdata(reg[getreg(&pc)])); 396 reg[n] = (int)lua_touserdata(L, getnum);
366 reg[n] = lua_pop();
367 } 397 }
368 else if EQ("settagmethod") { 398 else if EQ("settagmethod") {
369 int n = getreg(&pc); 399 int n = getnum;
370 lua_settagmethod((int)lua_getnumber(reg[n]), getname(&pc)); 400 lua_settagmethod(L, n, getname);
371 }
372 else if EQ("beginblock") {
373 lua_beginblock();
374 }
375 else if EQ("endblock") {
376 lua_endblock();
377 } 401 }
378 else if EQ("newstate") { 402 else if EQ("newstate") {
379 int stacksize = getnum(&pc); 403 int stacksize = getnum;
380 lua_State *L1 = lua_newstate(stacksize, getnum(&pc)); 404 lua_State *L1 = lua_newstate(stacksize, getnum);
381 if (L1) 405 if (L1)
382 lua_pushuserdata(L1); 406 lua_pushuserdata(L, L1);
383 else 407 else
384 lua_pushnil(); 408 lua_pushnil(L);
385 } 409 }
386 else if EQ("closestate") { 410 else if EQ("closestate") {
387 (lua_close)((lua_State *)lua_getuserdata(reg[getreg(&pc)])); 411 (lua_close)((lua_State *)lua_touserdata(L, getnum));
388 } 412 }
389 else if EQ("doremote") { 413 else if EQ("doremote") {
390 lua_Object ol1 = reg[getreg(&pc)]; 414 int ol1 = getnum;
391 lua_Object str = reg[getreg(&pc)]; 415 int str = getnum;
392 lua_State *L1; 416 lua_State *L1;
393 lua_Object temp;
394 int status; 417 int status;
395 if (!lua_isuserdata(ol1) || !lua_isstring(str)) 418 if (!lua_isuserdata(L, ol1) || !lua_isstring(L, str))
396 lua_error("bad arguments for `doremote'"); 419 lua_error(L, "bad arguments for `doremote'");
397 L1 = (lua_State *)lua_getuserdata(ol1); 420 L1 = (lua_State *)lua_touserdata(L, ol1);
398 status = (lua_dostring)(L1, lua_getstring(str)); 421 status = lua_dostring(L1, lua_tostring(L, str));
399 if (status != 0) { 422 if (status != 0) {
400 lua_pushnil(); 423 lua_pushnil(L);
401 lua_pushnumber(status); 424 lua_pushnumber(L, status);
402 } 425 }
403 else { 426 else {
404 int i = 1; 427 int i = 0;
405 while ((temp = (lua_getresult)(L1, i++)) != LUA_NOOBJECT) 428 while (!lua_isnull(L, ++i))
406 lua_pushstring((lua_getstring)(L1, temp)); 429 lua_pushstring(L, lua_tostring(L1, i));
407 } 430 }
408 } 431 }
409#if LUA_DEPRECATETFUNCS 432 else luaL_verror(L, "unknown instruction %.30s", buff);
410 else if EQ("rawsetglobal") {
411 lua_rawsetglobal(getname(&pc));
412 }
413 else if EQ("rawgetglobal") {
414 int n = getreg(&pc);
415 reg[n] = lua_rawgetglobal(getname(&pc));
416 }
417#endif
418 else luaL_verror(lua_state, "unknown command in `testC': %.20s", inst);
419 } 433 }
434 return 0;
420} 435}
421 436
422/* }====================================================== */ 437/* }====================================================== */
@@ -424,22 +439,20 @@ static void testC (void) {
424 439
425 440
426static const struct luaL_reg tests_funcs[] = { 441static const struct luaL_reg tests_funcs[] = {
427 {"hash", (lua_CFunction)hash_query}, 442 {"hash", hash_query},
428 {"limits", (lua_CFunction)get_limits}, 443 {"limits", get_limits},
429 {"listcode", (lua_CFunction)listcode}, 444 {"listcode", listcode},
430 {"liststrings", (lua_CFunction)liststrings}, 445 {"liststrings", liststrings},
431 {"listlocals", (lua_CFunction)listlocals}, 446 {"listlocals", listlocals},
432 {"querystr", (lua_CFunction)string_query}, 447 {"querystr", string_query},
433 {"querytab", (lua_CFunction)table_query}, 448 {"querytab", table_query},
434 {"testC", (lua_CFunction)testC}, 449 {"testC", testC},
435 {"totalmem", (lua_CFunction)mem_query} 450 {"totalmem", mem_query}
436}; 451};
437 452
438 453
439void luaB_opentests (lua_State *L) { 454void luaB_opentests (lua_State *L) {
440 if (lua_state != NULL) return; /* do not open tests for auxiliar states */ 455 luaL_openl(L, tests_funcs);
441 lua_state = L;
442 luaL_openl(tests_funcs);
443} 456}
444 457
445#endif 458#endif
diff --git a/lua.c b/lua.c
index b3b8e6ea..3a50ceb2 100644
--- a/lua.c
+++ b/lua.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lua.c,v 1.44 2000/08/09 19:16:57 roberto Exp roberto $ 2** $Id: lua.c,v 1.45 2000/08/14 17:45:59 roberto Exp roberto $
3** Lua stand-alone interpreter 3** Lua stand-alone interpreter
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -10,14 +10,14 @@
10#include <stdlib.h> 10#include <stdlib.h>
11#include <string.h> 11#include <string.h>
12 12
13#define LUA_SINGLESTATE
14
15#include "lua.h" 13#include "lua.h"
16 14
17#include "luadebug.h" 15#include "luadebug.h"
18#include "lualib.h" 16#include "lualib.h"
19 17
18
20lua_State *lua_state = NULL; 19lua_State *lua_state = NULL;
20#define L lua_state
21 21
22 22
23#ifndef PROMPT 23#ifndef PROMPT
@@ -54,10 +54,10 @@ extern void USERINIT (void);
54#else 54#else
55#define USERINIT userinit 55#define USERINIT userinit
56static void userinit (void) { 56static void userinit (void) {
57 lua_iolibopen(); 57 lua_iolibopen(L);
58 lua_strlibopen(); 58 lua_strlibopen(L);
59 lua_mathlibopen(); 59 lua_mathlibopen(L);
60 lua_dblibopen(); 60 lua_dblibopen(L);
61} 61}
62#endif 62#endif
63 63
@@ -68,10 +68,10 @@ static handler lreset (void) {
68 68
69 69
70static void lstop (void) { 70static void lstop (void) {
71 lua_setlinehook(lua_state, old_linehook); 71 lua_setlinehook(L, old_linehook);
72 lua_setcallhook(lua_state, old_callhook); 72 lua_setcallhook(L, old_callhook);
73 lreset(); 73 lreset();
74 lua_error("interrupted!"); 74 lua_error(L, "interrupted!");
75} 75}
76 76
77 77
@@ -79,15 +79,15 @@ static void laction (int i) {
79 (void)i; /* to avoid warnings */ 79 (void)i; /* to avoid warnings */
80 signal(SIGINT, SIG_DFL); /* if another SIGINT happens before lstop, 80 signal(SIGINT, SIG_DFL); /* if another SIGINT happens before lstop,
81 terminate process (default action) */ 81 terminate process (default action) */
82 old_linehook = lua_setlinehook(lua_state, (lua_Hook)lstop); 82 old_linehook = lua_setlinehook(L, (lua_Hook)lstop);
83 old_callhook = lua_setcallhook(lua_state, (lua_Hook)lstop); 83 old_callhook = lua_setcallhook(L, (lua_Hook)lstop);
84} 84}
85 85
86 86
87static int ldo (int (*f)(lua_State *L, const char *), const char *name) { 87static int ldo (int (*f)(lua_State *l, const char *), const char *name) {
88 int res; 88 int res;
89 handler h = lreset(); 89 handler h = lreset();
90 res = f(lua_state, name); /* dostring | dofile */ 90 res = f(L, name); /* dostring | dofile */
91 signal(SIGINT, h); /* restore old action */ 91 signal(SIGINT, h); /* restore old action */
92 if (res == LUA_ERRMEM) { 92 if (res == LUA_ERRMEM) {
93 /* Lua gives no message in such case, so lua.c provides one */ 93 /* Lua gives no message in such case, so lua.c provides one */
@@ -122,29 +122,29 @@ static void print_version (void) {
122static void assign (char *arg) { 122static void assign (char *arg) {
123 char *eq = strchr(arg, '='); 123 char *eq = strchr(arg, '=');
124 *eq = '\0'; /* spilt `arg' in two strings (name & value) */ 124 *eq = '\0'; /* spilt `arg' in two strings (name & value) */
125 lua_pushstring(eq+1); 125 lua_pushstring(L, eq+1);
126 lua_setglobal(arg); 126 lua_setglobal(L, arg);
127} 127}
128 128
129 129
130static lua_Object getargs (char *argv[]) { 130static void getargs (char *argv[]) {
131 lua_Object args = lua_createtable();
132 int i; 131 int i;
132 lua_newtable(L);
133 for (i=0; argv[i]; i++) { 133 for (i=0; argv[i]; i++) {
134 /* arg[i] = argv[i] */ 134 /* arg[i] = argv[i] */
135 lua_pushobject(args); lua_pushnumber(i); 135 lua_pushobject(L, -1); lua_pushnumber(L, i);
136 lua_pushstring(argv[i]); lua_settable(); 136 lua_pushstring(L, argv[i]); lua_settable(L);
137 } 137 }
138 /* arg.n = maximum index in table `arg' */ 138 /* arg.n = maximum index in table `arg' */
139 lua_pushobject(args); lua_pushstring("n"); 139 lua_pushobject(L, -1); lua_pushstring(L, "n");
140 lua_pushnumber(i-1); lua_settable(); 140 lua_pushnumber(L, i-1); lua_settable(L);
141 return args;
142} 141}
143 142
144 143
145static void l_getargs (void) { 144static int l_getargs (lua_State *l) {
146 char **argv = (char **)lua_getuserdata(lua_getparam(1)); 145 char **argv = (char **)lua_touserdata(l, 1);
147 lua_pushobject(getargs(argv)); 146 getargs(argv);
147 return 1;
148} 148}
149 149
150 150
@@ -173,9 +173,11 @@ static void manual_input (int version, int prompt) {
173 while (cont) { 173 while (cont) {
174 char buffer[MAXINPUT]; 174 char buffer[MAXINPUT];
175 int i = 0; 175 int i = 0;
176 lua_beginblock();
177 if (prompt) { 176 if (prompt) {
178 const char *s = lua_getstring(lua_getglobal("_PROMPT")); 177 const char *s;
178 lua_getglobal(L, "_PROMPT");
179 s = lua_tostring(L, -1);
180 lua_settop(L, -1); /* remove global */
179 if (!s) s = PROMPT; 181 if (!s) s = PROMPT;
180 fputs(s, stdout); 182 fputs(s, stdout);
181 } 183 }
@@ -198,7 +200,7 @@ static void manual_input (int version, int prompt) {
198 } 200 }
199 buffer[i] = '\0'; 201 buffer[i] = '\0';
200 ldo(lua_dostring, buffer); 202 ldo(lua_dostring, buffer);
201 lua_endblock(); 203 lua_settop(L, 0); /* remove eventual results */
202 } 204 }
203 printf("\n"); 205 printf("\n");
204} 206}
@@ -262,8 +264,8 @@ static int handle_argv (char *argv[], struct Options *opt) {
262 print_message(); 264 print_message();
263 return EXIT_FAILURE; 265 return EXIT_FAILURE;
264 } 266 }
265 lua_pushobject(getargs(argv+i)); /* collect remaining arguments */ 267 getargs(argv+i); /* collect remaining arguments */
266 lua_setglobal("arg"); 268 lua_setglobal(L, "arg");
267 return file_input(argv[i]); /* stop scanning arguments */ 269 return file_input(argv[i]); /* stop scanning arguments */
268 } 270 }
269 case 's': { 271 case 's': {
@@ -296,9 +298,9 @@ static void getstacksize (int argc, char *argv[], struct Options *opt) {
296 298
297 299
298static void register_getargs (char *argv[]) { 300static void register_getargs (char *argv[]) {
299 lua_pushuserdata(argv); 301 lua_pushuserdata(L, argv);
300 lua_pushcclosure(l_getargs, 1); 302 lua_pushcclosure(L, l_getargs, 1);
301 lua_setglobal("getargs"); 303 lua_setglobal(L, "getargs");
302} 304}
303 305
304 306
@@ -307,12 +309,12 @@ int main (int argc, char *argv[]) {
307 int status; 309 int status;
308 opt.toclose = 0; 310 opt.toclose = 0;
309 getstacksize(argc, argv, &opt); /* handle option `-s' */ 311 getstacksize(argc, argv, &opt); /* handle option `-s' */
310 lua_state = lua_newstate(opt.stacksize, 1); /* create state */ 312 L = lua_newstate(opt.stacksize, 1); /* create state */
311 USERINIT(); /* open libraries */ 313 USERINIT(); /* open libraries */
312 register_getargs(argv); /* create `getargs' function */ 314 register_getargs(argv); /* create `getargs' function */
313 status = handle_argv(argv+1, &opt); 315 status = handle_argv(argv+1, &opt);
314 if (opt.toclose) 316 if (opt.toclose)
315 lua_close(); 317 lua_close(L);
316 return status; 318 return status;
317} 319}
318 320
diff --git a/lua.h b/lua.h
index 96f3597a..43459a4d 100644
--- a/lua.h
+++ b/lua.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lua.h,v 1.58 2000/08/14 19:10:14 roberto Exp roberto $ 2** $Id: lua.h,v 1.59 2000/08/17 13:18:01 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
@@ -30,8 +30,10 @@
30 30
31#define LUA_ANYTAG (-1) 31#define LUA_ANYTAG (-1)
32 32
33#define LUA_MULTRET (-1)
33 34
34/* error code for lua_do* */ 35
36/* error codes for lua_do* */
35#define LUA_ERRFILE 2 37#define LUA_ERRFILE 2
36#define LUA_ERRSYNTAX 3 38#define LUA_ERRSYNTAX 3
37#define LUA_ERRRUN 1 39#define LUA_ERRRUN 1
@@ -40,95 +42,103 @@
40 42
41typedef struct lua_State lua_State; 43typedef struct lua_State lua_State;
42 44
43typedef void (*lua_CFunction) (lua_State *L); 45typedef int (*lua_CFunction) (lua_State *L);
44
45typedef struct lua_TObject *lua_Object;
46
47#define LUA_NOOBJECT ((lua_Object)0)
48 46
49 47
48/*
49** state manipulation
50*/
50lua_State *lua_newstate (int stacksize, int builtin); 51lua_State *lua_newstate (int stacksize, int builtin);
51void lua_close (lua_State *L); 52void lua_close (lua_State *L);
52 53
53lua_Object lua_settagmethod (lua_State *L, int tag, const char *event);
54 /* In: new method */
55lua_Object lua_gettagmethod (lua_State *L, int tag, const char *event);
56 54
57int lua_newtag (lua_State *L); 55/*
58int lua_copytagmethods (lua_State *L, int tagto, int tagfrom); 56** basic stack manipulation
59void lua_settag (lua_State *L, int tag); /* In: object */ 57*/
60 58int lua_gettop (lua_State *L);
61void lua_error (lua_State *L, const char *s); 59void lua_settop (lua_State *L, int index);
62int lua_dofile (lua_State *L, const char *filename); 60void lua_pushobject (lua_State *L, int index);
63 /* Out: returns */
64int lua_dostring (lua_State *L, const char *str);
65 /* Out: returns */
66int lua_dobuffer (lua_State *L, const char *buff, size_t size,
67 const char *name); /* Out: returns */
68int lua_callfunction (lua_State *L, lua_Object f);
69 /* In: arguments; Out: returns */
70
71void lua_beginblock (lua_State *L);
72void lua_endblock (lua_State *L);
73
74void lua_pushglobals (lua_State *L);
75void lua_setglobals (lua_State *L, lua_Object newtable);
76 61
77lua_Object lua_lua2C (lua_State *L, int number);
78#define lua_getparam lua_lua2C
79#define lua_getresult lua_lua2C
80 62
81const char *lua_type (lua_State *L, lua_Object obj); 63/*
64** access functions (stack -> C)
65*/
82 66
83int lua_isnil (lua_State *L, lua_Object obj); 67const char *lua_type (lua_State *L, int index);
84int lua_istable (lua_State *L, lua_Object obj); 68int lua_isnumber (lua_State *L, int index);
85int lua_isuserdata (lua_State *L, lua_Object obj); 69int lua_iscfunction (lua_State *L, int index);
86int lua_iscfunction (lua_State *L, lua_Object obj); 70int lua_tag (lua_State *L, int index);
87int lua_isnumber (lua_State *L, lua_Object obj);
88int lua_isstring (lua_State *L, lua_Object obj);
89int lua_isfunction (lua_State *L, lua_Object obj);
90 71
91int lua_equal (lua_State *L, lua_Object o1, lua_Object o2); 72int lua_equal (lua_State *L, int index1, int index2);
92 73
93double lua_getnumber (lua_State *L, lua_Object obj); 74double lua_tonumber (lua_State *L, int index);
94const char *lua_getstring (lua_State *L, lua_Object obj); 75const char *lua_tostring (lua_State *L, int index);
95size_t lua_strlen (lua_State *L, lua_Object obj); 76size_t lua_strlen (lua_State *L, int index);
96lua_CFunction lua_getcfunction (lua_State *L, lua_Object obj); 77lua_CFunction lua_tocfunction (lua_State *L, int index);
97void *lua_getuserdata (lua_State *L, lua_Object obj); 78void *lua_touserdata (lua_State *L, int index);
98 79
99 80
100void lua_pushnil (lua_State *L); 81/*
82** push functions (C -> stack)
83*/
84void lua_pushnil (lua_State *L);
101void lua_pushnumber (lua_State *L, double n); 85void lua_pushnumber (lua_State *L, double n);
102void lua_pushlstring (lua_State *L, const char *s, size_t len); 86void lua_pushlstring (lua_State *L, const char *s, size_t len);
103void lua_pushstring (lua_State *L, const char *s); 87void lua_pushstring (lua_State *L, const char *s);
104void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n); 88void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
105void lua_pushusertag (lua_State *L, void *u, int tag); 89void lua_pushusertag (lua_State *L, void *u, int tag);
106void lua_pushobject (lua_State *L, lua_Object obj);
107 90
108lua_Object lua_pop (lua_State *L);
109 91
110lua_Object lua_getglobal (lua_State *L, const char *name); 92/*
111void lua_setglobal (lua_State *L, const char *name); /* In: value */ 93** get functions (Lua -> stack)
94*/
95void lua_getglobal (lua_State *L, const char *name);
96void lua_gettable (lua_State *L);
97void lua_rawget (lua_State *L);
98void lua_getglobals (lua_State *L);
99void lua_gettagmethod (lua_State *L, int tag, const char *event);
112 100
113void lua_settable (lua_State *L); /* In: table, index, value */ 101int lua_getref (lua_State *L, int ref);
114lua_Object lua_gettable (lua_State *L); /* In: table, index */
115 102
116void lua_rawset (lua_State *L); /* In: table, index, value */ 103void lua_newtable (lua_State *L);
117lua_Object lua_rawget (lua_State *L); /* In: table, index */
118 104
119int lua_tag (lua_State *L, lua_Object obj);
120 105
121int lua_next (lua_State *L, lua_Object o, int i); 106/*
122 /* Out: index, value */ 107** set functions (stack -> Lua)
108*/
109void lua_setglobal (lua_State *L, const char *name);
110void lua_settable (lua_State *L);
111void lua_rawset (lua_State *L);
112void lua_setglobals (lua_State *L);
113void lua_settagmethod (lua_State *L, int tag, const char *event);
114int lua_ref (lua_State *L, int lock);
123 115
124int lua_ref (lua_State *L, int lock); /* In: value */
125int lua_pushref (lua_State *L, int ref); /* Out: value */
126void lua_unref (lua_State *L, int ref);
127 116
128lua_Object lua_createtable (lua_State *L); 117/*
118** "do" functions (run Lua code)
119*/
120int lua_call (lua_State *L, int nargs, int nresults);
121int lua_dofile (lua_State *L, const char *filename);
122int lua_dostring (lua_State *L, const char *str);
123int lua_dobuffer (lua_State *L, const char *buff, size_t size,
124 const char *name);
125
126
127/*
128** miscelaneous functions
129*/
130int lua_newtag (lua_State *L);
131int lua_copytagmethods (lua_State *L, int tagto, int tagfrom);
132void lua_settag (lua_State *L, int tag);
133
134void lua_error (lua_State *L, const char *s);
135
136void lua_unref (lua_State *L, int ref);
129 137
130long lua_collectgarbage (lua_State *L, long limit); 138long lua_collectgarbage (lua_State *L, long limit);
131 139
140int lua_next (lua_State *L, int index, int i);
141
132 142
133 143
134/* 144/*
@@ -137,122 +147,17 @@ long lua_collectgarbage (lua_State *L, long limit);
137** =============================================================== 147** ===============================================================
138*/ 148*/
139 149
140#ifndef LUA_SINGLESTATE
141
142#define lua_call(L,name) lua_callfunction(L, lua_getglobal(L, name))
143#define lua_getref(L, ref) (lua_pushref(L, ref) ? lua_pop(L) : LUA_NOOBJECT)
144#define lua_refobject(L,o,l) (lua_pushobject(L, o), lua_ref(L, l))
145#define lua_register(L,n,f) (lua_pushcfunction(L, f), lua_setglobal(L, n)) 150#define lua_register(L,n,f) (lua_pushcfunction(L, f), lua_setglobal(L, n))
146#define lua_pushuserdata(L,u) lua_pushusertag(L, u, 0) 151#define lua_pushuserdata(L,u) lua_pushusertag(L, u, 0)
147#define lua_pushcfunction(L,f) lua_pushcclosure(L, f, 0) 152#define lua_pushcfunction(L,f) lua_pushcclosure(L, f, 0)
148#define lua_clonetag(L,t) lua_copytagmethods(L, lua_newtag(L), (t)) 153#define lua_clonetag(L,t) lua_copytagmethods(L, lua_newtag(L), (t))
149 154
150#else 155#define lua_isfunction(L,n) (*lua_type(L,n) == 'f')
151 156#define lua_isstring(L,n) (lua_tostring(L,n))
152#define lua_call(name) lua_callfunction(lua_getglobal(name)) 157#define lua_istable(L,n) (*lua_type(L,n) == 't')
153#define lua_getref(ref) (lua_pushref(ref) ? lua_pop() : LUA_NOOBJECT) 158#define lua_isuserdata(L,n) (*lua_type(L,n) == 'u')
154#define lua_refobject(o,l) (lua_pushobject(o), lua_ref(l)) 159#define lua_isnil(L,n) (lua_type(L,n)[2] == 'l')
155#define lua_register(n,f) (lua_pushcfunction(f), lua_setglobal(n)) 160#define lua_isnull(L,n) (*lua_type(L,n) == 'N')
156#define lua_pushuserdata(u) lua_pushusertag(u, 0)
157#define lua_pushcfunction(f) lua_pushcclosure(f, 0)
158#define lua_clonetag(t) lua_copytagmethods(lua_newtag(), (t))
159
160#endif
161
162
163
164#ifdef LUA_SINGLESTATE
165/*
166** {==============================================================
167** Macros for single-state use
168** ===============================================================
169*/
170
171extern lua_State *lua_state;
172
173#define lua_open() ((void)(lua_state?0:(lua_state=lua_newstate(0, 1))))
174
175#define lua_close() (lua_close)(lua_state)
176#define lua_settagmethod(tag,event) (lua_settagmethod)(lua_state, tag,event)
177#define lua_gettagmethod(tag,event) (lua_gettagmethod)(lua_state, tag,event)
178#define lua_newtag() (lua_newtag)(lua_state)
179#define lua_copytagmethods(tagto,tagfrom) \
180 (lua_copytagmethods)(lua_state, tagto,tagfrom)
181#define lua_settag(tag) (lua_settag)(lua_state, tag)
182#define lua_error(s) (lua_error)(lua_state, s)
183#define lua_dofile(filename) (lua_dofile)(lua_state, filename)
184#define lua_dostring(str) (lua_dostring)(lua_state, str)
185#define lua_dobuffer(b,s,n) (lua_dobuffer)(lua_state, b,s,n)
186#define lua_callfunction(f) (lua_callfunction)(lua_state, f)
187#define lua_beginblock() (lua_beginblock)(lua_state)
188#define lua_endblock() (lua_endblock)(lua_state)
189#define lua_pushglobals() (lua_pushglobals)(lua_state)
190#define lua_setglobals(t) (lua_setglobals)(lua_state, t)
191#define lua_lua2C(number) (lua_lua2C)(lua_state, number)
192#define lua_type(obj) (lua_type)(lua_state, obj)
193#define lua_isnil(obj) (lua_isnil)(lua_state, obj)
194#define lua_istable(obj) (lua_istable)(lua_state, obj)
195#define lua_isuserdata(obj) (lua_isuserdata)(lua_state, obj)
196#define lua_iscfunction(obj) (lua_iscfunction)(lua_state, obj)
197#define lua_isnumber(obj) (lua_isnumber)(lua_state, obj)
198#define lua_isstring(obj) (lua_isstring)(lua_state, obj)
199#define lua_isfunction(obj) (lua_isfunction)(lua_state, obj)
200#define lua_equal(o1,o2) (lua_equal)(lua_state, o1,o2)
201#define lua_getnumber(obj) (lua_getnumber)(lua_state, obj)
202#define lua_getstring(obj) (lua_getstring)(lua_state, obj)
203#define lua_strlen(obj) (lua_strlen)(lua_state, obj)
204#define lua_getcfunction(obj) (lua_getcfunction)(lua_state, obj)
205#define lua_getuserdata(obj) (lua_getuserdata)(lua_state, obj)
206#define lua_pushnil() (lua_pushnil)(lua_state)
207#define lua_pushnumber(n) (lua_pushnumber)(lua_state, n)
208#define lua_pushlstring(s,len) (lua_pushlstring)(lua_state, s,len)
209#define lua_pushstring(s) (lua_pushstring)(lua_state, s)
210#define lua_pushusertag(u,tag) (lua_pushusertag)(lua_state, u,tag)
211#define lua_pushobject(obj) (lua_pushobject)(lua_state, obj)
212#define lua_pop() (lua_pop)(lua_state)
213#define lua_getglobal(name) (lua_getglobal)(lua_state, name)
214#define lua_setglobal(name) (lua_setglobal)(lua_state, name)
215#define lua_settable() (lua_settable)(lua_state)
216#define lua_gettable() (lua_gettable)(lua_state)
217#define lua_rawset() (lua_rawset)(lua_state)
218#define lua_rawget() (lua_rawget)(lua_state)
219#define lua_tag(obj) (lua_tag)(lua_state, obj)
220#define lua_next(o,i) (lua_next)(lua_state, o,i)
221#define lua_ref(lock) (lua_ref)(lua_state, lock)
222#define lua_pushref(ref) (lua_pushref)(lua_state, ref)
223#define lua_unref(ref) (lua_unref)(lua_state, ref)
224#define lua_createtable() (lua_createtable)(lua_state)
225#define lua_collectgarbage(limit) (lua_collectgarbage)(lua_state, limit)
226/*
227** the following typecast is a little dirty, but we know of no other
228** way to keep compatibility with old definition of `lua_CFunction'
229*/
230#define lua_pushcclosure(fn,n) \
231 (lua_pushcclosure)(lua_state, (lua_CFunction)(fn), n)
232
233
234/*
235** }==============================================================
236*/
237#endif
238
239/*
240** compatibility with 3.2
241** these functions are only available when Lua is compiled with
242** the option LUA_DEPRECATETFUNCS
243*/
244
245#define lua_rawsettable lua_rawset
246#define lua_rawgettable lua_rawget
247
248lua_Object lua_rawgetglobal (lua_State *L, const char *name);
249void lua_rawsetglobal (lua_State *L, const char *name);/* In: value */
250
251#ifdef LUA_SINGLESTATE
252#define lua_rawgetglobal(name) (lua_rawgetglobal(lua_state, name))
253#define lua_rawsetglobal(name) (lua_rawsetglobal(lua_state, name))
254#endif
255
256 161
257#endif 162#endif
258 163
diff --git a/luadebug.h b/luadebug.h
index 6944cc17..67472ad9 100644
--- a/luadebug.h
+++ b/luadebug.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: luadebug.h,v 1.11 2000/08/08 20:42:07 roberto Exp roberto $ 2** $Id: luadebug.h,v 1.12 2000/08/11 16:17:28 roberto Exp roberto $
3** Debugging API 3** Debugging API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -19,8 +19,8 @@ typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
19 19
20int lua_getstack (lua_State *L, int level, lua_Debug *ar); 20int lua_getstack (lua_State *L, int level, lua_Debug *ar);
21int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar); 21int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
22int lua_getlocal (lua_State *L, const lua_Debug *ar, lua_Localvar *v); 22const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int localnum);
23int lua_setlocal (lua_State *L, const lua_Debug *ar, lua_Localvar *v); 23const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int localnum);
24 24
25lua_Hook lua_setcallhook (lua_State *L, lua_Hook func); 25lua_Hook lua_setcallhook (lua_State *L, lua_Hook func);
26lua_Hook lua_setlinehook (lua_State *L, lua_Hook func); 26lua_Hook lua_setlinehook (lua_State *L, lua_Hook func);
@@ -36,16 +36,8 @@ struct lua_Debug {
36 const char *name; /* (n) */ 36 const char *name; /* (n) */
37 const char *namewhat; /* (n) `global', `tag method', `local', `field' */ 37 const char *namewhat; /* (n) `global', `tag method', `local', `field' */
38 int nups; /* (u) number of upvalues */ 38 int nups; /* (u) number of upvalues */
39 lua_Object func; /* (f) function being executed */
40 /* private part */ 39 /* private part */
41 lua_Object _func; /* active function */ 40 struct lua_TObject *_func; /* active function */
42};
43
44
45struct lua_Localvar {
46 int index;
47 const char *name;
48 lua_Object value;
49}; 41};
50 42
51 43
diff --git a/lundump.c b/lundump.c
index 386bebc9..2e3478ad 100644
--- a/lundump.c
+++ b/lundump.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lundump.c,v 1.24 2000/08/09 19:16:57 roberto Exp roberto $ 2** $Id: lundump.c,v 1.25 2000/08/24 14:19:39 roberto Exp roberto $
3** load bytecodes from files 3** load bytecodes from files
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -130,7 +130,7 @@ static void LoadCode (lua_State* L, Proto* tf, ZIO* Z)
130} 130}
131 131
132static void LoadLocals (lua_State* L, Proto* tf, ZIO* Z) 132static void LoadLocals (lua_State* L, Proto* tf, ZIO* Z)
133{ 133{
134} 134}
135 135
136static Proto* LoadFunction (lua_State* L, ZIO* Z, int native); 136static Proto* LoadFunction (lua_State* L, ZIO* Z, int native);