Roberto Ierusalimschy 23 лет назад
Родитель
Сommit
9aff171f3b
18 измененных файлов с 166 добавлено и 121 удалено
  1. 23 0
      lapi.c
  2. 10 9
      lbaselib.c
  3. 61 62
      lcode.c
  4. 4 4
      ldebug.c
  5. 4 2
      lgc.c
  6. 3 3
      llex.c
  7. 4 4
      llex.h
  8. 3 1
      lobject.c
  9. 8 1
      lobject.h
  10. 3 3
      lopcodes.c
  11. 3 4
      lopcodes.h
  12. 11 1
      lparser.c
  13. 3 1
      lparser.h
  14. 3 0
      ltable.c
  15. 2 8
      ltests.c
  16. 1 1
      ltm.c
  17. 8 3
      lua.h
  18. 12 14
      lvm.c

+ 23 - 0
lapi.c

@@ -174,6 +174,12 @@ LUA_API int lua_isnumber (lua_State *L, int index) {
 }
 
 
+LUA_API int lua_istrue (lua_State *L, int index) {
+  TObject *o = luaA_indexAcceptable(L, index);
+  return (o != NULL && !l_isfalse(o));
+}
+
+
 LUA_API int lua_isstring (lua_State *L, int index) {
   int t = lua_type(L, index);
   return (t == LUA_TSTRING || t == LUA_TNUMBER);
@@ -213,6 +219,15 @@ LUA_API lua_Number lua_tonumber (lua_State *L, int index) {
 }
 
 
+LUA_API int lua_toboolean (lua_State *L, int index) {
+  const TObject *o = luaA_indexAcceptable(L, index);
+  if (o != NULL && (ttype(o) == LUA_TBOOLEAN))
+    return bvalue(o);
+  else
+    return -1;
+}
+
+
 LUA_API const char *lua_tostring (lua_State *L, int index) {
   StkId o = luaA_indexAcceptable(L, index);
   if (o == NULL)
@@ -323,6 +338,14 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
 }
 
 
+LUA_API void lua_pushboolean (lua_State *L, int b) {
+  lua_lock(L);
+  setbvalue(L->top, b);
+  api_incr_top(L);
+  lua_unlock(L);
+}
+
+
 
 /*
 ** get functions (Lua -> stack)

+ 10 - 9
lbaselib.c

@@ -216,10 +216,8 @@ static int luaB_type (lua_State *L) {
   if (lua_isnull(L, 2))
     lua_pushstring(L, lua_typename(L, lua_type(L, 1)));
   else {
-    if (strcmp(lua_typename(L, lua_type(L, 1)), luaL_check_string(L, 2)) == 0)
-      lua_pushnumber(L, 1);
-    else
-      lua_pushnil(L);
+    lua_pushboolean(L,
+       (strcmp(lua_typename(L, lua_type(L, 1)), luaL_check_string(L, 2)) == 0));
   }
   return 1;
 }
@@ -401,8 +399,12 @@ static int luaB_tostring (lua_State *L) {
     case LUA_TSTRING:
       lua_pushvalue(L, 1);
       return 1;
+    case LUA_TBOOLEAN:
+      lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false"));
+      return 1;
     case LUA_TTABLE:
-      sprintf(buff, "%.40s: %p", lua_typename(L, lua_type(L, 1)), lua_topointer(L, 1));
+      sprintf(buff, "%.40s: %p", lua_typename(L, lua_type(L, 1)),
+                                 lua_topointer(L, 1));
       break;
     case LUA_TFUNCTION:
       sprintf(buff, "function: %p", lua_topointer(L, 1));
@@ -464,9 +466,8 @@ static int luaB_foreach (lua_State *L) {
 
 static int luaB_assert (lua_State *L) {
   luaL_check_any(L, 1);
-  if (lua_isnil(L, 1))
-    luaL_verror(L, "assertion failed!  %.90s",
-                   luaL_opt_string(L, 2, ""));
+  if (!lua_istrue(L, 1))
+    luaL_verror(L, "assertion failed!  %.90s", luaL_opt_string(L, 2, ""));
   lua_settop(L, 1);
   return 1;
 }
@@ -542,7 +543,7 @@ static int sort_comp (lua_State *L, int a, int b) {
     lua_pushvalue(L, a-1);  /* -1 to compensate function */
     lua_pushvalue(L, b-2);  /* -2 to compensate function and `a' */
     lua_rawcall(L, 2, 1);
-    res = !lua_isnil(L, -1);
+    res = lua_istrue(L, -1);
     lua_pop(L, 1);
     return res;
   }

