mirror of
https://github.com/lua/lua
synced 2024-11-22 21:01:26 +03:00
performance details.
This commit is contained in:
parent
d11e5adf55
commit
d83c2a8455
171
llex.c
171
llex.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: llex.c,v 1.47 1999/12/22 16:58:36 roberto Exp roberto $
|
** $Id: llex.c,v 1.48 1999/12/30 12:40:29 roberto Exp roberto $
|
||||||
** Lexical Analyzer
|
** Lexical Analyzer
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -33,7 +33,7 @@
|
|||||||
/* ORDER RESERVED */
|
/* ORDER RESERVED */
|
||||||
static const char *const reserved [] = {"and", "do", "else", "elseif", "end",
|
static const char *const reserved [] = {"and", "do", "else", "elseif", "end",
|
||||||
"function", "if", "local", "nil", "not", "or", "repeat", "return", "then",
|
"function", "if", "local", "nil", "not", "or", "repeat", "return", "then",
|
||||||
"until", "while"};
|
"until", "while", "", "..", "...", "==", ">=", "<=", "~=", "", "", ""};
|
||||||
|
|
||||||
|
|
||||||
void luaX_init (lua_State *L) {
|
void luaX_init (lua_State *L) {
|
||||||
@ -57,9 +57,15 @@ void luaX_syntaxerror (LexState *ls, const char *s, const char *token) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaX_error (LexState *ls, const char *s) {
|
void luaX_error (LexState *ls, const char *s, int token) {
|
||||||
save(ls->L, '\0');
|
char buff[TOKEN_LEN];
|
||||||
luaX_syntaxerror(ls, s, luaL_buffer(ls->L));
|
luaX_token2str(token, buff);
|
||||||
|
if (buff[0] == '\0') {
|
||||||
|
save(ls->L, '\0');
|
||||||
|
luaX_syntaxerror(ls, s, luaL_buffer(ls->L));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
luaX_syntaxerror(ls, s, buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -156,7 +162,7 @@ static void ifskip (lua_State *L, LexState *LS) {
|
|||||||
if (LS->current == '\n')
|
if (LS->current == '\n')
|
||||||
inclinenumber(L, LS);
|
inclinenumber(L, LS);
|
||||||
else if (LS->current == EOZ)
|
else if (LS->current == EOZ)
|
||||||
luaX_error(LS, "input ends inside a $if");
|
luaX_error(LS, "input ends inside a $if", EOS);
|
||||||
else next(LS);
|
else next(LS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -231,13 +237,13 @@ static void inclinenumber (lua_State *L, LexState *LS) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int read_long_string (lua_State *L, LexState *LS) {
|
static void read_long_string (lua_State *L, LexState *LS) {
|
||||||
int cont = 0;
|
int cont = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
switch (LS->current) {
|
switch (LS->current) {
|
||||||
case EOZ:
|
case EOZ:
|
||||||
luaX_error(LS, "unfinished long string");
|
luaX_error(LS, "unfinished long string", STRING);
|
||||||
return EOS; /* to avoid warnings */
|
break; /* to avoid warnings */
|
||||||
case '[':
|
case '[':
|
||||||
save_and_next(L, LS);
|
save_and_next(L, LS);
|
||||||
if (LS->current == '[') {
|
if (LS->current == '[') {
|
||||||
@ -264,7 +270,52 @@ static int read_long_string (lua_State *L, LexState *LS) {
|
|||||||
save_and_next(L, LS); /* skip the second ']' */
|
save_and_next(L, LS); /* skip the second ']' */
|
||||||
LS->seminfo.ts = luaS_newlstr(L, L->Mbuffer+(L->Mbuffbase+2),
|
LS->seminfo.ts = luaS_newlstr(L, L->Mbuffer+(L->Mbuffbase+2),
|
||||||
L->Mbuffnext-L->Mbuffbase-4);
|
L->Mbuffnext-L->Mbuffbase-4);
|
||||||
return STRING;
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void read_string (lua_State *L, LexState *LS, int del) {
|
||||||
|
save_and_next(L, LS);
|
||||||
|
while (LS->current != del) {
|
||||||
|
switch (LS->current) {
|
||||||
|
case EOZ: case '\n':
|
||||||
|
luaX_error(LS, "unfinished string", STRING);
|
||||||
|
break; /* to avoid warnings */
|
||||||
|
case '\\':
|
||||||
|
next(LS); /* do not save the '\' */
|
||||||
|
switch (LS->current) {
|
||||||
|
case 'a': save(L, '\a'); next(LS); break;
|
||||||
|
case 'b': save(L, '\b'); next(LS); break;
|
||||||
|
case 'f': save(L, '\f'); next(LS); break;
|
||||||
|
case 'n': save(L, '\n'); next(LS); break;
|
||||||
|
case 'r': save(L, '\r'); next(LS); break;
|
||||||
|
case 't': save(L, '\t'); next(LS); break;
|
||||||
|
case 'v': save(L, '\v'); next(LS); break;
|
||||||
|
case '\n': save(L, '\n'); inclinenumber(L, LS); break;
|
||||||
|
case '0': case '1': case '2': case '3': case '4':
|
||||||
|
case '5': case '6': case '7': case '8': case '9': {
|
||||||
|
int c = 0;
|
||||||
|
int i = 0;
|
||||||
|
do {
|
||||||
|
c = 10*c + (LS->current-'0');
|
||||||
|
next(LS);
|
||||||
|
} while (++i<3 && isdigit(LS->current));
|
||||||
|
if (c != (unsigned char)c)
|
||||||
|
luaX_error(LS, "escape sequence too large", STRING);
|
||||||
|
save(L, c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: /* handles \\, \", \', and \? */
|
||||||
|
save(L, LS->current);
|
||||||
|
next(LS);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
save_and_next(L, LS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
save_and_next(L, LS); /* skip delimiter */
|
||||||
|
LS->seminfo.ts = luaS_newlstr(L, L->Mbuffer+(L->Mbuffbase+1),
|
||||||
|
L->Mbuffnext-L->Mbuffbase-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -283,10 +334,9 @@ int luaX_lex (LexState *LS) {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
case '-':
|
case '-':
|
||||||
save_and_next(L, LS);
|
next(LS);
|
||||||
if (LS->current != '-') return '-';
|
if (LS->current != '-') return '-';
|
||||||
do { next(LS); } while (LS->current != '\n' && LS->current != EOZ);
|
do { next(LS); } while (LS->current != '\n' && LS->current != EOZ);
|
||||||
luaL_resetbuffer(L);
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case '[':
|
case '[':
|
||||||
@ -294,88 +344,41 @@ int luaX_lex (LexState *LS) {
|
|||||||
if (LS->current != '[') return '[';
|
if (LS->current != '[') return '[';
|
||||||
else {
|
else {
|
||||||
save_and_next(L, LS); /* pass the second '[' */
|
save_and_next(L, LS); /* pass the second '[' */
|
||||||
return read_long_string(L, LS);
|
read_long_string(L, LS);
|
||||||
|
return STRING;
|
||||||
}
|
}
|
||||||
|
|
||||||
case '=':
|
case '=':
|
||||||
save_and_next(L, LS);
|
next(LS);
|
||||||
if (LS->current != '=') return '=';
|
if (LS->current != '=') return '=';
|
||||||
else { save_and_next(L, LS); return EQ; }
|
else { next(LS); return EQ; }
|
||||||
|
|
||||||
case '<':
|
case '<':
|
||||||
save_and_next(L, LS);
|
next(LS);
|
||||||
if (LS->current != '=') return '<';
|
if (LS->current != '=') return '<';
|
||||||
else { save_and_next(L, LS); return LE; }
|
else { next(LS); return LE; }
|
||||||
|
|
||||||
case '>':
|
case '>':
|
||||||
save_and_next(L, LS);
|
next(LS);
|
||||||
if (LS->current != '=') return '>';
|
if (LS->current != '=') return '>';
|
||||||
else { save_and_next(L, LS); return GE; }
|
else { next(LS); return GE; }
|
||||||
|
|
||||||
case '~':
|
case '~':
|
||||||
save_and_next(L, LS);
|
next(LS);
|
||||||
if (LS->current != '=') return '~';
|
if (LS->current != '=') return '~';
|
||||||
else { save_and_next(L, LS); return NE; }
|
else { next(LS); return NE; }
|
||||||
|
|
||||||
case '"':
|
case '"':
|
||||||
case '\'': {
|
case '\'':
|
||||||
int del = LS->current;
|
read_string(L, LS, LS->current);
|
||||||
save_and_next(L, LS);
|
|
||||||
while (LS->current != del) {
|
|
||||||
switch (LS->current) {
|
|
||||||
case EOZ:
|
|
||||||
case '\n':
|
|
||||||
luaX_error(LS, "unfinished string");
|
|
||||||
return EOS; /* to avoid warnings */
|
|
||||||
case '\\':
|
|
||||||
next(LS); /* do not save the '\' */
|
|
||||||
switch (LS->current) {
|
|
||||||
case 'a': save(L, '\a'); next(LS); break;
|
|
||||||
case 'b': save(L, '\b'); next(LS); break;
|
|
||||||
case 'f': save(L, '\f'); next(LS); break;
|
|
||||||
case 'n': save(L, '\n'); next(LS); break;
|
|
||||||
case 'r': save(L, '\r'); next(LS); break;
|
|
||||||
case 't': save(L, '\t'); next(LS); break;
|
|
||||||
case 'v': save(L, '\v'); next(LS); break;
|
|
||||||
case '\n': save(L, '\n'); inclinenumber(L, LS); break;
|
|
||||||
default : {
|
|
||||||
if (isdigit(LS->current)) {
|
|
||||||
int c = 0;
|
|
||||||
int i = 0;
|
|
||||||
do {
|
|
||||||
c = 10*c + (LS->current-'0');
|
|
||||||
next(LS);
|
|
||||||
} while (++i<3 && isdigit(LS->current));
|
|
||||||
if (c != (unsigned char)c)
|
|
||||||
luaX_error(LS, "escape sequence too large");
|
|
||||||
save(L, c);
|
|
||||||
}
|
|
||||||
else { /* handles \, ", ', and ? */
|
|
||||||
save(L, LS->current);
|
|
||||||
next(LS);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
save_and_next(L, LS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
save_and_next(L, LS); /* skip delimiter */
|
|
||||||
LS->seminfo.ts = luaS_newlstr(L, L->Mbuffer+(L->Mbuffbase+1),
|
|
||||||
L->Mbuffnext-L->Mbuffbase-2);
|
|
||||||
return STRING;
|
return STRING;
|
||||||
}
|
|
||||||
|
|
||||||
case '.':
|
case '.':
|
||||||
save_and_next(L, LS);
|
save_and_next(L, LS);
|
||||||
if (LS->current == '.')
|
if (LS->current == '.') {
|
||||||
{
|
next(LS);
|
||||||
save_and_next(L, LS);
|
if (LS->current == '.') {
|
||||||
if (LS->current == '.')
|
next(LS);
|
||||||
{
|
|
||||||
save_and_next(L, LS);
|
|
||||||
return DOTS; /* ... */
|
return DOTS; /* ... */
|
||||||
}
|
}
|
||||||
else return CONC; /* .. */
|
else return CONC; /* .. */
|
||||||
@ -392,14 +395,14 @@ int luaX_lex (LexState *LS) {
|
|||||||
save_and_next(L, LS);
|
save_and_next(L, LS);
|
||||||
if (LS->current == '.') {
|
if (LS->current == '.') {
|
||||||
save(L, '.');
|
save(L, '.');
|
||||||
luaX_error(LS,
|
luaX_error(LS, "ambiguous syntax"
|
||||||
"ambiguous syntax (decimal point x string concatenation)");
|
" (decimal point x string concatenation)", NUMBER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fraction: /* LUA_NUMBER */
|
fraction: /* LUA_NUMBER */
|
||||||
while (isdigit(LS->current))
|
while (isdigit(LS->current))
|
||||||
save_and_next(L, LS);
|
save_and_next(L, LS);
|
||||||
if (toupper(LS->current) == 'E') {
|
if (LS->current == 'e' || LS->current == 'E') {
|
||||||
save_and_next(L, LS); /* read 'E' */
|
save_and_next(L, LS); /* read 'E' */
|
||||||
if (LS->current == '+' || LS->current == '-')
|
if (LS->current == '+' || LS->current == '-')
|
||||||
save_and_next(L, LS); /* optional exponent sign */
|
save_and_next(L, LS); /* optional exponent sign */
|
||||||
@ -408,23 +411,25 @@ int luaX_lex (LexState *LS) {
|
|||||||
}
|
}
|
||||||
save(L, '\0');
|
save(L, '\0');
|
||||||
if (!luaO_str2d(L->Mbuffer+L->Mbuffbase, &LS->seminfo.r))
|
if (!luaO_str2d(L->Mbuffer+L->Mbuffbase, &LS->seminfo.r))
|
||||||
luaX_error(LS, "malformed number");
|
luaX_error(LS, "malformed number", NUMBER);
|
||||||
return NUMBER;
|
return NUMBER;
|
||||||
|
|
||||||
case EOZ:
|
case EOZ:
|
||||||
if (LS->iflevel > 0)
|
if (LS->iflevel > 0)
|
||||||
luaX_error(LS, "input ends inside a $if");
|
luaX_error(LS, "input ends inside a $if", EOS);
|
||||||
return EOS;
|
return EOS;
|
||||||
|
|
||||||
|
case '_': goto tname;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (LS->current != '_' && !isalpha(LS->current)) {
|
if (!isalpha(LS->current)) {
|
||||||
int c = LS->current;
|
int c = LS->current;
|
||||||
if (iscntrl(c))
|
if (iscntrl(c))
|
||||||
luaX_invalidchar(LS, c);
|
luaX_invalidchar(LS, c);
|
||||||
save_and_next(L, LS);
|
next(LS);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
else { /* identifier or reserved word */
|
tname: { /* identifier or reserved word */
|
||||||
TaggedString *ts;
|
TaggedString *ts;
|
||||||
do {
|
do {
|
||||||
save_and_next(L, LS);
|
save_and_next(L, LS);
|
||||||
|
4
llex.h
4
llex.h
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: llex.h,v 1.15 1999/11/22 13:12:07 roberto Exp roberto $
|
** $Id: llex.h,v 1.16 1999/12/27 17:33:22 roberto Exp roberto $
|
||||||
** Lexical Analyzer
|
** Lexical Analyzer
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -63,7 +63,7 @@ void luaX_init (lua_State *L);
|
|||||||
void luaX_setinput (lua_State *L, LexState *LS, ZIO *z);
|
void luaX_setinput (lua_State *L, LexState *LS, ZIO *z);
|
||||||
int luaX_lex (LexState *LS);
|
int luaX_lex (LexState *LS);
|
||||||
void luaX_syntaxerror (LexState *ls, const char *s, const char *token);
|
void luaX_syntaxerror (LexState *ls, const char *s, const char *token);
|
||||||
void luaX_error (LexState *ls, const char *s);
|
void luaX_error (LexState *ls, const char *s, int token);
|
||||||
void luaX_token2str (int token, char *s);
|
void luaX_token2str (int token, char *s);
|
||||||
|
|
||||||
|
|
||||||
|
17
lobject.c
17
lobject.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lobject.c,v 1.28 1999/12/23 18:19:57 roberto Exp roberto $
|
** $Id: lobject.c,v 1.29 1999/12/30 18:28:40 roberto Exp roberto $
|
||||||
** Some generic functions over Lua objects
|
** Some generic functions over Lua objects
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -87,9 +87,9 @@ int luaO_str2d (const char *s, real *result) { /* LUA_NUMBER */
|
|||||||
int point = 0; /* number of decimal digits */
|
int point = 0; /* number of decimal digits */
|
||||||
int sig;
|
int sig;
|
||||||
while (isspace((unsigned char)*s)) s++;
|
while (isspace((unsigned char)*s)) s++;
|
||||||
sig = 1;
|
sig = 0;
|
||||||
switch (*s) {
|
switch (*s) {
|
||||||
case '-': sig = -1; /* go through */
|
case '-': sig = 1; /* go through */
|
||||||
case '+': s++;
|
case '+': s++;
|
||||||
}
|
}
|
||||||
if (! (isdigit((unsigned char)*s) ||
|
if (! (isdigit((unsigned char)*s) ||
|
||||||
@ -104,20 +104,21 @@ int luaO_str2d (const char *s, real *result) { /* LUA_NUMBER */
|
|||||||
point++;
|
point++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
a *= sig;
|
if (sig) a = -a;
|
||||||
if (toupper((unsigned char)*s) == 'E') {
|
if (*s == 'e' || *s == 'E') {
|
||||||
int e = 0;
|
int e = 0;
|
||||||
s++;
|
s++;
|
||||||
sig = 1;
|
sig = 0;
|
||||||
switch (*s) {
|
switch (*s) {
|
||||||
case '-': sig = -1; /* go through */
|
case '-': sig = 1; /* go through */
|
||||||
case '+': s++;
|
case '+': s++;
|
||||||
}
|
}
|
||||||
if (!isdigit((unsigned char)*s)) return 0; /* no digit in the exponent? */
|
if (!isdigit((unsigned char)*s)) return 0; /* no digit in the exponent? */
|
||||||
do {
|
do {
|
||||||
e = 10*e + (*(s++)-'0');
|
e = 10*e + (*(s++)-'0');
|
||||||
} while (isdigit((unsigned char)*s));
|
} while (isdigit((unsigned char)*s));
|
||||||
point -= sig*e;
|
if (sig) e = -e;
|
||||||
|
point -= e;
|
||||||
}
|
}
|
||||||
while (isspace((unsigned char)*s)) s++;
|
while (isspace((unsigned char)*s)) s++;
|
||||||
if (*s != '\0') return 0; /* invalid trailing characters? */
|
if (*s != '\0') return 0; /* invalid trailing characters? */
|
||||||
|
87
lparser.c
87
lparser.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lparser.c,v 1.54 2000/01/12 16:24:39 roberto Exp roberto $
|
** $Id: lparser.c,v 1.55 2000/01/25 13:57:18 roberto Exp roberto $
|
||||||
** LL(1) Parser and code generator for Lua
|
** LL(1) Parser and code generator for Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -119,11 +119,16 @@ static void exp1 (LexState *ls);
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void luaY_error (LexState *ls, const char *msg) {
|
||||||
|
luaX_error(ls, msg, ls->token);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void checklimit (LexState *ls, int val, int limit, const char *msg) {
|
static void checklimit (LexState *ls, int val, int limit, const char *msg) {
|
||||||
if (val > limit) {
|
if (val > limit) {
|
||||||
char buff[100];
|
char buff[100];
|
||||||
sprintf(buff, "too many %.50s (limit=%d)", msg, limit);
|
sprintf(buff, "too many %.50s (limit=%d)", msg, limit);
|
||||||
luaX_error(ls, buff);
|
luaY_error(ls, buff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,7 +150,7 @@ static void deltastack (LexState *ls, int delta) {
|
|||||||
fs->stacksize += delta;
|
fs->stacksize += delta;
|
||||||
if (fs->stacksize > fs->maxstacksize) {
|
if (fs->stacksize > fs->maxstacksize) {
|
||||||
if (fs->stacksize > MAX_BYTE)
|
if (fs->stacksize > MAX_BYTE)
|
||||||
luaX_error(ls, "function/expression too complex");
|
luaY_error(ls, "function/expression too complex");
|
||||||
fs->maxstacksize = fs->stacksize;
|
fs->maxstacksize = fs->stacksize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -160,7 +165,7 @@ static void code_oparg_at (LexState *ls, int pc, OpCode op,
|
|||||||
code[pc+1] = (Byte)arg;
|
code[pc+1] = (Byte)arg;
|
||||||
}
|
}
|
||||||
else if (arg > MAX_ARG)
|
else if (arg > MAX_ARG)
|
||||||
luaX_error(ls, "code too long");
|
luaY_error(ls, "code too long");
|
||||||
else { /* MAX_BYTE < arg < MAX_ARG */
|
else { /* MAX_BYTE < arg < MAX_ARG */
|
||||||
if (arg > MAX_WORD) {
|
if (arg > MAX_WORD) {
|
||||||
code[pc] = (Byte)LONGARG;
|
code[pc] = (Byte)LONGARG;
|
||||||
@ -599,20 +604,6 @@ static void close_func (LexState *ls) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static const int expfollow [] = {ELSE, ELSEIF, THEN, IF, WHILE, REPEAT,
|
|
||||||
DO, NAME, LOCAL, FUNCTION, END, UNTIL, RETURN, ')', ']', '}', ';',
|
|
||||||
EOS, ',', 0};
|
|
||||||
|
|
||||||
|
|
||||||
static int is_in (int tok, const int *toks) {
|
|
||||||
const int *t;
|
|
||||||
for (t=toks; *t; t++)
|
|
||||||
if (*t == tok) return t-toks;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void next (LexState *ls) {
|
static void next (LexState *ls) {
|
||||||
ls->token = luaX_lex(ls);
|
ls->token = luaX_lex(ls);
|
||||||
}
|
}
|
||||||
@ -622,12 +613,12 @@ static void error_expected (LexState *ls, int token) {
|
|||||||
char buff[100], t[TOKEN_LEN];
|
char buff[100], t[TOKEN_LEN];
|
||||||
luaX_token2str(token, t);
|
luaX_token2str(token, t);
|
||||||
sprintf(buff, "`%.20s' expected", t);
|
sprintf(buff, "`%.20s' expected", t);
|
||||||
luaX_error(ls, buff);
|
luaY_error(ls, buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void error_unexpected (LexState *ls) {
|
static void error_unexpected (LexState *ls) {
|
||||||
luaX_error(ls, "unexpected token");
|
luaY_error(ls, "unexpected token");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -641,7 +632,7 @@ static void error_unmatched (LexState *ls, int what, int who, int where) {
|
|||||||
luaX_token2str(who, t_who);
|
luaX_token2str(who, t_who);
|
||||||
sprintf(buff, "`%.20s' expected (to close `%.20s' at line %d)",
|
sprintf(buff, "`%.20s' expected (to close `%.20s' at line %d)",
|
||||||
t_what, t_who, where);
|
t_what, t_who, where);
|
||||||
luaX_error(ls, buff);
|
luaY_error(ls, buff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -661,7 +652,7 @@ static void check_match (LexState *ls, int what, int who, int where) {
|
|||||||
static int checkname (LexState *ls) {
|
static int checkname (LexState *ls) {
|
||||||
int sc;
|
int sc;
|
||||||
if (ls->token != NAME)
|
if (ls->token != NAME)
|
||||||
luaX_error(ls, "<name> expected");
|
luaY_error(ls, "<name> expected");
|
||||||
sc = string_constant(ls, ls->fs, ls->seminfo.ts);
|
sc = string_constant(ls, ls->fs, ls->seminfo.ts);
|
||||||
next(ls);
|
next(ls);
|
||||||
return sc;
|
return sc;
|
||||||
@ -691,7 +682,7 @@ TProtoFunc *luaY_parser (lua_State *L, ZIO *z) {
|
|||||||
next(&lexstate); /* read first token */
|
next(&lexstate); /* read first token */
|
||||||
chunk(&lexstate);
|
chunk(&lexstate);
|
||||||
if (lexstate.token != EOS)
|
if (lexstate.token != EOS)
|
||||||
luaX_error(&lexstate, "<eof> expected");
|
luaY_error(&lexstate, "<eof> expected");
|
||||||
close_func(&lexstate);
|
close_func(&lexstate);
|
||||||
return funcstate.f;
|
return funcstate.f;
|
||||||
}
|
}
|
||||||
@ -782,7 +773,7 @@ static int funcparams (LexState *ls, int slf, vardesc *v) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
luaX_error(ls, "function arguments expected");
|
luaY_error(ls, "function arguments expected");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
code_setname(ls, v);
|
code_setname(ls, v);
|
||||||
@ -871,7 +862,7 @@ static void recfield (LexState *ls) {
|
|||||||
check(ls, ']');
|
check(ls, ']');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: luaX_error(ls, "<name> or `[' expected");
|
default: luaY_error(ls, "<name> or `[' expected");
|
||||||
}
|
}
|
||||||
check(ls, '=');
|
check(ls, '=');
|
||||||
exp1(ls);
|
exp1(ls);
|
||||||
@ -977,7 +968,7 @@ static void constructor (LexState *ls) {
|
|||||||
next(ls);
|
next(ls);
|
||||||
constructor_part(ls, &other_cd);
|
constructor_part(ls, &other_cd);
|
||||||
if (cd.k == other_cd.k) /* repeated parts? */
|
if (cd.k == other_cd.k) /* repeated parts? */
|
||||||
luaX_error(ls, "invalid constructor syntax");
|
luaY_error(ls, "invalid constructor syntax");
|
||||||
nelems += other_cd.n;
|
nelems += other_cd.n;
|
||||||
}
|
}
|
||||||
check_match(ls, '}', '{', line);
|
check_match(ls, '}', '{', line);
|
||||||
@ -992,8 +983,8 @@ static void constructor (LexState *ls) {
|
|||||||
/*
|
/*
|
||||||
** {======================================================================
|
** {======================================================================
|
||||||
** For parsing expressions, we use a classic stack with priorities.
|
** For parsing expressions, we use a classic stack with priorities.
|
||||||
** Each binary operator is represented by its index in `binop' + FIRSTBIN
|
** Each binary operator is represented by an index: EQ=2, NE=3, ... '^'=13.
|
||||||
** (EQ=2, NE=3, ... '^'=13). The unary NOT is 0 and UNMINUS is 1.
|
** The unary NOT is 0 and UNMINUS is 1.
|
||||||
** =======================================================================
|
** =======================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1008,8 +999,6 @@ static void constructor (LexState *ls) {
|
|||||||
*/
|
*/
|
||||||
#define POW 13
|
#define POW 13
|
||||||
|
|
||||||
static const int binop [] = {EQ, NE, '>', '<', LE, GE, CONC,
|
|
||||||
'+', '-', '*', '/', '^', 0};
|
|
||||||
|
|
||||||
static const int priority [POW+1] = {5, 5, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 4, 6};
|
static const int priority [POW+1] = {5, 5, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 4, 6};
|
||||||
|
|
||||||
@ -1024,10 +1013,31 @@ typedef struct stack_op {
|
|||||||
} stack_op;
|
} stack_op;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** returns the index of a binary operator
|
||||||
|
*/
|
||||||
|
static int binop (int op) {
|
||||||
|
switch (op) {
|
||||||
|
case EQ: return FIRSTBIN;
|
||||||
|
case NE: return FIRSTBIN+1;
|
||||||
|
case '>': return FIRSTBIN+2;
|
||||||
|
case '<': return FIRSTBIN+3;
|
||||||
|
case LE: return FIRSTBIN+4;
|
||||||
|
case GE: return FIRSTBIN+5;
|
||||||
|
case CONC: return FIRSTBIN+6;
|
||||||
|
case '+': return FIRSTBIN+7;
|
||||||
|
case '-': return FIRSTBIN+8;
|
||||||
|
case '*': return FIRSTBIN+9;
|
||||||
|
case '/': return FIRSTBIN+10;
|
||||||
|
case '^': return FIRSTBIN+11;
|
||||||
|
default: return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void push (LexState *ls, stack_op *s, int op) {
|
static void push (LexState *ls, stack_op *s, int op) {
|
||||||
if (s->top >= MAXOPS)
|
if (s->top >= MAXOPS)
|
||||||
luaX_error(ls, "expression too complex");
|
luaY_error(ls, "expression too complex");
|
||||||
s->ops[s->top++] = op;
|
s->ops[s->top++] = op;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1086,7 +1096,7 @@ static void simpleexp (LexState *ls, vardesc *v, stack_op *s) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
luaX_error(ls, "<expression> expected");
|
luaY_error(ls, "<expression> expected");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
v->k = VEXP; v->info = 0;
|
v->k = VEXP; v->info = 0;
|
||||||
@ -1108,8 +1118,7 @@ static void arith_exp (LexState *ls, vardesc *v) {
|
|||||||
int op;
|
int op;
|
||||||
s.top = 0;
|
s.top = 0;
|
||||||
prefixexp(ls, v, &s);
|
prefixexp(ls, v, &s);
|
||||||
while ((op = is_in(ls->token, binop)) >= 0) {
|
while ((op = binop(ls->token)) >= 0) {
|
||||||
op += FIRSTBIN;
|
|
||||||
lua_pushvar(ls, v);
|
lua_pushvar(ls, v);
|
||||||
/* '^' is right associative, so must 'simulate' a higher priority */
|
/* '^' is right associative, so must 'simulate' a higher priority */
|
||||||
pop_to(ls, &s, (op == POW)?priority[op]+1:priority[op]);
|
pop_to(ls, &s, (op == POW)?priority[op]+1:priority[op]);
|
||||||
@ -1129,8 +1138,6 @@ static void exp1 (LexState *ls) {
|
|||||||
vardesc v;
|
vardesc v;
|
||||||
expr(ls, &v);
|
expr(ls, &v);
|
||||||
lua_pushvar(ls, &v);
|
lua_pushvar(ls, &v);
|
||||||
if (is_in(ls->token, expfollow) < 0)
|
|
||||||
luaX_error(ls, "malformed expression");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1180,7 +1187,7 @@ static int assignment (LexState *ls, vardesc *v, int nvars) {
|
|||||||
next(ls);
|
next(ls);
|
||||||
var_or_func(ls, &nv);
|
var_or_func(ls, &nv);
|
||||||
if (nv.k == VEXP)
|
if (nv.k == VEXP)
|
||||||
luaX_error(ls, "syntax error");
|
luaY_error(ls, "syntax error");
|
||||||
left = assignment(ls, &nv, nvars+1);
|
left = assignment(ls, &nv, nvars+1);
|
||||||
}
|
}
|
||||||
else { /* assignment -> '=' explist1 */
|
else { /* assignment -> '=' explist1 */
|
||||||
@ -1313,7 +1320,7 @@ static void namestat (LexState *ls) {
|
|||||||
var_or_func(ls, &v);
|
var_or_func(ls, &v);
|
||||||
if (v.k == VEXP) { /* stat -> func */
|
if (v.k == VEXP) { /* stat -> func */
|
||||||
if (v.info == 0) /* is just an upper value? */
|
if (v.info == 0) /* is just an upper value? */
|
||||||
luaX_error(ls, "syntax error");
|
luaY_error(ls, "syntax error");
|
||||||
close_exp(ls, v.info, 0);
|
close_exp(ls, v.info, 0);
|
||||||
}
|
}
|
||||||
else { /* stat -> ['%'] NAME assignment */
|
else { /* stat -> ['%'] NAME assignment */
|
||||||
@ -1410,14 +1417,14 @@ static void parlist (LexState *ls) {
|
|||||||
case NAME: /* tailparlist -> NAME [',' tailparlist] */
|
case NAME: /* tailparlist -> NAME [',' tailparlist] */
|
||||||
goto init;
|
goto init;
|
||||||
|
|
||||||
default: luaX_error(ls, "<name> or `...' expected");
|
default: luaY_error(ls, "<name> or `...' expected");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ')': break; /* parlist -> empty */
|
case ')': break; /* parlist -> empty */
|
||||||
|
|
||||||
default: luaX_error(ls, "<name> or `...' expected");
|
default: luaY_error(ls, "<name> or `...' expected");
|
||||||
}
|
}
|
||||||
code_args(ls, nparams, dots);
|
code_args(ls, nparams, dots);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user