aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-12-11 20:48:44 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-12-11 20:48:44 -0200
commit9aff171f3bf0125314a29a5ca952470b2d83708e (patch)
tree8d1b400e0108198bde554a31731c655113bc4086
parented9be5e1f0d4b68aa848f85744ad959d7a57c9f4 (diff)
downloadlua-9aff171f3bf0125314a29a5ca952470b2d83708e.tar.gz
lua-9aff171f3bf0125314a29a5ca952470b2d83708e.tar.bz2
lua-9aff171f3bf0125314a29a5ca952470b2d83708e.zip
new type `boolean'
-rw-r--r--lapi.c23
-rw-r--r--lbaselib.c19
-rw-r--r--lcode.c123
-rw-r--r--ldebug.c8
-rw-r--r--lgc.c6
-rw-r--r--llex.c6
-rw-r--r--llex.h8
-rw-r--r--lobject.c4
-rw-r--r--lobject.h9
-rw-r--r--lopcodes.c6
-rw-r--r--lopcodes.h7
-rw-r--r--lparser.c12
-rw-r--r--lparser.h4
-rw-r--r--ltable.c3
-rw-r--r--ltests.c10
-rw-r--r--ltm.c2
-rw-r--r--lua.h11
-rw-r--r--lvm.c26
18 files changed, 166 insertions, 121 deletions
diff --git a/lapi.c b/lapi.c
index af151636..50578513 100644
--- a/lapi.c
+++ b/lapi.c
@@ -174,6 +174,12 @@ LUA_API int lua_isnumber (lua_State *L, int index) {
174} 174}
175 175
176 176
177LUA_API int lua_istrue (lua_State *L, int index) {
178 TObject *o = luaA_indexAcceptable(L, index);
179 return (o != NULL && !l_isfalse(o));
180}
181
182
177LUA_API int lua_isstring (lua_State *L, int index) { 183LUA_API int lua_isstring (lua_State *L, int index) {
178 int t = lua_type(L, index); 184 int t = lua_type(L, index);
179 return (t == LUA_TSTRING || t == LUA_TNUMBER); 185 return (t == LUA_TSTRING || t == LUA_TNUMBER);
@@ -213,6 +219,15 @@ LUA_API lua_Number lua_tonumber (lua_State *L, int index) {
213} 219}
214 220
215 221
222LUA_API int lua_toboolean (lua_State *L, int index) {
223 const TObject *o = luaA_indexAcceptable(L, index);
224 if (o != NULL && (ttype(o) == LUA_TBOOLEAN))
225 return bvalue(o);
226 else
227 return -1;
228}
229
230
216LUA_API const char *lua_tostring (lua_State *L, int index) { 231LUA_API const char *lua_tostring (lua_State *L, int index) {
217 StkId o = luaA_indexAcceptable(L, index); 232 StkId o = luaA_indexAcceptable(L, index);
218 if (o == NULL) 233 if (o == NULL)
@@ -323,6 +338,14 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
323} 338}
324 339
325 340
341LUA_API void lua_pushboolean (lua_State *L, int b) {
342 lua_lock(L);
343 setbvalue(L->top, b);
344 api_incr_top(L);
345 lua_unlock(L);
346}
347
348
326 349
327/* 350/*
328** get functions (Lua -> stack) 351** get functions (Lua -> stack)
diff --git a/lbaselib.c b/lbaselib.c
index bb66ab32..8f53a0d9 100644
--- a/lbaselib.c
+++ b/lbaselib.c
@@ -216,10 +216,8 @@ static int luaB_type (lua_State *L) {
216 if (lua_isnull(L, 2)) 216 if (lua_isnull(L, 2))
217 lua_pushstring(L, lua_typename(L, lua_type(L, 1))); 217 lua_pushstring(L, lua_typename(L, lua_type(L, 1)));
218 else { 218 else {
219 if (strcmp(lua_typename(L, lua_type(L, 1)), luaL_check_string(L, 2)) == 0) 219 lua_pushboolean(L,
220 lua_pushnumber(L, 1); 220 (strcmp(lua_typename(L, lua_type(L, 1)), luaL_check_string(L, 2)) == 0));
221 else
222 lua_pushnil(L);
223 } 221 }
224 return 1; 222 return 1;
225} 223}
@@ -401,8 +399,12 @@ static int luaB_tostring (lua_State *L) {
401 case LUA_TSTRING: 399 case LUA_TSTRING:
402 lua_pushvalue(L, 1); 400 lua_pushvalue(L, 1);
403 return 1; 401 return 1;
402 case LUA_TBOOLEAN:
403 lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false"));
404 return 1;
404 case LUA_TTABLE: 405 case LUA_TTABLE:
405 sprintf(buff, "%.40s: %p", lua_typename(L, lua_type(L, 1)), lua_topointer(L, 1)); 406 sprintf(buff, "%.40s: %p", lua_typename(L, lua_type(L, 1)),
407 lua_topointer(L, 1));
406 break; 408 break;
407 case LUA_TFUNCTION: 409 case LUA_TFUNCTION:
408 sprintf(buff, "function: %p", lua_topointer(L, 1)); 410 sprintf(buff, "function: %p", lua_topointer(L, 1));
@@ -464,9 +466,8 @@ static int luaB_foreach (lua_State *L) {
464 466
465static int luaB_assert (lua_State *L) { 467static int luaB_assert (lua_State *L) {
466 luaL_check_any(L, 1); 468 luaL_check_any(L, 1);
467 if (lua_isnil(L, 1)) 469 if (!lua_istrue(L, 1))
468 luaL_verror(L, "assertion failed! %.90s", 470 luaL_verror(L, "assertion failed! %.90s", luaL_opt_string(L, 2, ""));
469 luaL_opt_string(L, 2, ""));
470 lua_settop(L, 1); 471 lua_settop(L, 1);
471 return 1; 472 return 1;
472} 473}
@@ -542,7 +543,7 @@ static int sort_comp (lua_State *L, int a, int b) {
542 lua_pushvalue(L, a-1); /* -1 to compensate function */ 543 lua_pushvalue(L, a-1); /* -1 to compensate function */
543 lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */ 544 lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */
544 lua_rawcall(L, 2, 1); 545 lua_rawcall(L, 2, 1);
545 res = !lua_isnil(L, -1); 546 res = lua_istrue(L, -1);
546 lua_pop(L, 1); 547 lua_pop(L, 1);
547 return res; 548 return res;
548 } 549 }
diff --git a/lcode.c b/lcode.c
index 210450fa..4e8d23c1 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 1.82 2001/09/07 17:39:10 roberto Exp $ 2** $Id: lcode.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
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*/
@@ -221,10 +221,10 @@ static void freeexp (FuncState *fs, expdesc *e) {
221} 221}
222 222
223 223
224static int addk (FuncState *fs, TObject *k) { 224static int addk (FuncState *fs, TObject *k, TObject *v) {
225 const TObject *index = luaH_get(fs->h, k); 225 const TObject *index = luaH_get(fs->h, k);
226 if (ttype(index) == LUA_TNUMBER) { 226 if (ttype(index) == LUA_TNUMBER) {
227 lua_assert(luaO_equalObj(&fs->f->k[cast(int, nvalue(index))], k)); 227 lua_assert(luaO_equalObj(&fs->f->k[cast(int, nvalue(index))], v));
228 return cast(int, nvalue(index)); 228 return cast(int, nvalue(index));
229 } 229 }
230 else { /* constant not found; create a new entry */ 230 else { /* constant not found; create a new entry */
@@ -232,7 +232,7 @@ static int addk (FuncState *fs, TObject *k) {
232 Proto *f = fs->f; 232 Proto *f = fs->f;
233 luaM_growvector(fs->L, f->k, fs->nk, f->sizek, TObject, 233 luaM_growvector(fs->L, f->k, fs->nk, f->sizek, TObject,
234 MAXARG_Bc, "constant table overflow"); 234 MAXARG_Bc, "constant table overflow");
235 setobj(&f->k[fs->nk], k); 235 setobj(&f->k[fs->nk], v);
236 setnvalue(&o, fs->nk); 236 setnvalue(&o, fs->nk);
237 luaH_set(fs->L, fs->h, k, &o); 237 luaH_set(fs->L, fs->h, k, &o);
238 return fs->nk++; 238 return fs->nk++;
@@ -243,14 +243,22 @@ static int addk (FuncState *fs, TObject *k) {
243int luaK_stringk (FuncState *fs, TString *s) { 243int luaK_stringk (FuncState *fs, TString *s) {
244 TObject o; 244 TObject o;
245 setsvalue(&o, s); 245 setsvalue(&o, s);
246 return addk(fs, &o); 246 return addk(fs, &o, &o);
247} 247}
248 248
249 249
250static int number_constant (FuncState *fs, lua_Number r) { 250static int number_constant (FuncState *fs, lua_Number r) {
251 TObject o; 251 TObject o;
252 setnvalue(&o, r); 252 setnvalue(&o, r);
253 return addk(fs, &o); 253 return addk(fs, &o, &o);
254}
255
256
257static int nil_constant (FuncState *fs) {
258 TObject k, v;
259 setnilvalue(&v);
260 sethvalue(&k, fs->h); /* cannot use nil as key; instead use table itself */
261 return addk(fs, &k, &v);
254} 262}
255 263
256 264
@@ -298,27 +306,29 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) {
298} 306}
299 307
300 308
301static int code_label (FuncState *fs, OpCode op, int A, int sBc) { 309static int code_label (FuncState *fs, int A, int b, int jump) {
302 luaK_getlabel(fs); /* those instructions may be jump targets */ 310 luaK_getlabel(fs); /* those instructions may be jump targets */
303 return luaK_codeAsBc(fs, op, A, sBc); 311 return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
304} 312}
305 313
306 314
307static void dischargejumps (FuncState *fs, expdesc *e, int reg) { 315static void dischargejumps (FuncState *fs, expdesc *e, int reg) {
308 if (hasjumps(e)) { 316 if (hasjumps(e)) {
309 int final; /* position after whole expression */ 317 int final; /* position after whole expression */
310 int p_nil = NO_JUMP; /* position of an eventual PUSHNIL */ 318 int p_f = NO_JUMP; /* position of an eventual PUSH false */
311 int p_1 = NO_JUMP; /* position of an eventual PUSHINT */ 319 int p_t = NO_JUMP; /* position of an eventual PUSH true */
312 if (need_value(fs, e->f, OP_TESTF) || need_value(fs, e->t, OP_TESTT)) { 320 if (need_value(fs, e->f, OP_TESTF) || need_value(fs, e->t, OP_TESTT)) {
313 /* expression needs values */ 321 /* expression needs values */
314 if (e->k != VJMP) 322 if (e->k != VJMP) {
315 code_label(fs, OP_JMP, 0, 2); /* to jump over both pushes */ 323 luaK_getlabel(fs); /* these instruction may be jump target */
316 p_nil = code_label(fs, OP_NILJMP, reg, 0); 324 luaK_codeAsBc(fs, OP_JMP, 0, 2); /* to jump over both pushes */
317 p_1 = code_label(fs, OP_LOADINT, reg, 1); 325 }
326 p_f = code_label(fs, reg, 0, 1);
327 p_t = code_label(fs, reg, 1, 0);
318 } 328 }
319 final = luaK_getlabel(fs); 329 final = luaK_getlabel(fs);
320 luaK_patchlistaux(fs, e->f, p_nil, NO_REG, final, reg, p_nil); 330 luaK_patchlistaux(fs, e->f, p_f, NO_REG, final, reg, p_f);
321 luaK_patchlistaux(fs, e->t, final, reg, p_1, NO_REG, p_1); 331 luaK_patchlistaux(fs, e->t, final, reg, p_t, NO_REG, p_t);
322 } 332 }
323 e->f = e->t = NO_JUMP; 333 e->f = e->t = NO_JUMP;
324} 334}
@@ -331,6 +341,10 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
331 luaK_nil(fs, reg, 1); 341 luaK_nil(fs, reg, 1);
332 break; 342 break;
333 } 343 }
344 case VFALSE: case VTRUE: {
345 luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
346 break;
347 }
334 case VNUMBER: { 348 case VNUMBER: {
335 lua_Number f = e->u.n; 349 lua_Number f = e->u.n;
336 int i = cast(int, f); 350 int i = cast(int, f);
@@ -424,13 +438,25 @@ void luaK_exp2val (FuncState *fs, expdesc *e) {
424 438
425int luaK_exp2RK (FuncState *fs, expdesc *e) { 439int luaK_exp2RK (FuncState *fs, expdesc *e) {
426 luaK_exp2val(fs, e); 440 luaK_exp2val(fs, e);
427 if (e->k == VNUMBER && fs->nk + MAXSTACK <= MAXARG_C) { 441 switch (e->k) {
428 e->u.i.info = number_constant(fs, e->u.n); 442 case VNUMBER: case VNIL: {
429 e->k = VK; 443 if (fs->nk + MAXSTACK <= MAXARG_C) { /* constant fit in argC? */
444 e->u.i.info = (e->k == VNIL) ? nil_constant(fs) :
445 number_constant(fs, e->u.n);
446 e->k = VK;
447 return e->u.i.info + MAXSTACK;
448 }
449 else break;
450 }
451 case VK: {
452 if (e->u.i.info + MAXSTACK <= MAXARG_C) /* constant fit in argC? */
453 return e->u.i.info + MAXSTACK;
454 else break;
455 }
456 default: break;
430 } 457 }
431 else if (!(e->k == VK && e->u.i.info + MAXSTACK <= MAXARG_C)) 458 /* not a constant in the right range: put in a register */
432 luaK_exp2anyreg(fs, e); /* not a constant in the right range */ 459 return luaK_exp2anyreg(fs, e);
433 return (e->k == VK) ? e->u.i.info+MAXSTACK : e->u.i.info;
434} 460}
435 461
436 462
@@ -521,11 +547,11 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) {
521 int pc; /* pc of last jump */ 547 int pc; /* pc of last jump */
522 luaK_dischargevars(fs, e); 548 luaK_dischargevars(fs, e);
523 switch (e->k) { 549 switch (e->k) {
524 case VK: case VNUMBER: { 550 case VK: case VNUMBER: case VTRUE: {
525 pc = NO_JUMP; /* always true; do nothing */ 551 pc = NO_JUMP; /* always true; do nothing */
526 break; 552 break;
527 } 553 }
528 case VNIL: { 554 case VFALSE: {
529 pc = luaK_codeAsBc(fs, OP_JMP, 0, NO_JUMP); /* always jump */ 555 pc = luaK_codeAsBc(fs, OP_JMP, 0, NO_JUMP); /* always jump */
530 break; 556 break;
531 } 557 }
@@ -534,14 +560,8 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) {
534 pc = e->u.i.info; 560 pc = e->u.i.info;
535 break; 561 break;
536 } 562 }
537 case VRELOCABLE:
538 case VNONRELOC: {
539 pc = jumponcond(fs, e, OP_TESTF);
540 break;
541 }
542 default: { 563 default: {
543 pc = 0; /* to avoid warnings */ 564 pc = jumponcond(fs, e, OP_TESTF);
544 lua_assert(0); /* cannot happen */
545 break; 565 break;
546 } 566 }
547 } 567 }
@@ -555,23 +575,20 @@ static void luaK_goiffalse (FuncState *fs, expdesc *e) {
555 int pc; /* pc of last jump */ 575 int pc; /* pc of last jump */
556 luaK_dischargevars(fs, e); 576 luaK_dischargevars(fs, e);
557 switch (e->k) { 577 switch (e->k) {
558 case VNIL: { 578 case VNIL: case VFALSE: {
559 pc = NO_JUMP; /* always false; do nothing */ 579 pc = NO_JUMP; /* always false; do nothing */
560 break; 580 break;
561 } 581 }
562 case VJMP: { 582 case VTRUE: {
563 pc = e->u.i.info; 583 pc = luaK_codeAsBc(fs, OP_JMP, 0, NO_JUMP); /* always jump */
564 break; 584 break;
565 } 585 }
566 case VK: case VNUMBER: /* cannot optimize it (`or' must keep value) */ 586 case VJMP: {
567 case VRELOCABLE: 587 pc = e->u.i.info;
568 case VNONRELOC: {
569 pc = jumponcond(fs, e, OP_TESTT);
570 break; 588 break;
571 } 589 }
572 default: { 590 default: {
573 pc = 0; /* to avoid warnings */ 591 pc = jumponcond(fs, e, OP_TESTT);
574 lua_assert(0); /* cannot happen */
575 break; 592 break;
576 } 593 }
577 } 594 }
@@ -584,13 +601,12 @@ static void luaK_goiffalse (FuncState *fs, expdesc *e) {
584static void codenot (FuncState *fs, expdesc *e) { 601static void codenot (FuncState *fs, expdesc *e) {
585 luaK_dischargevars(fs, e); 602 luaK_dischargevars(fs, e);
586 switch (e->k) { 603 switch (e->k) {
587 case VNIL: { 604 case VNIL: case VFALSE: {
588 e->u.n = 1; 605 e->k = VTRUE;
589 e->k = VNUMBER;
590 break; 606 break;
591 } 607 }
592 case VK: case VNUMBER: { 608 case VK: case VNUMBER: case VTRUE: {
593 e->k = VNIL; 609 e->k = VFALSE;
594 break; 610 break;
595 } 611 }
596 case VJMP: { 612 case VJMP: {
@@ -719,23 +735,6 @@ void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
719 } 735 }
720 break; 736 break;
721 } 737 }
722 case OPR_EQ: case OPR_NE: {
723 luaK_exp2val(fs, e2);
724 if (e2->k == VNIL) { /* exp x= nil ? */
725 if (e1->k == VK) { /* constant x= nil ? */
726 if (op == OPR_EQ) /* constant == nil ? */
727 e1->k = VNIL; /* always false */
728 /* else always true (leave the constant itself) */
729 }
730 else {
731 OpCode opc = (op == OPR_EQ) ? OP_TESTF : OP_TESTT;
732 e1->u.i.info = jumponcond(fs, e1, opc);
733 e1->k = VJMP;
734 }
735 break;
736 }
737 /* else go through */
738 }
739 default: { 738 default: {
740 int o1, o2; 739 int o1, o2;
741 OpCode opc; 740 OpCode opc;
diff --git a/ldebug.c b/ldebug.c
index 954c68c0..410bbbbf 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -359,6 +359,10 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
359 if (testOpMode(op, OpModeT)) 359 if (testOpMode(op, OpModeT))
360 check(GET_OPCODE(pt->code[pc+1]) == OP_CJMP); 360 check(GET_OPCODE(pt->code[pc+1]) == OP_CJMP);
361 switch (op) { 361 switch (op) {
362 case OP_LOADBOOL: {
363 check(c == 0 || pc+2 < pt->sizecode); /* check its jump */
364 break;
365 }
362 case OP_LOADNIL: { 366 case OP_LOADNIL: {
363 if (a <= reg && reg <= b) 367 if (a <= reg && reg <= b)
364 last = pc; /* set registers from `a' to `b' */ 368 last = pc; /* set registers from `a' to `b' */
@@ -393,10 +397,6 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
393 pc += b; /* do the jump */ 397 pc += b; /* do the jump */
394 break; 398 break;
395 } 399 }
396 case OP_NILJMP: {
397 check(pc+2 < pt->sizecode); /* check its jump */
398 break;
399 }
400 case OP_CALL: { 400 case OP_CALL: {
401 if (b != NO_REG) { 401 if (b != NO_REG) {
402 checkreg(pt, a+b); 402 checkreg(pt, a+b);
diff --git a/lgc.c b/lgc.c
index 29586007..e70dbc77 100644
--- a/lgc.c
+++ b/lgc.c
@@ -110,7 +110,9 @@ static void markobject (GCState *st, TObject *o) {
110 break; 110 break;
111 } 111 }
112 default: { 112 default: {
113 lua_assert(ttype(o) == LUA_TNIL || ttype(o) == LUA_TNUMBER); 113 lua_assert(ttype(o) == LUA_TNIL ||
114 ttype(o) == LUA_TNUMBER ||
115 ttype(o) == LUA_TBOOLEAN);
114 break; 116 break;
115 } 117 }
116 } 118 }
@@ -196,7 +198,7 @@ static int hasmark (const TObject *o) {
196 return ismarked(hvalue(o)); 198 return ismarked(hvalue(o));
197 case LUA_TFUNCTION: 199 case LUA_TFUNCTION:
198 return clvalue(o)->c.marked; 200 return clvalue(o)->c.marked;
199 default: /* number, nil */ 201 default: /* number, nil, boolean */
200 return 1; 202 return 1;
201 } 203 }
202} 204}
diff --git a/llex.c b/llex.c
index 6fb02f17..08815def 100644
--- a/llex.c
+++ b/llex.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: llex.c,v 1.92 2001/11/16 16:29:10 roberto Exp $ 2** $Id: llex.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
3** Lexical Analyzer 3** Lexical Analyzer
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -27,9 +27,9 @@
27/* ORDER RESERVED */ 27/* ORDER RESERVED */
28static const char *const token2string [] = { 28static const char *const token2string [] = {
29 "and", "break", "do", "else", "elseif", 29 "and", "break", "do", "else", "elseif",
30 "end", "for", "function", "global", "if", 30 "end", "false", "for", "function", "global", "if",
31 "in", "local", "nil", "not", "or", "repeat", 31 "in", "local", "nil", "not", "or", "repeat",
32 "return", "then", "until", "while", "", 32 "return", "then", "true", "until", "while", "",
33 "..", "...", "==", ">=", "<=", "~=", 33 "..", "...", "==", ">=", "<=", "~=",
34 "", "", "<eof>" 34 "", "", "<eof>"
35}; 35};
diff --git a/llex.h b/llex.h
index d90ff2d7..8f0ae213 100644
--- a/llex.h
+++ b/llex.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: llex.h,v 1.39 2001/11/16 16:29:10 roberto Exp $ 2** $Id: llex.h,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
3** Lexical Analyzer 3** Lexical Analyzer
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -24,9 +24,9 @@
24enum RESERVED { 24enum RESERVED {
25 /* terminal symbols denoted by reserved words */ 25 /* terminal symbols denoted by reserved words */
26 TK_AND = FIRST_RESERVED, TK_BREAK, 26 TK_AND = FIRST_RESERVED, TK_BREAK,
27 TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FOR, TK_FUNCTION, TK_GLOBAL, TK_IF, 27 TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION,
28 TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, TK_RETURN, TK_THEN, 28 TK_GLOBAL, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
29 TK_UNTIL, TK_WHILE, 29 TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
30 /* other terminal symbols */ 30 /* other terminal symbols */
31 TK_NAME, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER, 31 TK_NAME, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER,
32 TK_STRING, TK_EOS 32 TK_STRING, TK_EOS
diff --git a/lobject.c b/lobject.c
index 67ba2b62..15ae4893 100644
--- a/lobject.c
+++ b/lobject.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.c,v 1.71 2001/10/25 19:14:14 roberto Exp $ 2** $Id: lobject.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
3** Some generic functions over Lua objects 3** Some generic functions over Lua objects
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -57,6 +57,8 @@ int luaO_equalObj (const TObject *t1, const TObject *t2) {
57 return nvalue(t1) == nvalue(t2); 57 return nvalue(t1) == nvalue(t2);
58 case LUA_TNIL: 58 case LUA_TNIL:
59 return 1; 59 return 1;
60 case LUA_TBOOLEAN:
61 return bvalue(t1) == bvalue(t2);
60 default: /* all other types are equal if pointers are equal */ 62 default: /* all other types are equal if pointers are equal */
61 return tsvalue(t1) == tsvalue(t2); 63 return tsvalue(t1) == tsvalue(t2);
62 } 64 }
diff --git a/lobject.h b/lobject.h
index bf07e3db..9d197af2 100644
--- a/lobject.h
+++ b/lobject.h
@@ -37,7 +37,8 @@ typedef union {
37 union Closure *cl; 37 union Closure *cl;
38 struct Table *h; 38 struct Table *h;
39 struct lua_TObject *v; 39 struct lua_TObject *v;
40 lua_Number n; /* LUA_TNUMBER */ 40 lua_Number n;
41 int b;
41} Value; 42} Value;
42 43
43 44
@@ -55,7 +56,10 @@ typedef struct lua_TObject {
55#define clvalue(o) ((o)->value.cl) 56#define clvalue(o) ((o)->value.cl)
56#define hvalue(o) ((o)->value.h) 57#define hvalue(o) ((o)->value.h)
57#define vvalue(o) ((o)->value.v) 58#define vvalue(o) ((o)->value.v)
59#define bvalue(o) ((o)->value.b)
58 60
61#define l_isfalse(o) (ttype(o) == LUA_TNIL || \
62 (ttype(o) == LUA_TBOOLEAN && bvalue(o) == 0))
59 63
60/* Macros to set values */ 64/* Macros to set values */
61#define setnvalue(obj,x) \ 65#define setnvalue(obj,x) \
@@ -63,6 +67,9 @@ typedef struct lua_TObject {
63 67
64#define chgnvalue(obj,x) ((obj)->value.n=(x)) 68#define chgnvalue(obj,x) ((obj)->value.n=(x))
65 69
70#define setbvalue(obj,x) \
71 { TObject *_o=(obj); _o->tt=LUA_TBOOLEAN; _o->value.b=(x); }
72
66#define setsvalue(obj,x) \ 73#define setsvalue(obj,x) \
67 { TObject *_o=(obj); _o->tt=LUA_TSTRING; _o->value.ts=(x); } 74 { TObject *_o=(obj); _o->tt=LUA_TSTRING; _o->value.ts=(x); }
68 75
diff --git a/lopcodes.c b/lopcodes.c
index c0974d96..e52805e5 100644
--- a/lopcodes.c
+++ b/lopcodes.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.c,v 1.6 2001/10/25 19:14:14 roberto Exp $ 2** $Id: lopcodes.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
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
@@ -18,6 +18,7 @@ const char *const luaP_opnames[] = {
18 "MOVE", 18 "MOVE",
19 "LOADK", 19 "LOADK",
20 "LOADINT", 20 "LOADINT",
21 "LOADBOOL",
21 "LOADNIL", 22 "LOADNIL",
22 "GETUPVAL", 23 "GETUPVAL",
23 "GETGLOBAL", 24 "GETGLOBAL",
@@ -45,7 +46,6 @@ const char *const luaP_opnames[] = {
45 "TESTGE", 46 "TESTGE",
46 "TESTT", 47 "TESTT",
47 "TESTF", 48 "TESTF",
48 "NILJMP",
49 "CALL", 49 "CALL",
50 "RETURN", 50 "RETURN",
51 "FORPREP", 51 "FORPREP",
@@ -69,6 +69,7 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = {
69 opmode(0,0,1,0, 1,0,iABC) /* OP_MOVE */ 69 opmode(0,0,1,0, 1,0,iABC) /* OP_MOVE */
70 ,opmode(0,0,0,0, 1,1,iABc) /* OP_LOADK */ 70 ,opmode(0,0,0,0, 1,1,iABc) /* OP_LOADK */
71 ,opmode(0,0,0,0, 1,0,iAsBc) /* OP_LOADINT */ 71 ,opmode(0,0,0,0, 1,0,iAsBc) /* OP_LOADINT */
72 ,opmode(0,0,0,0, 1,0,iABC) /* OP_LOADBOOL */
72 ,opmode(0,0,1,0, 1,0,iABC) /* OP_LOADNIL */ 73 ,opmode(0,0,1,0, 1,0,iABC) /* OP_LOADNIL */
73 ,opmode(0,0,0,0, 1,0,iABC) /* OP_GETUPVAL */ 74 ,opmode(0,0,0,0, 1,0,iABC) /* OP_GETUPVAL */
74 ,opmode(0,0,0,0, 1,1,iABc) /* OP_GETGLOBAL */ 75 ,opmode(0,0,0,0, 1,1,iABc) /* OP_GETGLOBAL */
@@ -96,7 +97,6 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = {
96 ,opmode(1,0,0,1, 0,0,iABC) /* OP_TESTGE */ 97 ,opmode(1,0,0,1, 0,0,iABC) /* OP_TESTGE */
97 ,opmode(1,0,1,0, 1,0,iABC) /* OP_TESTT */ 98 ,opmode(1,0,1,0, 1,0,iABC) /* OP_TESTT */
98 ,opmode(1,0,1,0, 1,0,iABC) /* OP_TESTF */ 99 ,opmode(1,0,1,0, 1,0,iABC) /* OP_TESTF */
99 ,opmode(0,0,0,0, 1,0,iABc) /* OP_NILJMP */
100 ,opmode(0,0,0,0, 0,0,iABC) /* OP_CALL */ 100 ,opmode(0,0,0,0, 0,0,iABC) /* OP_CALL */
101 ,opmode(0,0,0,0, 0,0,iABC) /* OP_RETURN */ 101 ,opmode(0,0,0,0, 0,0,iABC) /* OP_RETURN */
102 ,opmode(0,0,0,0, 0,0,iAsBc) /* OP_FORPREP */ 102 ,opmode(0,0,0,0, 0,0,iAsBc) /* OP_FORPREP */
diff --git a/lopcodes.h b/lopcodes.h
index ce09a7a4..b9539a9a 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.h,v 1.82 2001/10/25 19:14:14 roberto Exp $ 2** $Id: lopcodes.h,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
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*/
@@ -130,6 +130,7 @@ name args description
130OP_MOVE,/* A B R(A) := R(B) */ 130OP_MOVE,/* A B R(A) := R(B) */
131OP_LOADK,/* A Bc R(A) := Kst(Bc) */ 131OP_LOADK,/* A Bc R(A) := Kst(Bc) */
132OP_LOADINT,/* A sBc R(A) := (Number)sBc */ 132OP_LOADINT,/* A sBc R(A) := (Number)sBc */
133OP_LOADBOOL,/* A B C R(A) := (Bool)B; if (C) PC++ */
133OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */ 134OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */
134OP_GETUPVAL,/* A B R(A) := UpValue[B] */ 135OP_GETUPVAL,/* A B R(A) := UpValue[B] */
135 136
@@ -165,9 +166,7 @@ OP_TESTGT,/* A C test := (R(A) > R/K(C)) */
165OP_TESTGE,/* A C test := (R(A) >= R/K(C)) */ 166OP_TESTGE,/* A C test := (R(A) >= R/K(C)) */
166 167
167OP_TESTT,/* A B test := R(B); if (test) R(A) := R(B) */ 168OP_TESTT,/* A B test := R(B); if (test) R(A) := R(B) */
168OP_TESTF,/* A B test := not R(B); if (test) R(A) := nil */ 169OP_TESTF,/* A B test := not R(B); if (test) R(A) := R(B) */
169
170OP_NILJMP,/* A Bc R(A) := nil; PC++; */
171 170
172OP_CALL,/* A B C R(A), ... ,R(A+C-1) := R(A)(R(A+1), ... ,R(A+B))*/ 171OP_CALL,/* A B C R(A), ... ,R(A+C-1) := R(A)(R(A+1), ... ,R(A+B))*/
173OP_RETURN,/* A B return R(A), ... ,R(A+B-1) (see (3)) */ 172OP_RETURN,/* A B return R(A), ... ,R(A+B-1) (see (3)) */
diff --git a/lparser.c b/lparser.c
index f5d722c4..838e6336 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.160 2001/10/25 19:14:14 roberto Exp $ 2** $Id: lparser.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
3** Lua Parser 3** Lua Parser
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -701,6 +701,16 @@ static void simpleexp (LexState *ls, expdesc *v) {
701 next(ls); 701 next(ls);
702 break; 702 break;
703 } 703 }
704 case TK_TRUE: {
705 init_exp(v, VTRUE, 0);
706 next(ls);
707 break;
708 }
709 case TK_FALSE: {
710 init_exp(v, VFALSE, 0);
711 next(ls);
712 break;
713 }
704 case '{': { /* constructor */ 714 case '{': { /* constructor */
705 constructor(ls, v); 715 constructor(ls, v);
706 break; 716 break;
diff --git a/lparser.h b/lparser.h
index 724230a8..70c44543 100644
--- a/lparser.h
+++ b/lparser.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.h,v 1.35 2001/09/07 17:39:10 roberto Exp $ 2** $Id: lparser.h,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
3** Lua Parser 3** Lua Parser
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -32,6 +32,8 @@
32typedef enum { 32typedef enum {
33 VVOID, /* no value */ 33 VVOID, /* no value */
34 VNIL, 34 VNIL,
35 VTRUE,
36 VFALSE,
35 VNUMBER, /* n = value */ 37 VNUMBER, /* n = value */
36 VK, /* info = index of constant in `k' */ 38 VK, /* info = index of constant in `k' */
37 VLOCAL, /* info = local register */ 39 VLOCAL, /* info = local register */
diff --git a/ltable.c b/ltable.c
index 06e42a79..ac721f41 100644
--- a/ltable.c
+++ b/ltable.c
@@ -52,6 +52,7 @@
52#define hashnum(t,n) \ 52#define hashnum(t,n) \
53 (node(t, lmod(cast(lu_hash, cast(ls_hash, n)), sizenode(t)))) 53 (node(t, lmod(cast(lu_hash, cast(ls_hash, n)), sizenode(t))))
54#define hashstr(t,str) (node(t, lmod((str)->tsv.hash, sizenode(t)))) 54#define hashstr(t,str) (node(t, lmod((str)->tsv.hash, sizenode(t))))
55#define hashboolean(t,p) (node(t, lmod(p, sizenode(t))))
55#define hashpointer(t,p) (node(t, lmod(IntPoint(p), sizenode(t)))) 56#define hashpointer(t,p) (node(t, lmod(IntPoint(p), sizenode(t))))
56 57
57 58
@@ -65,6 +66,8 @@ Node *luaH_mainposition (const Table *t, const TObject *key) {
65 return hashnum(t, nvalue(key)); 66 return hashnum(t, nvalue(key));
66 case LUA_TSTRING: 67 case LUA_TSTRING:
67 return hashstr(t, tsvalue(key)); 68 return hashstr(t, tsvalue(key));
69 case LUA_TBOOLEAN:
70 return hashboolean(t, bvalue(key));
68 default: /* all other types are hashed as (void *) */ 71 default: /* all other types are hashed as (void *) */
69 return hashpointer(t, tsvalue(key)); 72 return hashpointer(t, tsvalue(key));
70 } 73 }
diff --git a/ltests.c b/ltests.c
index 282c58b6..feeeaee9 100644
--- a/ltests.c
+++ b/ltests.c
@@ -580,17 +580,11 @@ static int testC (lua_State *L) {
580 } 580 }
581 else if EQ("lessthan") { 581 else if EQ("lessthan") {
582 int a = getnum; 582 int a = getnum;
583 if (lua_lessthan(L, a, getnum)) 583 lua_pushboolean(L, lua_lessthan(L, a, getnum));
584 lua_pushnumber(L, 1);
585 else
586 lua_pushnil(L);
587 } 584 }
588 else if EQ("equal") { 585 else if EQ("equal") {
589 int a = getnum; 586 int a = getnum;
590 if (lua_equal(L, a, getnum)) 587 lua_pushboolean(L, lua_equal(L, a, getnum));
591 lua_pushnumber(L, 1);
592 else
593 lua_pushnil(L);
594 } 588 }
595 else if EQ("rawcall") { 589 else if EQ("rawcall") {
596 int narg = getnum; 590 int narg = getnum;
diff --git a/ltm.c b/ltm.c
index 5e5f1ab2..62c3b38a 100644
--- a/ltm.c
+++ b/ltm.c
@@ -19,7 +19,7 @@
19 19
20 20
21const char *const luaT_typenames[] = { 21const char *const luaT_typenames[] = {
22 "userdata", "nil", "number", "string", "table", "function" 22 "userdata", "nil", "number", "boolean", "string", "table", "function"
23}; 23};
24 24
25 25
diff --git a/lua.h b/lua.h
index fd7efb04..61d9e973 100644
--- a/lua.h
+++ b/lua.h
@@ -64,9 +64,10 @@ typedef int (*lua_CFunction) (lua_State *L);
64#define LUA_TUSERDATA 0 64#define LUA_TUSERDATA 0
65#define LUA_TNIL 1 65#define LUA_TNIL 1
66#define LUA_TNUMBER 2 66#define LUA_TNUMBER 2
67#define LUA_TSTRING 3 67#define LUA_TBOOLEAN 3
68#define LUA_TTABLE 4 68#define LUA_TSTRING 4
69#define LUA_TFUNCTION 5 69#define LUA_TTABLE 5
70#define LUA_TFUNCTION 6
70 71
71 72
72/* minimum Lua stack available to a C function */ 73/* minimum Lua stack available to a C function */
@@ -117,6 +118,7 @@ LUA_API int lua_stackspace (lua_State *L);
117*/ 118*/
118 119
119LUA_API int lua_isnumber (lua_State *L, int index); 120LUA_API int lua_isnumber (lua_State *L, int index);
121LUA_API int lua_istrue (lua_State *L, int index);
120LUA_API int lua_isstring (lua_State *L, int index); 122LUA_API int lua_isstring (lua_State *L, int index);
121LUA_API int lua_iscfunction (lua_State *L, int index); 123LUA_API int lua_iscfunction (lua_State *L, int index);
122LUA_API int lua_type (lua_State *L, int index); 124LUA_API int lua_type (lua_State *L, int index);
@@ -126,6 +128,7 @@ LUA_API int lua_equal (lua_State *L, int index1, int index2);
126LUA_API int lua_lessthan (lua_State *L, int index1, int index2); 128LUA_API int lua_lessthan (lua_State *L, int index1, int index2);
127 129
128LUA_API lua_Number lua_tonumber (lua_State *L, int index); 130LUA_API lua_Number lua_tonumber (lua_State *L, int index);
131LUA_API int lua_toboolean (lua_State *L, int index);
129LUA_API const char *lua_tostring (lua_State *L, int index); 132LUA_API const char *lua_tostring (lua_State *L, int index);
130LUA_API size_t lua_strlen (lua_State *L, int index); 133LUA_API size_t lua_strlen (lua_State *L, int index);
131LUA_API lua_CFunction lua_tocfunction (lua_State *L, int index); 134LUA_API lua_CFunction lua_tocfunction (lua_State *L, int index);
@@ -141,6 +144,7 @@ LUA_API void lua_pushnumber (lua_State *L, lua_Number n);
141LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len); 144LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len);
142LUA_API void lua_pushstring (lua_State *L, const char *s); 145LUA_API void lua_pushstring (lua_State *L, const char *s);
143LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n); 146LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
147LUA_API void lua_pushboolean (lua_State *L, int b);
144 148
145 149
146/* 150/*
@@ -222,6 +226,7 @@ LUA_API int lua_getweakmode (lua_State *L, int index);
222#define lua_istable(L,n) (lua_type(L,n) == LUA_TTABLE) 226#define lua_istable(L,n) (lua_type(L,n) == LUA_TTABLE)
223#define lua_isuserdata(L,n) (lua_type(L,n) == LUA_TUSERDATA) 227#define lua_isuserdata(L,n) (lua_type(L,n) == LUA_TUSERDATA)
224#define lua_isnil(L,n) (lua_type(L,n) == LUA_TNIL) 228#define lua_isnil(L,n) (lua_type(L,n) == LUA_TNIL)
229#define lua_isboolean(L,n) (lua_type(L,n) == LUA_TBOOLEAN)
225#define lua_isnull(L,n) (lua_type(L,n) == LUA_TNONE) 230#define lua_isnull(L,n) (lua_type(L,n) == LUA_TNONE)
226 231
227#define lua_pushliteral(L, s) lua_pushlstring(L, "" s, \ 232#define lua_pushliteral(L, s) lua_pushlstring(L, "" s, \
diff --git a/lvm.c b/lvm.c
index b49d8365..253c01a4 100644
--- a/lvm.c
+++ b/lvm.c
@@ -223,7 +223,7 @@ int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r) {
223 else { /* try TM */ 223 else { /* try TM */
224 if (!call_binTM(L, l, r, L->top, TM_LT)) 224 if (!call_binTM(L, l, r, L->top, TM_LT))
225 luaG_ordererror(L, l, r); 225 luaG_ordererror(L, l, r);
226 return (ttype(L->top) != LUA_TNIL); 226 return !l_isfalse(L->top);
227 } 227 }
228} 228}
229 229
@@ -369,6 +369,11 @@ StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) {
369 setnvalue(ra, (lua_Number)GETARG_sBc(i)); 369 setnvalue(ra, (lua_Number)GETARG_sBc(i));
370 break; 370 break;
371 } 371 }
372 case OP_LOADBOOL: {
373 setbvalue(ra, GETARG_B(i));
374 if (GETARG_C(i)) pc++; /* skip next instruction (if C) */
375 break;
376 }
372 case OP_LOADNIL: { 377 case OP_LOADNIL: {
373 TObject *rb = RB(i); 378 TObject *rb = RB(i);
374 do { 379 do {
@@ -450,11 +455,8 @@ StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) {
450 break; 455 break;
451 } 456 }
452 case OP_NOT: { 457 case OP_NOT: {
453 if (ttype(RB(i)) == LUA_TNIL) { 458 int res = l_isfalse(RB(i)); /* next assignment may change this value */
454 setnvalue(ra, 1); 459 setbvalue(ra, res);
455 } else {
456 setnilvalue(ra);
457 }
458 break; 460 break;
459 } 461 }
460 case OP_CONCAT: { 462 case OP_CONCAT: {
@@ -508,7 +510,7 @@ StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) {
508 case OP_TESTT: { 510 case OP_TESTT: {
509 StkId rb = RB(i); 511 StkId rb = RB(i);
510 lua_assert(GET_OPCODE(*pc) == OP_CJMP); 512 lua_assert(GET_OPCODE(*pc) == OP_CJMP);
511 if (ttype(rb) != LUA_TNIL) { 513 if (!l_isfalse(rb)) {
512 setobj(ra, rb); 514 setobj(ra, rb);
513 dojump(pc, *pc); 515 dojump(pc, *pc);
514 } 516 }
@@ -516,19 +518,15 @@ StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) {
516 break; 518 break;
517 } 519 }
518 case OP_TESTF: { 520 case OP_TESTF: {
521 StkId rb = RB(i);
519 lua_assert(GET_OPCODE(*pc) == OP_CJMP); 522 lua_assert(GET_OPCODE(*pc) == OP_CJMP);
520 if (ttype(RB(i)) == LUA_TNIL) { 523 if (l_isfalse(rb)) {
521 setnilvalue(ra); 524 setobj(ra, rb);
522 dojump(pc, *pc); 525 dojump(pc, *pc);
523 } 526 }
524 pc++; 527 pc++;
525 break; 528 break;
526 } 529 }
527 case OP_NILJMP: {
528 setnilvalue(ra);
529 pc++;
530 break;
531 }
532 case OP_CALL: { 530 case OP_CALL: {
533 int c; 531 int c;
534 int b = GETARG_B(i); 532 int b = GETARG_B(i);