aboutsummaryrefslogtreecommitdiff
path: root/lstrlib.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-11-08 12:50:23 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-11-08 12:50:23 -0200
commit26679ea35bf261f2b5edc2fb2f5cc4df483fd50d (patch)
tree94c99ed74251cdf3e10a7e52560c3a7a78053ad1 /lstrlib.c
parentc3e5946fb2b7b5781d9bca9d303967abe6263482 (diff)
downloadlua-26679ea35bf261f2b5edc2fb2f5cc4df483fd50d.tar.gz
lua-26679ea35bf261f2b5edc2fb2f5cc4df483fd50d.tar.bz2
lua-26679ea35bf261f2b5edc2fb2f5cc4df483fd50d.zip
new function 'luaV_flttointeger' to convert floats to integers (without
string coercions) + string operands to bitwise operations handled by string metamethods
Diffstat (limited to 'lstrlib.c')
-rw-r--r--lstrlib.c80
1 files changed, 71 insertions, 9 deletions
diff --git a/lstrlib.c b/lstrlib.c
index c7cfa421..626c9159 100644
--- a/lstrlib.c
+++ b/lstrlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstrlib.c,v 1.256 2017/05/19 16:29:40 roberto Exp roberto $ 2** $Id: lstrlib.c,v 1.257 2017/07/07 16:34:32 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*/
@@ -220,17 +220,49 @@ static int tonum (lua_State *L, int arg) {
220} 220}
221 221
222 222
223static int toint (lua_State *L, int arg) {
224 if (!tonum(L, arg))
225 return 0; /* not coercible to a number */
226 else if (lua_isinteger(L, arg))
227 return 1; /* already an integer */
228 else { /* a float */
229 int ok;
230 lua_Integer n = lua_tointegerx(L, arg, &ok);
231 if (!ok)
232 return 0;
233 else {
234 lua_pop(L, 1); /* remove the float */
235 lua_pushinteger(L, n); /* push an integer */
236 return 1;
237 }
238 }
239}
240
241
242static void trymt (lua_State *L, const char *mtname) {
243 lua_settop(L, 2); /* back to the original arguments */
244 if (lua_type(L, 2) == LUA_TSTRING || !luaL_getmetafield(L, 2, mtname))
245 luaL_error(L, "attempt to %s a '%s' with a '%s'", mtname + 2,
246 luaL_typename(L, -2), luaL_typename(L, -1));
247 lua_insert(L, -3); /* put metamethod before arguments */
248 lua_call(L, 2, 1); /* call metamethod */
249}
250
251
223static int arith (lua_State *L, int op, const char *mtname) { 252static int arith (lua_State *L, int op, const char *mtname) {
224 if (tonum(L, 1) && tonum(L, 2)) 253 if (tonum(L, 1) && tonum(L, 2))
225 lua_arith(L, op); /* result will be on the top */ 254 lua_arith(L, op); /* result will be on the top */
226 else { 255 else
227 lua_settop(L, 2); /* back to the original arguments */ 256 trymt(L, mtname);
228 if (lua_type(L, 2) == LUA_TSTRING || !luaL_getmetafield(L, 2, mtname)) 257 return 1;
229 return luaL_error(L, "attempt to %s a '%s' with a '%s'", mtname + 2, 258}
230 luaL_typename(L, -2), luaL_typename(L, -1)); 259
231 lua_insert(L, -3); /* put metamethod before arguments */ 260
232 lua_call(L, 2, 1); /* call metamethod */ 261static int bitwise (lua_State *L, int op, const char *mtname) {
233 } 262 if (toint(L, 1) && toint(L, 2))
263 lua_arith(L, op); /* result will be on the top */
264 else
265 trymt(L, mtname);
234 return 1; 266 return 1;
235} 267}
236 268
@@ -267,6 +299,30 @@ static int arith_unm (lua_State *L) {
267 return arith(L, LUA_OPUNM, "__unm"); 299 return arith(L, LUA_OPUNM, "__unm");
268} 300}
269 301
302static int bitwise_band (lua_State *L) {
303 return bitwise(L, LUA_OPBAND, "__band");
304}
305
306static int bitwise_bor (lua_State *L) {
307 return bitwise(L, LUA_OPBOR, "__bor");
308}
309
310static int bitwise_bxor (lua_State *L) {
311 return bitwise(L, LUA_OPBXOR, "__bxor");
312}
313
314static int bitwise_shl (lua_State *L) {
315 return bitwise(L, LUA_OPSHL, "__shl");
316}
317
318static int bitwise_shr (lua_State *L) {
319 return bitwise(L, LUA_OPSHR, "__shr");
320}
321
322static int bitwise_bnot (lua_State *L) {
323 return bitwise(L, LUA_OPBNOT, "__bnot");
324}
325
270 326
271static const luaL_Reg stringmetamethods[] = { 327static const luaL_Reg stringmetamethods[] = {
272 {"__add", arith_add}, 328 {"__add", arith_add},
@@ -277,6 +333,12 @@ static const luaL_Reg stringmetamethods[] = {
277 {"__div", arith_div}, 333 {"__div", arith_div},
278 {"__idiv", arith_idiv}, 334 {"__idiv", arith_idiv},
279 {"__unm", arith_unm}, 335 {"__unm", arith_unm},
336 {"__band", bitwise_band},
337 {"__bor", bitwise_bor},
338 {"__bxor", bitwise_bxor},
339 {"__shl", bitwise_shl},
340 {"__shr", bitwise_shr},
341 {"__bnot", bitwise_bnot},
280 {"__index", NULL}, /* placeholder */ 342 {"__index", NULL}, /* placeholder */
281 {NULL, NULL} 343 {NULL, NULL}
282}; 344};