diff options
| -rw-r--r-- | lvm.c | 57 |
1 files changed, 42 insertions, 15 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 1.272 2002/12/06 17:09:00 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.273 2002/12/11 12:34:22 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 | */ |
| @@ -204,6 +204,33 @@ static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2, | |||
| 204 | } | 204 | } |
| 205 | 205 | ||
| 206 | 206 | ||
| 207 | static const TObject *get_compTM (lua_State *L, Table *mt1, Table *mt2, | ||
| 208 | TMS event) { | ||
| 209 | const TObject *tm1 = fasttm(L, mt1, event); | ||
| 210 | const TObject *tm2; | ||
| 211 | if (tm1 == NULL) return NULL; /* no metamethod */ | ||
| 212 | if (mt1 == mt2) return tm1; /* same metatables => same metamethods */ | ||
| 213 | tm2 = fasttm(L, mt2, event); | ||
| 214 | if (tm2 == NULL) return NULL; /* no metamethod */ | ||
| 215 | if (luaO_rawequalObj(tm1, tm2)) /* same metamethods? */ | ||
| 216 | return tm1; | ||
| 217 | return NULL; | ||
| 218 | } | ||
| 219 | |||
| 220 | |||
| 221 | static int call_orderTM (lua_State *L, const TObject *p1, const TObject *p2, | ||
| 222 | TMS event) { | ||
| 223 | const TObject *tm1 = luaT_gettmbyobj(L, p1, event); | ||
| 224 | const TObject *tm2; | ||
| 225 | if (ttisnil(tm1)) return -1; /* no metamethod? */ | ||
| 226 | tm2 = luaT_gettmbyobj(L, p2, event); | ||
| 227 | if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */ | ||
| 228 | return -1; | ||
| 229 | callTMres(L, tm1, p1, p2); | ||
| 230 | return !l_isfalse(L->top); | ||
| 231 | } | ||
| 232 | |||
| 233 | |||
| 207 | static int luaV_strcmp (const TString *ls, const TString *rs) { | 234 | static int luaV_strcmp (const TString *ls, const TString *rs) { |
| 208 | const char *l = getstr(ls); | 235 | const char *l = getstr(ls); |
| 209 | size_t ll = ls->tsv.len; | 236 | size_t ll = ls->tsv.len; |
| @@ -227,29 +254,31 @@ static int luaV_strcmp (const TString *ls, const TString *rs) { | |||
| 227 | 254 | ||
| 228 | 255 | ||
| 229 | int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r) { | 256 | int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r) { |
| 257 | int res; | ||
| 230 | if (ttype(l) != ttype(r)) | 258 | if (ttype(l) != ttype(r)) |
| 231 | return luaG_ordererror(L, l, r); | 259 | return luaG_ordererror(L, l, r); |
| 232 | else if (ttisnumber(l)) | 260 | else if (ttisnumber(l)) |
| 233 | return nvalue(l) < nvalue(r); | 261 | return nvalue(l) < nvalue(r); |
| 234 | else if (ttisstring(l)) | 262 | else if (ttisstring(l)) |
| 235 | return luaV_strcmp(tsvalue(l), tsvalue(r)) < 0; | 263 | return luaV_strcmp(tsvalue(l), tsvalue(r)) < 0; |
| 236 | else if (call_binTM(L, l, r, L->top, TM_LT)) | 264 | else if ((res = call_orderTM(L, l, r, TM_LT)) != -1) |
| 237 | return !l_isfalse(L->top); | 265 | return res; |
| 238 | return luaG_ordererror(L, l, r); | 266 | return luaG_ordererror(L, l, r); |
| 239 | } | 267 | } |
| 240 | 268 | ||
| 241 | 269 | ||
| 242 | static int luaV_lessequal (lua_State *L, const TObject *l, const TObject *r) { | 270 | static int luaV_lessequal (lua_State *L, const TObject *l, const TObject *r) { |
| 271 | int res; | ||
| 243 | if (ttype(l) != ttype(r)) | 272 | if (ttype(l) != ttype(r)) |
| 244 | return luaG_ordererror(L, l, r); | 273 | return luaG_ordererror(L, l, r); |
| 245 | else if (ttisnumber(l)) | 274 | else if (ttisnumber(l)) |
| 246 | return nvalue(l) <= nvalue(r); | 275 | return nvalue(l) <= nvalue(r); |
| 247 | else if (ttisstring(l)) | 276 | else if (ttisstring(l)) |
| 248 | return luaV_strcmp(tsvalue(l), tsvalue(r)) <= 0; | 277 | return luaV_strcmp(tsvalue(l), tsvalue(r)) <= 0; |
| 249 | else if (call_binTM(L, l, r, L->top, TM_LE)) /* first try `le' */ | 278 | else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */ |
| 250 | return !l_isfalse(L->top); | 279 | return res; |
| 251 | else if (call_binTM(L, r, l, L->top, TM_LT)) /* else try `lt' */ | 280 | else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */ |
| 252 | return l_isfalse(L->top); | 281 | return !res; |
| 253 | return luaG_ordererror(L, l, r); | 282 | return luaG_ordererror(L, l, r); |
| 254 | } | 283 | } |
| 255 | 284 | ||
| @@ -264,20 +293,18 @@ int luaV_equalval (lua_State *L, const TObject *t1, const TObject *t2) { | |||
| 264 | case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); | 293 | case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); |
| 265 | case LUA_TUSERDATA: { | 294 | case LUA_TUSERDATA: { |
| 266 | if (uvalue(t1) == uvalue(t2)) return 1; | 295 | if (uvalue(t1) == uvalue(t2)) return 1; |
| 267 | else if ((tm = fasttm(L, uvalue(t1)->uv.metatable, TM_EQ)) == NULL && | 296 | tm = get_compTM(L, uvalue(t1)->uv.metatable, uvalue(t2)->uv.metatable, |
| 268 | (tm = fasttm(L, uvalue(t2)->uv.metatable, TM_EQ)) == NULL) | 297 | TM_EQ); |
| 269 | return 0; /* no TM */ | 298 | break; /* will try TM */ |
| 270 | else break; /* will try TM */ | ||
| 271 | } | 299 | } |
| 272 | case LUA_TTABLE: { | 300 | case LUA_TTABLE: { |
| 273 | if (hvalue(t1) == hvalue(t2)) return 1; | 301 | if (hvalue(t1) == hvalue(t2)) return 1; |
| 274 | else if ((tm = fasttm(L, hvalue(t1)->metatable, TM_EQ)) == NULL && | 302 | tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); |
| 275 | (tm = fasttm(L, hvalue(t2)->metatable, TM_EQ)) == NULL) | 303 | break; /* will try TM */ |
| 276 | return 0; /* no TM */ | ||
| 277 | else break; /* will try TM */ | ||
| 278 | } | 304 | } |
| 279 | default: return gcvalue(t1) == gcvalue(t2); | 305 | default: return gcvalue(t1) == gcvalue(t2); |
| 280 | } | 306 | } |
| 307 | if (tm == NULL) return 0; /* no TM? */ | ||
| 281 | callTMres(L, tm, t1, t2); /* call TM */ | 308 | callTMres(L, tm, t1, t2); /* call TM */ |
| 282 | return !l_isfalse(L->top); | 309 | return !l_isfalse(L->top); |
| 283 | } | 310 | } |
