Showing the changes to src/lparser.c (1 of 138 files). Show all
Unified · Split
| @@ -1,16 +1,18 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.c,v 1.117 2000/11/29 11:57:42 roberto Exp $ | 2 | ** $Id: lparser.c,v 1.208 2003/04/03 13:35:34 roberto Exp $ |
| 3 | ** LL(1) Parser and code generator for Lua | 3 | ** Lua Parser |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | 7 | ||
| 8 | #include <stdio.h> | ||
| 9 | #include <string.h> | 8 | #include <string.h> |
| 10 | 9 | ||
| 10 | #define lparser_c | ||
| 11 | |||
| 11 | #include "lua.h" | 12 | #include "lua.h" |
| 12 | 13 | ||
| 13 | #include "lcode.h" | 14 | #include "lcode.h" |
| 15 | #include "ldebug.h" | ||
| 14 | #include "lfunc.h" | 16 | #include "lfunc.h" |
| 15 | #include "llex.h" | 17 | #include "llex.h" |
| 16 | #include "lmem.h" | 18 | #include "lmem.h" |
| @@ -21,35 +23,34 @@ · 4 unmodified lines | |||
| 21 | #include "lstring.h" | 23 | #include "lstring.h" |
| 22 | 24 | ||
| 23 | 25 | ||
| 24 | /* | ||
| 25 | ** Constructors descriptor: | ||
| 26 | ** `n' indicates number of elements, and `k' signals whether | ||
| 27 | ** it is a list constructor (k = 0) or a record constructor (k = 1) | ||
| 28 | ** or empty (k = ';' or '}') | ||
| 29 | */ | ||
| 30 | typedef struct Constdesc { | ||
| 31 | int n; | ||
| 32 | int k; | ||
| 33 | } Constdesc; | ||
| 34 | 26 | ||
| 35 | 27 | ||
| 36 | typedef struct Breaklabel { | 28 | #define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]]) |
| 37 | struct Breaklabel *previous; /* chain */ | 29 | |
| 38 | int breaklist; | 30 | |
| 39 | int stacklevel; | 31 | #define enterlevel(ls) if (++(ls)->nestlevel > LUA_MAXPARSERLEVEL) \ |
| 40 | } Breaklabel; | 32 | luaX_syntaxerror(ls, "too many syntax levels"); |
| 33 | #define leavelevel(ls) ((ls)->nestlevel--) | ||
| 41 | 34 | ||
| 42 | 35 | ||
| 36 | /* | ||
| 37 | ** nodes for block list (list of active blocks) | ||
| 38 | */ | ||
| 39 | typedef struct BlockCnt { | ||
| 40 | struct BlockCnt *previous; /* chain */ | ||
| 41 | int breaklist; /* list of jumps out of this loop */ | ||
| 42 | int nactvar; /* # active local variables outside the breakable structure */ | ||
| 43 | int upval; /* true if some variable in the block is an upvalue */ | ||
| 44 | int isbreakable; /* true if `block' is a loop */ | ||
| 45 | } BlockCnt; | ||
| 46 | |||
| 43 | 47 | ||
| 44 | 48 | ||
| 45 | /* | 49 | /* |
| 46 | ** prototypes for recursive non-terminal functions | 50 | ** prototypes for recursive non-terminal functions |
| 47 | */ | 51 | */ |
| 48 | static void body (LexState *ls, int needself, int line); | ||
| 49 | static void chunk (LexState *ls); | 52 | static void chunk (LexState *ls); |
| 50 | static void constructor (LexState *ls); | ||
| 51 | static void expr (LexState *ls, expdesc *v); | 53 | static void expr (LexState *ls, expdesc *v); |
| 52 | static void exp1 (LexState *ls); | ||
| 53 | 54 | ||
| 54 | 55 | ||
| 55 | 56 | ||
| @@ -65,32 +66,18 @@ static void next (LexState *ls) { · 9 unmodified lines | |||
| 65 | 66 | ||
| 66 | 67 | ||
| 67 | static void lookahead (LexState *ls) { | 68 | static void lookahead (LexState *ls) { |
| 68 | LUA_ASSERT(ls->lookahead.token == TK_EOS, "two look-aheads"); | 69 | lua_assert(ls->lookahead.token == TK_EOS); |
| 69 | ls->lookahead.token = luaX_lex(ls, &ls->lookahead.seminfo); | 70 | ls->lookahead.token = luaX_lex(ls, &ls->lookahead.seminfo); |
| 70 | } | 71 | } |
| 71 | 72 | ||
| 72 | 73 | ||
| 73 | static void error_expected (LexState *ls, int token) { | 74 | static void error_expected (LexState *ls, int token) { |
| 74 | char buff[100], t[TOKEN_LEN]; | 75 | luaX_syntaxerror(ls, |
| 75 | luaX_token2str(token, t); | 76 | luaO_pushfstring(ls->L, "`%s' expected", luaX_token2str(ls, token))); |
| 76 | sprintf(buff, "`%.20s' expected", t); | ||
| 77 | luaK_error(ls, buff); | ||
| 78 | } | 77 | } |
| 79 | 78 | ||
| 80 | 79 | ||
| 81 | static void check (LexState *ls, int c) { | 80 | static int testnext (LexState *ls, int c) { |
| 82 | if (ls->t.token != c) | ||
| 83 | error_expected(ls, c); | ||
| 84 | next(ls); | ||
| 85 | } | ||
| 86 | |||
| 87 | |||
| 88 | static void check_condition (LexState *ls, int c, const char *msg) { | ||
| 89 | if (!c) luaK_error(ls, msg); | ||
| 90 | } | ||
| 91 | |||
| 92 | |||
| 93 | static int optional (LexState *ls, int c) { | ||
| 94 | if (ls->t.token == c) { | 81 | if (ls->t.token == c) { |
| 95 | next(ls); | 82 | next(ls); |
| 96 | return 1; | 83 | return 1; |
| @@ -99,40 +86,26 @@ static int optional (LexState *ls, int c) { · 2 unmodified lines | |||
| 99 | } | 86 | } |
| 100 | 87 | ||
| 101 | 88 | ||
| 89 | static void check (LexState *ls, int c) { | ||
| 90 | if (!testnext(ls, c)) | ||
| 91 | error_expected(ls, c); | ||
| 92 | } | ||
| 93 | |||
| 94 | |||
| 95 | #define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); } | ||
| 96 | |||
| 97 | |||
| 98 | |||
| 102 | static void check_match (LexState *ls, int what, int who, int where) { | 99 | static void check_match (LexState *ls, int what, int who, int where) { |
| 103 | if (ls->t.token != what) { | 100 | if (!testnext(ls, what)) { |
| 104 | if (where == ls->linenumber) | 101 | if (where == ls->linenumber) |
| 105 | error_expected(ls, what); | 102 | error_expected(ls, what); |
| 106 | else { | 103 | else { |
| 107 | char buff[100]; | 104 | luaX_syntaxerror(ls, luaO_pushfstring(ls->L, |
| 108 | char t_what[TOKEN_LEN], t_who[TOKEN_LEN]; | 105 | "`%s' expected (to close `%s' at line %d)", |
| 109 | luaX_token2str(what, t_what); | 106 | luaX_token2str(ls, what), luaX_token2str(ls, who), where)); |
| 110 | luaX_token2str(who, t_who); | ||
| 111 | sprintf(buff, "`%.20s' expected (to close `%.20s' at line %d)", | ||
| 112 | t_what, t_who, where); | ||
| 113 | luaK_error(ls, buff); | ||
| 114 | } | 107 | } |
| 115 | } | 108 | } |
| 116 | next(ls); | ||
| 117 | } | ||
| 118 | |||
| 119 | |||
| 120 | static int string_constant (FuncState *fs, TString *s) { | ||
| 121 | Proto *f = fs->f; | ||
| 122 | int c = s->u.s.constindex; | ||
| 123 | if (c >= f->nkstr || f->kstr[c] != s) { | ||
| 124 | luaM_growvector(fs->L, f->kstr, f->nkstr, 1, TString *, | ||
| 125 | "constant table overflow", MAXARG_U); | ||
| 126 | c = f->nkstr++; | ||
| 127 | f->kstr[c] = s; | ||
| 128 | s->u.s.constindex = c; /* hint for next time */ | ||
| 129 | } | ||
| 130 | return c; | ||
| 131 | } | ||
| 132 | |||
| 133 | |||
| 134 | static void code_string (LexState *ls, TString *s) { | ||
| 135 | luaK_kstr(ls, string_constant(ls->fs, s)); | ||
| 136 | } | 109 | } |
| 137 | 110 | ||
| 138 | 111 | ||
| @@ -145,182 +118,224 @@ static TString *str_checkname (LexState *ls) { · 6 unmodified lines | |||
| 145 | } | 118 | } |
| 146 | 119 | ||
| 147 | 120 | ||
| 148 | static int checkname (LexState *ls) { | 121 | static void init_exp (expdesc *e, expkind k, int i) { |
| 149 | return string_constant(ls->fs, str_checkname(ls)); | 122 | e->f = e->t = NO_JUMP; |
| 123 | e->k = k; | ||
| 124 | e->info = i; | ||
| 125 | } | ||
| 126 | |||
| 127 | |||
| 128 | static void codestring (LexState *ls, expdesc *e, TString *s) { | ||
| 129 | init_exp(e, VK, luaK_stringK(ls->fs, s)); | ||
| 130 | } | ||
| 131 | |||
| 132 | |||
| 133 | static void checkname(LexState *ls, expdesc *e) { | ||
| 134 | codestring(ls, e, str_checkname(ls)); | ||
| 150 | } | 135 | } |
| 151 | 136 | ||
| 152 | 137 | ||
| 153 | static int luaI_registerlocalvar (LexState *ls, TString *varname) { | 138 | static int luaI_registerlocalvar (LexState *ls, TString *varname) { |
| 154 | Proto *f = ls->fs->f; | 139 | FuncState *fs = ls->fs; |
| 155 | luaM_growvector(ls->L, f->locvars, f->nlocvars, 1, LocVar, "", MAX_INT); | 140 | Proto *f = fs->f; |
| 156 | f->locvars[f->nlocvars].varname = varname; | 141 | luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, |
| 157 | return f->nlocvars++; | 142 | LocVar, MAX_INT, ""); |
| 143 | f->locvars[fs->nlocvars].varname = varname; | ||
| 144 | return fs->nlocvars++; | ||
| 158 | } | 145 | } |
| 159 | 146 | ||
| 160 | 147 | ||
| 161 | static void new_localvar (LexState *ls, TString *name, int n) { | 148 | static void new_localvar (LexState *ls, TString *name, int n) { |
| 162 | FuncState *fs = ls->fs; | 149 | FuncState *fs = ls->fs; |
| 163 | luaX_checklimit(ls, fs->nactloc+n+1, MAXLOCALS, "local variables"); | 150 | luaX_checklimit(ls, fs->nactvar+n+1, MAXVARS, "local variables"); |
| 164 | fs->actloc[fs->nactloc+n] = luaI_registerlocalvar(ls, name); | 151 | fs->actvar[fs->nactvar+n] = luaI_registerlocalvar(ls, name); |
| 165 | } | 152 | } |
| 166 | 153 | ||
| 167 | 154 | ||
| 168 | static void adjustlocalvars (LexState *ls, int nvars) { | 155 | static void adjustlocalvars (LexState *ls, int nvars) { |
| 169 | FuncState *fs = ls->fs; | 156 | FuncState *fs = ls->fs; |
| 170 | while (nvars--) | 157 | fs->nactvar += nvars; |
| 171 | fs->f->locvars[fs->actloc[fs->nactloc++]].startpc = fs->pc; | 158 | for (; nvars; nvars--) { |
| 159 | getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc; | ||
| 160 | } | ||
| 172 | } | 161 | } |
| 173 | 162 | ||
| 174 | 163 | ||
| 175 | static void removelocalvars (LexState *ls, int nvars) { | 164 | static void removevars (LexState *ls, int tolevel) { |
| 176 | FuncState *fs = ls->fs; | 165 | FuncState *fs = ls->fs; |
| 177 | while (nvars--) | 166 | while (fs->nactvar > tolevel) |
| 178 | fs->f->locvars[fs->actloc[--fs->nactloc]].endpc = fs->pc; | 167 | getlocvar(fs, --fs->nactvar).endpc = fs->pc; |
| 179 | } | 168 | } |
| 180 | 169 | ||
| 181 | 170 | ||
| 182 | static void new_localvarstr (LexState *ls, const char *name, int n) { | 171 | static void new_localvarstr (LexState *ls, const char *name, int n) { |
| 183 | new_localvar(ls, luaS_newfixed(ls->L, name), n); | 172 | new_localvar(ls, luaS_new(ls->L, name), n); |
| 184 | } | 173 | } |
| 185 | 174 | ||
| 186 | 175 | ||
| 187 | static int search_local (LexState *ls, TString *n, expdesc *var) { | 176 | static void create_local (LexState *ls, const char *name) { |
| 188 | FuncState *fs; | 177 | new_localvarstr(ls, name, 0); |
| 189 | int level = 0; | 178 | adjustlocalvars(ls, 1); |
| 190 | for (fs=ls->fs; fs; fs=fs->prev) { | ||
| 191 | int i; | ||
| 192 | for (i=fs->nactloc-1; i >= 0; i--) { | ||
| 193 | if (n == fs->f->locvars[fs->actloc[i]].varname) { | ||
| 194 | var->k = VLOCAL; | ||
| 195 | var->u.index = i; | ||
| 196 | return level; | ||
| 197 | } | ||
| 198 | } | ||
| 199 | level++; /* `var' not found; check outer level */ | ||
| 200 | } | ||
| 201 | var->k = VGLOBAL; /* not found in any level; must be global */ | ||
| 202 | return -1; | ||
| 203 | } | 179 | } |
| 204 | 180 | ||
| 205 | 181 | ||
| 206 | static void singlevar (LexState *ls, TString *n, expdesc *var) { | 182 | static int indexupvalue (FuncState *fs, TString *name, expdesc *v) { |
| 207 | int level = search_local(ls, n, var); | 183 | int i; |
| 208 | if (level >= 1) /* neither local (0) nor global (-1)? */ | 184 | Proto *f = fs->f; |
| 209 | luaX_syntaxerror(ls, "cannot access a variable in outer scope", n->str); | 185 | for (i=0; i<f->nups; i++) { |
| 210 | else if (level == -1) /* global? */ | 186 | if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->info) { |
| 211 | var->u.index = string_constant(ls->fs, n); | 187 | lua_assert(fs->f->upvalues[i] == name); |
| 188 | return i; | ||
| 189 | } | ||
| 190 | } | ||
| 191 | /* new one */ | ||
| 192 | luaX_checklimit(fs->ls, f->nups + 1, MAXUPVALUES, "upvalues"); | ||
| 193 | luaM_growvector(fs->L, fs->f->upvalues, f->nups, fs->f->sizeupvalues, | ||
| 194 | TString *, MAX_INT, ""); | ||
| 195 | fs->f->upvalues[f->nups] = name; | ||
| 196 | fs->upvalues[f->nups] = *v; | ||
| 197 | return f->nups++; | ||
| 212 | } | 198 | } |
| 213 | 199 | ||
| 214 | 200 | ||
| 215 | static int indexupvalue (LexState *ls, expdesc *v) { | 201 | static int searchvar (FuncState *fs, TString *n) { |
| 216 | FuncState *fs = ls->fs; | ||
| 217 | int i; | 202 | int i; |
| 218 | for (i=0; i<fs->nupvalues; i++) { | 203 | for (i=fs->nactvar-1; i >= 0; i--) { |
| 219 | if (fs->upvalues[i].k == v->k && fs->upvalues[i].u.index == v->u.index) | 204 | if (n == getlocvar(fs, i).varname) |
| 220 | return i; | 205 | return i; |
| 221 | } | 206 | } |
| 222 | /* new one */ | 207 | return -1; /* not found */ |
| 223 | luaX_checklimit(ls, fs->nupvalues+1, MAXUPVALUES, "upvalues"); | ||
| 224 | fs->upvalues[fs->nupvalues] = *v; | ||
| 225 | return fs->nupvalues++; | ||
| 226 | } | 208 | } |
| 227 | 209 | ||
| 228 | 210 | ||
| 229 | static void pushupvalue (LexState *ls, TString *n) { | 211 | static void markupval (FuncState *fs, int level) { |
| 230 | FuncState *fs = ls->fs; | 212 | BlockCnt *bl = fs->bl; |
| 231 | expdesc v; | 213 | while (bl && bl->nactvar > level) bl = bl->previous; |
| 232 | int level = search_local(ls, n, &v); | 214 | if (bl) bl->upval = 1; |
| 233 | if (level == -1) { /* global? */ | 215 | } |
| 234 | if (fs->prev == NULL) | 216 | |
| 235 | luaX_syntaxerror(ls, "cannot access upvalue in main", n->str); | 217 | |
| 236 | v.u.index = string_constant(fs->prev, n); | 218 | static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { |
| 219 | if (fs == NULL) /* no more levels? */ | ||
| 220 | init_exp(var, VGLOBAL, NO_REG); /* default is global variable */ | ||
| 221 | else { | ||
| 222 | int v = searchvar(fs, n); /* look up at current level */ | ||
| 223 | if (v >= 0) { | ||
| 224 | init_exp(var, VLOCAL, v); | ||
| 225 | if (!base) | ||
| 226 | markupval(fs, v); /* local will be used as an upval */ | ||
| 227 | } | ||
| 228 | else { /* not found at current level; try upper one */ | ||
| 229 | singlevaraux(fs->prev, n, var, 0); | ||
| 230 | if (var->k == VGLOBAL) { | ||
| 231 | if (base) | ||
| 232 | var->info = luaK_stringK(fs, n); /* info points to global name */ | ||
| 233 | } | ||
| 234 | else { /* LOCAL or UPVAL */ | ||
| 235 | var->info = indexupvalue(fs, n, var); | ||
| 236 | var->k = VUPVAL; /* upvalue in this level */ | ||
| 237 | } | ||
| 238 | } | ||
| 237 | } | 239 | } |
| 238 | else if (level != 1) | ||
| 239 | luaX_syntaxerror(ls, | ||
| 240 | "upvalue must be global or local to immediately outer scope", n->str); | ||
| 241 | luaK_code1(fs, OP_PUSHUPVALUE, indexupvalue(ls, &v)); | ||
| 242 | } | 240 | } |
| 243 | 241 | ||
| 244 | 242 | ||
| 245 | static void adjust_mult_assign (LexState *ls, int nvars, int nexps) { | 243 | static TString *singlevar (LexState *ls, expdesc *var, int base) { |
| 244 | TString *varname = str_checkname(ls); | ||
| 245 | singlevaraux(ls->fs, varname, var, base); | ||
| 246 | return varname; | ||
| 247 | } | ||
| 248 | |||
| 249 | |||
| 250 | static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { | ||
| 246 | FuncState *fs = ls->fs; | 251 | FuncState *fs = ls->fs; |
| 247 | int diff = nexps - nvars; | 252 | int extra = nvars - nexps; |
| 248 | if (nexps > 0 && luaK_lastisopen(fs)) { /* list ends in a function call */ | 253 | if (e->k == VCALL) { |
| 249 | diff--; /* do not count function call itself */ | 254 | extra++; /* includes call itself */ |
| 250 | if (diff <= 0) { /* more variables than values? */ | 255 | if (extra <= 0) extra = 0; |
| 251 | luaK_setcallreturns(fs, -diff); /* function call provide extra values */ | 256 | else luaK_reserveregs(fs, extra-1); |
| 252 | diff = 0; /* no more difference */ | 257 | luaK_setcallreturns(fs, e, extra); /* call provides the difference */ |
| 258 | } | ||
| 259 | else { | ||
| 260 | if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */ | ||
| 261 | if (extra > 0) { | ||
| 262 | int reg = fs->freereg; | ||
| 263 | luaK_reserveregs(fs, extra); | ||
| 264 | luaK_nil(fs, reg, extra); | ||
| 253 | } | 265 | } |
| 254 | else /* more values than variables */ | ||
| 255 | luaK_setcallreturns(fs, 0); /* call should provide no value */ | ||
| 256 | } | 266 | } |
| 257 | /* push or pop eventual difference between list lengths */ | ||
| 258 | luaK_adjuststack(fs, diff); | ||
| 259 | } | 267 | } |
| 260 | 268 | ||
| 261 | 269 | ||
| 262 | static void code_params (LexState *ls, int nparams, int dots) { | 270 | static void code_params (LexState *ls, int nparams, int dots) { |
| 263 | FuncState *fs = ls->fs; | 271 | FuncState *fs = ls->fs; |
| 264 | adjustlocalvars(ls, nparams); | 272 | adjustlocalvars(ls, nparams); |
| 265 | luaX_checklimit(ls, fs->nactloc, MAXPARAMS, "parameters"); | 273 | luaX_checklimit(ls, fs->nactvar, MAXPARAMS, "parameters"); |
| 266 | fs->f->numparams = fs->nactloc; /* `self' could be there already */ | 274 | fs->f->numparams = cast(lu_byte, fs->nactvar); |
| 267 | fs->f->is_vararg = dots; | 275 | fs->f->is_vararg = cast(lu_byte, dots); |
| 268 | if (dots) { | 276 | if (dots) |
| 269 | new_localvarstr(ls, "arg", 0); | 277 | create_local(ls, "arg"); |
| 270 | adjustlocalvars(ls, 1); | 278 | luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */ |
| 271 | } | ||
| 272 | luaK_deltastack(fs, fs->nactloc); /* count parameters in the stack */ | ||
| 273 | } | 279 | } |
| 274 | 280 | ||
| 275 | 281 | ||
| 276 | static void enterbreak (FuncState *fs, Breaklabel *bl) { | 282 | static void enterblock (FuncState *fs, BlockCnt *bl, int isbreakable) { |
| 277 | bl->stacklevel = fs->stacklevel; | ||
| 278 | bl->breaklist = NO_JUMP; | 283 | bl->breaklist = NO_JUMP; |
| 284 | bl->isbreakable = isbreakable; | ||
| 285 | bl->nactvar = fs->nactvar; | ||
| 286 | bl->upval = 0; | ||
| 279 | bl->previous = fs->bl; | 287 | bl->previous = fs->bl; |
| 280 | fs->bl = bl; | 288 | fs->bl = bl; |
| 289 | lua_assert(fs->freereg == fs->nactvar); | ||
| 281 | } | 290 | } |
| 282 | 291 | ||
| 283 | 292 | ||
| 284 | static void leavebreak (FuncState *fs, Breaklabel *bl) { | 293 | static void leaveblock (FuncState *fs) { |
| 294 | BlockCnt *bl = fs->bl; | ||
| 285 | fs->bl = bl->previous; | 295 | fs->bl = bl->previous; |
| 286 | LUA_ASSERT(bl->stacklevel == fs->stacklevel, "wrong levels"); | 296 | removevars(fs->ls, bl->nactvar); |
| 287 | luaK_patchlist(fs, bl->breaklist, luaK_getlabel(fs)); | 297 | if (bl->upval) |
| 298 | luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); | ||
| 299 | lua_assert(bl->nactvar == fs->nactvar); | ||
| 300 | fs->freereg = fs->nactvar; /* free registers */ | ||
| 301 | luaK_patchtohere(fs, bl->breaklist); | ||
| 288 | } | 302 | } |
| 289 | 303 | ||
| 290 | 304 | ||
| 291 | static void pushclosure (LexState *ls, FuncState *func) { | 305 | static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { |
| 292 | FuncState *fs = ls->fs; | 306 | FuncState *fs = ls->fs; |
| 293 | Proto *f = fs->f; | 307 | Proto *f = fs->f; |
| 294 | int i; | 308 | int i; |
| 295 | for (i=0; i<func->nupvalues; i++) | 309 | luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, |
| 296 | luaK_tostack(ls, &func->upvalues[i], 1); | 310 | MAXARG_Bx, "constant table overflow"); |
| 297 | luaM_growvector(ls->L, f->kproto, f->nkproto, 1, Proto *, | 311 | f->p[fs->np++] = func->f; |
| 298 | "constant table overflow", MAXARG_A); | 312 | init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); |
| 299 | f->kproto[f->nkproto++] = func->f; | 313 | for (i=0; i<func->f->nups; i++) { |
| 300 | luaK_code2(fs, OP_CLOSURE, f->nkproto-1, func->nupvalues); | 314 | OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; |
| 315 | luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0); | ||
| 316 | } | ||
| 301 | } | 317 | } |
| 302 | 318 | ||
| 303 | 319 | ||
| 304 | static void open_func (LexState *ls, FuncState *fs) { | 320 | static void open_func (LexState *ls, FuncState *fs) { |
| 305 | Proto *f = luaF_newproto(ls->L); | 321 | Proto *f = luaF_newproto(ls->L); |
| 322 | fs->f = f; | ||
| 306 | fs->prev = ls->fs; /* linked list of funcstates */ | 323 | fs->prev = ls->fs; /* linked list of funcstates */ |
| 307 | fs->ls = ls; | 324 | fs->ls = ls; |
| 308 | fs->L = ls->L; | 325 | fs->L = ls->L; |
| 309 | ls->fs = fs; | 326 | ls->fs = fs; |
| 310 | fs->stacklevel = 0; | ||
| 311 | fs->nactloc = 0; | ||
| 312 | fs->nupvalues = 0; | ||
| 313 | fs->bl = NULL; | ||
| 314 | fs->f = f; | ||
| 315 | f->source = ls->source; | ||
| 316 | fs->pc = 0; | 327 | fs->pc = 0; |
| 317 | fs->lasttarget = 0; | 328 | fs->lasttarget = 0; |
| 318 | fs->lastline = 0; | 329 | fs->jpc = NO_JUMP; |
| 319 | fs->jlt = NO_JUMP; | 330 | fs->freereg = 0; |
| 320 | f->code = NULL; | 331 | fs->nk = 0; |
| 321 | f->maxstacksize = 0; | 332 | fs->h = luaH_new(ls->L, 0, 0); |
| 322 | f->numparams = 0; /* default for main chunk */ | 333 | fs->np = 0; |
| 323 | f->is_vararg = 0; /* default for main chunk */ | 334 | fs->nlocvars = 0; |
| 335 | fs->nactvar = 0; | ||
| 336 | fs->bl = NULL; | ||
| 337 | f->source = ls->source; | ||
| 338 | f->maxstacksize = 2; /* registers 0/1 are always valid */ | ||
| 324 | } | 339 | } |
| 325 | 340 | ||
| 326 | 341 | ||
| @@ -328,33 +343,40 @@ static void close_func (LexState *ls) { · 1 unmodified line | |||
| 328 | lua_State *L = ls->L; | 343 | lua_State *L = ls->L; |
| 329 | FuncState *fs = ls->fs; | 344 | FuncState *fs = ls->fs; |
| 330 | Proto *f = fs->f; | 345 | Proto *f = fs->f; |
| 331 | luaK_code0(fs, OP_END); | 346 | removevars(ls, 0); |
| 332 | luaK_getlabel(fs); /* close eventual list of pending jumps */ | 347 | luaK_codeABC(fs, OP_RETURN, 0, 1, 0); /* final return */ |
| 333 | luaM_reallocvector(L, f->code, fs->pc, Instruction); | 348 | luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); |
| 334 | luaM_reallocvector(L, f->kstr, f->nkstr, TString *); | 349 | f->sizecode = fs->pc; |
| 335 | luaM_reallocvector(L, f->knum, f->nknum, Number); | 350 | luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int); |
| 336 | luaM_reallocvector(L, f->kproto, f->nkproto, Proto *); | 351 | f->sizelineinfo = fs->pc; |
| 337 | removelocalvars(ls, fs->nactloc); | 352 | luaM_reallocvector(L, f->k, f->sizek, fs->nk, TObject); |
| 338 | luaM_reallocvector(L, f->locvars, f->nlocvars, LocVar); | 353 | f->sizek = fs->nk; |
| 339 | luaM_reallocvector(L, f->lineinfo, f->nlineinfo+1, int); | 354 | luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *); |
| 340 | f->lineinfo[f->nlineinfo++] = MAX_INT; /* end flag */ | 355 | f->sizep = fs->np; |
| 341 | luaF_protook(L, f, fs->pc); /* proto is ok now */ | 356 | luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); |
| 357 | f->sizelocvars = fs->nlocvars; | ||
| 358 | luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *); | ||
| 359 | f->sizeupvalues = f->nups; | ||
| 360 | lua_assert(luaG_checkcode(f)); | ||
| 361 | lua_assert(fs->bl == NULL); | ||
| 342 | ls->fs = fs->prev; | 362 | ls->fs = fs->prev; |
| 343 | LUA_ASSERT(fs->bl == NULL, "wrong list end"); | ||
| 344 | } | 363 | } |
| 345 | 364 | ||
| 346 | 365 | ||
| 347 | Proto *luaY_parser (lua_State *L, ZIO *z) { | 366 | Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff) { |
| 348 | struct LexState lexstate; | 367 | struct LexState lexstate; |
| 349 | struct FuncState funcstate; | 368 | struct FuncState funcstate; |
| 369 | lexstate.buff = buff; | ||
| 370 | lexstate.nestlevel = 0; | ||
| 350 | luaX_setinput(L, &lexstate, z, luaS_new(L, zname(z))); | 371 | luaX_setinput(L, &lexstate, z, luaS_new(L, zname(z))); |
| 351 | open_func(&lexstate, &funcstate); | 372 | open_func(&lexstate, &funcstate); |
| 352 | next(&lexstate); /* read first token */ | 373 | next(&lexstate); /* read first token */ |
| 353 | chunk(&lexstate); | 374 | chunk(&lexstate); |
| 354 | check_condition(&lexstate, (lexstate.t.token == TK_EOS), "<eof> expected"); | 375 | check_condition(&lexstate, (lexstate.t.token == TK_EOS), "<eof> expected"); |
| 355 | close_func(&lexstate); | 376 | close_func(&lexstate); |
| 356 | LUA_ASSERT(funcstate.prev == NULL, "wrong list end"); | 377 | lua_assert(funcstate.prev == NULL); |
| 357 | LUA_ASSERT(funcstate.nupvalues == 0, "no upvalues in main"); | 378 | lua_assert(funcstate.f->nups == 0); |
| 379 | lua_assert(lexstate.nestlevel == 0); | ||
| 358 | return funcstate.f; | 380 | return funcstate.f; |
| 359 | } | 381 | } |
| 360 | 382 | ||
| @@ -365,235 +387,239 @@ Proto *luaY_parser (lua_State *L, ZIO *z) { · 4 unmodified lines | |||
| 365 | /*============================================================*/ | 387 | /*============================================================*/ |
| 366 | 388 | ||
| 367 | 389 | ||
| 368 | static int explist1 (LexState *ls) { | 390 | static void luaY_field (LexState *ls, expdesc *v) { |
| 369 | /* explist1 -> expr { ',' expr } */ | 391 | /* field -> ['.' | ':'] NAME */ |
| 370 | int n = 1; /* at least one expression */ | 392 | FuncState *fs = ls->fs; |
| 371 | expdesc v; | 393 | expdesc key; |
| 372 | expr(ls, &v); | 394 | luaK_exp2anyreg(fs, v); |
| 373 | while (ls->t.token == ',') { | 395 | next(ls); /* skip the dot or colon */ |
| 374 | luaK_tostack(ls, &v, 1); /* gets only 1 value from previous expression */ | 396 | checkname(ls, &key); |
| 375 | next(ls); /* skip comma */ | 397 | luaK_indexed(fs, v, &key); |
| 376 | expr(ls, &v); | ||
| 377 | n++; | ||
| 378 | } | ||
| 379 | luaK_tostack(ls, &v, 0); /* keep open number of values of last expression */ | ||
| 380 | return n; | ||
| 381 | } | 398 | } |
| 382 | 399 | ||
| 383 | 400 | ||
| 384 | static void funcargs (LexState *ls, int slf) { | 401 | static void luaY_index (LexState *ls, expdesc *v) { |
| 402 | /* index -> '[' expr ']' */ | ||
| 403 | next(ls); /* skip the '[' */ | ||
| 404 | expr(ls, v); | ||
| 405 | luaK_exp2val(ls->fs, v); | ||
| 406 | check(ls, ']'); | ||
| 407 | } | ||
| 408 | |||
| 409 | |||
| 410 | /* | ||
| 411 | ** {====================================================================== | ||
| 412 | ** Rules for Constructors | ||
| 413 | ** ======================================================================= | ||
| 414 | */ | ||
| 415 | |||
| 416 | |||
| 417 | struct ConsControl { | ||
| 418 | expdesc v; /* last list item read */ | ||
| 419 | expdesc *t; /* table descriptor */ | ||
| 420 | int nh; /* total number of `record' elements */ | ||
| 421 | int na; /* total number of array elements */ | ||
| 422 | int tostore; /* number of array elements pending to be stored */ | ||
| 423 | }; | ||
| 424 | |||
| 425 | |||
| 426 | static void recfield (LexState *ls, struct ConsControl *cc) { | ||
| 427 | /* recfield -> (NAME | `['exp1`]') = exp1 */ | ||
| 385 | FuncState *fs = ls->fs; | 428 | FuncState *fs = ls->fs; |
| 386 | int slevel = fs->stacklevel - slf - 1; /* where is func in the stack */ | 429 | int reg = ls->fs->freereg; |
| 387 | switch (ls->t.token) { | 430 | expdesc key, val; |
| 388 | case '(': { /* funcargs -> '(' [ explist1 ] ')' */ | 431 | if (ls->t.token == TK_NAME) { |
| 389 | int line = ls->linenumber; | 432 | luaX_checklimit(ls, cc->nh, MAX_INT, "items in a constructor"); |
| 390 | int nargs = 0; | 433 | cc->nh++; |
| 391 | next(ls); | 434 | checkname(ls, &key); |
| 392 | if (ls->t.token != ')') /* arg list not empty? */ | 435 | } |
| 393 | nargs = explist1(ls); | 436 | else /* ls->t.token == '[' */ |
| 394 | check_match(ls, ')', '(', line); | 437 | luaY_index(ls, &key); |
| 395 | #ifdef LUA_COMPAT_ARGRET | 438 | check(ls, '='); |
| 396 | if (nargs > 0) /* arg list is not empty? */ | 439 | luaK_exp2RK(fs, &key); |
| 397 | luaK_setcallreturns(fs, 1); /* last call returns only 1 value */ | 440 | expr(ls, &val); |
| 398 | #else | 441 | luaK_codeABC(fs, OP_SETTABLE, cc->t->info, luaK_exp2RK(fs, &key), |
| 399 | UNUSED(nargs); /* to avoid warnings */ | 442 | luaK_exp2RK(fs, &val)); |
| 400 | #endif | 443 | fs->freereg = reg; /* free registers */ |
| 401 | break; | 444 | } |
| 402 | } | 445 | |
| 403 | case '{': { /* funcargs -> constructor */ | 446 | |
| 404 | constructor(ls); | 447 | static void closelistfield (FuncState *fs, struct ConsControl *cc) { |
| 405 | break; | 448 | if (cc->v.k == VVOID) return; /* there is no list item */ |
| 406 | } | 449 | luaK_exp2nextreg(fs, &cc->v); |
| 407 | case TK_STRING: { /* funcargs -> STRING */ | 450 | cc->v.k = VVOID; |
| 408 | code_string(ls, ls->t.seminfo.ts); /* must use `seminfo' before `next' */ | 451 | if (cc->tostore == LFIELDS_PER_FLUSH) { |
| 409 | next(ls); | 452 | luaK_codeABx(fs, OP_SETLIST, cc->t->info, cc->na-1); /* flush */ |
| 410 | break; | 453 | cc->tostore = 0; /* no more items pending */ |
| 411 | } | 454 | fs->freereg = cc->t->info + 1; /* free registers */ |
| 412 | default: { | ||
| 413 | luaK_error(ls, "function arguments expected"); | ||
| 414 | break; | ||
| 415 | } | ||
| 416 | } | 455 | } |
| 417 | fs->stacklevel = slevel; /* call will remove function and arguments */ | ||
| 418 | luaK_code2(fs, OP_CALL, slevel, MULT_RET); | ||
| 419 | } | 456 | } |
| 420 | 457 | ||
| 421 | 458 | ||
| 422 | static void var_or_func_tail (LexState *ls, expdesc *v) { | 459 | static void lastlistfield (FuncState *fs, struct ConsControl *cc) { |
| 423 | for (;;) { | 460 | if (cc->tostore == 0) return; |
| 424 | switch (ls->t.token) { | 461 | if (cc->v.k == VCALL) { |
| 425 | case '.': { /* var_or_func_tail -> '.' NAME */ | 462 | luaK_setcallreturns(fs, &cc->v, LUA_MULTRET); |
| 426 | next(ls); | 463 | luaK_codeABx(fs, OP_SETLISTO, cc->t->info, cc->na-1); |
| 427 | luaK_tostack(ls, v, 1); /* `v' must be on stack */ | 464 | } |
| 428 | luaK_kstr(ls, checkname(ls)); | 465 | else { |
| 429 | v->k = VINDEXED; | 466 | if (cc->v.k != VVOID) |
| 430 | break; | 467 | luaK_exp2nextreg(fs, &cc->v); |
| 431 | } | 468 | luaK_codeABx(fs, OP_SETLIST, cc->t->info, cc->na-1); |
| 432 | case '[': { /* var_or_func_tail -> '[' exp1 ']' */ | 469 | } |
| 433 | next(ls); | 470 | fs->freereg = cc->t->info + 1; /* free registers */ |
| 434 | luaK_tostack(ls, v, 1); /* `v' must be on stack */ | 471 | } |
| 435 | v->k = VINDEXED; | 472 | |
| 436 | exp1(ls); | 473 | |
| 437 | check(ls, ']'); | 474 | static void listfield (LexState *ls, struct ConsControl *cc) { |
| 475 | expr(ls, &cc->v); | ||
| 476 | luaX_checklimit(ls, cc->na, MAXARG_Bx, "items in a constructor"); | ||
| 477 | cc->na++; | ||
| 478 | cc->tostore++; | ||
| 479 | } | ||
| 480 | |||
| 481 | |||
| 482 | static void constructor (LexState *ls, expdesc *t) { | ||
| 483 | /* constructor -> ?? */ | ||
| 484 | FuncState *fs = ls->fs; | ||
| 485 | int line = ls->linenumber; | ||
| 486 | int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); | ||
| 487 | struct ConsControl cc; | ||
| 488 | cc.na = cc.nh = cc.tostore = 0; | ||
| 489 | cc.t = t; | ||
| 490 | init_exp(t, VRELOCABLE, pc); | ||
| 491 | init_exp(&cc.v, VVOID, 0); /* no value (yet) */ | ||
| 492 | luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */ | ||
| 493 | check(ls, '{'); | ||
| 494 | do { | ||
| 495 | lua_assert(cc.v.k == VVOID || cc.tostore > 0); | ||
| 496 | testnext(ls, ';'); /* compatibility only */ | ||
| 497 | if (ls->t.token == '}') break; | ||
| 498 | closelistfield(fs, &cc); | ||
| 499 | switch(ls->t.token) { | ||
| 500 | case TK_NAME: { /* may be listfields or recfields */ | ||
| 501 | lookahead(ls); | ||
| 502 | if (ls->lookahead.token != '=') /* expression? */ | ||
| 503 | listfield(ls, &cc); | ||
| 504 | else | ||
| 505 | recfield(ls, &cc); | ||
| 438 | break; | 506 | break; |
| 439 | } | 507 | } |
| 440 | case ':': { /* var_or_func_tail -> ':' NAME funcargs */ | 508 | case '[': { /* constructor_item -> recfield */ |
| 441 | int name; | 509 | recfield(ls, &cc); |
| 442 | next(ls); | ||
| 443 | name = checkname(ls); | ||
| 444 | luaK_tostack(ls, v, 1); /* `v' must be on stack */ | ||
| 445 | luaK_code1(ls->fs, OP_PUSHSELF, name); | ||
| 446 | funcargs(ls, 1); | ||
| 447 | v->k = VEXP; | ||
| 448 | v->u.l.t = v->u.l.f = NO_JUMP; | ||
| 449 | break; | 510 | break; |
| 450 | } | 511 | } |
| 451 | case '(': case TK_STRING: case '{': { /* var_or_func_tail -> funcargs */ | 512 | default: { /* constructor_part -> listfield */ |
| 452 | luaK_tostack(ls, v, 1); /* `v' must be on stack */ | 513 | listfield(ls, &cc); |
| 453 | funcargs(ls, 0); | ||
| 454 | v->k = VEXP; | ||
| 455 | v->u.l.t = v->u.l.f = NO_JUMP; | ||
| 456 | break; | 514 | break; |
| 457 | } | 515 | } |
| 458 | default: return; /* should be follow... */ | ||
| 459 | } | 516 | } |
| 460 | } | 517 | } while (testnext(ls, ',') || testnext(ls, ';')); |
| 461 | } | 518 | check_match(ls, '}', '{', line); |
| 462 | 519 | lastlistfield(fs, &cc); | |
| 463 | 520 | SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */ | |
| 464 | static void var_or_func (LexState *ls, expdesc *v) { | 521 | SETARG_C(fs->f->code[pc], luaO_log2(cc.nh)+1); /* set initial table size */ |
| 465 | /* var_or_func -> ['%'] NAME var_or_func_tail */ | ||
| 466 | if (optional(ls, '%')) { /* upvalue? */ | ||
| 467 | pushupvalue(ls, str_checkname(ls)); | ||
| 468 | v->k = VEXP; | ||
| 469 | v->u.l.t = v->u.l.f = NO_JUMP; | ||
| 470 | } | ||
| 471 | else /* variable name */ | ||
| 472 | singlevar(ls, str_checkname(ls), v); | ||
| 473 | var_or_func_tail(ls, v); | ||
| 474 | } | 522 | } |
| 475 | 523 | ||
| 524 | /* }====================================================================== */ | ||
| 476 | 525 | ||
| 477 | 526 | ||
| 478 | /* | ||
| 479 | ** {====================================================================== | ||
| 480 | ** Rules for Constructors | ||
| 481 | ** ======================================================================= | ||
| 482 | */ | ||
| 483 | |||
| 484 | 527 | ||
| 485 | static void recfield (LexState *ls) { | 528 | static void parlist (LexState *ls) { |
| 486 | /* recfield -> (NAME | '['exp1']') = exp1 */ | 529 | /* parlist -> [ param { `,' param } ] */ |
| 487 | switch (ls->t.token) { | 530 | int nparams = 0; |
| 488 | case TK_NAME: { | 531 | int dots = 0; |
| 489 | luaK_kstr(ls, checkname(ls)); | 532 | if (ls->t.token != ')') { /* is `parlist' not empty? */ |
| 490 | break; | 533 | do { |
| 491 | } | 534 | switch (ls->t.token) { |
| 492 | case '[': { | 535 | case TK_DOTS: dots = 1; next(ls); break; |
| 493 | next(ls); | 536 | case TK_NAME: new_localvar(ls, str_checkname(ls), nparams++); break; |
| 494 | exp1(ls); | 537 | default: luaX_syntaxerror(ls, "<name> or `...' expected"); |
| 495 | check(ls, ']'); | 538 | } |
| 496 | break; | 539 | } while (!dots && testnext(ls, ',')); |
| 497 | } | ||
| 498 | default: luaK_error(ls, "<name> or `[' expected"); | ||
| 499 | } | 540 | } |
| 500 | check(ls, '='); | 541 | code_params(ls, nparams, dots); |
| 501 | exp1(ls); | ||
| 502 | } | 542 | } |
| 503 | 543 | ||
| 504 | 544 | ||
| 505 | static int recfields (LexState *ls) { | 545 | static void body (LexState *ls, expdesc *e, int needself, int line) { |
| 506 | /* recfields -> recfield { ',' recfield } [','] */ | 546 | /* body -> `(' parlist `)' chunk END */ |
| 507 | FuncState *fs = ls->fs; | 547 | FuncState new_fs; |
| 508 | int n = 1; /* at least one element */ | 548 | open_func(ls, &new_fs); |
| 509 | recfield(ls); | 549 | new_fs.f->lineDefined = line; |
| 510 | while (ls->t.token == ',') { | 550 | check(ls, '('); |
| 511 | next(ls); | 551 | if (needself) |
| 512 | if (ls->t.token == ';' || ls->t.token == '}') | 552 | create_local(ls, "self"); |
| 513 | break; | 553 | parlist(ls); |
| 514 | recfield(ls); | 554 | check(ls, ')'); |
| 515 | n++; | 555 | chunk(ls); |
| 516 | if (n%RFIELDS_PER_FLUSH == 0) | 556 | check_match(ls, TK_END, TK_FUNCTION, line); |
| 517 | luaK_code1(fs, OP_SETMAP, RFIELDS_PER_FLUSH); | 557 | close_func(ls); |
| 518 | } | 558 | pushclosure(ls, &new_fs, e); |
| 519 | luaK_code1(fs, OP_SETMAP, n%RFIELDS_PER_FLUSH); | ||
| 520 | return n; | ||
| 521 | } | 559 | } |
| 522 | 560 | ||
| 523 | 561 | ||
| 524 | static int listfields (LexState *ls) { | 562 | static int explist1 (LexState *ls, expdesc *v) { |
| 525 | /* listfields -> exp1 { ',' exp1 } [','] */ | 563 | /* explist1 -> expr { `,' expr } */ |
| 526 | FuncState *fs = ls->fs; | 564 | int n = 1; /* at least one expression */ |
| 527 | int n = 1; /* at least one element */ | 565 | expr(ls, v); |
| 528 | exp1(ls); | 566 | while (testnext(ls, ',')) { |
| 529 | while (ls->t.token == ',') { | 567 | luaK_exp2nextreg(ls->fs, v); |
| 530 | next(ls); | 568 | expr(ls, v); |
| 531 | if (ls->t.token == ';' || ls->t.token == '}') | ||
| 532 | break; | ||
| 533 | exp1(ls); | ||
| 534 | n++; | 569 | n++; |
| 535 | luaX_checklimit(ls, n/LFIELDS_PER_FLUSH, MAXARG_A, | ||
| 536 | "`item groups' in a list initializer"); | ||
| 537 | if (n%LFIELDS_PER_FLUSH == 0) | ||
| 538 | luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH); | ||
| 539 | } | 570 | } |
| 540 | luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH, n%LFIELDS_PER_FLUSH); | ||
| 541 | return n; | 571 | return n; |
| 542 | } | 572 | } |
| 543 | 573 | ||
| 544 | 574 | ||
| 545 | 575 | static void funcargs (LexState *ls, expdesc *f) { | |
| 546 | static void constructor_part (LexState *ls, Constdesc *cd) { | 576 | FuncState *fs = ls->fs; |
| 577 | expdesc args; | ||
| 578 | int base, nparams; | ||
| 579 | int line = ls->linenumber; | ||
| 547 | switch (ls->t.token) { | 580 | switch (ls->t.token) { |
| 548 | case ';': case '}': { /* constructor_part -> empty */ | 581 | case '(': { /* funcargs -> `(' [ explist1 ] `)' */ |
| 549 | cd->n = 0; | 582 | if (line != ls->lastline) |
| 550 | cd->k = ls->t.token; | 583 | luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)"); |
| 584 | next(ls); | ||
| 585 | if (ls->t.token == ')') /* arg list is empty? */ | ||
| 586 | args.k = VVOID; | ||
| 587 | else { | ||
| 588 | explist1(ls, &args); | ||
| 589 | luaK_setcallreturns(fs, &args, LUA_MULTRET); | ||
| 590 | } | ||
| 591 | check_match(ls, ')', '(', line); | ||
| 551 | break; | 592 | break; |
| 552 | } | 593 | } |
| 553 | case TK_NAME: { /* may be listfields or recfields */ | 594 | case '{': { /* funcargs -> constructor */ |
| 554 | lookahead(ls); | 595 | constructor(ls, &args); |
| 555 | if (ls->lookahead.token != '=') /* expression? */ | ||
| 556 | goto case_default; | ||
| 557 | /* else go through to recfields */ | ||
| 558 | } | ||
| 559 | case '[': { /* constructor_part -> recfields */ | ||
| 560 | cd->n = recfields(ls); | ||
| 561 | cd->k = 1; /* record */ | ||
| 562 | break; | 596 | break; |
| 563 | } | 597 | } |
| 564 | default: { /* constructor_part -> listfields */ | 598 | case TK_STRING: { /* funcargs -> STRING */ |
| 565 | case_default: | 599 | codestring(ls, &args, ls->t.seminfo.ts); |
| 566 | cd->n = listfields(ls); | 600 | next(ls); /* must use `seminfo' before `next' */ |
| 567 | cd->k = 0; /* list */ | ||
| 568 | break; | 601 | break; |
| 569 | } | 602 | } |
| 603 | default: { | ||
| 604 | luaX_syntaxerror(ls, "function arguments expected"); | ||
| 605 | return; | ||
| 606 | } | ||
| 570 | } | 607 | } |
| 571 | } | 608 | lua_assert(f->k == VNONRELOC); |
| 572 | 609 | base = f->info; /* base register for call */ | |
| 573 | 610 | if (args.k == VCALL) | |
| 574 | static void constructor (LexState *ls) { | 611 | nparams = LUA_MULTRET; /* open call */ |
| 575 | /* constructor -> '{' constructor_part [';' constructor_part] '}' */ | 612 | else { |
| 576 | FuncState *fs = ls->fs; | 613 | if (args.k != VVOID) |
| 577 | int line = ls->linenumber; | 614 | luaK_exp2nextreg(fs, &args); /* close last argument */ |
| 578 | int pc = luaK_code1(fs, OP_CREATETABLE, 0); | 615 | nparams = fs->freereg - (base+1); |
| 579 | int nelems; | ||
| 580 | Constdesc cd; | ||
| 581 | check(ls, '{'); | ||
| 582 | constructor_part(ls, &cd); | ||
| 583 | nelems = cd.n; | ||
| 584 | if (optional(ls, ';')) { | ||
| 585 | Constdesc other_cd; | ||
| 586 | constructor_part(ls, &other_cd); | ||
| 587 | check_condition(ls, (cd.k != other_cd.k), "invalid constructor syntax"); | ||
| 588 | nelems += other_cd.n; | ||
| 589 | } | 616 | } |
| 590 | check_match(ls, '}', '{', line); | 617 | init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2)); |
| 591 | luaX_checklimit(ls, nelems, MAXARG_U, "elements in a table constructor"); | 618 | luaK_fixline(fs, line); |
| 592 | SETARG_U(fs->f->code[pc], nelems); /* set initial table size */ | 619 | fs->freereg = base+1; /* call remove function and arguments and leaves |
| 620 | (unless changed) one result */ | ||
| 593 | } | 621 | } |
| 594 | 622 | ||
| 595 | /* }====================================================================== */ | ||
| 596 | |||
| 597 | 623 | ||
| 598 | 624 | ||
| 599 | 625 | ||
| @@ -604,58 +630,121 @@ static void constructor (LexState *ls) { · 4 unmodified lines | |||
| 604 | */ | 630 | */ |
| 605 | 631 | ||
| 606 | 632 | ||
| 607 | static void simpleexp (LexState *ls, expdesc *v) { | 633 | static void prefixexp (LexState *ls, expdesc *v) { |
| 608 | FuncState *fs = ls->fs; | 634 | /* prefixexp -> NAME | '(' expr ')' */ |
| 609 | switch (ls->t.token) { | 635 | switch (ls->t.token) { |
| 610 | case TK_NUMBER: { /* simpleexp -> NUMBER */ | 636 | case '(': { |
| 611 | Number r = ls->t.seminfo.r; | 637 | int line = ls->linenumber; |
| 612 | next(ls); | 638 | next(ls); |
| 613 | luaK_number(fs, r); | 639 | expr(ls, v); |
| 640 | check_match(ls, ')', '(', line); | ||
| 641 | luaK_dischargevars(ls->fs, v); | ||
| 642 | return; | ||
| 643 | } | ||
| 644 | case TK_NAME: { | ||
| 645 | singlevar(ls, v, 1); | ||
| 646 | return; | ||
| 647 | } | ||
| 648 | #ifdef LUA_COMPATUPSYNTAX | ||
| 649 | case '%': { /* for compatibility only */ | ||
| 650 | TString *varname; | ||
| 651 | int line = ls->linenumber; | ||
| 652 | next(ls); /* skip `%' */ | ||
| 653 | varname = singlevar(ls, v, 1); | ||
| 654 | if (v->k != VUPVAL) | ||
| 655 | luaX_errorline(ls, "global upvalues are obsolete", | ||
| 656 | getstr(varname), line); | ||
| 657 | return; | ||
| 658 | } | ||
| 659 | #endif | ||
| 660 | default: { | ||
| 661 | luaX_syntaxerror(ls, "unexpected symbol"); | ||
| 662 | return; | ||
| 663 | } | ||
| 664 | } | ||
| 665 | } | ||
| 666 | |||
| 667 | |||
| 668 | static void primaryexp (LexState *ls, expdesc *v) { | ||
| 669 | /* primaryexp -> | ||
| 670 | prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */ | ||
| 671 | FuncState *fs = ls->fs; | ||
| 672 | prefixexp(ls, v); | ||
| 673 | for (;;) { | ||
| 674 | switch (ls->t.token) { | ||
| 675 | case '.': { /* field */ | ||
| 676 | luaY_field(ls, v); | ||
| 677 | break; | ||
| 678 | } | ||
| 679 | case '[': { /* `[' exp1 `]' */ | ||
| 680 | expdesc key; | ||
| 681 | luaK_exp2anyreg(fs, v); | ||
| 682 | luaY_index(ls, &key); | ||
| 683 | luaK_indexed(fs, v, &key); | ||
| 684 | break; | ||
| 685 | } | ||
| 686 | case ':': { /* `:' NAME funcargs */ | ||
| 687 | expdesc key; | ||
| 688 | next(ls); | ||
| 689 | checkname(ls, &key); | ||
| 690 | luaK_self(fs, v, &key); | ||
| 691 | funcargs(ls, v); | ||
| 692 | break; | ||
| 693 | } | ||
| 694 | case '(': case TK_STRING: case '{': { /* funcargs */ | ||
| 695 | luaK_exp2nextreg(fs, v); | ||
| 696 | funcargs(ls, v); | ||
| 697 | break; | ||
| 698 | } | ||
| 699 | default: return; | ||
| 700 | } | ||
| 701 | } | ||
| 702 | } | ||
| 703 | |||
| 704 | |||
| 705 | static void simpleexp (LexState *ls, expdesc *v) { | ||
| 706 | /* simpleexp -> NUMBER | STRING | NIL | constructor | FUNCTION body | ||
| 707 | | primaryexp */ | ||
| 708 | switch (ls->t.token) { | ||
| 709 | case TK_NUMBER: { | ||
| 710 | init_exp(v, VK, luaK_numberK(ls->fs, ls->t.seminfo.r)); | ||
| 711 | next(ls); /* must use `seminfo' before `next' */ | ||
| 614 | break; | 712 | break; |
| 615 | } | 713 | } |
| 616 | case TK_STRING: { /* simpleexp -> STRING */ | 714 | case TK_STRING: { |
| 617 | code_string(ls, ls->t.seminfo.ts); /* must use `seminfo' before `next' */ | 715 | codestring(ls, v, ls->t.seminfo.ts); |
| 618 | next(ls); | 716 | next(ls); /* must use `seminfo' before `next' */ |
| 619 | break; | 717 | break; |
| 620 | } | 718 | } |
| 621 | case TK_NIL: { /* simpleexp -> NIL */ | 719 | case TK_NIL: { |
| 622 | luaK_adjuststack(fs, -1); | 720 | init_exp(v, VNIL, 0); |
| 623 | next(ls); | 721 | next(ls); |
| 624 | break; | 722 | break; |
| 625 | } | 723 | } |
| 626 | case '{': { /* simpleexp -> constructor */ | 724 | case TK_TRUE: { |
| 627 | constructor(ls); | 725 | init_exp(v, VTRUE, 0); |
| 726 | next(ls); | ||
| 628 | break; | 727 | break; |
| 629 | } | 728 | } |
| 630 | case TK_FUNCTION: { /* simpleexp -> FUNCTION body */ | 729 | case TK_FALSE: { |
| 730 | init_exp(v, VFALSE, 0); | ||
| 631 | next(ls); | 731 | next(ls); |
| 632 | body(ls, 0, ls->linenumber); | ||
| 633 | break; | 732 | break; |
| 634 | } | 733 | } |
| 635 | case '(': { /* simpleexp -> '(' expr ')' */ | 734 | case '{': { /* constructor */ |
| 636 | next(ls); | 735 | constructor(ls, v); |
| 637 | expr(ls, v); | 736 | break; |
| 638 | check(ls, ')'); | ||
| 639 | return; | ||
| 640 | } | 737 | } |
| 641 | case TK_NAME: case '%': { | 738 | case TK_FUNCTION: { |
| 642 | var_or_func(ls, v); | 739 | next(ls); |
| 643 | return; | 740 | body(ls, v, 0, ls->linenumber); |
| 741 | break; | ||
| 644 | } | 742 | } |
| 645 | default: { | 743 | default: { |
| 646 | luaK_error(ls, "<expression> expected"); | 744 | primaryexp(ls, v); |
| 647 | return; | 745 | break; |
| 648 | } | 746 | } |
| 649 | } | 747 | } |
| 650 | v->k = VEXP; | ||
| 651 | v->u.l.t = v->u.l.f = NO_JUMP; | ||
| 652 | } | ||
| 653 | |||
| 654 | |||
| 655 | static void exp1 (LexState *ls) { | ||
| 656 | expdesc v; | ||
| 657 | expr(ls, &v); | ||
| 658 | luaK_tostack(ls, &v, 1); | ||
| 659 | } | 748 | } |
| 660 | 749 | ||
| 661 | 750 | ||
| @@ -690,17 +779,17 @@ static BinOpr getbinopr (int op) { · 28 unmodified lines | |||
| 690 | 779 | ||
| 691 | 780 | ||
| 692 | static const struct { | 781 | static const struct { |
| 693 | char left; /* left priority for each binary operator */ | 782 | lu_byte left; /* left priority for each binary operator */ |
| 694 | char right; /* right priority */ | 783 | lu_byte right; /* right priority */ |
| 695 | } priority[] = { /* ORDER OPR */ | 784 | } priority[] = { /* ORDER OPR */ |
| 696 | {5, 5}, {5, 5}, {6, 6}, {6, 6}, /* arithmetic */ | 785 | {6, 6}, {6, 6}, {7, 7}, {7, 7}, /* arithmetic */ |
| 697 | {9, 8}, {4, 3}, /* power and concat (right associative) */ | 786 | {10, 9}, {5, 4}, /* power and concat (right associative) */ |
| 698 | {2, 2}, {2, 2}, /* equality */ | 787 | {3, 3}, {3, 3}, /* equality */ |
| 699 | {2, 2}, {2, 2}, {2, 2}, {2, 2}, /* order */ | 788 | {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */ |
| 700 | {1, 1}, {1, 1} /* logical */ | 789 | {2, 2}, {1, 1} /* logical (and/or) */ |
| 701 | }; | 790 | }; |
| 702 | 791 | ||
| 703 | #define UNARY_PRIORITY 7 /* priority for unary operators */ | 792 | #define UNARY_PRIORITY 8 /* priority for unary operators */ |
| 704 | 793 | ||
| 705 | 794 | ||
| 706 | /* | 795 | /* |
| @@ -709,25 +798,28 @@ static const struct { · 2 unmodified lines | |||
| 709 | */ | 798 | */ |
| 710 | static BinOpr subexpr (LexState *ls, expdesc *v, int limit) { | 799 | static BinOpr subexpr (LexState *ls, expdesc *v, int limit) { |
| 711 | BinOpr op; | 800 | BinOpr op; |
| 712 | UnOpr uop = getunopr(ls->t.token); | 801 | UnOpr uop; |
| 802 | enterlevel(ls); | ||
| 803 | uop = getunopr(ls->t.token); | ||
| 713 | if (uop != OPR_NOUNOPR) { | 804 | if (uop != OPR_NOUNOPR) { |
| 714 | next(ls); | 805 | next(ls); |
| 715 | subexpr(ls, v, UNARY_PRIORITY); | 806 | subexpr(ls, v, UNARY_PRIORITY); |
| 716 | luaK_prefix(ls, uop, v); | 807 | luaK_prefix(ls->fs, uop, v); |
| 717 | } | 808 | } |
| 718 | else simpleexp(ls, v); | 809 | else simpleexp(ls, v); |
| 719 | /* expand while operators have priorities higher than `limit' */ | 810 | /* expand while operators have priorities higher than `limit' */ |
| 720 | op = getbinopr(ls->t.token); | 811 | op = getbinopr(ls->t.token); |
| 721 | while (op != OPR_NOBINOPR && priority[op].left > limit) { | 812 | while (op != OPR_NOBINOPR && cast(int, priority[op].left) > limit) { |
| 722 | expdesc v2; | 813 | expdesc v2; |
| 723 | BinOpr nextop; | 814 | BinOpr nextop; |
| 724 | next(ls); | 815 | next(ls); |
| 725 | luaK_infix(ls, op, v); | 816 | luaK_infix(ls->fs, op, v); |
| 726 | /* read sub-expression with higher priority */ | 817 | /* read sub-expression with higher priority */ |
| 727 | nextop = subexpr(ls, &v2, priority[op].right); | 818 | nextop = subexpr(ls, &v2, cast(int, priority[op].right)); |
| 728 | luaK_posfix(ls, op, v, &v2); | 819 | luaK_posfix(ls->fs, op, v, &v2); |
| 729 | op = nextop; | 820 | op = nextop; |
| 730 | } | 821 | } |
| 822 | leavelevel(ls); | ||
| 731 | return op; /* return first untreated operator */ | 823 | return op; /* return first untreated operator */ |
| 732 | } | 824 | } |
| 733 | 825 | ||
| @@ -739,6 +831,7 @@ static void expr (LexState *ls, expdesc *v) { · 5 unmodified lines | |||
| 739 | /* }==================================================================== */ | 831 | /* }==================================================================== */ |
| 740 | 832 | ||
| 741 | 833 | ||
| 834 | |||
| 742 | /* | 835 | /* |
| 743 | ** {====================================================================== | 836 | ** {====================================================================== |
| 744 | ** Rules for Statements | 837 | ** Rules for Statements |
| @@ -759,61 +852,151 @@ static int block_follow (int token) { · 14 unmodified lines | |||
| 759 | static void block (LexState *ls) { | 852 | static void block (LexState *ls) { |
| 760 | /* block -> chunk */ | 853 | /* block -> chunk */ |
| 761 | FuncState *fs = ls->fs; | 854 | FuncState *fs = ls->fs; |
| 762 | int nactloc = fs->nactloc; | 855 | BlockCnt bl; |
| 856 | enterblock(fs, &bl, 0); | ||
| 763 | chunk(ls); | 857 | chunk(ls); |
| 764 | luaK_adjuststack(fs, fs->nactloc - nactloc); /* remove local variables */ | 858 | lua_assert(bl.breaklist == NO_JUMP); |
| 765 | removelocalvars(ls, fs->nactloc - nactloc); | 859 | leaveblock(fs); |
| 766 | } | 860 | } |
| 767 | 861 | ||
| 768 | 862 | ||
| 769 | static int assignment (LexState *ls, expdesc *v, int nvars) { | 863 | /* |
| 770 | int left = 0; /* number of values left in the stack after assignment */ | 864 | ** structure to chain all variables in the left-hand side of an |
| 771 | luaX_checklimit(ls, nvars, MAXVARSLH, "variables in a multiple assignment"); | 865 | ** assignment |
| 772 | if (ls->t.token == ',') { /* assignment -> ',' NAME assignment */ | 866 | */ |
| 773 | expdesc nv; | 867 | struct LHS_assign { |
| 774 | next(ls); | 868 | struct LHS_assign *prev; |
| 775 | var_or_func(ls, &nv); | 869 | expdesc v; /* variable (global, local, upvalue, or indexed) */ |
| 776 | check_condition(ls, (nv.k != VEXP), "syntax error"); | 870 | }; |
| 777 | left = assignment(ls, &nv, nvars+1); | 871 | |
| 872 | |||
| 873 | /* | ||
| 874 | ** check whether, in an assignment to a local variable, the local variable | ||
| 875 | ** is needed in a previous assignment (to a table). If so, save original | ||
| 876 | ** local value in a safe place and use this safe copy in the previous | ||
| 877 | ** assignment. | ||
| 878 | */ | ||
| 879 | static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { | ||
| 880 | FuncState *fs = ls->fs; | ||
| 881 | int extra = fs->freereg; /* eventual position to save local variable */ | ||
| 882 | int conflict = 0; | ||
| 883 | for (; lh; lh = lh->prev) { | ||
| 884 | if (lh->v.k == VINDEXED) { | ||
| 885 | if (lh->v.info == v->info) { /* conflict? */ | ||
| 886 | conflict = 1; | ||
| 887 | lh->v.info = extra; /* previous assignment will use safe copy */ | ||
| 888 | } | ||
| 889 | if (lh->v.aux == v->info) { /* conflict? */ | ||
| 890 | conflict = 1; | ||
| 891 | lh->v.aux = extra; /* previous assignment will use safe copy */ | ||
| 892 | } | ||
| 893 | } | ||
| 894 | } | ||
| 895 | if (conflict) { | ||
| 896 | luaK_codeABC(fs, OP_MOVE, fs->freereg, v->info, 0); /* make copy */ | ||
| 897 | luaK_reserveregs(fs, 1); | ||
| 778 | } | 898 | } |
| 779 | else { /* assignment -> '=' explist1 */ | 899 | } |
| 900 | |||
| 901 | |||
| 902 | static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { | ||
| 903 | expdesc e; | ||
| 904 | check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, | ||
| 905 | "syntax error"); | ||
| 906 | if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */ | ||
| 907 | struct LHS_assign nv; | ||
| 908 | nv.prev = lh; | ||
| 909 | primaryexp(ls, &nv.v); | ||
| 910 | if (nv.v.k == VLOCAL) | ||
| 911 | check_conflict(ls, lh, &nv.v); | ||
| 912 | assignment(ls, &nv, nvars+1); | ||
| 913 | } | ||
| 914 | else { /* assignment -> `=' explist1 */ | ||
| 780 | int nexps; | 915 | int nexps; |
| 781 | check(ls, '='); | 916 | check(ls, '='); |
| 782 | nexps = explist1(ls); | 917 | nexps = explist1(ls, &e); |
| 783 | adjust_mult_assign(ls, nvars, nexps); | 918 | if (nexps != nvars) { |
| 784 | } | 919 | adjust_assign(ls, nvars, nexps, &e); |
| 785 | if (v->k != VINDEXED) | 920 | if (nexps > nvars) |
| 786 | luaK_storevar(ls, v); | 921 | ls->fs->freereg -= nexps - nvars; /* remove extra values */ |
| 787 | else { /* there may be garbage between table-index and value */ | 922 | } |
| 788 | luaK_code2(ls->fs, OP_SETTABLE, left+nvars+2, 1); | 923 | else { |
| 789 | left += 2; | 924 | luaK_setcallreturns(ls->fs, &e, 1); /* close last expression */ |
| 925 | luaK_storevar(ls->fs, &lh->v, &e); | ||
| 926 | return; /* avoid default */ | ||
| 927 | } | ||
| 790 | } | 928 | } |
| 791 | return left; | 929 | init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ |
| 930 | luaK_storevar(ls->fs, &lh->v, &e); | ||
| 792 | } | 931 | } |
| 793 | 932 | ||
| 794 | 933 | ||
| 795 | static void cond (LexState *ls, expdesc *v) { | 934 | static void cond (LexState *ls, expdesc *v) { |
| 796 | /* cond -> exp */ | 935 | /* cond -> exp */ |
| 797 | expr(ls, v); /* read condition */ | 936 | expr(ls, v); /* read condition */ |
| 798 | luaK_goiftrue(ls->fs, v, 0); | 937 | if (v->k == VNIL) v->k = VFALSE; /* `falses' are all equal here */ |
| 938 | luaK_goiftrue(ls->fs, v); | ||
| 939 | luaK_patchtohere(ls->fs, v->t); | ||
| 799 | } | 940 | } |
| 800 | 941 | ||
| 801 | 942 | ||
| 943 | /* | ||
| 944 | ** The while statement optimizes its code by coding the condition | ||
| 945 | ** after its body (and thus avoiding one jump in the loop). | ||
| 946 | */ | ||
| 947 | |||
| 948 | /* | ||
| 949 | ** maximum size of expressions for optimizing `while' code | ||
| 950 | */ | ||
| 951 | #ifndef MAXEXPWHILE | ||
| 952 | #define MAXEXPWHILE 100 | ||
| 953 | #endif | ||
| 954 | |||
| 955 | /* | ||
| 956 | ** the call `luaK_goiffalse' may grow the size of an expression by | ||
| 957 | ** at most this: | ||
| 958 | */ | ||
| 959 | #define EXTRAEXP 5 | ||
| 960 | |||
| 802 | static void whilestat (LexState *ls, int line) { | 961 | static void whilestat (LexState *ls, int line) { |
| 803 | /* whilestat -> WHILE cond DO block END */ | 962 | /* whilestat -> WHILE cond DO block END */ |
| 963 | Instruction codeexp[MAXEXPWHILE + EXTRAEXP]; | ||
| 964 | int lineexp; | ||
| 965 | int i; | ||
| 966 | int sizeexp; | ||
| 804 | FuncState *fs = ls->fs; | 967 | FuncState *fs = ls->fs; |
| 805 | int while_init = luaK_getlabel(fs); | 968 | int whileinit, blockinit, expinit; |
| 806 | expdesc v; | 969 | expdesc v; |
| 807 | Breaklabel bl; | 970 | BlockCnt bl; |
| 808 | enterbreak(fs, &bl); | 971 | next(ls); /* skip WHILE */ |
| 809 | next(ls); | 972 | whileinit = luaK_jump(fs); /* jump to condition (which will be moved) */ |
| 810 | cond(ls, &v); | 973 | expinit = luaK_getlabel(fs); |
| 974 | expr(ls, &v); /* parse condition */ | ||
| 975 | if (v.k == VK) v.k = VTRUE; /* `trues' are all equal here */ | ||
| 976 | lineexp = ls->linenumber; | ||
| 977 | luaK_goiffalse(fs, &v); | ||
| 978 | luaK_concat(fs, &v.f, fs->jpc); | ||
| 979 | fs->jpc = NO_JUMP; | ||
| 980 | sizeexp = fs->pc - expinit; /* size of expression code */ | ||
| 981 | if (sizeexp > MAXEXPWHILE) | ||
| 982 | luaX_syntaxerror(ls, "`while' condition too complex"); | ||
| 983 | for (i = 0; i < sizeexp; i++) /* save `exp' code */ | ||
| 984 | codeexp[i] = fs->f->code[expinit + i]; | ||
| 985 | fs->pc = expinit; /* remove `exp' code */ | ||
| 986 | enterblock(fs, &bl, 1); | ||
| 811 | check(ls, TK_DO); | 987 | check(ls, TK_DO); |
| 988 | blockinit = luaK_getlabel(fs); | ||
| 812 | block(ls); | 989 | block(ls); |
| 813 | luaK_patchlist(fs, luaK_jump(fs), while_init); | 990 | luaK_patchtohere(fs, whileinit); /* initial jump jumps to here */ |
| 814 | luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs)); | 991 | /* move `exp' back to code */ |
| 992 | if (v.t != NO_JUMP) v.t += fs->pc - expinit; | ||
| 993 | if (v.f != NO_JUMP) v.f += fs->pc - expinit; | ||
| 994 | for (i=0; i<sizeexp; i++) | ||
| 995 | luaK_code(fs, codeexp[i], lineexp); | ||
| 815 | check_match(ls, TK_END, TK_WHILE, line); | 996 | check_match(ls, TK_END, TK_WHILE, line); |
| 816 | leavebreak(fs, &bl); | 997 | leaveblock(fs); |
| 998 | luaK_patchlist(fs, v.t, blockinit); /* true conditions go back to loop */ | ||
| 999 | luaK_patchtohere(fs, v.f); /* false conditions finish the loop */ | ||
| 817 | } | 1000 | } |
| 818 | 1001 | ||
| 819 | 1002 | ||
| @@ -822,64 +1005,86 @@ static void repeatstat (LexState *ls, int line) { · 2 unmodified lines | |||
| 822 | FuncState *fs = ls->fs; | 1005 | FuncState *fs = ls->fs; |
| 823 | int repeat_init = luaK_getlabel(fs); | 1006 | int repeat_init = luaK_getlabel(fs); |
| 824 | expdesc v; | 1007 | expdesc v; |
| 825 | Breaklabel bl; | 1008 | BlockCnt bl; |
| 826 | enterbreak(fs, &bl); | 1009 | enterblock(fs, &bl, 1); |
| 827 | next(ls); | 1010 | next(ls); |
| 828 | block(ls); | 1011 | block(ls); |
| 829 | check_match(ls, TK_UNTIL, TK_REPEAT, line); | 1012 | check_match(ls, TK_UNTIL, TK_REPEAT, line); |
| 830 | cond(ls, &v); | 1013 | cond(ls, &v); |
| 831 | luaK_patchlist(fs, v.u.l.f, repeat_init); | 1014 | luaK_patchlist(fs, v.f, repeat_init); |
| 832 | leavebreak(fs, &bl); | 1015 | leaveblock(fs); |
| 833 | } | 1016 | } |
| 834 | 1017 | ||
| 835 | 1018 | ||
| 836 | static void forbody (LexState *ls, int nvar, OpCode prepfor, OpCode loopfor) { | 1019 | static int exp1 (LexState *ls) { |
| 837 | /* forbody -> DO block END */ | 1020 | expdesc e; |
| 1021 | int k; | ||
| 1022 | expr(ls, &e); | ||
| 1023 | k = e.k; | ||
| 1024 | luaK_exp2nextreg(ls->fs, &e); | ||
| 1025 | return k; | ||
| 1026 | } | ||
| 1027 | |||
| 1028 | |||
| 1029 | static void forbody (LexState *ls, int base, int line, int nvars, int isnum) { | ||
| 1030 | BlockCnt bl; | ||
| 838 | FuncState *fs = ls->fs; | 1031 | FuncState *fs = ls->fs; |
| 839 | int prep = luaK_code1(fs, prepfor, NO_JUMP); | 1032 | int prep, endfor; |
| 840 | int blockinit = luaK_getlabel(fs); | 1033 | adjustlocalvars(ls, nvars); /* scope for all variables */ |
| 841 | check(ls, TK_DO); | 1034 | check(ls, TK_DO); |
| 842 | adjustlocalvars(ls, nvar); /* scope for control variables */ | 1035 | enterblock(fs, &bl, 1); /* loop block */ |
| 1036 | prep = luaK_getlabel(fs); | ||
| 843 | block(ls); | 1037 | block(ls); |
| 844 | luaK_patchlist(fs, luaK_code1(fs, loopfor, NO_JUMP), blockinit); | 1038 | luaK_patchtohere(fs, prep-1); |
| 845 | luaK_patchlist(fs, prep, luaK_getlabel(fs)); | 1039 | endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) : |
| 846 | removelocalvars(ls, nvar); | 1040 | luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars - 3); |
| 1041 | luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */ | ||
| 1042 | luaK_patchlist(fs, (isnum) ? endfor : luaK_jump(fs), prep); | ||
| 1043 | leaveblock(fs); | ||
| 847 | } | 1044 | } |
| 848 | 1045 | ||
| 849 | 1046 | ||
| 850 | static void fornum (LexState *ls, TString *varname) { | 1047 | static void fornum (LexState *ls, TString *varname, int line) { |
| 851 | /* fornum -> NAME = exp1,exp1[,exp1] forbody */ | 1048 | /* fornum -> NAME = exp1,exp1[,exp1] DO body */ |
| 852 | FuncState *fs = ls->fs; | 1049 | FuncState *fs = ls->fs; |
| 1050 | int base = fs->freereg; | ||
| 1051 | new_localvar(ls, varname, 0); | ||
| 1052 | new_localvarstr(ls, "(for limit)", 1); | ||
| 1053 | new_localvarstr(ls, "(for step)", 2); | ||
| 853 | check(ls, '='); | 1054 | check(ls, '='); |
| 854 | exp1(ls); /* initial value */ | 1055 | exp1(ls); /* initial value */ |
| 855 | check(ls, ','); | 1056 | check(ls, ','); |
| 856 | exp1(ls); /* limit */ | 1057 | exp1(ls); /* limit */ |
| 857 | if (optional(ls, ',')) | 1058 | if (testnext(ls, ',')) |
| 858 | exp1(ls); /* optional step */ | 1059 | exp1(ls); /* optional step */ |
| 859 | else | 1060 | else { /* default step = 1 */ |
| 860 | luaK_code1(fs, OP_PUSHINT, 1); /* default step */ | 1061 | luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1)); |
| 861 | new_localvar(ls, varname, 0); | 1062 | luaK_reserveregs(fs, 1); |
| 862 | new_localvarstr(ls, "(limit)", 1); | 1063 | } |
| 863 | new_localvarstr(ls, "(step)", 2); | 1064 | luaK_codeABC(fs, OP_SUB, fs->freereg - 3, fs->freereg - 3, fs->freereg - 1); |
| 864 | forbody(ls, 3, OP_FORPREP, OP_FORLOOP); | 1065 | luaK_jump(fs); |
| 1066 | forbody(ls, base, line, 3, 1); | ||
| 865 | } | 1067 | } |
| 866 | 1068 | ||
| 867 | 1069 | ||
| 868 | static void forlist (LexState *ls, TString *indexname) { | 1070 | static void forlist (LexState *ls, TString *indexname) { |
| 869 | /* forlist -> NAME,NAME IN exp1 forbody */ | 1071 | /* forlist -> NAME {,NAME} IN explist1 DO body */ |
| 870 | TString *valname; | 1072 | FuncState *fs = ls->fs; |
| 871 | check(ls, ','); | 1073 | expdesc e; |
| 872 | valname = str_checkname(ls); | 1074 | int nvars = 0; |
| 873 | /* next test is dirty, but avoids `in' being a reserved word */ | 1075 | int line; |
| 874 | check_condition(ls, | 1076 | int base = fs->freereg; |
| 875 | (ls->t.token == TK_NAME && ls->t.seminfo.ts == luaS_new(ls->L, "in")), | 1077 | new_localvarstr(ls, "(for generator)", nvars++); |
| 876 | "`in' expected"); | 1078 | new_localvarstr(ls, "(for state)", nvars++); |
| 877 | next(ls); /* skip `in' */ | 1079 | new_localvar(ls, indexname, nvars++); |
| 878 | exp1(ls); /* table */ | 1080 | while (testnext(ls, ',')) |
| 879 | new_localvarstr(ls, "(table)", 0); | 1081 | new_localvar(ls, str_checkname(ls), nvars++); |
| 880 | new_localvar(ls, indexname, 1); | 1082 | check(ls, TK_IN); |
| 881 | new_localvar(ls, valname, 2); | 1083 | line = ls->linenumber; |
| 882 | forbody(ls, 3, OP_LFORPREP, OP_LFORLOOP); | 1084 | adjust_assign(ls, nvars, explist1(ls, &e), &e); |
| 1085 | luaK_checkstack(fs, 3); /* extra space to call generator */ | ||
| 1086 | luaK_codeAsBx(fs, OP_TFORPREP, base, NO_JUMP); | ||
| 1087 | forbody(ls, base, line, nvars, 0); | ||
| 883 | } | 1088 | } |
| 884 | 1089 | ||
| 885 | 1090 | ||
| @@ -887,17 +1092,17 @@ static void forstat (LexState *ls, int line) { · 1 unmodified line | |||
| 887 | /* forstat -> fornum | forlist */ | 1092 | /* forstat -> fornum | forlist */ |
| 888 | FuncState *fs = ls->fs; | 1093 | FuncState *fs = ls->fs; |
| 889 | TString *varname; | 1094 | TString *varname; |
| 890 | Breaklabel bl; | 1095 | BlockCnt bl; |
| 891 | enterbreak(fs, &bl); | 1096 | enterblock(fs, &bl, 0); /* block to control variable scope */ |
| 892 | next(ls); /* skip `for' */ | 1097 | next(ls); /* skip `for' */ |
| 893 | varname = str_checkname(ls); /* first variable name */ | 1098 | varname = str_checkname(ls); /* first variable name */ |
| 894 | switch (ls->t.token) { | 1099 | switch (ls->t.token) { |
| 895 | case '=': fornum(ls, varname); break; | 1100 | case '=': fornum(ls, varname, line); break; |
| 896 | case ',': forlist(ls, varname); break; | 1101 | case ',': case TK_IN: forlist(ls, varname); break; |
| 897 | default: luaK_error(ls, "`=' or `,' expected"); | 1102 | default: luaX_syntaxerror(ls, "`=' or `in' expected"); |
| 898 | } | 1103 | } |
| 899 | check_match(ls, TK_END, TK_FOR, line); | 1104 | check_match(ls, TK_END, TK_FOR, line); |
| 900 | leavebreak(fs, &bl); | 1105 | leaveblock(fs); |
| 901 | } | 1106 | } |
| 902 | 1107 | ||
| 903 | 1108 | ||
| @@ -918,49 +1123,60 @@ static void ifstat (LexState *ls, int line) { · 14 unmodified lines | |||
| 918 | test_then_block(ls, &v); /* IF cond THEN block */ | 1123 | test_then_block(ls, &v); /* IF cond THEN block */ |
| 919 | while (ls->t.token == TK_ELSEIF) { | 1124 | while (ls->t.token == TK_ELSEIF) { |
| 920 | luaK_concat(fs, &escapelist, luaK_jump(fs)); | 1125 | luaK_concat(fs, &escapelist, luaK_jump(fs)); |
| 921 | luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs)); | 1126 | luaK_patchtohere(fs, v.f); |
| 922 | test_then_block(ls, &v); /* ELSEIF cond THEN block */ | 1127 | test_then_block(ls, &v); /* ELSEIF cond THEN block */ |
| 923 | } | 1128 | } |
| 924 | if (ls->t.token == TK_ELSE) { | 1129 | if (ls->t.token == TK_ELSE) { |
| 925 | luaK_concat(fs, &escapelist, luaK_jump(fs)); | 1130 | luaK_concat(fs, &escapelist, luaK_jump(fs)); |
| 926 | luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs)); | 1131 | luaK_patchtohere(fs, v.f); |
| 927 | next(ls); /* skip ELSE */ | 1132 | next(ls); /* skip ELSE (after patch, for correct line info) */ |
| 928 | block(ls); /* `else' part */ | 1133 | block(ls); /* `else' part */ |
| 929 | } | 1134 | } |
| 930 | else | 1135 | else |
| 931 | luaK_concat(fs, &escapelist, v.u.l.f); | 1136 | luaK_concat(fs, &escapelist, v.f); |
| 932 | luaK_patchlist(fs, escapelist, luaK_getlabel(fs)); | 1137 | luaK_patchtohere(fs, escapelist); |
| 933 | check_match(ls, TK_END, TK_IF, line); | 1138 | check_match(ls, TK_END, TK_IF, line); |
| 934 | } | 1139 | } |
| 935 | 1140 | ||
| 936 | 1141 | ||
| 1142 | static void localfunc (LexState *ls) { | ||
| 1143 | expdesc v, b; | ||
| 1144 | new_localvar(ls, str_checkname(ls), 0); | ||
| 1145 | init_exp(&v, VLOCAL, ls->fs->freereg++); | ||
| 1146 | adjustlocalvars(ls, 1); | ||
| 1147 | body(ls, &b, 0, ls->linenumber); | ||
| 1148 | luaK_storevar(ls->fs, &v, &b); | ||
| 1149 | } | ||
| 1150 | |||
| 1151 | |||
| 937 | static void localstat (LexState *ls) { | 1152 | static void localstat (LexState *ls) { |
| 938 | /* stat -> LOCAL NAME {',' NAME} ['=' explist1] */ | 1153 | /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */ |
| 939 | int nvars = 0; | 1154 | int nvars = 0; |
| 940 | int nexps; | 1155 | int nexps; |
| 1156 | expdesc e; | ||
| 941 | do { | 1157 | do { |
| 942 | next(ls); /* skip LOCAL or ',' */ | ||
| 943 | new_localvar(ls, str_checkname(ls), nvars++); | 1158 | new_localvar(ls, str_checkname(ls), nvars++); |
| 944 | } while (ls->t.token == ','); | 1159 | } while (testnext(ls, ',')); |
| 945 | if (optional(ls, '=')) | 1160 | if (testnext(ls, '=')) |
| 946 | nexps = explist1(ls); | 1161 | nexps = explist1(ls, &e); |
| 947 | else | 1162 | else { |
| 1163 | e.k = VVOID; | ||
| 948 | nexps = 0; | 1164 | nexps = 0; |
| 949 | adjust_mult_assign(ls, nvars, nexps); | 1165 | } |
| 1166 | adjust_assign(ls, nvars, nexps, &e); | ||
| 950 | adjustlocalvars(ls, nvars); | 1167 | adjustlocalvars(ls, nvars); |
| 951 | } | 1168 | } |
| 952 | 1169 | ||
| 953 | 1170 | ||
| 954 | static int funcname (LexState *ls, expdesc *v) { | 1171 | static int funcname (LexState *ls, expdesc *v) { |
| 955 | /* funcname -> NAME [':' NAME | '.' NAME] */ | 1172 | /* funcname -> NAME {field} [`:' NAME] */ |
| 956 | int needself = 0; | 1173 | int needself = 0; |
| 957 | singlevar(ls, str_checkname(ls), v); | 1174 | singlevar(ls, v, 1); |
| 958 | if (ls->t.token == ':' || ls->t.token == '.') { | 1175 | while (ls->t.token == '.') |
| 959 | needself = (ls->t.token == ':'); | 1176 | luaY_field(ls, v); |
| 960 | next(ls); | 1177 | if (ls->t.token == ':') { |
| 961 | luaK_tostack(ls, v, 1); | 1178 | needself = 1; |
| 962 | luaK_kstr(ls, checkname(ls)); | 1179 | luaY_field(ls, v); |
| 963 | v->k = VINDEXED; | ||
| 964 | } | 1180 | } |
| 965 | return needself; | 1181 | return needself; |
| 966 | } | 1182 | } |
| @@ -969,26 +1185,26 @@ static int funcname (LexState *ls, expdesc *v) { · 2 unmodified lines | |||
| 969 | static void funcstat (LexState *ls, int line) { | 1185 | static void funcstat (LexState *ls, int line) { |
| 970 | /* funcstat -> FUNCTION funcname body */ | 1186 | /* funcstat -> FUNCTION funcname body */ |
| 971 | int needself; | 1187 | int needself; |
| 972 | expdesc v; | 1188 | expdesc v, b; |
| 973 | next(ls); /* skip FUNCTION */ | 1189 | next(ls); /* skip FUNCTION */ |
| 974 | needself = funcname(ls, &v); | 1190 | needself = funcname(ls, &v); |
| 975 | body(ls, needself, line); | 1191 | body(ls, &b, needself, line); |
| 976 | luaK_storevar(ls, &v); | 1192 | luaK_storevar(ls->fs, &v, &b); |
| 1193 | luaK_fixline(ls->fs, line); /* definition `happens' in the first line */ | ||
| 977 | } | 1194 | } |
| 978 | 1195 | ||
| 979 | 1196 | ||
| 980 | static void namestat (LexState *ls) { | 1197 | static void exprstat (LexState *ls) { |
| 981 | /* stat -> func | ['%'] NAME assignment */ | 1198 | /* stat -> func | assignment */ |
| 982 | FuncState *fs = ls->fs; | 1199 | FuncState *fs = ls->fs; |
| 983 | expdesc v; | 1200 | struct LHS_assign v; |
| 984 | var_or_func(ls, &v); | 1201 | primaryexp(ls, &v.v); |
| 985 | if (v.k == VEXP) { /* stat -> func */ | 1202 | if (v.v.k == VCALL) { /* stat -> func */ |
| 986 | check_condition(ls, luaK_lastisopen(fs), "syntax error"); /* an upvalue? */ | 1203 | luaK_setcallreturns(fs, &v.v, 0); /* call statement uses no results */ |
| 987 | luaK_setcallreturns(fs, 0); /* call statement uses no results */ | ||
| 988 | } | 1204 | } |
| 989 | else { /* stat -> ['%'] NAME assignment */ | 1205 | else { /* stat -> assignment */ |
| 990 | int left = assignment(ls, &v, 1); | 1206 | v.prev = NULL; |
| 991 | luaK_adjuststack(fs, left); /* remove eventual garbage left on stack */ | 1207 | assignment(ls, &v, 1); |
| 992 | } | 1208 | } |
| 993 | } | 1209 | } |
| 994 | 1210 | ||
| @@ -996,30 +1212,55 @@ static void namestat (LexState *ls) { · 1 unmodified line | |||
| 996 | static void retstat (LexState *ls) { | 1212 | static void retstat (LexState *ls) { |
| 997 | /* stat -> RETURN explist */ | 1213 | /* stat -> RETURN explist */ |
| 998 | FuncState *fs = ls->fs; | 1214 | FuncState *fs = ls->fs; |
| 1215 | expdesc e; | ||
| 1216 | int first, nret; /* registers with returned values */ | ||
| 999 | next(ls); /* skip RETURN */ | 1217 | next(ls); /* skip RETURN */ |
| 1000 | if (!block_follow(ls->t.token) && ls->t.token != ';') | 1218 | if (block_follow(ls->t.token) || ls->t.token == ';') |
| 1001 | explist1(ls); /* optional return values */ | 1219 | first = nret = 0; /* return no values */ |
| 1002 | luaK_code1(fs, OP_RETURN, ls->fs->nactloc); | 1220 | else { |
| 1003 | fs->stacklevel = fs->nactloc; /* removes all temp values */ | 1221 | nret = explist1(ls, &e); /* optional return values */ |
| 1222 | if (e.k == VCALL) { | ||
| 1223 | luaK_setcallreturns(fs, &e, LUA_MULTRET); | ||
| 1224 | if (nret == 1) { /* tail call? */ | ||
| 1225 | SET_OPCODE(getcode(fs,&e), OP_TAILCALL); | ||
| 1226 | lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar); | ||
| 1227 | } | ||
| 1228 | first = fs->nactvar; | ||
| 1229 | nret = LUA_MULTRET; /* return all values */ | ||
| 1230 | } | ||
| 1231 | else { | ||
| 1232 | if (nret == 1) /* only one single value? */ | ||
| 1233 | first = luaK_exp2anyreg(fs, &e); | ||
| 1234 | else { | ||
| 1235 | luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */ | ||
| 1236 | first = fs->nactvar; /* return all `active' values */ | ||
| 1237 | lua_assert(nret == fs->freereg - first); | ||
| 1238 | } | ||
| 1239 | } | ||
| 1240 | } | ||
| 1241 | luaK_codeABC(fs, OP_RETURN, first, nret+1, 0); | ||
| 1004 | } | 1242 | } |
| 1005 | 1243 | ||
| 1006 | 1244 | ||
| 1007 | static void breakstat (LexState *ls) { | 1245 | static void breakstat (LexState *ls) { |
| 1008 | /* stat -> BREAK [NAME] */ | 1246 | /* stat -> BREAK [NAME] */ |
| 1009 | FuncState *fs = ls->fs; | 1247 | FuncState *fs = ls->fs; |
| 1010 | int currentlevel = fs->stacklevel; | 1248 | BlockCnt *bl = fs->bl; |
| 1011 | Breaklabel *bl = fs->bl; | 1249 | int upval = 0; |
| 1012 | if (!bl) | ||
| 1013 | luaK_error(ls, "no loop to break"); | ||
| 1014 | next(ls); /* skip BREAK */ | 1250 | next(ls); /* skip BREAK */ |
| 1015 | luaK_adjuststack(fs, currentlevel - bl->stacklevel); | 1251 | while (bl && !bl->isbreakable) { |
| 1252 | upval |= bl->upval; | ||
| 1253 | bl = bl->previous; | ||
| 1254 | } | ||
| 1255 | if (!bl) | ||
| 1256 | luaX_syntaxerror(ls, "no loop to break"); | ||
| 1257 | if (upval) | ||
| 1258 | luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); | ||
| 1016 | luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); | 1259 | luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); |
| 1017 | /* correct stack for compiler and symbolic execution */ | ||
| 1018 | luaK_adjuststack(fs, bl->stacklevel - currentlevel); | ||
| 1019 | } | 1260 | } |
| 1020 | 1261 | ||
| 1021 | 1262 | ||
| 1022 | static int stat (LexState *ls) { | 1263 | static int statement (LexState *ls) { |
| 1023 | int line = ls->linenumber; /* may be needed for error messages */ | 1264 | int line = ls->linenumber; /* may be needed for error messages */ |
| 1024 | switch (ls->t.token) { | 1265 | switch (ls->t.token) { |
| 1025 | case TK_IF: { /* stat -> ifstat */ | 1266 | case TK_IF: { /* stat -> ifstat */ |
| @@ -1044,16 +1285,16 @@ static int stat (LexState *ls) { · 18 unmodified lines | |||
| 1044 | repeatstat(ls, line); | 1285 | repeatstat(ls, line); |
| 1045 | return 0; | 1286 | return 0; |
| 1046 | } | 1287 | } |
| 1047 | case TK_FUNCTION: { /* stat -> funcstat */ | 1288 | case TK_FUNCTION: { |
| 1048 | funcstat(ls, line); | 1289 | funcstat(ls, line); /* stat -> funcstat */ |
| 1049 | return 0; | 1290 | return 0; |
| 1050 | } | 1291 | } |
| 1051 | case TK_LOCAL: { /* stat -> localstat */ | 1292 | case TK_LOCAL: { /* stat -> localstat */ |
| 1052 | localstat(ls); | 1293 | next(ls); /* skip LOCAL */ |
| 1053 | return 0; | 1294 | if (testnext(ls, TK_FUNCTION)) /* local function? */ |
| 1054 | } | 1295 | localfunc(ls); |
| 1055 | case TK_NAME: case '%': { /* stat -> namestat */ | 1296 | else |
| 1056 | namestat(ls); | 1297 | localstat(ls); |
| 1057 | return 0; | 1298 | return 0; |
| 1058 | } | 1299 | } |
| 1059 | case TK_RETURN: { /* stat -> retstat */ | 1300 | case TK_RETURN: { /* stat -> retstat */ |
| @@ -1065,60 +1306,24 @@ static int stat (LexState *ls) { · 5 unmodified lines | |||
| 1065 | return 1; /* must be last statement */ | 1306 | return 1; /* must be last statement */ |
| 1066 | } | 1307 | } |
| 1067 | default: { | 1308 | default: { |
| 1068 | luaK_error(ls, "<statement> expected"); | 1309 | exprstat(ls); |
| 1069 | return 0; /* to avoid warnings */ | 1310 | return 0; /* to avoid warnings */ |
| 1070 | } | 1311 | } |
| 1071 | } | 1312 | } |
| 1072 | } | 1313 | } |
| 1073 | 1314 | ||
| 1074 | 1315 | ||
| 1075 | static void parlist (LexState *ls) { | ||
| 1076 | /* parlist -> [ param { ',' param } ] */ | ||
| 1077 | int nparams = 0; | ||
| 1078 | int dots = 0; | ||
| 1079 | if (ls->t.token != ')') { /* is `parlist' not empty? */ | ||
| 1080 | do { | ||
| 1081 | switch (ls->t.token) { | ||
| 1082 | case TK_DOTS: next(ls); dots = 1; break; | ||
| 1083 | case TK_NAME: new_localvar(ls, str_checkname(ls), nparams++); break; | ||
| 1084 | default: luaK_error(ls, "<name> or `...' expected"); | ||
| 1085 | } | ||
| 1086 | } while (!dots && optional(ls, ',')); | ||
| 1087 | } | ||
| 1088 | code_params(ls, nparams, dots); | ||
| 1089 | } | ||
| 1090 | |||
| 1091 | |||
| 1092 | static void body (LexState *ls, int needself, int line) { | ||
| 1093 | /* body -> '(' parlist ')' chunk END */ | ||
| 1094 | FuncState new_fs; | ||
| 1095 | open_func(ls, &new_fs); | ||
| 1096 | new_fs.f->lineDefined = line; | ||
| 1097 | check(ls, '('); | ||
| 1098 | if (needself) { | ||
| 1099 | new_localvarstr(ls, "self", 0); | ||
| 1100 | adjustlocalvars(ls, 1); | ||
| 1101 | } | ||
| 1102 | parlist(ls); | ||
| 1103 | check(ls, ')'); | ||
| 1104 | chunk(ls); | ||
| 1105 | check_match(ls, TK_END, TK_FUNCTION, line); | ||
| 1106 | close_func(ls); | ||
| 1107 | pushclosure(ls, &new_fs); | ||
| 1108 | } | ||
| 1109 | |||
| 1110 | |||
| 1111 | /* }====================================================================== */ | ||
| 1112 | |||
| 1113 | |||
| 1114 | static void chunk (LexState *ls) { | 1316 | static void chunk (LexState *ls) { |
| 1115 | /* chunk -> { stat [';'] } */ | 1317 | /* chunk -> { stat [`;'] } */ |
| 1116 | int islast = 0; | 1318 | int islast = 0; |
| 1319 | enterlevel(ls); | ||
| 1117 | while (!islast && !block_follow(ls->t.token)) { | 1320 | while (!islast && !block_follow(ls->t.token)) { |
| 1118 | islast = stat(ls); | 1321 | islast = statement(ls); |
| 1119 | optional(ls, ';'); | 1322 | testnext(ls, ';'); |
| 1120 | LUA_ASSERT(ls->fs->stacklevel == ls->fs->nactloc, | 1323 | lua_assert(ls->fs->freereg >= ls->fs->nactvar); |
| 1121 | "stack size != # local vars"); | 1324 | ls->fs->freereg = ls->fs->nactvar; /* free registers */ |
| 1122 | } | 1325 | } |
| 1326 | leavelevel(ls); | ||
| 1123 | } | 1327 | } |
| 1124 | 1328 | ||
| 1329 | /* }====================================================================== */ | ||