This commit is contained in:
Roberto Ierusalimschy 2020-10-22 15:54:46 -03:00
parent e4a38eb0e8
commit d742a193e5
3 changed files with 34 additions and 26 deletions

25
llex.c
View File

@ -254,9 +254,10 @@ static int read_numeral (LexState *ls, SemInfo *seminfo) {
/*
** reads a sequence '[=*[' or ']=*]', leaving the last bracket.
** If sequence is well formed, return its number of '='s + 2; otherwise,
** return 1 if there is no '='s or 0 otherwise (an unfinished '[==...').
** read a sequence '[=*[' or ']=*]', leaving the last bracket. If
** sequence is well formed, return its number of '='s + 2; otherwise,
** return 1 if it is a single bracket (no '='s and no 2nd bracket);
** otherwise (an unfinished '[==...') return 0.
*/
static size_t skip_sep (LexState *ls) {
size_t count = 0;
@ -481,34 +482,34 @@ static int llex (LexState *ls, SemInfo *seminfo) {
}
case '=': {
next(ls);
if (check_next1(ls, '=')) return TK_EQ;
if (check_next1(ls, '=')) return TK_EQ; /* '==' */
else return '=';
}
case '<': {
next(ls);
if (check_next1(ls, '=')) return TK_LE;
else if (check_next1(ls, '<')) return TK_SHL;
if (check_next1(ls, '=')) return TK_LE; /* '<=' */
else if (check_next1(ls, '<')) return TK_SHL; /* '<<' */
else return '<';
}
case '>': {
next(ls);
if (check_next1(ls, '=')) return TK_GE;
else if (check_next1(ls, '>')) return TK_SHR;
if (check_next1(ls, '=')) return TK_GE; /* '>=' */
else if (check_next1(ls, '>')) return TK_SHR; /* '>>' */
else return '>';
}
case '/': {
next(ls);
if (check_next1(ls, '/')) return TK_IDIV;
if (check_next1(ls, '/')) return TK_IDIV; /* '//' */
else return '/';
}
case '~': {
next(ls);
if (check_next1(ls, '=')) return TK_NE;
if (check_next1(ls, '=')) return TK_NE; /* '~=' */
else return '~';
}
case ':': {
next(ls);
if (check_next1(ls, ':')) return TK_DBCOLON;
if (check_next1(ls, ':')) return TK_DBCOLON; /* '::' */
else return ':';
}
case '"': case '\'': { /* short literal strings */
@ -547,7 +548,7 @@ static int llex (LexState *ls, SemInfo *seminfo) {
return TK_NAME;
}
}
else { /* single-char tokens (+ - / ...) */
else { /* single-char tokens ('+', '*', '%', '{', '}', ...) */
int c = ls->current;
next(ls);
return c;

View File

@ -945,7 +945,7 @@ static void setvararg (FuncState *fs, int nparams) {
static void parlist (LexState *ls) {
/* parlist -> [ param { ',' param } ] */
/* parlist -> [ {NAME ','} (NAME | '...') ] */
FuncState *fs = ls->fs;
Proto *f = fs->f;
int nparams = 0;
@ -953,12 +953,12 @@ static void parlist (LexState *ls) {
if (ls->t.token != ')') { /* is 'parlist' not empty? */
do {
switch (ls->t.token) {
case TK_NAME: { /* param -> NAME */
case TK_NAME: {
new_localvar(ls, str_checkname(ls));
nparams++;
break;
}
case TK_DOTS: { /* param -> '...' */
case TK_DOTS: {
luaX_next(ls);
isvararg = 1;
break;
@ -1752,7 +1752,7 @@ static void checktoclose (LexState *ls, int level) {
static void localstat (LexState *ls) {
/* stat -> LOCAL ATTRIB NAME {',' ATTRIB NAME} ['=' explist] */
/* stat -> LOCAL NAME ATTRIB { ',' NAME ATTRIB } ['=' explist] */
FuncState *fs = ls->fs;
int toclose = -1; /* index of to-be-closed variable (if any) */
Vardesc *var; /* last variable */

View File

@ -166,17 +166,24 @@ static Node *mainpositionTV (const Table *t, const TValue *key) {
/*
** Check whether key 'k1' is equal to the key in node 'n2'.
** This equality is raw, so there are no metamethods. Floats
** with integer values have been normalized, so integers cannot
** be equal to floats. It is assumed that 'eqshrstr' is simply
** pointer equality, so that short strings are handled in the
** default case.
** Check whether key 'k1' is equal to the key in node 'n2'. This
** equality is raw, so there are no metamethods. Floats with integer
** values have been normalized, so integers cannot be equal to
** floats. It is assumed that 'eqshrstr' is simply pointer equality, so
** that short strings are handled in the default case.
** A true 'deadok' means to accept dead keys as equal to their original
** values, which can only happen if the original key was collectable.
** All dead values are compared in the default case, by pointer
** identity. (Note that dead long strings are also compared by
** identity).
** values. All dead keys are compared in the default case, by pointer
** identity. (Only collectable objects can produce dead keys.) Note that
** dead long strings are also compared by identity.
** Once a key is dead, its corresponding value may be collected, and
** then another value can be created with the same address. If this
** other value is given to 'next', 'equalkey' will signal a false
** positive. In a regular traversal, this situation should never happen,
** as all keys given to 'next' came from the table itself, and therefore
** could not have been collected. Outside a regular traversal, we
** have garbage in, garbage out. What is relevant is that this false
** positive does not break anything. (In particular, 'next' will return
** some other valid item on the table or nil.)
*/
static int equalkey (const TValue *k1, const Node *n2, int deadok) {
if ((rawtt(k1) != keytt(n2)) && /* not the same variants? */