aboutsummaryrefslogtreecommitdiff
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
parent6b8cdc9cdd545508af85d1de2013ea0fc64792b0 (diff)
downloadlua-eeab473fc8fdce39c3a0a495a6a790d7906c7bdc.tar.gz
lua-eeab473fc8fdce39c3a0a495a6a790d7906c7bdc.tar.bz2
lua-eeab473fc8fdce39c3a0a495a6a790d7906c7bdc.zip
new fallback __le (less equal), for partial order
-rw-r--r--lapi.c4
-rw-r--r--lcode.c35
-rw-r--r--lobject.h10
-rw-r--r--lopcodes.c12
-rw-r--r--lopcodes.h7
-rw-r--r--ltm.c7
-rw-r--r--ltm.h5
-rw-r--r--lvm.c62
-rw-r--r--lvm.h4
9 files changed, 77 insertions, 69 deletions
diff --git a/lapi.c b/lapi.c
index 3a58fbc0..8ae73ab9 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 1.195 2002/06/03 20:11:07 roberto Exp roberto $ 2** $Id: lapi.c,v 1.196 2002/06/06 12:40:22 roberto Exp roberto $
3** Lua API 3** Lua API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -226,7 +226,7 @@ LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
226 o1 = luaA_indexAcceptable(L, index1); 226 o1 = luaA_indexAcceptable(L, index1);
227 o2 = luaA_indexAcceptable(L, index2); 227 o2 = luaA_indexAcceptable(L, index2);
228 i = (o1 == NULL || o2 == NULL) ? 0 /* index out-of-range */ 228 i = (o1 == NULL || o2 == NULL) ? 0 /* index out-of-range */
229 : luaV_cmp(L, o1, o2, CMP_LT); 229 : luaV_lessthan(L, o1, o2);
230 lua_unlock(L); 230 lua_unlock(L);
231 return i; 231 return i;
232} 232}
diff --git a/lcode.c b/lcode.c
index af2a0838..174c826a 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 1.105 2002/05/27 20:35:40 roberto Exp roberto $ 2** $Id: lcode.c,v 1.106 2002/06/03 12:59:26 roberto Exp roberto $
3** Code generator for Lua 3** Code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -460,19 +460,8 @@ void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
460 460
461static void invertjump (FuncState *fs, expdesc *e) { 461static void invertjump (FuncState *fs, expdesc *e) {
462 Instruction *pc = getjumpcontrol(fs, e->info); 462 Instruction *pc = getjumpcontrol(fs, e->info);
463 OpCode op = GET_OPCODE(*pc); 463 lua_assert(testOpMode(GET_OPCODE(*pc), OpModeT));
464 switch (op) { 464 SETARG_B(*pc, !(GETARG_B(*pc)));
465 case OP_EQ: {
466 SETARG_B(*pc, !(GETARG_B(*pc)));
467 return;
468 }
469 case OP_CMP: {
470 SETARG_B(*pc, ~(GETARG_B(*pc)));
471 return;
472 }
473 default: lua_assert(0); /* invalid jump instruction */
474 }
475 SET_OPCODE(*pc, op);
476} 465}
477 466
478 467
@@ -629,12 +618,6 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
629} 618}
630 619
631 620
632
633static const int cmp_masks[] = { /* ORDER OPR */
634 CMP_LT, (CMP_LT | CMP_EQ), CMP_GT, (CMP_GT | CMP_EQ)
635};
636
637
638static void codebinop (FuncState *fs, expdesc *res, BinOpr op, 621static void codebinop (FuncState *fs, expdesc *res, BinOpr op,
639 int o1, int o2, int ic) { 622 int o1, int o2, int ic) {
640 switch (op) { 623 switch (op) {
@@ -644,7 +627,7 @@ static void codebinop (FuncState *fs, expdesc *res, BinOpr op,
644 lua_assert(!ic); 627 lua_assert(!ic);
645 /* go through */ 628 /* go through */
646 case OPR_ADD: 629 case OPR_ADD:
647 case OPR_MULT: { 630 case OPR_MULT: { /* ORDER OPR */
648 OpCode opc = cast(OpCode, (op - OPR_ADD) + OP_ADD); 631 OpCode opc = cast(OpCode, (op - OPR_ADD) + OP_ADD);
649 res->info = luaK_codeABC(fs, opc, 0, o1, o2); 632 res->info = luaK_codeABC(fs, opc, 0, o1, o2);
650 res->k = VRELOCABLE; 633 res->k = VRELOCABLE;
@@ -659,11 +642,13 @@ static void codebinop (FuncState *fs, expdesc *res, BinOpr op,
659 case OPR_LT: 642 case OPR_LT:
660 case OPR_LE: 643 case OPR_LE:
661 case OPR_GT: 644 case OPR_GT:
662 case OPR_GE: { 645 case OPR_GE: { /* ORDER OPR */
663 int mask = cmp_masks[op - OPR_LT]; 646 OpCode opc;
647 int i = op - OPR_LT;
664 if (ic) /* operands were interchanged? */ 648 if (ic) /* operands were interchanged? */
665 mask ^= (CMP_LT | CMP_GT); /* correct condition */ 649 i = (i+2)&3; /* correct operator */
666 res->info = luaK_condjump(fs, OP_CMP, o1, mask, o2); 650 opc = cast(OpCode, i + OP_LT);
651 res->info = luaK_condjump(fs, opc, o1, 1, o2);
667 res->k = VJMP; 652 res->k = VJMP;
668 break; 653 break;
669 } 654 }
diff --git a/lobject.h b/lobject.h
index 76855319..e818029e 100644
--- a/lobject.h
+++ b/lobject.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.h,v 1.132 2002/05/15 18:57:44 roberto Exp roberto $ 2** $Id: lobject.h,v 1.133 2002/05/16 18:39:46 roberto Exp roberto $
3** Type definitions for Lua objects 3** Type definitions for Lua objects
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -230,14 +230,6 @@ typedef struct Table {
230#define sizearray(t) ((t)->sizearray) 230#define sizearray(t) ((t)->sizearray)
231 231
232 232
233/*
234** masks for comparison results
235*/
236#define CMP_EQ 1
237#define CMP_LT 2
238#define CMP_GT 4
239#define CMP_N 8 /* not comparable values (e.g. NaN) */
240
241 233
242extern const TObject luaO_nilobject; 234extern const TObject luaO_nilobject;
243 235
diff --git a/lopcodes.c b/lopcodes.c
index bf0e617a..767c6bd5 100644
--- a/lopcodes.c
+++ b/lopcodes.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.c,v 1.18 2002/05/06 15:51:41 roberto Exp roberto $ 2** $Id: lopcodes.c,v 1.19 2002/05/13 13:09:00 roberto Exp roberto $
3** extracted automatically from lopcodes.h by mkprint.lua 3** extracted automatically from lopcodes.h by mkprint.lua
4** DO NOT EDIT 4** DO NOT EDIT
5** See Copyright Notice in lua.h 5** See Copyright Notice in lua.h
@@ -37,7 +37,10 @@ const char *const luaP_opnames[] = {
37 "CONCAT", 37 "CONCAT",
38 "JMP", 38 "JMP",
39 "EQ", 39 "EQ",
40 "CMP", 40 "LT",
41 "LE",
42 "GT",
43 "GE",
41 "TEST", 44 "TEST",
42 "CALL", 45 "CALL",
43 "TAILCALL", 46 "TAILCALL",
@@ -82,7 +85,10 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = {
82 ,opmode(0,0,1,1, 1,0,iABC) /* OP_CONCAT */ 85 ,opmode(0,0,1,1, 1,0,iABC) /* OP_CONCAT */
83 ,opmode(0,0,0,0, 0,0,iAsBx) /* OP_JMP */ 86 ,opmode(0,0,0,0, 0,0,iAsBx) /* OP_JMP */
84 ,opmode(1,0,0,1, 0,0,iABC) /* OP_EQ */ 87 ,opmode(1,0,0,1, 0,0,iABC) /* OP_EQ */
85 ,opmode(1,0,0,1, 0,0,iABC) /* OP_CMP */ 88 ,opmode(1,0,0,1, 0,0,iABC) /* OP_LT */
89 ,opmode(1,0,0,1, 0,0,iABC) /* OP_LE */
90 ,opmode(1,0,0,1, 0,0,iABC) /* OP_GT */
91 ,opmode(1,0,0,1, 0,0,iABC) /* OP_GE */
86 ,opmode(1,0,0,1, 1,0,iABC) /* OP_TEST */ 92 ,opmode(1,0,0,1, 1,0,iABC) /* OP_TEST */
87 ,opmode(0,0,0,0, 0,0,iABC) /* OP_CALL */ 93 ,opmode(0,0,0,0, 0,0,iABC) /* OP_CALL */
88 ,opmode(0,0,0,0, 0,0,iABC) /* OP_TAILCALL */ 94 ,opmode(0,0,0,0, 0,0,iABC) /* OP_TAILCALL */
diff --git a/lopcodes.h b/lopcodes.h
index 95b5b373..5852233e 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.h,v 1.97 2002/05/13 13:09:00 roberto Exp roberto $ 2** $Id: lopcodes.h,v 1.98 2002/06/06 18:17:33 roberto Exp roberto $
3** Opcodes for Lua virtual machine 3** Opcodes for Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -158,7 +158,10 @@ OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */
158OP_JMP,/* sBx PC += sBx */ 158OP_JMP,/* sBx PC += sBx */
159 159
160OP_EQ,/* A B C if ((R(A) == R/K(C)) ~= B) then pc++ */ 160OP_EQ,/* A B C if ((R(A) == R/K(C)) ~= B) then pc++ */
161OP_CMP,/* A B C if not (R(A) <B> R/K(C)) then pc++ (see note) */ 161OP_LT,/* A B C if ((R(A) < R/K(C)) ~= B) then pc++ */
162OP_LE,/* A B C if ((R(A) <= R/K(C)) ~= B) then pc++ */
163OP_GT,/* A B C if ((R(A) > R/K(C)) ~= B) then pc++ */
164OP_GE,/* A B C if ((R(A) >= R/K(C)) ~= B) then pc++ */
162 165
163OP_TEST,/* A B C if (R(C) <=> B) then R(A) := R(C) else pc++ */ 166OP_TEST,/* A B C if (R(C) <=> B) then R(A) := R(C) else pc++ */
164 167
diff --git a/ltm.c b/ltm.c
index 54762902..6b28ea63 100644
--- a/ltm.c
+++ b/ltm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltm.c,v 1.92 2002/05/27 20:35:40 roberto Exp roberto $ 2** $Id: ltm.c,v 1.93 2002/06/03 14:09:57 roberto Exp roberto $
3** Tag methods 3** Tag methods
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -28,8 +28,8 @@ void luaT_init (lua_State *L) {
28 "__gettable", "__settable", "__index", "__newindex", 28 "__gettable", "__settable", "__index", "__newindex",
29 "__gc", "__weakmode", 29 "__gc", "__weakmode",
30 "__add", "__sub", "__mul", "__div", 30 "__add", "__sub", "__mul", "__div",
31 "__pow", "__unm", "__lt", "__concat", 31 "__pow", "__unm", "__lt", "__le",
32 "__call" 32 "__concat", "__call"
33 }; 33 };
34 int i; 34 int i;
35 for (i=0; i<TM_N; i++) { 35 for (i=0; i<TM_N; i++) {
@@ -45,6 +45,7 @@ void luaT_init (lua_State *L) {
45*/ 45*/
46const TObject *luaT_gettm (Table *events, TMS event, TString *ename) { 46const TObject *luaT_gettm (Table *events, TMS event, TString *ename) {
47 const TObject *tm = luaH_getstr(events, ename); 47 const TObject *tm = luaH_getstr(events, ename);
48 lua_assert(event <= TM_WEAKMODE);
48 if (ttype(tm) == LUA_TNIL) { /* no tag method? */ 49 if (ttype(tm) == LUA_TNIL) { /* no tag method? */
49 events->flags |= (1u<<event); /* cache this fact */ 50 events->flags |= (1u<<event); /* cache this fact */
50 return NULL; 51 return NULL;
diff --git a/ltm.h b/ltm.h
index e6718492..39790c58 100644
--- a/ltm.h
+++ b/ltm.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltm.h,v 1.32 2002/05/20 19:51:06 roberto Exp roberto $ 2** $Id: ltm.h,v 1.33 2002/05/27 20:35:40 roberto Exp roberto $
3** Tag methods 3** Tag methods
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -20,7 +20,7 @@ typedef enum {
20 TM_INDEX, 20 TM_INDEX,
21 TM_NEWINDEX, 21 TM_NEWINDEX,
22 TM_GC, 22 TM_GC,
23 TM_WEAKMODE, 23 TM_WEAKMODE, /* last tag method with `fast' access */
24 TM_ADD, 24 TM_ADD,
25 TM_SUB, 25 TM_SUB,
26 TM_MUL, 26 TM_MUL,
@@ -28,6 +28,7 @@ typedef enum {
28 TM_POW, 28 TM_POW,
29 TM_UNM, 29 TM_UNM,
30 TM_LT, 30 TM_LT,
31 TM_LE,
31 TM_CONCAT, 32 TM_CONCAT,
32 TM_CALL, 33 TM_CALL,
33 TM_N /* number of elements in the enum */ 34 TM_N /* number of elements in the enum */
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 }
diff --git a/lvm.h b/lvm.h
index ccbf0e3a..0078a617 100644
--- a/lvm.h
+++ b/lvm.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.h,v 1.39 2002/05/06 15:51:41 roberto Exp roberto $ 2** $Id: lvm.h,v 1.40 2002/06/03 14:08:43 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*/
@@ -19,7 +19,7 @@
19 (((o) = luaV_tonumber(o,n)) != NULL)) 19 (((o) = luaV_tonumber(o,n)) != NULL))
20 20
21 21
22int luaV_cmp (lua_State *L, const TObject *l, const TObject *r, int cond); 22int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r);
23const TObject *luaV_tonumber (const TObject *obj, TObject *n); 23const TObject *luaV_tonumber (const TObject *obj, TObject *n);
24int luaV_tostring (lua_State *L, TObject *obj); 24int luaV_tostring (lua_State *L, TObject *obj);
25void luaV_gettable (lua_State *L, const TObject *t, TObject *key, StkId res); 25void luaV_gettable (lua_State *L, const TObject *t, TObject *key, StkId res);