diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-11-22 13:56:04 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-11-22 13:56:04 -0200 |
| commit | 35296e1fde705b3ac8356a4f4ce426497cf7b64c (patch) | |
| tree | 59b369957490dd472f04576afe4a225e399c2995 | |
| parent | bb0185b196773b878f0bf6b6c6a4a01dbf8c2b83 (diff) | |
| download | lua-35296e1fde705b3ac8356a4f4ce426497cf7b64c.tar.gz lua-35296e1fde705b3ac8356a4f4ce426497cf7b64c.tar.bz2 lua-35296e1fde705b3ac8356a4f4ce426497cf7b64c.zip | |
Details
comments and other janitorial work.
| -rw-r--r-- | lparser.c | 118 | ||||
| -rw-r--r-- | lparser.h | 2 | ||||
| -rw-r--r-- | lvm.c | 12 |
3 files changed, 93 insertions, 39 deletions
| @@ -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 | */ | ||
| 90 | static int testnext (LexState *ls, int c) { | 94 | static 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 | */ | ||
| 99 | static void check (LexState *ls, int c) { | 106 | static 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 | */ | ||
| 105 | static void checknext (LexState *ls, int c) { | 115 | static 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 | */ | ||
| 115 | static void check_match (LexState *ls, int what, int who, int where) { | 129 | static 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 | ||
| 149 | static void checkname (LexState *ls, expdesc *e) { | 163 | static 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 | */ | ||
| 154 | static int registerlocalvar (LexState *ls, TString *varname) { | 172 | static 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 | */ | ||
| 186 | static LocVar *getlocvar (FuncState *fs, int i) { | 207 | static 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 | */ |
| 196 | static void adjustlocalvars (LexState *ls, int nvars) { | 218 | static 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 | */ | ||
| 205 | static void removevars (FuncState *fs, int tolevel) { | 231 | static 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 | */ | ||
| 212 | static int searchupvalue (FuncState *fs, TString *name) { | 242 | static 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 | */ | ||
| 238 | static int searchvar (FuncState *fs, TString *n) { | 272 | static 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 | */ |
| 252 | static void markupval (FuncState *fs, int level) { | 286 | static 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 | */ |
| 265 | static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { | 300 | static 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 | */ | ||
| 290 | static void singlevar (LexState *ls, expdesc *var) { | 329 | static 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 | */ | ||
| 304 | static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { | 347 | static 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 | */ | ||
| 1051 | static const struct { | 1097 | static 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 | /* | |
| 1181 | static 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 | */ | ||
| 1233 | static 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); |
| @@ -78,7 +78,7 @@ typedef struct expdesc { | |||
| 78 | 78 | ||
| 79 | /* description of active local variable */ | 79 | /* description of active local variable */ |
| 80 | typedef struct Vardesc { | 80 | typedef struct Vardesc { |
| 81 | short idx; /* variable index in stack */ | 81 | short idx; /* index of the variable in the Proto's 'locvars' array */ |
| 82 | } Vardesc; | 82 | } Vardesc; |
| 83 | 83 | ||
| 84 | 84 | ||
| @@ -583,7 +583,7 @@ void luaV_concat (lua_State *L, int total) { | |||
| 583 | 583 | ||
| 584 | 584 | ||
| 585 | /* | 585 | /* |
| 586 | ** Main operation 'ra' = #rb'. | 586 | ** Main operation 'ra = #rb'. |
| 587 | */ | 587 | */ |
| 588 | void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) { | 588 | void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) { |
| 589 | const TValue *tm; | 589 | const TValue *tm; |
| @@ -757,11 +757,13 @@ void luaV_finishOp (lua_State *L) { | |||
| 757 | } | 757 | } |
| 758 | break; | 758 | break; |
| 759 | } | 759 | } |
| 760 | case OP_TFORCALL: case OP_CALL: case OP_TAILCALL: | 760 | default: { |
| 761 | case OP_SETTABUP: case OP_SETTABLE: | 761 | /* only these other opcodes can yield */ |
| 762 | case OP_SETI: case OP_SETFIELD: | 762 | lua_assert(op == OP_TFORCALL || op == OP_CALL || |
| 763 | op == OP_TAILCALL || op == OP_SETTABUP || op == OP_SETTABLE || | ||
| 764 | op == OP_SETI || op == OP_SETFIELD); | ||
| 763 | break; | 765 | break; |
| 764 | default: lua_assert(0); | 766 | } |
| 765 | } | 767 | } |
| 766 | } | 768 | } |
| 767 | 769 | ||
