diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-08-28 14:57:04 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-08-28 14:57:04 -0300 |
commit | 9fdf73bc9a6b4c6afbfff1d8181fface6b1c6761 (patch) | |
tree | da8d97d954e5ffabf9ff275df725f1e0a3a5b3e6 /lbuiltin.c | |
parent | f1fd9b5c2c21f24d25d7813f431a3495702ebea6 (diff) | |
download | lua-9fdf73bc9a6b4c6afbfff1d8181fface6b1c6761.tar.gz lua-9fdf73bc9a6b4c6afbfff1d8181fface6b1c6761.tar.bz2 lua-9fdf73bc9a6b4c6afbfff1d8181fface6b1c6761.zip |
first version for new API
Diffstat (limited to 'lbuiltin.c')
-rw-r--r-- | lbuiltin.c | 337 |
1 files changed, 187 insertions, 150 deletions
@@ -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 | |||
54 | static Number getsize (const Hash *h) { | 53 | static 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 | ||
75 | static Hash *gettable (lua_State *L, int arg) { | 74 | static 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 | */ |
93 | void luaB__ALERT (lua_State *L) { | 93 | int 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 | */ |
102 | void luaB__ERRORMESSAGE (lua_State *L) { | 103 | int 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 | */ |
123 | void luaB_print (lua_State *L) { | 125 | int 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 | ||
146 | void luaB_tonumber (lua_State *L) { | 147 | int 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 | ||
173 | void luaB_error (lua_State *L) { | 175 | int 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 | ||
177 | void luaB_setglobal (lua_State *L) { | 180 | int 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 | ||
184 | void luaB_getglobal (lua_State *L) { | 186 | int 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 | ||
188 | void luaB_tag (lua_State *L) { | 191 | int 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 | ||
192 | void luaB_settag (lua_State *L) { | 197 | int 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 | ||
199 | void luaB_newtag (lua_State *L) { | 205 | int 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 | ||
203 | void luaB_copytagmethods (lua_State *L) { | 210 | int 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 | ||
208 | void luaB_globals (lua_State *L) { | 216 | int 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 | ||
214 | void luaB_rawget (lua_State *L) { | 226 | int 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 | ||
220 | void luaB_rawset (lua_State *L) { | 233 | int 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 | ||
227 | void luaB_settagmethod (lua_State *L) { | 241 | int 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 | ||
239 | void luaB_gettagmethod (lua_State *L) { | 252 | int 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 | ||
245 | void luaB_collectgarbage (lua_State *L) { | 258 | int 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 | ||
250 | void luaB_type (lua_State *L) { | 264 | int 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 | ||
266 | static void passresults (lua_State *L) { | 281 | static 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 | ||
272 | void luaB_dostring (lua_State *L) { | 298 | int 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 | ||
284 | void luaB_dofile (lua_State *L) { | 308 | int 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 | ||
293 | void luaB_call (lua_State *L) { | 315 | int 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 | ||
334 | void luaB_next (lua_State *L) { | 360 | int 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 | ||
349 | void luaB_tostring (lua_State *L) { | 378 | int 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 | ||
392 | void luaB_assert (lua_State *L) { | 424 | int 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 | ||
399 | void luaB_getn (lua_State *L) { | 432 | int 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 | ||
411 | void luaB_tinsert (lua_State *L) { | 445 | int 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 | ||
429 | void luaB_tremove (lua_State *L) { | 462 | int 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 | ||
442 | static void luaB_foreachi (lua_State *L) { | 476 | static 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 | ||
460 | static void luaB_foreach (lua_State *L) { | 494 | static 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 | ||
495 | static int sort_comp (lua_State *L, lua_Object f, const TObject *a, | 529 | static 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 | ||
511 | static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) { | 545 | static 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 | ||
555 | void luaB_sort (lua_State *L) { | 589 | int 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 | */ |
618 | static void deprecated_func (lua_State *L) { | 654 | static 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 | ||