mirror of
https://github.com/lua/lua
synced 2024-11-22 12:51:30 +03:00
new type `boolean'
This commit is contained in:
parent
ed9be5e1f0
commit
9aff171f3b
23
lapi.c
23
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)
|
||||
|
19
lbaselib.c
19
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;
|
||||
}
|
||||
|
123
lcode.c
123
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 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;
|
||||
|
8
ldebug.c
8
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);
|
||||
|
6
lgc.c
6
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;
|
||||
}
|
||||
}
|
||||
|
6
llex.c
6
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>"
|
||||
};
|
||||
|
8
llex.h
8
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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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); }
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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)) */
|
||||
|
12
lparser.c
12
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;
|
||||
|
@ -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
ltable.c
3
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));
|
||||
}
|
||||
|
10
ltests.c
10
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;
|
||||
|
2
ltm.c
2
ltm.c
@ -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
11
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, \
|
||||
|
26
lvm.c
26
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);
|
||||
|
Loading…
Reference in New Issue
Block a user