aboutsummaryrefslogtreecommitdiff
path: root/lstrlib.c
diff options
context:
space:
mode:
Diffstat (limited to 'lstrlib.c')
-rw-r--r--lstrlib.c88
1 files changed, 86 insertions, 2 deletions
diff --git a/lstrlib.c b/lstrlib.c
index 89896fa6..c7cfa421 100644
--- a/lstrlib.c
+++ b/lstrlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstrlib.c,v 1.255 2017/03/14 12:40:44 roberto Exp roberto $ 2** $Id: lstrlib.c,v 1.256 2017/05/19 16:29:40 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*/
@@ -203,6 +203,88 @@ static int str_dump (lua_State *L) {
203 203
204/* 204/*
205** {====================================================== 205** {======================================================
206** METAMETHODS
207** =======================================================
208*/
209
210static int tonum (lua_State *L, int arg) {
211 if (lua_type(L, arg) == LUA_TNUMBER) { /* already a number? */
212 lua_pushvalue(L, arg);
213 return 1;
214 }
215 else { /* check whether it is a numerical string */
216 size_t len;
217 const char *s = lua_tolstring(L, arg, &len);
218 return (s != NULL && lua_stringtonumber(L, s) == len + 1);
219 }
220}
221
222
223static int arith (lua_State *L, int op, const char *mtname) {
224 if (tonum(L, 1) && tonum(L, 2))
225 lua_arith(L, op); /* result will be on the top */
226 else {
227 lua_settop(L, 2); /* back to the original arguments */
228 if (lua_type(L, 2) == LUA_TSTRING || !luaL_getmetafield(L, 2, mtname))
229 return luaL_error(L, "attempt to %s a '%s' with a '%s'", mtname + 2,
230 luaL_typename(L, -2), luaL_typename(L, -1));
231 lua_insert(L, -3); /* put metamethod before arguments */
232 lua_call(L, 2, 1); /* call metamethod */
233 }
234 return 1;
235}
236
237
238static int arith_add (lua_State *L) {
239 return arith(L, LUA_OPADD, "__add");
240}
241
242static int arith_sub (lua_State *L) {
243 return arith(L, LUA_OPSUB, "__sub");
244}
245
246static int arith_mul (lua_State *L) {
247 return arith(L, LUA_OPMUL, "__mul");
248}
249
250static int arith_mod (lua_State *L) {
251 return arith(L, LUA_OPMOD, "__mod");
252}
253
254static int arith_pow (lua_State *L) {
255 return arith(L, LUA_OPPOW, "__pow");
256}
257
258static int arith_div (lua_State *L) {
259 return arith(L, LUA_OPDIV, "__div");
260}
261
262static int arith_idiv (lua_State *L) {
263 return arith(L, LUA_OPIDIV, "__idiv");
264}
265
266static int arith_unm (lua_State *L) {
267 return arith(L, LUA_OPUNM, "__unm");
268}
269
270
271static const luaL_Reg stringmetamethods[] = {
272 {"__add", arith_add},
273 {"__sub", arith_sub},
274 {"__mul", arith_mul},
275 {"__mod", arith_mod},
276 {"__pow", arith_pow},
277 {"__div", arith_div},
278 {"__idiv", arith_idiv},
279 {"__unm", arith_unm},
280 {"__index", NULL}, /* placeholder */
281 {NULL, NULL}
282};
283
284/* }====================================================== */
285
286/*
287** {======================================================
206** PATTERN MATCHING 288** PATTERN MATCHING
207** ======================================================= 289** =======================================================
208*/ 290*/
@@ -1576,7 +1658,9 @@ static const luaL_Reg strlib[] = {
1576 1658
1577 1659
1578static void createmetatable (lua_State *L) { 1660static void createmetatable (lua_State *L) {
1579 lua_createtable(L, 0, 1); /* table to be metatable for strings */ 1661 /* table to be metatable for strings */
1662 luaL_newlibtable(L, stringmetamethods);
1663 luaL_setfuncs(L, stringmetamethods, 0);
1580 lua_pushliteral(L, ""); /* dummy string */ 1664 lua_pushliteral(L, ""); /* dummy string */
1581 lua_pushvalue(L, -2); /* copy table */ 1665 lua_pushvalue(L, -2); /* copy table */
1582 lua_setmetatable(L, -2); /* set table as metatable for strings */ 1666 lua_setmetatable(L, -2); /* set table as metatable for strings */