diff options
Diffstat (limited to 'lvm.c')
| -rw-r--r-- | lvm.c | 34 |
1 files changed, 20 insertions, 14 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 1.123 2000/08/09 14:49:41 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.124 2000/08/09 19:16:57 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 | */ |
| @@ -121,7 +121,7 @@ void luaV_gettable (lua_State *L, StkId top) { | |||
| 121 | im = luaT_getimbyObj(L, table, IM_GETTABLE); | 121 | im = luaT_getimbyObj(L, table, IM_GETTABLE); |
| 122 | if (ttype(im) == TAG_NIL) { | 122 | if (ttype(im) == TAG_NIL) { |
| 123 | L->top = top; | 123 | L->top = top; |
| 124 | luaG_indexerror(L, table); | 124 | luaG_typeerror(L, table, "index"); |
| 125 | } | 125 | } |
| 126 | } | 126 | } |
| 127 | else { /* object is a table... */ | 127 | else { /* object is a table... */ |
| @@ -156,7 +156,7 @@ void luaV_settable (lua_State *L, StkId t, StkId top) { | |||
| 156 | L->top = top; | 156 | L->top = top; |
| 157 | im = luaT_getimbyObj(L, t, IM_SETTABLE); | 157 | im = luaT_getimbyObj(L, t, IM_SETTABLE); |
| 158 | if (ttype(im) == TAG_NIL) | 158 | if (ttype(im) == TAG_NIL) |
| 159 | luaG_indexerror(L, t); | 159 | luaG_typeerror(L, t, "index"); |
| 160 | } | 160 | } |
| 161 | else { /* object is a table... */ | 161 | else { /* object is a table... */ |
| 162 | im = luaT_getim(L, hvalue(t)->htag, IM_SETTABLE); | 162 | im = luaT_getim(L, hvalue(t)->htag, IM_SETTABLE); |
| @@ -223,7 +223,7 @@ void luaV_setglobal (lua_State *L, TString *s, StkId top) { | |||
| 223 | } | 223 | } |
| 224 | 224 | ||
| 225 | 225 | ||
| 226 | static void call_binTM (lua_State *L, StkId top, IMS event, const char *msg) { | 226 | static int call_binTM (lua_State *L, StkId top, IMS event) { |
| 227 | /* try first operand */ | 227 | /* try first operand */ |
| 228 | const TObject *im = luaT_getimbyObj(L, top-2, event); | 228 | const TObject *im = luaT_getimbyObj(L, top-2, event); |
| 229 | L->top = top; | 229 | L->top = top; |
| @@ -232,16 +232,18 @@ static void call_binTM (lua_State *L, StkId top, IMS event, const char *msg) { | |||
| 232 | if (ttype(im) == TAG_NIL) { | 232 | if (ttype(im) == TAG_NIL) { |
| 233 | im = luaT_getim(L, 0, event); /* try a `global' method */ | 233 | im = luaT_getim(L, 0, event); /* try a `global' method */ |
| 234 | if (ttype(im) == TAG_NIL) | 234 | if (ttype(im) == TAG_NIL) |
| 235 | lua_error(L, msg); | 235 | return 0; /* error */ |
| 236 | } | 236 | } |
| 237 | } | 237 | } |
| 238 | lua_pushstring(L, luaT_eventname[event]); | 238 | lua_pushstring(L, luaT_eventname[event]); |
| 239 | luaD_callTM(L, im, 3, 1); | 239 | luaD_callTM(L, im, 3, 1); |
| 240 | return 1; | ||
| 240 | } | 241 | } |
| 241 | 242 | ||
| 242 | 243 | ||
| 243 | static void call_arith (lua_State *L, StkId top, IMS event) { | 244 | static void call_arith (lua_State *L, StkId top, IMS event) { |
| 244 | call_binTM(L, top, event, "unexpected type in arithmetic operation"); | 245 | if (!call_binTM(L, top, event)) |
| 246 | luaG_binerror(L, top-2, TAG_NUMBER, "perform arithmetic on"); | ||
| 245 | } | 247 | } |
| 246 | 248 | ||
| 247 | 249 | ||
| @@ -276,7 +278,8 @@ int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top) | |||
| 276 | luaD_checkstack(L, 2); | 278 | luaD_checkstack(L, 2); |
| 277 | *top++ = *l; | 279 | *top++ = *l; |
| 278 | *top++ = *r; | 280 | *top++ = *r; |
| 279 | call_binTM(L, top, IM_LT, "unexpected type in comparison"); | 281 | if (!call_binTM(L, top, IM_LT)) |
| 282 | lua_error(L, "unexpected type in comparison"); | ||
| 280 | L->top--; | 283 | L->top--; |
| 281 | return (ttype(L->top) != TAG_NIL); | 284 | return (ttype(L->top) != TAG_NIL); |
| 282 | } | 285 | } |
| @@ -286,8 +289,10 @@ int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top) | |||
| 286 | static void strconc (lua_State *L, int total, StkId top) { | 289 | static void strconc (lua_State *L, int total, StkId top) { |
| 287 | do { | 290 | do { |
| 288 | int n = 2; /* number of elements handled in this pass (at least 2) */ | 291 | int n = 2; /* number of elements handled in this pass (at least 2) */ |
| 289 | if (tostring(L, top-2) || tostring(L, top-1)) | 292 | if (tostring(L, top-2) || tostring(L, top-1)) { |
| 290 | call_binTM(L, top, IM_CONCAT, "unexpected type for concatenation"); | 293 | if (!call_binTM(L, top, IM_CONCAT)) |
| 294 | luaG_binerror(L, top-2, TAG_STRING, "concat"); | ||
| 295 | } | ||
| 291 | else if (tsvalue(top-1)->u.s.len > 0) { /* if len=0, do nothing */ | 296 | else if (tsvalue(top-1)->u.s.len > 0) { /* if len=0, do nothing */ |
| 292 | /* at least two string values; get as many as possible */ | 297 | /* at least two string values; get as many as possible */ |
| 293 | lint32 tl = (lint32)tsvalue(top-1)->u.s.len + | 298 | lint32 tl = (lint32)tsvalue(top-1)->u.s.len + |
| @@ -508,7 +513,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 508 | } | 513 | } |
| 509 | 514 | ||
| 510 | case OP_ADD: | 515 | case OP_ADD: |
| 511 | if (tonumber(top-1) || tonumber(top-2)) | 516 | if (tonumber(top-2) || tonumber(top-1)) |
| 512 | call_arith(L, top, IM_ADD); | 517 | call_arith(L, top, IM_ADD); |
| 513 | else | 518 | else |
| 514 | nvalue(top-2) += nvalue(top-1); | 519 | nvalue(top-2) += nvalue(top-1); |
| @@ -526,7 +531,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 526 | break; | 531 | break; |
| 527 | 532 | ||
| 528 | case OP_SUB: | 533 | case OP_SUB: |
| 529 | if (tonumber(top-1) || tonumber(top-2)) | 534 | if (tonumber(top-2) || tonumber(top-1)) |
| 530 | call_arith(L, top, IM_SUB); | 535 | call_arith(L, top, IM_SUB); |
| 531 | else | 536 | else |
| 532 | nvalue(top-2) -= nvalue(top-1); | 537 | nvalue(top-2) -= nvalue(top-1); |
| @@ -534,7 +539,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 534 | break; | 539 | break; |
| 535 | 540 | ||
| 536 | case OP_MULT: | 541 | case OP_MULT: |
| 537 | if (tonumber(top-1) || tonumber(top-2)) | 542 | if (tonumber(top-2) || tonumber(top-1)) |
| 538 | call_arith(L, top, IM_MUL); | 543 | call_arith(L, top, IM_MUL); |
| 539 | else | 544 | else |
| 540 | nvalue(top-2) *= nvalue(top-1); | 545 | nvalue(top-2) *= nvalue(top-1); |
| @@ -542,7 +547,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 542 | break; | 547 | break; |
| 543 | 548 | ||
| 544 | case OP_DIV: | 549 | case OP_DIV: |
| 545 | if (tonumber(top-1) || tonumber(top-2)) | 550 | if (tonumber(top-2) || tonumber(top-1)) |
| 546 | call_arith(L, top, IM_DIV); | 551 | call_arith(L, top, IM_DIV); |
| 547 | else | 552 | else |
| 548 | nvalue(top-2) /= nvalue(top-1); | 553 | nvalue(top-2) /= nvalue(top-1); |
| @@ -550,7 +555,8 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 550 | break; | 555 | break; |
| 551 | 556 | ||
| 552 | case OP_POW: | 557 | case OP_POW: |
| 553 | call_binTM(L, top, IM_POW, "undefined operation"); | 558 | if (!call_binTM(L, top, IM_POW)) |
| 559 | lua_error(L, "undefined operation"); | ||
| 554 | top--; | 560 | top--; |
| 555 | break; | 561 | break; |
| 556 | 562 | ||