+ 61 - 62
lcode.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lcode.c,v 1.82 2001/09/07 17:39:10 roberto Exp $
+** $Id: lcode.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -221,10 +221,10 @@ static void freeexp (FuncState *fs, expdesc *e) {
 }
 
 
-static int addk (FuncState *fs, TObject *k) {
+static int addk (FuncState *fs, TObject *k, TObject *v) {
   const TObject *index = luaH_get(fs->h, k);
   if (ttype(index) == LUA_TNUMBER) {
-    lua_assert(luaO_equalObj(&fs->f->k[cast(int, nvalue(index))], k));
+    lua_assert(luaO_equalObj(&fs->f->k[cast(int, nvalue(index))], v));
     return cast(int, nvalue(index));
   }
   else {  /* constant not found; create a new entry */
@@ -232,7 +232,7 @@ static int addk (FuncState *fs, TObject *k) {
     Proto *f = fs->f;
     luaM_growvector(fs->L, f->k, fs->nk, f->sizek, TObject,
                     MAXARG_Bc, "constant table overflow");
-    setobj(&f->k[fs->nk], k);
+    setobj(&f->k[fs->nk], v);
     setnvalue(&o, fs->nk);
     luaH_set(fs->L, fs->h, k, &o);
     return fs->nk++;
@@ -243,14 +243,22 @@ static int addk (FuncState *fs, TObject *k) {
 int luaK_stringk (FuncState *fs, TString *s) {
   TObject o;
   setsvalue(&o, s);
-  return addk(fs, &o);
+  return addk(fs, &o, &o);
 }
 
 
 static int number_constant (FuncState *fs, lua_Number r) {
   TObject o;
   setnvalue(&o, r);
-  return addk(fs, &o);
+  return addk(fs, &o, &o);
+}
+
+
+static int nil_constant (FuncState *fs) {
+  TObject k, v;
+  setnilvalue(&v);
+  sethvalue(&k, fs->h);  /* cannot use nil as key; instead use table itself */
+  return addk(fs, &k, &v);
 }
 
 
@@ -298,27 +306,29 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) {
 }
 
 
-static int code_label (FuncState *fs, OpCode op, int A, int sBc) {
+static int code_label (FuncState *fs, int A, int b, int jump) {
   luaK_getlabel(fs);  /* those instructions may be jump targets */
-  return luaK_codeAsBc(fs, op, A, sBc);
+  return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
 }
 
 
 static void dischargejumps (FuncState *fs, expdesc *e, int reg) {
   if (hasjumps(e)) {
     int final;  /* position after whole expression */
-    int p_nil = NO_JUMP;  /* position of an eventual PUSHNIL */
-    int p_1 = NO_JUMP;  /* position of an eventual PUSHINT */
+    int p_f = NO_JUMP;  /* position of an eventual PUSH false */
+    int p_t = NO_JUMP;  /* position of an eventual PUSH true */
     if (need_value(fs, e->f, OP_TESTF) || need_value(fs, e->t, OP_TESTT)) {
       /* expression needs values */
-      if (e->k != VJMP)
-        code_label(fs, OP_JMP, 0, 2);  /* to jump over both pushes */
-      p_nil = code_label(fs, OP_NILJMP, reg, 0);
-      p_1 = code_label(fs, OP_LOADINT, reg, 1);
+      if (e->k != VJMP) {
+        luaK_getlabel(fs);  /* these instruction may be jump target */
+        luaK_codeAsBc(fs, OP_JMP, 0, 2);  /* to jump over both pushes */
+      }
+      p_f = code_label(fs, reg, 0, 1);
+      p_t = code_label(fs, reg, 1, 0);
     }
     final = luaK_getlabel(fs);
-    luaK_patchlistaux(fs, e->f, p_nil, NO_REG, final,    reg, p_nil);
-    luaK_patchlistaux(fs, e->t, final,    reg,   p_1, NO_REG,   p_1);
+    luaK_patchlistaux(fs, e->f, p_f, NO_REG, final, reg, p_f);
+    luaK_patchlistaux(fs, e->t, final, reg, p_t, NO_REG, p_t);
   }
   e->f = e->t = NO_JUMP;
 }
@@ -331,6 +341,10 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
       luaK_nil(fs, reg, 1);
       break;
     }
+    case VFALSE:  case VTRUE: {
+      luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
+      break;
+    }
     case VNUMBER: {
       lua_Number f = e->u.n;
       int i = cast(int, f);
@@ -424,13 +438,25 @@ void luaK_exp2val (FuncState *fs, expdesc *e) {
 
 int luaK_exp2RK (FuncState *fs, expdesc *e) {
   luaK_exp2val(fs, e);
-  if (e->k == VNUMBER && fs->nk + MAXSTACK <= MAXARG_C) {
-      e->u.i.info = number_constant(fs, e->u.n);
-      e->k = VK;
+  switch (e->k) {
+    case VNUMBER: case VNIL: {
+      if (fs->nk + MAXSTACK <= MAXARG_C) {  /* constant fit in argC? */
+        e->u.i.info = (e->k == VNIL) ? nil_constant(fs) :
+                                       number_constant(fs, e->u.n);
+        e->k = VK;
+        return e->u.i.info + MAXSTACK;
+      }
+      else break;
+    }
+    case VK: {
+      if (e->u.i.info + MAXSTACK <= MAXARG_C)  /* constant fit in argC? */
+        return e->u.i.info + MAXSTACK;
+      else break;
+    }
+    default: break;
   }
-  else if (!(e->k == VK && e->u.i.info + MAXSTACK <= MAXARG_C))
-    luaK_exp2anyreg(fs, e);  /* not a constant in the right range */
-  return (e->k == VK) ? e->u.i.info+MAXSTACK : e->u.i.info;
+  /* not a constant in the right range: put in a register */
+  return luaK_exp2anyreg(fs, e);
 }
 
 
@@ -521,11 +547,11 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) {
   int pc;  /* pc of last jump */
   luaK_dischargevars(fs, e);
   switch (e->k) {
-    case VK: case VNUMBER: {
+    case VK: case VNUMBER: case VTRUE: {
       pc = NO_JUMP;  /* always true; do nothing */
       break;
     }
-    case VNIL: {
+    case VFALSE: {
       pc = luaK_codeAsBc(fs, OP_JMP, 0, NO_JUMP);  /* always jump */
       break;
     }
@@ -534,14 +560,8 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) {
       pc = e->u.i.info;
       break;
     }
-    case VRELOCABLE:
-    case VNONRELOC: {
-      pc = jumponcond(fs, e, OP_TESTF);
-      break;
-    }
     default: {
-      pc = 0;  /* to avoid warnings */
-      lua_assert(0);  /* cannot happen */
+      pc = jumponcond(fs, e, OP_TESTF);
       break;
     }
   }
@@ -555,23 +575,20 @@ static void luaK_goiffalse (FuncState *fs, expdesc *e) {
   int pc;  /* pc of last jump */
   luaK_dischargevars(fs, e);
   switch (e->k) {
-    case VNIL: {
+    case VNIL: case VFALSE: {
       pc = NO_JUMP;  /* always false; do nothing */
       break;
     }
-    case VJMP: {
-      pc = e->u.i.info;
+    case VTRUE: {
+      pc = luaK_codeAsBc(fs, OP_JMP, 0, NO_JUMP);  /* always jump */
       break;
     }
-    case VK: case VNUMBER:  /* cannot optimize it (`or' must keep value) */
-    case VRELOCABLE:
-    case VNONRELOC: {
-      pc = jumponcond(fs, e, OP_TESTT);
+    case VJMP: {
+      pc = e->u.i.info;
       break;
     }
     default: {
-      pc = 0;  /* to avoid warnings */
-      lua_assert(0);  /* cannot happen */
+      pc = jumponcond(fs, e, OP_TESTT);
       break;
     }
   }
@@ -584,13 +601,12 @@ static void luaK_goiffalse (FuncState *fs, expdesc *e) {
 static void codenot (FuncState *fs, expdesc *e) {
   luaK_dischargevars(fs, e);
   switch (e->k) {
-    case VNIL: {
-      e->u.n = 1;
-      e->k = VNUMBER;
+    case VNIL: case VFALSE: {
+      e->k = VTRUE;
       break;
     }
-    case VK:  case VNUMBER: {
-      e->k = VNIL;
+    case VK:  case VNUMBER: case VTRUE: {
+      e->k = VFALSE;
       break;
     }
     case VJMP: {
@@ -719,23 +735,6 @@ void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
       }
       break;
     }
-    case OPR_EQ: case OPR_NE: {
-      luaK_exp2val(fs, e2);
-      if (e2->k == VNIL) {  /* exp x= nil ? */
-        if (e1->k == VK) {  /* constant x= nil ? */
-          if (op == OPR_EQ)  /* constant == nil ? */
-            e1->k = VNIL;  /* always false */
-          /* else always true (leave the constant itself) */
-        }
-        else {
-          OpCode opc = (op == OPR_EQ) ? OP_TESTF : OP_TESTT;
-          e1->u.i.info = jumponcond(fs, e1, opc);
-          e1->k = VJMP;
-        }
-        break;
-      }
-      /* else go through */
-    }
     default: {
       int o1, o2;
       OpCode opc;

+ 4 - 4
ldebug.c

@@ -359,6 +359,10 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
     if (testOpMode(op, OpModeT))
       check(GET_OPCODE(pt->code[pc+1]) == OP_CJMP);
     switch (op) {
+      case OP_LOADBOOL: {
+        check(c == 0 || pc+2 < pt->sizecode);  /* check its jump */
+        break;
+      }
       case OP_LOADNIL: {
         if (a <= reg && reg <= b)
           last = pc;  /* set registers from `a' to `b' */
@@ -393,10 +397,6 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
           pc += b;  /* do the jump */
         break;
       }
-      case OP_NILJMP: {
-        check(pc+2 < pt->sizecode);  /* check its jump */
-        break;
-      }
       case OP_CALL: {
         if (b != NO_REG) {
           checkreg(pt, a+b);

+ 4 - 2
lgc.c

@@ -110,7 +110,9 @@ static void markobject (GCState *st, TObject *o) {
       break;
     }
     default: {
-      lua_assert(ttype(o) == LUA_TNIL || ttype(o) == LUA_TNUMBER);
+      lua_assert(ttype(o) == LUA_TNIL ||
+                 ttype(o) == LUA_TNUMBER ||
+                 ttype(o) == LUA_TBOOLEAN);
       break;
     }
   }
@@ -196,7 +198,7 @@ static int hasmark (const TObject *o) {
       return ismarked(hvalue(o));
     case LUA_TFUNCTION:
       return clvalue(o)->c.marked;
-    default:  /* number, nil */
+    default:  /* number, nil, boolean */
       return 1;
   }
 }

+ 3 - 3
llex.c

@@ -1,5 +1,5 @@
 /*
-** $Id: llex.c,v 1.92 2001/11/16 16:29:10 roberto Exp $
+** $Id: llex.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
 ** Lexical Analyzer
 ** See Copyright Notice in lua.h
 */
@@ -27,9 +27,9 @@
 /* ORDER RESERVED */
 static const char *const token2string [] = {
     "and", "break", "do", "else", "elseif",
-    "end", "for", "function", "global", "if",
+    "end", "false", "for", "function", "global", "if",
     "in", "local", "nil", "not", "or", "repeat",
-    "return", "then", "until", "while", "",
+    "return", "then", "true", "until", "while", "",
     "..", "...", "==", ">=", "<=", "~=",
     "", "", "<eof>"
 };

+ 4 - 4
llex.h

@@ -1,5 +1,5 @@
 /*
-** $Id: llex.h,v 1.39 2001/11/16 16:29:10 roberto Exp $
+** $Id: llex.h,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
 ** Lexical Analyzer
 ** See Copyright Notice in lua.h
 */
@@ -24,9 +24,9 @@
 enum RESERVED {
   /* terminal symbols denoted by reserved words */
   TK_AND = FIRST_RESERVED, TK_BREAK,
-  TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FOR, TK_FUNCTION, TK_GLOBAL, TK_IF,
-  TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, TK_RETURN, TK_THEN,
-  TK_UNTIL, TK_WHILE,
+  TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION,
+  TK_GLOBAL, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
+  TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
   /* other terminal symbols */
   TK_NAME, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER,
   TK_STRING, TK_EOS

+ 3 - 1
lobject.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lobject.c,v 1.71 2001/10/25 19:14:14 roberto Exp $
+** $Id: lobject.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
 ** Some generic functions over Lua objects
 ** See Copyright Notice in lua.h
 */
@@ -57,6 +57,8 @@ int luaO_equalObj (const TObject *t1, const TObject *t2) {
       return nvalue(t1) == nvalue(t2);
     case LUA_TNIL:
       return 1;
+    case LUA_TBOOLEAN:
+      return bvalue(t1) == bvalue(t2);
     default:  /* all other types are equal if pointers are equal */
       return tsvalue(t1) == tsvalue(t2);
   }

+ 8 - 1
lobject.h

@@ -37,7 +37,8 @@ typedef union {
   union Closure *cl;
   struct Table *h;
   struct lua_TObject *v;
-  lua_Number n;		/* LUA_TNUMBER */
+  lua_Number n;
+  int b;
 } Value;
 
 
@@ -55,7 +56,10 @@ typedef struct lua_TObject {
 #define clvalue(o)      ((o)->value.cl)
 #define hvalue(o)       ((o)->value.h)
 #define vvalue(o)	((o)->value.v)
+#define bvalue(o)	((o)->value.b)
 
+#define l_isfalse(o)	(ttype(o) == LUA_TNIL || \
+			(ttype(o) == LUA_TBOOLEAN && bvalue(o) == 0))
 
 /* Macros to set values */
 #define setnvalue(obj,x) \
@@ -63,6 +67,9 @@ typedef struct lua_TObject {
 
 #define chgnvalue(obj,x)	((obj)->value.n=(x))
 
+#define setbvalue(obj,x) \
+  { TObject *_o=(obj); _o->tt=LUA_TBOOLEAN; _o->value.b=(x); }
+
 #define setsvalue(obj,x) \
   { TObject *_o=(obj); _o->tt=LUA_TSTRING; _o->value.ts=(x); }
 

+ 3 - 3
lopcodes.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lopcodes.c,v 1.6 2001/10/25 19:14:14 roberto Exp $
+** $Id: lopcodes.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
 ** extracted automatically from lopcodes.h by mkprint.lua
 ** DO NOT EDIT
 ** See Copyright Notice in lua.h
@@ -18,6 +18,7 @@ const char *const luaP_opnames[] = {
   "MOVE",
   "LOADK",
   "LOADINT",
+  "LOADBOOL",
   "LOADNIL",
   "GETUPVAL",
   "GETGLOBAL",
@@ -45,7 +46,6 @@ const char *const luaP_opnames[] = {
   "TESTGE",
   "TESTT",
   "TESTF",
-  "NILJMP",
   "CALL",
   "RETURN",
   "FORPREP",
@@ -69,6 +69,7 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = {
   opmode(0,0,1,0, 1,0,iABC)		/* OP_MOVE */
  ,opmode(0,0,0,0, 1,1,iABc)		/* OP_LOADK */
  ,opmode(0,0,0,0, 1,0,iAsBc)		/* OP_LOADINT */
+ ,opmode(0,0,0,0, 1,0,iABC)		/* OP_LOADBOOL */
  ,opmode(0,0,1,0, 1,0,iABC)		/* OP_LOADNIL */
  ,opmode(0,0,0,0, 1,0,iABC)		/* OP_GETUPVAL */
  ,opmode(0,0,0,0, 1,1,iABc)		/* OP_GETGLOBAL */
@@ -96,7 +97,6 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = {
  ,opmode(1,0,0,1, 0,0,iABC)		/* OP_TESTGE */
  ,opmode(1,0,1,0, 1,0,iABC)		/* OP_TESTT */
  ,opmode(1,0,1,0, 1,0,iABC)		/* OP_TESTF */
- ,opmode(0,0,0,0, 1,0,iABc)		/* OP_NILJMP */
  ,opmode(0,0,0,0, 0,0,iABC)		/* OP_CALL */
  ,opmode(0,0,0,0, 0,0,iABC)		/* OP_RETURN */
  ,opmode(0,0,0,0, 0,0,iAsBc)		/* OP_FORPREP */

+ 3 - 4
lopcodes.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lopcodes.h,v 1.82 2001/10/25 19:14:14 roberto Exp $
+** $Id: lopcodes.h,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
 ** Opcodes for Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -130,6 +130,7 @@ name		args	description
 OP_MOVE,/*	A B	R(A) := R(B)					*/
 OP_LOADK,/*	A Bc	R(A) := Kst(Bc)					*/
 OP_LOADINT,/*	A sBc	R(A) := (Number)sBc				*/
+OP_LOADBOOL,/*	A B C	R(A) := (Bool)B; if (C) PC++			*/
 OP_LOADNIL,/*	A B	R(A) := ... := R(B) := nil			*/
 OP_GETUPVAL,/*	A B	R(A) := UpValue[B]				*/
 
@@ -165,9 +166,7 @@ OP_TESTGT,/*	A C	test := (R(A) > R/K(C))				*/
 OP_TESTGE,/*	A C	test := (R(A) >= R/K(C))			*/
 
 OP_TESTT,/*	A B	test := R(B); if (test) R(A) := R(B)		*/
-OP_TESTF,/*	A B	test := not R(B); if (test) R(A) := nil		*/
-
-OP_NILJMP,/*	A Bc	R(A) := nil; PC++;				*/
+OP_TESTF,/*	A B	test := not R(B); if (test) R(A) := R(B)	*/
 
 OP_CALL,/*	A B C	R(A), ... ,R(A+C-1) := R(A)(R(A+1), ... ,R(A+B))*/
 OP_RETURN,/*	A B	return R(A), ... ,R(A+B-1)	(see (3))	*/

+ 11 - 1
lparser.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lparser.c,v 1.160 2001/10/25 19:14:14 roberto Exp $
+** $Id: lparser.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
 ** Lua Parser
 ** See Copyright Notice in lua.h
 */
@@ -701,6 +701,16 @@ static void simpleexp (LexState *ls, expdesc *v) {
       next(ls);
       break;
     }
+    case TK_TRUE: {
+      init_exp(v, VTRUE, 0);
+      next(ls);
+      break;
+    }
+    case TK_FALSE: {
+      init_exp(v, VFALSE, 0);
+      next(ls);
+      break;
+    }
     case '{': {  /* constructor */
       constructor(ls, v);
       break;

+ 3 - 1
lparser.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lparser.h,v 1.35 2001/09/07 17:39:10 roberto Exp $
+** $Id: lparser.h,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
 ** Lua Parser
 ** See Copyright Notice in lua.h
 */
@@ -32,6 +32,8 @@
 typedef enum {
   VVOID,	/* no value */
   VNIL,
+  VTRUE,
+  VFALSE,
   VNUMBER,	/* n = value */
   VK,		/* info = index of constant in `k' */
   VLOCAL,	/* info = local register */

+ 3 - 0
ltable.c

@@ -52,6 +52,7 @@
 #define hashnum(t,n)	\
            (node(t, lmod(cast(lu_hash, cast(ls_hash, n)), sizenode(t))))
 #define hashstr(t,str)	 (node(t, lmod((str)->tsv.hash, sizenode(t))))
+#define hashboolean(t,p) (node(t, lmod(p, sizenode(t))))
 #define hashpointer(t,p) (node(t, lmod(IntPoint(p), sizenode(t))))
 
 
@@ -65,6 +66,8 @@ Node *luaH_mainposition (const Table *t, const TObject *key) {
       return hashnum(t, nvalue(key));
     case LUA_TSTRING:
       return hashstr(t, tsvalue(key));
+    case LUA_TBOOLEAN:
+      return hashboolean(t, bvalue(key));
     default:  /* all other types are hashed as (void *) */
       return hashpointer(t, tsvalue(key));
   }

+ 2 - 8
ltests.c

@@ -580,17 +580,11 @@ static int testC (lua_State *L) {
     }
     else if EQ("lessthan") {
       int a = getnum;
-      if (lua_lessthan(L, a, getnum))
-        lua_pushnumber(L, 1);
-      else
-        lua_pushnil(L);
+      lua_pushboolean(L, lua_lessthan(L, a, getnum));
     }
     else if EQ("equal") {
       int a = getnum;
-      if (lua_equal(L, a, getnum))
-        lua_pushnumber(L, 1);
-      else
-        lua_pushnil(L);
+      lua_pushboolean(L, lua_equal(L, a, getnum));
     }
     else if EQ("rawcall") {
       int narg = getnum;

+ 1 - 1
ltm.c

@@ -19,7 +19,7 @@
 
 
 const char *const luaT_typenames[] = {
-  "userdata", "nil", "number", "string", "table", "function"
+  "userdata", "nil", "number", "boolean", "string", "table", "function"
 };
 
 

+ 8 - 3
lua.h

@@ -64,9 +64,10 @@ typedef int (*lua_CFunction) (lua_State *L);
 #define LUA_TUSERDATA	0
 #define LUA_TNIL	1
 #define LUA_TNUMBER	2
-#define LUA_TSTRING	3
-#define LUA_TTABLE	4
-#define LUA_TFUNCTION	5
+#define LUA_TBOOLEAN	3
+#define LUA_TSTRING	4
+#define LUA_TTABLE	5
+#define LUA_TFUNCTION	6
 
 
 /* minimum Lua stack available to a C function */
@@ -117,6 +118,7 @@ LUA_API int   lua_stackspace (lua_State *L);
 */
 
 LUA_API int             lua_isnumber (lua_State *L, int index);
+LUA_API int             lua_istrue (lua_State *L, int index);
 LUA_API int             lua_isstring (lua_State *L, int index);
 LUA_API int             lua_iscfunction (lua_State *L, int index);
 LUA_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);
 LUA_API int            lua_lessthan (lua_State *L, int index1, int index2);
 
 LUA_API lua_Number      lua_tonumber (lua_State *L, int index);
+LUA_API int             lua_toboolean (lua_State *L, int index);
 LUA_API const char *lua_tostring (lua_State *L, int index);
 LUA_API size_t          lua_strlen (lua_State *L, int index);
 LUA_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);
 LUA_API void  lua_pushlstring (lua_State *L, const char *s, size_t len);
 LUA_API void  lua_pushstring (lua_State *L, const char *s);
 LUA_API void  lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
+LUA_API void  lua_pushboolean (lua_State *L, int b);
 
 
 /*
@@ -222,6 +226,7 @@ LUA_API int   lua_getweakmode (lua_State *L, int index);
 #define lua_istable(L,n)	(lua_type(L,n) == LUA_TTABLE)
 #define lua_isuserdata(L,n)	(lua_type(L,n) == LUA_TUSERDATA)
 #define lua_isnil(L,n)		(lua_type(L,n) == LUA_TNIL)
+#define lua_isboolean(L,n)	(lua_type(L,n) == LUA_TBOOLEAN)
 #define lua_isnull(L,n)		(lua_type(L,n) == LUA_TNONE)
 
 #define lua_pushliteral(L, s)	lua_pushlstring(L, "" s, \

+ 12 - 14
lvm.c

@@ -223,7 +223,7 @@ int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r) {
   else {  /* try TM */
     if (!call_binTM(L, l, r, L->top, TM_LT))
       luaG_ordererror(L, l, r);
-    return (ttype(L->top) != LUA_TNIL);
+    return !l_isfalse(L->top);
   }
 }
 
@@ -369,6 +369,11 @@ StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) {
         setnvalue(ra, (lua_Number)GETARG_sBc(i));
         break;
       }
+      case OP_LOADBOOL: {
+        setbvalue(ra, GETARG_B(i));
+        if (GETARG_C(i)) pc++;  /* skip next instruction (if C) */
+        break;
+      }
       case OP_LOADNIL: {
         TObject *rb = RB(i);
         do {
@@ -450,11 +455,8 @@ StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) {
         break;
       }
       case OP_NOT: {
-        if (ttype(RB(i)) == LUA_TNIL) {
-          setnvalue(ra, 1);
-        } else {
-          setnilvalue(ra);
-        }
+        int res = l_isfalse(RB(i));  /* next assignment may change this value */
+        setbvalue(ra, res);
         break;
       }
       case OP_CONCAT: {
@@ -508,7 +510,7 @@ StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) {
       case OP_TESTT: {
         StkId rb = RB(i);
         lua_assert(GET_OPCODE(*pc) == OP_CJMP);
-        if (ttype(rb) != LUA_TNIL) {
+        if (!l_isfalse(rb)) {
           setobj(ra, rb);
           dojump(pc, *pc);
         }
@@ -516,19 +518,15 @@ StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) {
         break;
       }
       case OP_TESTF: {
+        StkId rb = RB(i);
         lua_assert(GET_OPCODE(*pc) == OP_CJMP);
-        if (ttype(RB(i)) == LUA_TNIL) {
-          setnilvalue(ra);
+        if (l_isfalse(rb)) {
+          setobj(ra, rb);
           dojump(pc, *pc);
         }
         pc++;
         break;
       }
-      case OP_NILJMP: {
-        setnilvalue(ra);
-        pc++;
-        break;
-      }
       case OP_CALL: {
         int c;
         int b = GETARG_B(i);