aboutsummaryrefslogtreecommitdiff
path: root/lvm.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-06-12 11:56:22 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-06-12 11:56:22 -0300
commiteeab473fc8fdce39c3a0a495a6a790d7906c7bdc (patch)
treef260370b15d8a196f4168d3e64dafb35c8083282 /lvm.c
parent6b8cdc9cdd545508af85d1de2013ea0fc64792b0 (diff)
downloadlua-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.c62
1 files changed, 41 insertions, 21 deletions
diff --git a/lvm.c b/lvm.c
index 8d22e9c1..d68710b8 100644
--- a/lvm.c
+++ b/lvm.c
@@ -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
226int luaV_cmp (lua_State *L, const TObject *l, const TObject *r, int cond) { 225int 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
238static 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 }