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

View File

@ -945,7 +945,7 @@ static void setvararg (FuncState *fs, int nparams) {
static void parlist (LexState *ls) { static void parlist (LexState *ls) {
/* parlist -> [ param { ',' param } ] */ /* parlist -> [ {NAME ','} (NAME | '...') ] */
FuncState *fs = ls->fs; FuncState *fs = ls->fs;
Proto *f = fs->f; Proto *f = fs->f;
int nparams = 0; int nparams = 0;
@ -953,12 +953,12 @@ static void parlist (LexState *ls) {
if (ls->t.token != ')') { /* is 'parlist' not empty? */ if (ls->t.token != ')') { /* is 'parlist' not empty? */
do { do {
switch (ls->t.token) { switch (ls->t.token) {
case TK_NAME: { /* param -> NAME */ case TK_NAME: {
new_localvar(ls, str_checkname(ls)); new_localvar(ls, str_checkname(ls));
nparams++; nparams++;
break; break;
} }
case TK_DOTS: { /* param -> '...' */ case TK_DOTS: {
luaX_next(ls); luaX_next(ls);
isvararg = 1; isvararg = 1;
break; break;
@ -1752,7 +1752,7 @@ static void checktoclose (LexState *ls, int level) {
static void localstat (LexState *ls) { static void localstat (LexState *ls) {
/* stat -> LOCAL ATTRIB NAME {',' ATTRIB NAME} ['=' explist] */ /* stat -> LOCAL NAME ATTRIB { ',' NAME ATTRIB } ['=' explist] */
FuncState *fs = ls->fs; FuncState *fs = ls->fs;
int toclose = -1; /* index of to-be-closed variable (if any) */ int toclose = -1; /* index of to-be-closed variable (if any) */
Vardesc *var; /* last variable */ 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'. ** Check whether key 'k1' is equal to the key in node 'n2'. This
** This equality is raw, so there are no metamethods. Floats ** equality is raw, so there are no metamethods. Floats with integer
** with integer values have been normalized, so integers cannot ** values have been normalized, so integers cannot be equal to
** be equal to floats. It is assumed that 'eqshrstr' is simply ** floats. It is assumed that 'eqshrstr' is simply pointer equality, so
** pointer equality, so that short strings are handled in the ** that short strings are handled in the default case.
** default case.
** A true 'deadok' means to accept dead keys as equal to their original ** A true 'deadok' means to accept dead keys as equal to their original
** values, which can only happen if the original key was collectable. ** values. All dead keys are compared in the default case, by pointer
** All dead values are compared in the default case, by pointer ** identity. (Only collectable objects can produce dead keys.) Note that
** identity. (Note that dead long strings are also compared by ** dead long strings are also compared by identity.
** 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) { static int equalkey (const TValue *k1, const Node *n2, int deadok) {
if ((rawtt(k1) != keytt(n2)) && /* not the same variants? */ if ((rawtt(k1) != keytt(n2)) && /* not the same variants? */