diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-06-12 11:56:22 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-06-12 11:56:22 -0300 |
commit | eeab473fc8fdce39c3a0a495a6a790d7906c7bdc (patch) | |
tree | f260370b15d8a196f4168d3e64dafb35c8083282 /lvm.c | |
parent | 6b8cdc9cdd545508af85d1de2013ea0fc64792b0 (diff) | |
download | lua-eeab473fc8fdce39c3a0a495a6a790d7906c7bdc.tar.gz lua-eeab473fc8fdce39c3a0a495a6a790d7906c7bdc.tar.bz2 lua-eeab473fc8fdce39c3a0a495a6a790d7906c7bdc.zip |
new fallback __le (less equal), for partial order
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 62 |
1 files changed, 41 insertions, 21 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 1.235 2002/06/05 12:34:19 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.236 2002/06/06 18:17:33 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 | */ |
@@ -207,14 +207,13 @@ static int luaV_strcmp (const TString *ls, const TString *rs) { | |||
207 | size_t lr = rs->tsv.len; | 207 | size_t lr = rs->tsv.len; |
208 | for (;;) { | 208 | for (;;) { |
209 | int temp = strcoll(l, r); | 209 | int temp = strcoll(l, r); |
210 | if (temp < 0) return CMP_LT; | 210 | if (temp != 0) return temp; |
211 | else if (temp > 0) return CMP_GT; | ||
212 | else { /* strings are equal up to a `\0' */ | 211 | else { /* strings are equal up to a `\0' */ |
213 | size_t len = strlen(l); /* index of first `\0' in both strings */ | 212 | size_t len = strlen(l); /* index of first `\0' in both strings */ |
214 | if (len == lr) /* r is finished? */ | 213 | if (len == lr) /* r is finished? */ |
215 | return (len == ll) ? CMP_EQ : CMP_GT; /* l is eq. or gt. than r */ | 214 | return (len == ll) ? 0 : 1; |
216 | else if (len == ll) /* l is finished? */ | 215 | else if (len == ll) /* l is finished? */ |
217 | return CMP_LT; /* l is smaller than r (because r is not finished) */ | 216 | return -1; /* l is smaller than r (because r is not finished) */ |
218 | /* both strings longer than `len'; go on comparing (after the `\0') */ | 217 | /* both strings longer than `len'; go on comparing (after the `\0') */ |
219 | len++; | 218 | len++; |
220 | l += len; ll -= len; r += len; lr -= len; | 219 | l += len; ll -= len; r += len; lr -= len; |
@@ -223,24 +222,30 @@ static int luaV_strcmp (const TString *ls, const TString *rs) { | |||
223 | } | 222 | } |
224 | 223 | ||
225 | 224 | ||
226 | int luaV_cmp (lua_State *L, const TObject *l, const TObject *r, int cond) { | 225 | int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r) { |
227 | if (ttype(l) == LUA_TNUMBER && ttype(r) == LUA_TNUMBER) { | 226 | if (ttype(l) == LUA_TNUMBER && ttype(r) == LUA_TNUMBER) |
228 | lua_Number n1 = nvalue(l); | 227 | return nvalue(l) < nvalue(r); |
229 | lua_Number n2 = nvalue(r); | ||
230 | if (n1 < n2) return (cond & CMP_LT); | ||
231 | else if (n1 > n2) return (cond & CMP_GT); | ||
232 | else if (n1 == n2) return (cond & CMP_EQ); | ||
233 | else return (cond & CMP_N); | ||
234 | } | ||
235 | else if (ttype(l) == LUA_TSTRING && ttype(r) == LUA_TSTRING) | 228 | else if (ttype(l) == LUA_TSTRING && ttype(r) == LUA_TSTRING) |
236 | return luaV_strcmp(tsvalue(l), tsvalue(r)) & cond; | 229 | return luaV_strcmp(tsvalue(l), tsvalue(r)) < 0; |
237 | else { /* try TM */ | 230 | else { /* try TM */ |
238 | if (cond & CMP_EQ ? cond & CMP_LT : cond & CMP_GT) { /* `<=' or `>' ? */ | ||
239 | const TObject *temp = l; l = r; r = temp; /* exchange terms */ | ||
240 | } | ||
241 | if (!call_binTM(L, l, r, L->top, TM_LT)) | 231 | if (!call_binTM(L, l, r, L->top, TM_LT)) |
242 | luaG_ordererror(L, l, r); | 232 | luaG_ordererror(L, l, r); |
243 | return (cond & CMP_EQ) ? l_isfalse(L->top) : !l_isfalse(L->top); | 233 | return !l_isfalse(L->top); |
234 | } | ||
235 | } | ||
236 | |||
237 | |||
238 | static int luaV_lessequal (lua_State *L, const TObject *l, const TObject *r) { | ||
239 | if (ttype(l) == LUA_TNUMBER && ttype(r) == LUA_TNUMBER) | ||
240 | return nvalue(l) <= nvalue(r); | ||
241 | else if (ttype(l) == LUA_TSTRING && ttype(r) == LUA_TSTRING) | ||
242 | return luaV_strcmp(tsvalue(l), tsvalue(r)) <= 0; | ||
243 | else { /* try TM */ | ||
244 | if (call_binTM(L, l, r, L->top, TM_LE)) /* first try `le' */ | ||
245 | return !l_isfalse(L->top); | ||
246 | else if (!call_binTM(L, r, l, L->top, TM_LT)) /* else try `lt' */ | ||
247 | luaG_ordererror(L, l, r); | ||
248 | return l_isfalse(L->top); | ||
244 | } | 249 | } |
245 | } | 250 | } |
246 | 251 | ||
@@ -463,8 +468,23 @@ StkId luaV_execute (lua_State *L) { | |||
463 | else dojump(pc, GETARG_sBx(*pc) + 1); | 468 | else dojump(pc, GETARG_sBx(*pc) + 1); |
464 | break; | 469 | break; |
465 | } | 470 | } |
466 | case OP_CMP: { | 471 | case OP_LT: { |
467 | if (!(luaV_cmp(L, ra, RKC(i), GETARG_B(i)))) pc++; | 472 | if (luaV_lessthan(L, ra, RKC(i)) != GETARG_B(i)) pc++; |
473 | else dojump(pc, GETARG_sBx(*pc) + 1); | ||
474 | break; | ||
475 | } | ||
476 | case OP_LE: { | ||
477 | if (luaV_lessequal(L, ra, RKC(i)) != GETARG_B(i)) pc++; | ||
478 | else dojump(pc, GETARG_sBx(*pc) + 1); | ||
479 | break; | ||
480 | } | ||
481 | case OP_GT: { | ||
482 | if (luaV_lessthan(L, RKC(i), ra) != GETARG_B(i)) pc++; | ||
483 | else dojump(pc, GETARG_sBx(*pc) + 1); | ||
484 | break; | ||
485 | } | ||
486 | case OP_GE: { | ||
487 | if (luaV_lessequal(L, RKC(i), ra) != GETARG_B(i)) pc++; | ||
468 | else dojump(pc, GETARG_sBx(*pc) + 1); | 488 | else dojump(pc, GETARG_sBx(*pc) + 1); |
469 | break; | 489 | break; |
470 | } | 490 | } |