new type `boolean'

This commit is contained in:
Roberto Ierusalimschy 2001-12-11 20:48:44 -02:00
parent ed9be5e1f0
commit 9aff171f3b
18 changed files with 166 additions and 121 deletions

23
lapi.c
View File

@ -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)

View File

@ -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;
}

123
lcode.c
View File

@ -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 VTRUE: {
pc = luaK_codeAsBc(fs, OP_JMP, 0, NO_JUMP); /* always jump */
break;
}
case VJMP: {
pc = e->u.i.info;
break;
}
case VK: case VNUMBER: /* cannot optimize it (`or' must keep value) */
case VRELOCABLE:
case VNONRELOC: {
pc = jumponcond(fs, e, OP_TESTT);
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;

View File

@ -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);

6
lgc.c
View File

@ -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;
}
}

6
llex.c
View File

@ -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>"
};

8
llex.h
View File

@ -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

View File

@ -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);
}

View File

@ -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); }

View File

@ -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 */

View File

@ -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)) */

View File

@ -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;

View File

@ -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 */

View File

@ -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));
}

View File

@ -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;

2
ltm.c
View File

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

11
lua.h
View File

@ -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, \

26
lvm.c
View File

@ -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);