aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
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 /lparser.c
parentbb0185b196773b878f0bf6b6c6a4a01dbf8c2b83 (diff)
downloadlua-35296e1fde705b3ac8356a4f4ce426497cf7b64c.tar.gz
lua-35296e1fde705b3ac8356a4f4ce426497cf7b64c.tar.bz2
lua-35296e1fde705b3ac8356a4f4ce426497cf7b64c.zip
Details
comments and other janitorial work.
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c118
1 files changed, 85 insertions, 33 deletions
diff --git a/lparser.c b/lparser.c
index afc5aeab..e525e578 100644
--- a/lparser.c
+++ b/lparser.c
@@ -10,6 +10,7 @@
10#include "lprefix.h" 10#include "lprefix.h"
11 11
12 12
13#include <limits.h>
13#include <string.h> 14#include <string.h>
14 15
15#include "lua.h" 16#include "lua.h"
@@ -87,6 +88,9 @@ static void checklimit (FuncState *fs, int v, int l, const char *what) {
87} 88}
88 89
89 90
91/*
92** Test whether next token is 'c'; if so, skip it.
93*/
90static int testnext (LexState *ls, int c) { 94static int testnext (LexState *ls, int c) {
91 if (ls->t.token == c) { 95 if (ls->t.token == c) {
92 luaX_next(ls); 96 luaX_next(ls);
@@ -96,12 +100,18 @@ static int testnext (LexState *ls, int c) {
96} 100}
97 101
98 102
103/*
104** Check that next token is 'c'.
105*/
99static void check (LexState *ls, int c) { 106static void check (LexState *ls, int c) {
100 if (ls->t.token != c) 107 if (ls->t.token != c)
101 error_expected(ls, c); 108 error_expected(ls, c);
102} 109}
103 110
104 111
112/*
113** Check that next token is 'c' and skip it.
114*/
105static void checknext (LexState *ls, int c) { 115static void checknext (LexState *ls, int c) {
106 check(ls, c); 116 check(ls, c);
107 luaX_next(ls); 117 luaX_next(ls);
@@ -111,11 +121,15 @@ static void checknext (LexState *ls, int c) {
111#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); } 121#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); }
112 122
113 123
114 124/*
125** Check that next token is 'what' and skip it. In case of error,
126** raise an error that the expected 'what' should match a 'who'
127** in line 'where' (if that is not the current line).
128*/
115static void check_match (LexState *ls, int what, int who, int where) { 129static void check_match (LexState *ls, int what, int who, int where) {
116 if (unlikely(!testnext(ls, what))) { 130 if (unlikely(!testnext(ls, what))) {
117 if (where == ls->linenumber) 131 if (where == ls->linenumber) /* all in the same line? */
118 error_expected(ls, what); 132 error_expected(ls, what); /* do not need a complex message */
119 else { 133 else {
120 luaX_syntaxerror(ls, luaO_pushfstring(ls->L, 134 luaX_syntaxerror(ls, luaO_pushfstring(ls->L,
121 "%s expected (to close %s at line %d)", 135 "%s expected (to close %s at line %d)",
@@ -146,11 +160,15 @@ static void codestring (LexState *ls, expdesc *e, TString *s) {
146} 160}
147 161
148 162
149static void checkname (LexState *ls, expdesc *e) { 163static void codename (LexState *ls, expdesc *e) {
150 codestring(ls, e, str_checkname(ls)); 164 codestring(ls, e, str_checkname(ls));
151} 165}
152 166
153 167
168/*
169** Register a new local variable in the active 'Proto' (for debug
170** information).
171*/
154static int registerlocalvar (LexState *ls, TString *varname) { 172static int registerlocalvar (LexState *ls, TString *varname) {
155 FuncState *fs = ls->fs; 173 FuncState *fs = ls->fs;
156 Proto *f = fs->f; 174 Proto *f = fs->f;
@@ -183,6 +201,9 @@ static void new_localvar (LexState *ls, TString *name) {
183 new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char)) - 1)); 201 new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char)) - 1));
184 202
185 203
204/*
205** Get the debug-information entry for current variable 'i'.
206*/
186static LocVar *getlocvar (FuncState *fs, int i) { 207static LocVar *getlocvar (FuncState *fs, int i) {
187 int idx = fs->ls->dyd->actvar.arr[fs->firstlocal + i].idx; 208 int idx = fs->ls->dyd->actvar.arr[fs->firstlocal + i].idx;
188 lua_assert(idx < fs->nlocvars); 209 lua_assert(idx < fs->nlocvars);
@@ -192,6 +213,7 @@ static LocVar *getlocvar (FuncState *fs, int i) {
192 213
193/* 214/*
194** Start the scope for the last 'nvars' created variables. 215** Start the scope for the last 'nvars' created variables.
216** (debug info.)
195*/ 217*/
196static void adjustlocalvars (LexState *ls, int nvars) { 218static void adjustlocalvars (LexState *ls, int nvars) {
197 FuncState *fs = ls->fs; 219 FuncState *fs = ls->fs;
@@ -202,6 +224,10 @@ static void adjustlocalvars (LexState *ls, int nvars) {
202} 224}
203 225
204 226
227/*
228** Close the scope for all variables up to level 'tolevel'.
229** (debug info.)
230*/
205static void removevars (FuncState *fs, int tolevel) { 231static void removevars (FuncState *fs, int tolevel) {
206 fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel); 232 fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel);
207 while (fs->nactvar > tolevel) 233 while (fs->nactvar > tolevel)
@@ -209,6 +235,10 @@ static void removevars (FuncState *fs, int tolevel) {
209} 235}
210 236
211 237
238/*
239** Search the upvalues of the function 'fs' for one
240** with the given 'name'.
241*/
212static int searchupvalue (FuncState *fs, TString *name) { 242static int searchupvalue (FuncState *fs, TString *name) {
213 int i; 243 int i;
214 Upvaldesc *up = fs->f->upvalues; 244 Upvaldesc *up = fs->f->upvalues;
@@ -235,6 +265,10 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
235} 265}
236 266
237 267
268/*
269** Look for an active local variable with the name 'n' in the
270** function 'fs'.
271*/
238static int searchvar (FuncState *fs, TString *n) { 272static int searchvar (FuncState *fs, TString *n) {
239 int i; 273 int i;
240 for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) { 274 for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) {
@@ -246,8 +280,8 @@ static int searchvar (FuncState *fs, TString *n) {
246 280
247 281
248/* 282/*
249 Mark block where variable at given level was defined 283** Mark block where variable at given level was defined
250 (to emit close instructions later). 284** (to emit close instructions later).
251*/ 285*/
252static void markupval (FuncState *fs, int level) { 286static void markupval (FuncState *fs, int level) {
253 BlockCnt *bl = fs->bl; 287 BlockCnt *bl = fs->bl;
@@ -259,8 +293,9 @@ static void markupval (FuncState *fs, int level) {
259 293
260 294
261/* 295/*
262 Find variable with given name 'n'. If it is an upvalue, add this 296** Find a variable with the given name 'n'. If it is an upvalue, add
263 upvalue into all intermediate functions. 297** this upvalue into all intermediate functions. If it is a global, set
298** 'var' as 'void' as a flag.
264*/ 299*/
265static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { 300static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
266 if (fs == NULL) /* no more levels? */ 301 if (fs == NULL) /* no more levels? */
@@ -287,6 +322,10 @@ static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
287} 322}
288 323
289 324
325/*
326** Find a variable with the given name 'n', handling global variables
327** too.
328*/
290static void singlevar (LexState *ls, expdesc *var) { 329static void singlevar (LexState *ls, expdesc *var) {
291 TString *varname = str_checkname(ls); 330 TString *varname = str_checkname(ls);
292 FuncState *fs = ls->fs; 331 FuncState *fs = ls->fs;
@@ -301,25 +340,29 @@ static void singlevar (LexState *ls, expdesc *var) {
301} 340}
302 341
303 342
343/*
344** Adjust the number of results from an expression list 'e' with 'nexps'
345** expressions to 'nvars' values.
346*/
304static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { 347static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
305 FuncState *fs = ls->fs; 348 FuncState *fs = ls->fs;
306 int extra = nvars - nexps; 349 int needed = nvars - nexps; /* extra values needed */
307 if (hasmultret(e->k)) { 350 if (hasmultret(e->k)) { /* last expression has multiple returns? */
308 extra++; /* includes call itself */ 351 int extra = needed + 1; /* discount last expression itself */
309 if (extra < 0) extra = 0; 352 if (extra < 0)
353 extra = 0;
310 luaK_setreturns(fs, e, extra); /* last exp. provides the difference */ 354 luaK_setreturns(fs, e, extra); /* last exp. provides the difference */
311 if (extra > 1) luaK_reserveregs(fs, extra-1);
312 } 355 }
313 else { 356 else {
314 if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */ 357 if (e->k != VVOID) /* at least one expression? */
315 if (extra > 0) { 358 luaK_exp2nextreg(fs, e); /* close last expression */
316 int reg = fs->freereg; 359 if (needed > 0) /* missing values? */
317 luaK_reserveregs(fs, extra); 360 luaK_nil(fs, fs->freereg, needed); /* complete with nils */
318 luaK_nil(fs, reg, extra);
319 }
320 } 361 }
321 if (nexps > nvars) 362 if (needed > 0)
322 ls->fs->freereg -= nexps - nvars; /* remove extra values */ 363 luaK_reserveregs(fs, needed); /* registers for extra values */
364 else /* adding 'needed' is actually a subtraction */
365 fs->freereg += needed; /* remove extra values */
323} 366}
324 367
325 368
@@ -632,7 +675,7 @@ static void fieldsel (LexState *ls, expdesc *v) {
632 expdesc key; 675 expdesc key;
633 luaK_exp2anyregup(fs, v); 676 luaK_exp2anyregup(fs, v);
634 luaX_next(ls); /* skip the dot or colon */ 677 luaX_next(ls); /* skip the dot or colon */
635 checkname(ls, &key); 678 codename(ls, &key);
636 luaK_indexed(fs, v, &key); 679 luaK_indexed(fs, v, &key);
637} 680}
638 681
@@ -669,7 +712,7 @@ static void recfield (LexState *ls, struct ConsControl *cc) {
669 expdesc tab, key, val; 712 expdesc tab, key, val;
670 if (ls->t.token == TK_NAME) { 713 if (ls->t.token == TK_NAME) {
671 checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); 714 checklimit(fs, cc->nh, MAX_INT, "items in a constructor");
672 checkname(ls, &key); 715 codename(ls, &key);
673 } 716 }
674 else /* ls->t.token == '[' */ 717 else /* ls->t.token == '[' */
675 yindex(ls, &key); 718 yindex(ls, &key);
@@ -938,7 +981,7 @@ static void suffixedexp (LexState *ls, expdesc *v) {
938 case ':': { /* ':' NAME funcargs */ 981 case ':': { /* ':' NAME funcargs */
939 expdesc key; 982 expdesc key;
940 luaX_next(ls); 983 luaX_next(ls);
941 checkname(ls, &key); 984 codename(ls, &key);
942 luaK_self(fs, v, &key); 985 luaK_self(fs, v, &key);
943 funcargs(ls, v, line); 986 funcargs(ls, v, line);
944 break; 987 break;
@@ -1048,6 +1091,9 @@ static BinOpr getbinopr (int op) {
1048} 1091}
1049 1092
1050 1093
1094/*
1095** Priority table for binary operators.
1096*/
1051static const struct { 1097static const struct {
1052 lu_byte left; /* left priority for each binary operator */ 1098 lu_byte left; /* left priority for each binary operator */
1053 lu_byte right; /* right priority */ 1099 lu_byte right; /* right priority */
@@ -1076,9 +1122,9 @@ static BinOpr subexpr (LexState *ls, expdesc *v, int limit) {
1076 UnOpr uop; 1122 UnOpr uop;
1077 enterlevel(ls); 1123 enterlevel(ls);
1078 uop = getunopr(ls->t.token); 1124 uop = getunopr(ls->t.token);
1079 if (uop != OPR_NOUNOPR) { 1125 if (uop != OPR_NOUNOPR) { /* prefix (unary) operator? */
1080 int line = ls->linenumber; 1126 int line = ls->linenumber;
1081 luaX_next(ls); 1127 luaX_next(ls); /* skip operator */
1082 subexpr(ls, v, UNARY_PRIORITY); 1128 subexpr(ls, v, UNARY_PRIORITY);
1083 luaK_prefix(ls->fs, uop, v, line); 1129 luaK_prefix(ls->fs, uop, v, line);
1084 } 1130 }
@@ -1089,7 +1135,7 @@ static BinOpr subexpr (LexState *ls, expdesc *v, int limit) {
1089 expdesc v2; 1135 expdesc v2;
1090 BinOpr nextop; 1136 BinOpr nextop;
1091 int line = ls->linenumber; 1137 int line = ls->linenumber;
1092 luaX_next(ls); 1138 luaX_next(ls); /* skip operator */
1093 luaK_infix(ls->fs, op, v); 1139 luaK_infix(ls->fs, op, v);
1094 /* read sub-expression with higher priority */ 1140 /* read sub-expression with higher priority */
1095 nextop = subexpr(ls, &v2, priority[op].right); 1141 nextop = subexpr(ls, &v2, priority[op].right);
@@ -1177,21 +1223,27 @@ static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
1177 } 1223 }
1178} 1224}
1179 1225
1180 1226/*
1181static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { 1227** Parse and compile a mulitple assignment. The first "variable"
1228** (a 'suffixedexp') was already read by the caller.
1229**
1230** assignment -> suffixedexp restassign
1231** restassign -> ',' suffixedexp restassign | '=' explist
1232*/
1233static void restassign (LexState *ls, struct LHS_assign *lh, int nvars) {
1182 expdesc e; 1234 expdesc e;
1183 check_condition(ls, vkisvar(lh->v.k), "syntax error"); 1235 check_condition(ls, vkisvar(lh->v.k), "syntax error");
1184 if (testnext(ls, ',')) { /* assignment -> ',' suffixedexp assignment */ 1236 if (testnext(ls, ',')) { /* restassign -> ',' suffixedexp restassign */
1185 struct LHS_assign nv; 1237 struct LHS_assign nv;
1186 nv.prev = lh; 1238 nv.prev = lh;
1187 suffixedexp(ls, &nv.v); 1239 suffixedexp(ls, &nv.v);
1188 if (!vkisindexed(nv.v.k)) 1240 if (!vkisindexed(nv.v.k))
1189 check_conflict(ls, lh, &nv.v); 1241 check_conflict(ls, lh, &nv.v);
1190 enterlevel(ls); /* control recursion depth */ 1242 enterlevel(ls); /* control recursion depth */
1191 assignment(ls, &nv, nvars+1); 1243 restassign(ls, &nv, nvars+1);
1192 leavelevel(ls); 1244 leavelevel(ls);
1193 } 1245 }
1194 else { /* assignment -> '=' explist */ 1246 else { /* restassign -> '=' explist */
1195 int nexps; 1247 int nexps;
1196 checknext(ls, '='); 1248 checknext(ls, '=');
1197 nexps = explist(ls, &e); 1249 nexps = explist(ls, &e);
@@ -1627,7 +1679,7 @@ static void exprstat (LexState *ls) {
1627 suffixedexp(ls, &v.v); 1679 suffixedexp(ls, &v.v);
1628 if (ls->t.token == '=' || ls->t.token == ',') { /* stat -> assignment ? */ 1680 if (ls->t.token == '=' || ls->t.token == ',') { /* stat -> assignment ? */
1629 v.prev = NULL; 1681 v.prev = NULL;
1630 assignment(ls, &v, 1); 1682 restassign(ls, &v, 1);
1631 } 1683 }
1632 else { /* stat -> func */ 1684 else { /* stat -> func */
1633 Instruction *inst = &getinstruction(fs, &v.v); 1685 Instruction *inst = &getinstruction(fs, &v.v);