summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-11-22 13:56:04 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-11-22 13:56:04 -0200
commit35296e1fde705b3ac8356a4f4ce426497cf7b64c (patch)
tree59b369957490dd472f04576afe4a225e399c2995
parentbb0185b196773b878f0bf6b6c6a4a01dbf8c2b83 (diff)
downloadlua-github-35296e1fde705b3ac8356a4f4ce426497cf7b64c.tar.gz
Details
comments and other janitorial work.
-rw-r--r--lparser.c118
-rw-r--r--lparser.h2
-rw-r--r--lvm.c12
3 files changed, 93 insertions, 39 deletions
diff --git a/lparser.c b/lparser.c
index afc5aeab..e525e578 100644
--- a/lparser.c
+++ b/lparser.c
@@ -10,6 +10,7 @@
#include "lprefix.h"
+#include <limits.h>
#include <string.h>
#include "lua.h"
@@ -87,6 +88,9 @@ static void checklimit (FuncState *fs, int v, int l, const char *what) {
}
+/*
+** Test whether next token is 'c'; if so, skip it.
+*/
static int testnext (LexState *ls, int c) {
if (ls->t.token == c) {
luaX_next(ls);
@@ -96,12 +100,18 @@ static int testnext (LexState *ls, int c) {
}
+/*
+** Check that next token is 'c'.
+*/
static void check (LexState *ls, int c) {
if (ls->t.token != c)
error_expected(ls, c);
}
+/*
+** Check that next token is 'c' and skip it.
+*/
static void checknext (LexState *ls, int c) {
check(ls, c);
luaX_next(ls);
@@ -111,11 +121,15 @@ static void checknext (LexState *ls, int c) {
#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); }
-
+/*
+** Check that next token is 'what' and skip it. In case of error,
+** raise an error that the expected 'what' should match a 'who'
+** in line 'where' (if that is not the current line).
+*/
static void check_match (LexState *ls, int what, int who, int where) {
if (unlikely(!testnext(ls, what))) {
- if (where == ls->linenumber)
- error_expected(ls, what);
+ if (where == ls->linenumber) /* all in the same line? */
+ error_expected(ls, what); /* do not need a complex message */
else {
luaX_syntaxerror(ls, luaO_pushfstring(ls->L,
"%s expected (to close %s at line %d)",
@@ -146,11 +160,15 @@ static void codestring (LexState *ls, expdesc *e, TString *s) {
}
-static void checkname (LexState *ls, expdesc *e) {
+static void codename (LexState *ls, expdesc *e) {
codestring(ls, e, str_checkname(ls));
}
+/*
+** Register a new local variable in the active 'Proto' (for debug
+** information).
+*/
static int registerlocalvar (LexState *ls, TString *varname) {
FuncState *fs = ls->fs;
Proto *f = fs->f;
@@ -183,6 +201,9 @@ static void new_localvar (LexState *ls, TString *name) {
new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char)) - 1));
+/*
+** Get the debug-information entry for current variable 'i'.
+*/
static LocVar *getlocvar (FuncState *fs, int i) {
int idx = fs->ls->dyd->actvar.arr[fs->firstlocal + i].idx;
lua_assert(idx < fs->nlocvars);
@@ -192,6 +213,7 @@ static LocVar *getlocvar (FuncState *fs, int i) {
/*
** Start the scope for the last 'nvars' created variables.
+** (debug info.)
*/
static void adjustlocalvars (LexState *ls, int nvars) {
FuncState *fs = ls->fs;
@@ -202,6 +224,10 @@ static void adjustlocalvars (LexState *ls, int nvars) {
}
+/*
+** Close the scope for all variables up to level 'tolevel'.
+** (debug info.)
+*/
static void removevars (FuncState *fs, int tolevel) {
fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel);
while (fs->nactvar > tolevel)
@@ -209,6 +235,10 @@ static void removevars (FuncState *fs, int tolevel) {
}
+/*
+** Search the upvalues of the function 'fs' for one
+** with the given 'name'.
+*/
static int searchupvalue (FuncState *fs, TString *name) {
int i;
Upvaldesc *up = fs->f->upvalues;
@@ -235,6 +265,10 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
}
+/*
+** Look for an active local variable with the name 'n' in the
+** function 'fs'.
+*/
static int searchvar (FuncState *fs, TString *n) {
int i;
for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) {
@@ -246,8 +280,8 @@ static int searchvar (FuncState *fs, TString *n) {
/*
- Mark block where variable at given level was defined
- (to emit close instructions later).
+** Mark block where variable at given level was defined
+** (to emit close instructions later).
*/
static void markupval (FuncState *fs, int level) {
BlockCnt *bl = fs->bl;
@@ -259,8 +293,9 @@ static void markupval (FuncState *fs, int level) {
/*
- Find variable with given name 'n'. If it is an upvalue, add this
- upvalue into all intermediate functions.
+** Find a variable with the given name 'n'. If it is an upvalue, add
+** this upvalue into all intermediate functions. If it is a global, set
+** 'var' as 'void' as a flag.
*/
static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
if (fs == NULL) /* no more levels? */
@@ -287,6 +322,10 @@ static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
}
+/*
+** Find a variable with the given name 'n', handling global variables
+** too.
+*/
static void singlevar (LexState *ls, expdesc *var) {
TString *varname = str_checkname(ls);
FuncState *fs = ls->fs;
@@ -301,25 +340,29 @@ static void singlevar (LexState *ls, expdesc *var) {
}
+/*
+** Adjust the number of results from an expression list 'e' with 'nexps'
+** expressions to 'nvars' values.
+*/
static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
FuncState *fs = ls->fs;
- int extra = nvars - nexps;
- if (hasmultret(e->k)) {
- extra++; /* includes call itself */
- if (extra < 0) extra = 0;
+ int needed = nvars - nexps; /* extra values needed */
+ if (hasmultret(e->k)) { /* last expression has multiple returns? */
+ int extra = needed + 1; /* discount last expression itself */
+ if (extra < 0)
+ extra = 0;
luaK_setreturns(fs, e, extra); /* last exp. provides the difference */
- if (extra > 1) luaK_reserveregs(fs, extra-1);
}
else {
- if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */
- if (extra > 0) {
- int reg = fs->freereg;
- luaK_reserveregs(fs, extra);
- luaK_nil(fs, reg, extra);
- }
+ if (e->k != VVOID) /* at least one expression? */
+ luaK_exp2nextreg(fs, e); /* close last expression */
+ if (needed > 0) /* missing values? */
+ luaK_nil(fs, fs->freereg, needed); /* complete with nils */
}
- if (nexps > nvars)
- ls->fs->freereg -= nexps - nvars; /* remove extra values */
+ if (needed > 0)
+ luaK_reserveregs(fs, needed); /* registers for extra values */
+ else /* adding 'needed' is actually a subtraction */
+ fs->freereg += needed; /* remove extra values */
}
@@ -632,7 +675,7 @@ static void fieldsel (LexState *ls, expdesc *v) {
expdesc key;
luaK_exp2anyregup(fs, v);
luaX_next(ls); /* skip the dot or colon */
- checkname(ls, &key);
+ codename(ls, &key);
luaK_indexed(fs, v, &key);
}
@@ -669,7 +712,7 @@ static void recfield (LexState *ls, struct ConsControl *cc) {
expdesc tab, key, val;
if (ls->t.token == TK_NAME) {
checklimit(fs, cc->nh, MAX_INT, "items in a constructor");
- checkname(ls, &key);
+ codename(ls, &key);
}
else /* ls->t.token == '[' */
yindex(ls, &key);
@@ -938,7 +981,7 @@ static void suffixedexp (LexState *ls, expdesc *v) {
case ':': { /* ':' NAME funcargs */
expdesc key;
luaX_next(ls);
- checkname(ls, &key);
+ codename(ls, &key);
luaK_self(fs, v, &key);
funcargs(ls, v, line);
break;
@@ -1048,6 +1091,9 @@ static BinOpr getbinopr (int op) {
}
+/*
+** Priority table for binary operators.
+*/
static const struct {
lu_byte left; /* left priority for each binary operator */
lu_byte right; /* right priority */
@@ -1076,9 +1122,9 @@ static BinOpr subexpr (LexState *ls, expdesc *v, int limit) {
UnOpr uop;
enterlevel(ls);
uop = getunopr(ls->t.token);
- if (uop != OPR_NOUNOPR) {
+ if (uop != OPR_NOUNOPR) { /* prefix (unary) operator? */
int line = ls->linenumber;
- luaX_next(ls);
+ luaX_next(ls); /* skip operator */
subexpr(ls, v, UNARY_PRIORITY);
luaK_prefix(ls->fs, uop, v, line);
}
@@ -1089,7 +1135,7 @@ static BinOpr subexpr (LexState *ls, expdesc *v, int limit) {
expdesc v2;
BinOpr nextop;
int line = ls->linenumber;
- luaX_next(ls);
+ luaX_next(ls); /* skip operator */
luaK_infix(ls->fs, op, v);
/* read sub-expression with higher priority */
nextop = subexpr(ls, &v2, priority[op].right);
@@ -1177,21 +1223,27 @@ static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
}
}
-
-static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
+/*
+** Parse and compile a mulitple assignment. The first "variable"
+** (a 'suffixedexp') was already read by the caller.
+**
+** assignment -> suffixedexp restassign
+** restassign -> ',' suffixedexp restassign | '=' explist
+*/
+static void restassign (LexState *ls, struct LHS_assign *lh, int nvars) {
expdesc e;
check_condition(ls, vkisvar(lh->v.k), "syntax error");
- if (testnext(ls, ',')) { /* assignment -> ',' suffixedexp assignment */
+ if (testnext(ls, ',')) { /* restassign -> ',' suffixedexp restassign */
struct LHS_assign nv;
nv.prev = lh;
suffixedexp(ls, &nv.v);
if (!vkisindexed(nv.v.k))
check_conflict(ls, lh, &nv.v);
enterlevel(ls); /* control recursion depth */
- assignment(ls, &nv, nvars+1);
+ restassign(ls, &nv, nvars+1);
leavelevel(ls);
}
- else { /* assignment -> '=' explist */
+ else { /* restassign -> '=' explist */
int nexps;
checknext(ls, '=');
nexps = explist(ls, &e);
@@ -1627,7 +1679,7 @@ static void exprstat (LexState *ls) {
suffixedexp(ls, &v.v);
if (ls->t.token == '=' || ls->t.token == ',') { /* stat -> assignment ? */
v.prev = NULL;
- assignment(ls, &v, 1);
+ restassign(ls, &v, 1);
}
else { /* stat -> func */
Instruction *inst = &getinstruction(fs, &v.v);
diff --git a/lparser.h b/lparser.h
index 8b070b0e..3d6bd978 100644
--- a/lparser.h
+++ b/lparser.h
@@ -78,7 +78,7 @@ typedef struct expdesc {
/* description of active local variable */
typedef struct Vardesc {
- short idx; /* variable index in stack */
+ short idx; /* index of the variable in the Proto's 'locvars' array */
} Vardesc;
diff --git a/lvm.c b/lvm.c
index 7d5ab9db..ece7d77a 100644
--- a/lvm.c
+++ b/lvm.c
@@ -583,7 +583,7 @@ void luaV_concat (lua_State *L, int total) {
/*
-** Main operation 'ra' = #rb'.
+** Main operation 'ra = #rb'.
*/
void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
const TValue *tm;
@@ -757,11 +757,13 @@ void luaV_finishOp (lua_State *L) {
}
break;
}
- case OP_TFORCALL: case OP_CALL: case OP_TAILCALL:
- case OP_SETTABUP: case OP_SETTABLE:
- case OP_SETI: case OP_SETFIELD:
+ default: {
+ /* only these other opcodes can yield */
+ lua_assert(op == OP_TFORCALL || op == OP_CALL ||
+ op == OP_TAILCALL || op == OP_SETTABUP || op == OP_SETTABLE ||
+ op == OP_SETI || op == OP_SETFIELD);
break;
- default: lua_assert(0);
+ }
}
}