aboutsummaryrefslogtreecommitdiff
path: root/lvm.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-06-24 11:11:14 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-06-24 11:11:14 -0300
commitad41fc11eb2be960ee700c913c7a5c341d541af5 (patch)
tree1007dbff70a1fc91443d4c15540bee4a0767ed83 /lvm.c
parente182cf452fca5e00c6bd6a63642ce3ef8d7f7a53 (diff)
downloadlua-ad41fc11eb2be960ee700c913c7a5c341d541af5.tar.gz
lua-ad41fc11eb2be960ee700c913c7a5c341d541af5.tar.bz2
lua-ad41fc11eb2be960ee700c913c7a5c341d541af5.zip
details in arithmetic implementation
Diffstat (limited to 'lvm.c')
-rw-r--r--lvm.c98
1 files changed, 58 insertions, 40 deletions
diff --git a/lvm.c b/lvm.c
index 53aecc25..f74ec12d 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 1.240 2002/06/20 20:41:46 roberto Exp roberto $ 2** $Id: lvm.c,v 1.241 2002/06/24 13:08:45 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -182,13 +182,6 @@ static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2,
182} 182}
183 183
184 184
185static void call_arith (lua_State *L, StkId p1, const TObject *p2,
186 StkId res, TMS event) {
187 if (!call_binTM(L, p1, p2, res, event))
188 luaG_aritherror(L, p1, p2);
189}
190
191
192static int luaV_strcmp (const TString *ls, const TString *rs) { 185static int luaV_strcmp (const TString *ls, const TString *rs) {
193 const char *l = getstr(ls); 186 const char *l = getstr(ls);
194 size_t ll = ls->tsv.len; 187 size_t ll = ls->tsv.len;
@@ -300,23 +293,32 @@ void luaV_concat (lua_State *L, int total, int last) {
300} 293}
301 294
302 295
303static void powOp (lua_State *L, StkId ra, StkId rb, StkId rc) { 296static void Arith (lua_State *L, StkId ra, StkId rb, StkId rc, TMS op) {
304 const TObject *b = rb;
305 const TObject *c = rc;
306 ptrdiff_t res = savestack(L, ra);
307 TObject tempb, tempc; 297 TObject tempb, tempc;
308 if (tonumber(b, &tempb) && tonumber(c, &tempc)) { 298 const TObject *b, *c;
309 TObject f, o; 299 if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
310 setsvalue(&o, luaS_newliteral(L, "pow")); 300 (c = luaV_tonumber(rc, &tempc)) != NULL) {
311 f = *luaV_gettable(L, gt(L), &o); 301 switch (op) {
312 if (ttype(&f) != LUA_TFUNCTION) 302 case TM_ADD: setnvalue(ra, nvalue(b) + nvalue(c)); break;
313 luaG_runerror(L, "`pow' (for `^' operator) is not a function"); 303 case TM_SUB: setnvalue(ra, nvalue(b) - nvalue(c)); break;
314 callTMres(L, &f, b, c); 304 case TM_MUL: setnvalue(ra, nvalue(b) * nvalue(c)); break;
315 ra = restorestack(L, res); /* previous call may change stack */ 305 case TM_DIV: setnvalue(ra, nvalue(b) / nvalue(c)); break;
316 setobj(ra, L->top); 306 case TM_POW: {
307 const TObject *f = luaH_getstr(hvalue(registry(L)),
308 G(L)->tmname[TM_POW]);
309 ptrdiff_t res = savestack(L, ra);
310 if (ttype(f) != LUA_TFUNCTION)
311 luaG_runerror(L, "`pow' (for `^' operator) is not a function");
312 callTMres(L, f, b, c);
313 ra = restorestack(L, res); /* previous call may change stack */
314 setobj(ra, L->top);
315 break;
316 }
317 default: lua_assert(0); break;
318 }
317 } 319 }
318 else 320 else if (!call_binTM(L, rb, rc, ra, op))
319 call_arith(L, rb, rc, ra, TM_POW); 321 luaG_aritherror(L, rb, rc);
320} 322}
321 323
322 324
@@ -335,15 +337,6 @@ static void powOp (lua_State *L, StkId ra, StkId rb, StkId rc) {
335 k+GETARG_C(i)-MAXSTACK) 337 k+GETARG_C(i)-MAXSTACK)
336#define KBx(i) (k+GETARG_Bx(i)) 338#define KBx(i) (k+GETARG_Bx(i))
337 339
338#define Arith(op, optm) { \
339 const TObject *b = RB(i); const TObject *c = RKC(i); \
340 TObject tempb, tempc; \
341 if (tonumber(b, &tempb) && tonumber(c, &tempc)) { \
342 setnvalue(ra, nvalue(b) op nvalue(c)); \
343 } else \
344 call_arith(L, RB(i), RKC(i), ra, optm); \
345}
346
347 340
348#define dojump(pc, i) ((pc) += (i)) 341#define dojump(pc, i) ((pc) += (i))
349 342
@@ -435,34 +428,59 @@ StkId luaV_execute (lua_State *L) {
435 break; 428 break;
436 } 429 }
437 case OP_ADD: { 430 case OP_ADD: {
438 Arith( + , TM_ADD); 431 StkId rb = RB(i);
432 StkId rc = RKC(i);
433 if (ttype(rb) == LUA_TNUMBER && ttype(rc) == LUA_TNUMBER) {
434 setnvalue(ra, nvalue(rb) + nvalue(rc));
435 }
436 else
437 Arith(L, ra, rb, rc, TM_ADD);
439 break; 438 break;
440 } 439 }
441 case OP_SUB: { 440 case OP_SUB: {
442 Arith( - , TM_SUB); 441 StkId rb = RB(i);
442 StkId rc = RKC(i);
443 if (ttype(rb) == LUA_TNUMBER && ttype(rc) == LUA_TNUMBER) {
444 setnvalue(ra, nvalue(rb) - nvalue(rc));
445 }
446 else
447 Arith(L, ra, rb, rc, TM_SUB);
443 break; 448 break;
444 } 449 }
445 case OP_MUL: { 450 case OP_MUL: {
446 Arith( * , TM_MUL); 451 StkId rb = RB(i);
452 StkId rc = RKC(i);
453 if (ttype(rb) == LUA_TNUMBER && ttype(rc) == LUA_TNUMBER) {
454 setnvalue(ra, nvalue(rb) * nvalue(rc));
455 }
456 else
457 Arith(L, ra, rb, rc, TM_MUL);
447 break; 458 break;
448 } 459 }
449 case OP_DIV: { 460 case OP_DIV: {
450 Arith( / , TM_DIV); 461 StkId rb = RB(i);
462 StkId rc = RKC(i);
463 if (ttype(rb) == LUA_TNUMBER && ttype(rc) == LUA_TNUMBER) {
464 setnvalue(ra, nvalue(rb) / nvalue(rc));
465 }
466 else
467 Arith(L, ra, rb, rc, TM_DIV);
451 break; 468 break;
452 } 469 }
453 case OP_POW: { 470 case OP_POW: {
454 powOp(L, ra, RB(i), RKC(i)); 471 Arith(L, ra, RB(i), RKC(i), TM_POW);
455 break; 472 break;
456 } 473 }
457 case OP_UNM: { 474 case OP_UNM: {
458 const TObject *rb = RB(i); 475 const TObject *rb = RB(i);
459 if (tonumber(rb, ra)) { 476 TObject temp;
477 if (tonumber(rb, &temp)) {
460 setnvalue(ra, -nvalue(rb)); 478 setnvalue(ra, -nvalue(rb));
461 } 479 }
462 else { 480 else {
463 TObject temp;
464 setnilvalue(&temp); 481 setnilvalue(&temp);
465 call_arith(L, RB(i), &temp, ra, TM_UNM); 482 if (!call_binTM(L, RB(i), &temp, ra, TM_UNM))
483 luaG_aritherror(L, RB(i), &temp);
466 } 484 }
467 break; 485 break;
468 } 486 }