diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-03-03 09:33:59 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-03-03 09:33:59 -0300 |
| commit | f7840a3e0bc07813246b2bad6bf4579848187908 (patch) | |
| tree | 8fe680329b87a8f5ba2ffeb920f8bbeb300e64b8 | |
| parent | 1780e2c977da2eadd71a982b9db1db1d768ebd8a (diff) | |
| download | lua-f7840a3e0bc07813246b2bad6bf4579848187908.tar.gz lua-f7840a3e0bc07813246b2bad6bf4579848187908.tar.bz2 lua-f7840a3e0bc07813246b2bad6bf4579848187908.zip | |
new algorithm to parse expressions + distribution of code between lparser
and lcode.
| -rw-r--r-- | lcode.c | 191 | ||||
| -rw-r--r-- | lcode.h | 20 | ||||
| -rw-r--r-- | lparser.c | 504 | ||||
| -rw-r--r-- | lparser.h | 18 |
4 files changed, 371 insertions, 362 deletions
| @@ -1,16 +1,23 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: $ | 2 | ** $Id: lcode.c,v 1.1 2000/02/22 13:30:11 roberto Exp roberto $ |
| 3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | 7 | ||
| 8 | #include "lcode.h" | 8 | #include "lcode.h" |
| 9 | #include "ldo.h" | ||
| 9 | #include "llex.h" | 10 | #include "llex.h" |
| 10 | #include "lmem.h" | 11 | #include "lmem.h" |
| 11 | #include "lobject.h" | 12 | #include "lobject.h" |
| 12 | #include "lopcodes.h" | 13 | #include "lopcodes.h" |
| 13 | #include "lparser.h" | 14 | #include "lparser.h" |
| 15 | #include "lstring.h" | ||
| 16 | |||
| 17 | |||
| 18 | void luaK_error (LexState *ls, const char *msg) { | ||
| 19 | luaX_error(ls, msg, ls->token); | ||
| 20 | } | ||
| 14 | 21 | ||
| 15 | 22 | ||
| 16 | static Instruction *last_i (FuncState *fs) { | 23 | static Instruction *last_i (FuncState *fs) { |
| @@ -94,3 +101,185 @@ void luaK_fixjump (LexState *ls, int pc, int dest) { | |||
| 94 | } | 101 | } |
| 95 | 102 | ||
| 96 | 103 | ||
| 104 | void luaK_deltastack (LexState *ls, int delta) { | ||
| 105 | FuncState *fs = ls->fs; | ||
| 106 | fs->stacksize += delta; | ||
| 107 | if (delta > 0 && fs->stacksize > fs->f->maxstacksize) { | ||
| 108 | if (fs->stacksize > MAXSTACK) | ||
| 109 | luaK_error(ls, "function or expression too complex"); | ||
| 110 | fs->f->maxstacksize = fs->stacksize; | ||
| 111 | } | ||
| 112 | } | ||
| 113 | |||
| 114 | |||
| 115 | static int aux_code (LexState *ls, OpCode op, Instruction i, int delta) { | ||
| 116 | luaK_deltastack(ls, delta); | ||
| 117 | return luaK_code(ls, SET_OPCODE(i, op)); | ||
| 118 | } | ||
| 119 | |||
| 120 | |||
| 121 | int luaK_0 (LexState *ls, OpCode op, int delta) { | ||
| 122 | return aux_code(ls, op, 0, delta); | ||
| 123 | } | ||
| 124 | |||
| 125 | |||
| 126 | int luaK_U (LexState *ls, OpCode op, int u, int delta) { | ||
| 127 | Instruction i = SETARG_U(0, u); | ||
| 128 | return aux_code(ls, op, i, delta); | ||
| 129 | } | ||
| 130 | |||
| 131 | |||
| 132 | int luaK_S (LexState *ls, OpCode op, int s, int delta) { | ||
| 133 | Instruction i = SETARG_S(0, s); | ||
| 134 | return aux_code(ls, op, i, delta); | ||
| 135 | } | ||
| 136 | |||
| 137 | |||
| 138 | int luaK_AB (LexState *ls, OpCode op, int a, int b, int delta) { | ||
| 139 | Instruction i = SETARG_A(0, a); | ||
| 140 | i = SETARG_B(i, b); | ||
| 141 | return aux_code(ls, op, i, delta); | ||
| 142 | } | ||
| 143 | |||
| 144 | |||
| 145 | int luaK_kstr (LexState *ls, int c) { | ||
| 146 | return luaK_U(ls, PUSHSTRING, c, 1); | ||
| 147 | } | ||
| 148 | |||
| 149 | |||
| 150 | #ifndef LOOKBACKNUMS | ||
| 151 | #define LOOKBACKNUMS 20 /* arbitrary limit */ | ||
| 152 | #endif | ||
| 153 | |||
| 154 | static int real_constant (LexState *ls, real r) { | ||
| 155 | /* check whether `r' has appeared within the last LIM entries */ | ||
| 156 | TProtoFunc *f = ls->fs->f; | ||
| 157 | int c = f->nknum; | ||
| 158 | int lim = c < LOOKBACKNUMS ? 0 : c-LOOKBACKNUMS; | ||
| 159 | while (--c >= lim) | ||
| 160 | if (f->knum[c] == r) return c; | ||
| 161 | /* not found; create a new entry */ | ||
| 162 | luaM_growvector(ls->L, f->knum, f->nknum, 1, real, constantEM, MAXARG_U); | ||
| 163 | c = f->nknum++; | ||
| 164 | f->knum[c] = r; | ||
| 165 | return c; | ||
| 166 | } | ||
| 167 | |||
| 168 | |||
| 169 | int luaK_number (LexState *ls, real f) { | ||
| 170 | if (f <= (real)MAXARG_S && (int)f == f) | ||
| 171 | return luaK_S(ls, PUSHINT, (int)f, 1); /* f has a short integer value */ | ||
| 172 | else | ||
| 173 | return luaK_U(ls, PUSHNUM, real_constant(ls, f), 1); | ||
| 174 | } | ||
| 175 | |||
| 176 | |||
| 177 | int luaK_adjuststack (LexState *ls, int n) { | ||
| 178 | if (n > 0) | ||
| 179 | return luaK_U(ls, POP, n, -n); | ||
| 180 | else if (n < 0) | ||
| 181 | return luaK_U(ls, PUSHNIL, (-n)-1, -n); | ||
| 182 | else return 0; | ||
| 183 | } | ||
| 184 | |||
| 185 | |||
| 186 | int luaK_iscall (LexState *ls, int pc) { | ||
| 187 | return (GET_OPCODE(ls->fs->f->code[pc]) == CALL); | ||
| 188 | } | ||
| 189 | |||
| 190 | |||
| 191 | void luaK_setcallreturns (LexState *ls, int pc, int nresults) { | ||
| 192 | if (luaK_iscall(ls, pc)) { /* expression is a function call? */ | ||
| 193 | Instruction *i = &ls->fs->f->code[pc]; | ||
| 194 | int old_nresults = GETARG_B(*i); | ||
| 195 | if (old_nresults != MULT_RET) | ||
| 196 | luaK_deltastack(ls, -old_nresults); /* pop old nresults */ | ||
| 197 | *i = SETARG_B(*i, nresults); /* set nresults */ | ||
| 198 | if (nresults != MULT_RET) | ||
| 199 | luaK_deltastack(ls, nresults); /* push results */ | ||
| 200 | } | ||
| 201 | } | ||
| 202 | |||
| 203 | |||
| 204 | static void assertglobal (LexState *ls, int index) { | ||
| 205 | luaS_assertglobal(ls->L, ls->fs->f->kstr[index]); | ||
| 206 | } | ||
| 207 | |||
| 208 | |||
| 209 | void luaK_2stack (LexState *ls, expdesc *var) { | ||
| 210 | switch (var->k) { | ||
| 211 | case VLOCAL: | ||
| 212 | var->info = luaK_U(ls, PUSHLOCAL, var->info, 1); | ||
| 213 | break; | ||
| 214 | case VGLOBAL: | ||
| 215 | assertglobal(ls, var->info); /* make sure that there is a global */ | ||
| 216 | var->info = luaK_U(ls, GETGLOBAL, var->info, 1); | ||
| 217 | break; | ||
| 218 | case VINDEXED: | ||
| 219 | var->info = luaK_0(ls, GETTABLE, -1); | ||
| 220 | break; | ||
| 221 | case VEXP: | ||
| 222 | luaK_setcallreturns(ls, var->info, 1); /* call must return 1 value */ | ||
| 223 | break; | ||
| 224 | } | ||
| 225 | var->k = VEXP; | ||
| 226 | } | ||
| 227 | |||
| 228 | |||
| 229 | void luaK_storevar (LexState *ls, const expdesc *var) { | ||
| 230 | switch (var->k) { | ||
| 231 | case VLOCAL: | ||
| 232 | luaK_U(ls, SETLOCAL, var->info, -1); | ||
| 233 | break; | ||
| 234 | case VGLOBAL: | ||
| 235 | luaK_U(ls, SETGLOBAL, var->info, -1); | ||
| 236 | assertglobal(ls, var->info); /* make sure that there is a global */ | ||
| 237 | break; | ||
| 238 | case VINDEXED: | ||
| 239 | luaK_0(ls, SETTABLEPOP, -3); | ||
| 240 | break; | ||
| 241 | default: | ||
| 242 | LUA_INTERNALERROR(ls->L, "invalid var kind to store"); | ||
| 243 | } | ||
| 244 | } | ||
| 245 | |||
| 246 | |||
| 247 | void luaK_prefix (LexState *ls, int op, expdesc *v) { | ||
| 248 | luaK_2stack(ls, v); | ||
| 249 | if (op == '-') | ||
| 250 | v->info = luaK_0(ls, MINUSOP, 0); | ||
| 251 | else | ||
| 252 | v->info = luaK_0(ls, NOTOP, 0); | ||
| 253 | } | ||
| 254 | |||
| 255 | |||
| 256 | void luaK_infix (LexState *ls, expdesc *v) { | ||
| 257 | luaK_2stack(ls, v); | ||
| 258 | if (ls->token == AND) | ||
| 259 | v->info = luaK_0(ls, ONFJMP, -1); | ||
| 260 | else if (ls->token == OR) | ||
| 261 | v->info = luaK_0(ls, ONTJMP, -1); | ||
| 262 | } | ||
| 263 | |||
| 264 | |||
| 265 | void luaK_posfix (LexState *ls, int op, expdesc *v1, expdesc *v2) { | ||
| 266 | luaK_2stack(ls, v2); | ||
| 267 | switch (op) { | ||
| 268 | case AND: case OR: | ||
| 269 | luaK_fixjump(ls, v1->info, ls->fs->pc); | ||
| 270 | break; | ||
| 271 | case '+': v1->info = luaK_0(ls, ADDOP, -1); break; | ||
| 272 | case '-': v1->info = luaK_0(ls, SUBOP, -1); break; | ||
| 273 | case '*': v1->info = luaK_0(ls, MULTOP, -1); break; | ||
| 274 | case '/': v1->info = luaK_0(ls, DIVOP, -1); break; | ||
| 275 | case '^': v1->info = luaK_0(ls, POWOP, -1); break; | ||
| 276 | case CONC: v1->info = luaK_0(ls, CONCOP, -1); break; | ||
| 277 | case EQ: v1->info = luaK_0(ls, EQOP, -1); break; | ||
| 278 | case NE: v1->info = luaK_0(ls, NEQOP, -1); break; | ||
| 279 | case '>': v1->info = luaK_0(ls, GTOP, -1); break; | ||
| 280 | case '<': v1->info = luaK_0(ls, LTOP, -1); break; | ||
| 281 | case GE: v1->info = luaK_0(ls, GEOP, -1); break; | ||
| 282 | case LE: v1->info = luaK_0(ls, LEOP, -1); break; | ||
| 283 | } | ||
| 284 | } | ||
| 285 | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: $ | 2 | ** $Id: lcode.h,v 1.1 2000/02/22 13:31:19 roberto Exp roberto $ |
| 3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -9,11 +9,29 @@ | |||
| 9 | 9 | ||
| 10 | #include "llex.h" | 10 | #include "llex.h" |
| 11 | #include "lobject.h" | 11 | #include "lobject.h" |
| 12 | #include "lopcodes.h" | ||
| 13 | #include "lparser.h" | ||
| 12 | 14 | ||
| 13 | 15 | ||
| 16 | void luaK_error (LexState *ls, const char *msg); | ||
| 14 | int luaK_primitivecode (LexState *ls, Instruction i); | 17 | int luaK_primitivecode (LexState *ls, Instruction i); |
| 15 | int luaK_code (LexState *ls, Instruction i); | 18 | int luaK_code (LexState *ls, Instruction i); |
| 16 | void luaK_fixjump (LexState *ls, int pc, int dest); | 19 | void luaK_fixjump (LexState *ls, int pc, int dest); |
| 20 | void luaK_deltastack (LexState *ls, int delta); | ||
| 21 | int luaK_0 (LexState *ls, OpCode op, int delta); | ||
| 22 | int luaK_U (LexState *ls, OpCode op, int u, int delta); | ||
| 23 | int luaK_S (LexState *ls, OpCode op, int s, int delta); | ||
| 24 | int luaK_AB (LexState *ls, OpCode op, int a, int b, int delta); | ||
| 25 | int luaK_kstr (LexState *ls, int c); | ||
| 26 | int luaK_number (LexState *ls, real f); | ||
| 27 | int luaK_adjuststack (LexState *ls, int n); | ||
| 28 | int luaK_iscall (LexState *ls, int pc); | ||
| 29 | void luaK_setcallreturns (LexState *ls, int pc, int nresults); | ||
| 30 | void luaK_2stack (LexState *ls, expdesc *var); | ||
| 31 | void luaK_storevar (LexState *ls, const expdesc *var); | ||
| 32 | void luaK_prefix (LexState *ls, int op, expdesc *v); | ||
| 33 | void luaK_infix (LexState *ls, expdesc *v); | ||
| 34 | void luaK_posfix (LexState *ls, int op, expdesc *v1, expdesc *v2); | ||
| 17 | 35 | ||
| 18 | 36 | ||
| 19 | #endif | 37 | #endif |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.c,v 1.59 2000/02/14 16:51:08 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.60 2000/02/22 13:30:11 roberto Exp roberto $ |
| 3 | ** LL(1) Parser and code generator for Lua | 3 | ** LL(1) Parser and code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -51,10 +51,10 @@ typedef struct constdesc { | |||
| 51 | /* | 51 | /* |
| 52 | ** prototypes for recursive non-terminal functions | 52 | ** prototypes for recursive non-terminal functions |
| 53 | */ | 53 | */ |
| 54 | static void body (LexState *ls, int needself, int line); | 54 | static int body (LexState *ls, int needself, int line); |
| 55 | static void chunk (LexState *ls); | 55 | static void chunk (LexState *ls); |
| 56 | static void constructor (LexState *ls); | 56 | static int constructor (LexState *ls); |
| 57 | static void expr (LexState *ls, vardesc *v); | 57 | static void expr (LexState *ls, expdesc *v); |
| 58 | static void exp1 (LexState *ls); | 58 | static void exp1 (LexState *ls); |
| 59 | 59 | ||
| 60 | 60 | ||
| @@ -63,21 +63,16 @@ static void next (LexState *ls) { | |||
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | 65 | ||
| 66 | static void luaY_error (LexState *ls, const char *msg) { | ||
| 67 | luaX_error(ls, msg, ls->token); | ||
| 68 | } | ||
| 69 | |||
| 70 | |||
| 71 | static void error_expected (LexState *ls, int token) { | 66 | static void error_expected (LexState *ls, int token) { |
| 72 | char buff[100], t[TOKEN_LEN]; | 67 | char buff[100], t[TOKEN_LEN]; |
| 73 | luaX_token2str(token, t); | 68 | luaX_token2str(token, t); |
| 74 | sprintf(buff, "`%.20s' expected", t); | 69 | sprintf(buff, "`%.20s' expected", t); |
| 75 | luaY_error(ls, buff); | 70 | luaK_error(ls, buff); |
| 76 | } | 71 | } |
| 77 | 72 | ||
| 78 | 73 | ||
| 79 | static void error_unexpected (LexState *ls) { | 74 | static void error_unexpected (LexState *ls) { |
| 80 | luaY_error(ls, "unexpected token"); | 75 | luaK_error(ls, "unexpected token"); |
| 81 | } | 76 | } |
| 82 | 77 | ||
| 83 | 78 | ||
| @@ -91,7 +86,7 @@ static void error_unmatched (LexState *ls, int what, int who, int where) { | |||
| 91 | luaX_token2str(who, t_who); | 86 | luaX_token2str(who, t_who); |
| 92 | sprintf(buff, "`%.20s' expected (to close `%.20s' at line %d)", | 87 | sprintf(buff, "`%.20s' expected (to close `%.20s' at line %d)", |
| 93 | t_what, t_who, where); | 88 | t_what, t_who, where); |
| 94 | luaY_error(ls, buff); | 89 | luaK_error(ls, buff); |
| 95 | } | 90 | } |
| 96 | } | 91 | } |
| 97 | 92 | ||
| @@ -115,56 +110,14 @@ static void checklimit (LexState *ls, int val, int limit, const char *msg) { | |||
| 115 | if (val > limit) { | 110 | if (val > limit) { |
| 116 | char buff[100]; | 111 | char buff[100]; |
| 117 | sprintf(buff, "too many %.50s (limit=%d)", msg, limit); | 112 | sprintf(buff, "too many %.50s (limit=%d)", msg, limit); |
| 118 | luaY_error(ls, buff); | 113 | luaK_error(ls, buff); |
| 119 | } | 114 | } |
| 120 | } | 115 | } |
| 121 | 116 | ||
| 122 | 117 | ||
| 123 | |||
| 124 | static void deltastack (LexState *ls, int delta) { | ||
| 125 | FuncState *fs = ls->fs; | ||
| 126 | fs->stacksize += delta; | ||
| 127 | if (delta > 0 && fs->stacksize > fs->f->maxstacksize) { | ||
| 128 | checklimit(ls, fs->stacksize, MAXSTACK, "temporaries or local variables"); | ||
| 129 | fs->f->maxstacksize = fs->stacksize; | ||
| 130 | } | ||
| 131 | } | ||
| 132 | |||
| 133 | |||
| 134 | static int aux_code (LexState *ls, OpCode op, Instruction i, int delta) { | ||
| 135 | deltastack(ls, delta); | ||
| 136 | return luaK_code(ls, SET_OPCODE(i, op)); | ||
| 137 | } | ||
| 138 | |||
| 139 | |||
| 140 | static int code_0 (LexState *ls, OpCode op, int delta) { | ||
| 141 | return aux_code(ls, op, 0, delta); | ||
| 142 | } | ||
| 143 | |||
| 144 | |||
| 145 | |||
| 146 | static int code_U (LexState *ls, OpCode op, int u, int delta) { | ||
| 147 | Instruction i = SETARG_U(0, u); | ||
| 148 | return aux_code(ls, op, i, delta); | ||
| 149 | } | ||
| 150 | |||
| 151 | |||
| 152 | static int code_S (LexState *ls, OpCode op, int s, int delta) { | ||
| 153 | Instruction i = SETARG_S(0, s); | ||
| 154 | return aux_code(ls, op, i, delta); | ||
| 155 | } | ||
| 156 | |||
| 157 | |||
| 158 | static int code_AB (LexState *ls, OpCode op, int a, int b, int delta) { | ||
| 159 | Instruction i = SETARG_A(0, a); | ||
| 160 | i = SETARG_B(i, b); | ||
| 161 | return aux_code(ls, op, i, delta); | ||
| 162 | } | ||
| 163 | |||
| 164 | |||
| 165 | static void check_debugline (LexState *ls) { | 118 | static void check_debugline (LexState *ls) { |
| 166 | if (ls->L->debug && ls->linenumber != ls->fs->lastsetline) { | 119 | if (ls->L->debug && ls->linenumber != ls->fs->lastsetline) { |
| 167 | code_U(ls, SETLINE, ls->linenumber, 0); | 120 | luaK_U(ls, SETLINE, ls->linenumber, 0); |
| 168 | ls->fs->lastsetline = ls->linenumber; | 121 | ls->fs->lastsetline = ls->linenumber; |
| 169 | } | 122 | } |
| 170 | } | 123 | } |
| @@ -178,16 +131,6 @@ static void check_match (LexState *ls, int what, int who, int where) { | |||
| 178 | } | 131 | } |
| 179 | 132 | ||
| 180 | 133 | ||
| 181 | static void code_kstr (LexState *ls, int c) { | ||
| 182 | code_U(ls, PUSHSTRING, c, 1); | ||
| 183 | } | ||
| 184 | |||
| 185 | |||
| 186 | static void assertglobal (LexState *ls, int index) { | ||
| 187 | luaS_assertglobal(ls->L, ls->fs->f->kstr[index]); | ||
| 188 | } | ||
| 189 | |||
| 190 | |||
| 191 | static int string_constant (LexState *ls, FuncState *fs, TaggedString *s) { | 134 | static int string_constant (LexState *ls, FuncState *fs, TaggedString *s) { |
| 192 | TProtoFunc *f = fs->f; | 135 | TProtoFunc *f = fs->f; |
| 193 | int c = s->constindex; | 136 | int c = s->constindex; |
| @@ -202,39 +145,15 @@ static int string_constant (LexState *ls, FuncState *fs, TaggedString *s) { | |||
| 202 | } | 145 | } |
| 203 | 146 | ||
| 204 | 147 | ||
| 205 | static void code_string (LexState *ls, TaggedString *s) { | 148 | static int code_string (LexState *ls, TaggedString *s) { |
| 206 | code_kstr(ls, string_constant(ls, ls->fs, s)); | 149 | return luaK_kstr(ls, string_constant(ls, ls->fs, s)); |
| 207 | } | ||
| 208 | |||
| 209 | |||
| 210 | #define LIM 20 | ||
| 211 | static int real_constant (LexState *ls, real r) { | ||
| 212 | /* check whether `r' has appeared within the last LIM entries */ | ||
| 213 | TProtoFunc *f = ls->fs->f; | ||
| 214 | int c = f->nknum; | ||
| 215 | int lim = c < LIM ? 0 : c-LIM; | ||
| 216 | while (--c >= lim) | ||
| 217 | if (f->knum[c] == r) return c; | ||
| 218 | /* not found; create a new entry */ | ||
| 219 | luaM_growvector(ls->L, f->knum, f->nknum, 1, real, constantEM, MAXARG_U); | ||
| 220 | c = f->nknum++; | ||
| 221 | f->knum[c] = r; | ||
| 222 | return c; | ||
| 223 | } | ||
| 224 | |||
| 225 | |||
| 226 | static void code_number (LexState *ls, real f) { | ||
| 227 | if (f <= (real)MAXARG_S && (int)f == f) | ||
| 228 | code_S(ls, PUSHINT, (int)f, 1); /* f has a short integer value */ | ||
| 229 | else | ||
| 230 | code_U(ls, PUSHNUM, real_constant(ls, f), 1); | ||
| 231 | } | 150 | } |
| 232 | 151 | ||
| 233 | 152 | ||
| 234 | static int checkname (LexState *ls) { | 153 | static int checkname (LexState *ls) { |
| 235 | int sc; | 154 | int sc; |
| 236 | if (ls->token != NAME) | 155 | if (ls->token != NAME) |
| 237 | luaY_error(ls, "<name> expected"); | 156 | luaK_error(ls, "<name> expected"); |
| 238 | sc = string_constant(ls, ls->fs, ls->seminfo.ts); | 157 | sc = string_constant(ls, ls->fs, ls->seminfo.ts); |
| 239 | next(ls); | 158 | next(ls); |
| 240 | return sc; | 159 | return sc; |
| @@ -295,7 +214,7 @@ static int aux_localname (FuncState *fs, TaggedString *n) { | |||
| 295 | } | 214 | } |
| 296 | 215 | ||
| 297 | 216 | ||
| 298 | static void singlevar (LexState *ls, TaggedString *n, vardesc *var, int prev) { | 217 | static void singlevar (LexState *ls, TaggedString *n, expdesc *var, int prev) { |
| 299 | FuncState *fs = prev ? ls->fs->prev : ls->fs; | 218 | FuncState *fs = prev ? ls->fs->prev : ls->fs; |
| 300 | int i = aux_localname(fs, n); | 219 | int i = aux_localname(fs, n); |
| 301 | if (i >= 0) { /* local value? */ | 220 | if (i >= 0) { /* local value? */ |
| @@ -315,7 +234,7 @@ static void singlevar (LexState *ls, TaggedString *n, vardesc *var, int prev) { | |||
| 315 | 234 | ||
| 316 | static int indexupvalue (LexState *ls, TaggedString *n) { | 235 | static int indexupvalue (LexState *ls, TaggedString *n) { |
| 317 | FuncState *fs = ls->fs; | 236 | FuncState *fs = ls->fs; |
| 318 | vardesc v; | 237 | expdesc v; |
| 319 | int i; | 238 | int i; |
| 320 | singlevar(ls, n, &v, 1); | 239 | singlevar(ls, n, &v, 1); |
| 321 | for (i=0; i<fs->nupvalues; i++) { | 240 | for (i=0; i<fs->nupvalues; i++) { |
| @@ -330,48 +249,30 @@ static int indexupvalue (LexState *ls, TaggedString *n) { | |||
| 330 | } | 249 | } |
| 331 | 250 | ||
| 332 | 251 | ||
| 333 | static void pushupvalue (LexState *ls, TaggedString *n) { | 252 | static int pushupvalue (LexState *ls, TaggedString *n) { |
| 334 | if (ls->fs->prev == NULL) | 253 | if (ls->fs->prev == NULL) |
| 335 | luaX_syntaxerror(ls, "cannot access upvalue in main", n->str); | 254 | luaX_syntaxerror(ls, "cannot access upvalue in main", n->str); |
| 336 | if (aux_localname(ls->fs, n) >= 0) | 255 | if (aux_localname(ls->fs, n) >= 0) |
| 337 | luaX_syntaxerror(ls, "cannot access an upvalue in current scope", n->str); | 256 | luaX_syntaxerror(ls, "cannot access an upvalue in current scope", n->str); |
| 338 | code_U(ls, PUSHUPVALUE, indexupvalue(ls, n), 1); | 257 | return luaK_U(ls, PUSHUPVALUE, indexupvalue(ls, n), 1); |
| 339 | } | ||
| 340 | |||
| 341 | |||
| 342 | static void adjuststack (LexState *ls, int n) { | ||
| 343 | if (n > 0) | ||
| 344 | code_U(ls, POP, n, -n); | ||
| 345 | else if (n < 0) | ||
| 346 | code_U(ls, PUSHNIL, (-n)-1, -n); | ||
| 347 | } | ||
| 348 | |||
| 349 | |||
| 350 | static void close_call (LexState *ls, int pc, int nresults) { | ||
| 351 | if (pc > 0) { /* expression is an open function call? */ | ||
| 352 | Instruction *i = &ls->fs->f->code[pc]; | ||
| 353 | *i = SETARG_B(*i, nresults); /* set nresults */ | ||
| 354 | if (nresults != MULT_RET) | ||
| 355 | deltastack(ls, nresults); /* push results */ | ||
| 356 | } | ||
| 357 | } | 258 | } |
| 358 | 259 | ||
| 359 | 260 | ||
| 360 | static void adjust_mult_assign (LexState *ls, int nvars, listdesc *d) { | 261 | static void adjust_mult_assign (LexState *ls, int nvars, listdesc *d) { |
| 361 | int diff = d->n - nvars; | 262 | int diff = d->n - nvars; |
| 362 | if (d->pc == 0) { /* list is closed */ | 263 | if (d->n == 0 || !luaK_iscall(ls, d->pc)) { /* list is empty or closed */ |
| 363 | /* push or pop eventual difference between list lengths */ | 264 | /* push or pop eventual difference between list lengths */ |
| 364 | adjuststack(ls, diff); | 265 | luaK_adjuststack(ls, diff); |
| 365 | } | 266 | } |
| 366 | else { /* must correct function call */ | 267 | else { /* list ends in a function call; must correct it */ |
| 367 | diff--; /* do not count function call itself */ | 268 | diff--; /* do not count function call itself */ |
| 368 | if (diff <= 0) { /* more variables than values? */ | 269 | if (diff <= 0) { /* more variables than values? */ |
| 369 | /* function call must provide extra values */ | 270 | /* function call must provide extra values */ |
| 370 | close_call(ls, d->pc, -diff); | 271 | luaK_setcallreturns(ls, d->pc, -diff); |
| 371 | } | 272 | } |
| 372 | else { /* more values than variables */ | 273 | else { /* more values than variables */ |
| 373 | close_call(ls, d->pc, 0); /* call should provide no value */ | 274 | luaK_setcallreturns(ls, d->pc, 0); /* call should provide no value */ |
| 374 | adjuststack(ls, diff); /* pop eventual extra values */ | 275 | luaK_adjuststack(ls, diff); /* pop eventual extra values */ |
| 375 | } | 276 | } |
| 376 | } | 277 | } |
| 377 | } | 278 | } |
| @@ -385,15 +286,15 @@ static void code_args (LexState *ls, int nparams, int dots) { | |||
| 385 | fs->f->numparams = nparams; | 286 | fs->f->numparams = nparams; |
| 386 | fs->f->is_vararg = dots; | 287 | fs->f->is_vararg = dots; |
| 387 | if (!dots) | 288 | if (!dots) |
| 388 | deltastack(ls, nparams); | 289 | luaK_deltastack(ls, nparams); |
| 389 | else { | 290 | else { |
| 390 | deltastack(ls, nparams+1); | 291 | luaK_deltastack(ls, nparams+1); |
| 391 | add_localvar(ls, luaS_newfixed(ls->L, "arg")); | 292 | add_localvar(ls, luaS_newfixed(ls->L, "arg")); |
| 392 | } | 293 | } |
| 393 | } | 294 | } |
| 394 | 295 | ||
| 395 | 296 | ||
| 396 | static int getvarname (LexState *ls, vardesc *var) { | 297 | static int getvarname (LexState *ls, expdesc *var) { |
| 397 | switch (var->k) { | 298 | switch (var->k) { |
| 398 | case VGLOBAL: | 299 | case VGLOBAL: |
| 399 | return var->info; | 300 | return var->info; |
| @@ -407,55 +308,16 @@ static int getvarname (LexState *ls, vardesc *var) { | |||
| 407 | } | 308 | } |
| 408 | 309 | ||
| 409 | 310 | ||
| 410 | static void close_exp (LexState *ls, vardesc *var) { | 311 | static int func_onstack (LexState *ls, FuncState *func) { |
| 411 | switch (var->k) { | ||
| 412 | case VLOCAL: | ||
| 413 | code_U(ls, PUSHLOCAL, var->info, 1); | ||
| 414 | break; | ||
| 415 | case VGLOBAL: | ||
| 416 | code_U(ls, GETGLOBAL, var->info, 1); | ||
| 417 | assertglobal(ls, var->info); /* make sure that there is a global */ | ||
| 418 | break; | ||
| 419 | case VINDEXED: | ||
| 420 | code_0(ls, GETTABLE, -1); | ||
| 421 | break; | ||
| 422 | case VEXP: | ||
| 423 | close_call(ls, var->info, 1); /* call must return 1 value */ | ||
| 424 | break; | ||
| 425 | } | ||
| 426 | var->k = VEXP; | ||
| 427 | var->info = 0; /* now this is a closed expression */ | ||
| 428 | } | ||
| 429 | |||
| 430 | |||
| 431 | static void storevar (LexState *ls, const vardesc *var) { | ||
| 432 | switch (var->k) { | ||
| 433 | case VLOCAL: | ||
| 434 | code_U(ls, SETLOCAL, var->info, -1); | ||
| 435 | break; | ||
| 436 | case VGLOBAL: | ||
| 437 | code_U(ls, SETGLOBAL, var->info, -1); | ||
| 438 | assertglobal(ls, var->info); /* make sure that there is a global */ | ||
| 439 | break; | ||
| 440 | case VINDEXED: | ||
| 441 | code_0(ls, SETTABLEPOP, -3); | ||
| 442 | break; | ||
| 443 | default: | ||
| 444 | LUA_INTERNALERROR(ls->L, "invalid var kind to store"); | ||
| 445 | } | ||
| 446 | } | ||
| 447 | |||
| 448 | |||
| 449 | static void func_onstack (LexState *ls, FuncState *func) { | ||
| 450 | TProtoFunc *f = ls->fs->f; | 312 | TProtoFunc *f = ls->fs->f; |
| 451 | int i; | 313 | int i; |
| 452 | for (i=0; i<func->nupvalues; i++) | 314 | for (i=0; i<func->nupvalues; i++) |
| 453 | close_exp(ls, &func->upvalues[i]); | 315 | luaK_2stack(ls, &func->upvalues[i]); |
| 454 | luaM_growvector(ls->L, f->kproto, f->nkproto, 1, TProtoFunc *, | 316 | luaM_growvector(ls->L, f->kproto, f->nkproto, 1, TProtoFunc *, |
| 455 | constantEM, MAXARG_A); | 317 | constantEM, MAXARG_A); |
| 456 | f->kproto[f->nkproto++] = func->f; | 318 | f->kproto[f->nkproto++] = func->f; |
| 457 | deltastack(ls, 1); /* CLOSURE puts one extra element (before popping) */ | 319 | luaK_deltastack(ls, 1); /* CLOSURE puts one extra element before popping */ |
| 458 | code_AB(ls, CLOSURE, f->nkproto-1, func->nupvalues, -func->nupvalues); | 320 | return luaK_AB(ls, CLOSURE, f->nkproto-1, func->nupvalues, -func->nupvalues); |
| 459 | } | 321 | } |
| 460 | 322 | ||
| 461 | 323 | ||
| @@ -487,7 +349,7 @@ static void init_state (LexState *ls, FuncState *fs, TaggedString *source) { | |||
| 487 | static void close_func (LexState *ls) { | 349 | static void close_func (LexState *ls) { |
| 488 | FuncState *fs = ls->fs; | 350 | FuncState *fs = ls->fs; |
| 489 | TProtoFunc *f = fs->f; | 351 | TProtoFunc *f = fs->f; |
| 490 | code_0(ls, ENDCODE, 0); | 352 | luaK_0(ls, ENDCODE, 0); |
| 491 | luaM_reallocvector(ls->L, f->code, fs->pc, Instruction); | 353 | luaM_reallocvector(ls->L, f->code, fs->pc, Instruction); |
| 492 | luaM_reallocvector(ls->L, f->kstr, f->nkstr, TaggedString *); | 354 | luaM_reallocvector(ls->L, f->kstr, f->nkstr, TaggedString *); |
| 493 | luaM_reallocvector(ls->L, f->knum, f->nknum, real); | 355 | luaM_reallocvector(ls->L, f->knum, f->nknum, real); |
| @@ -509,7 +371,7 @@ TProtoFunc *luaY_parser (lua_State *L, ZIO *z) { | |||
| 509 | next(&lexstate); /* read first token */ | 371 | next(&lexstate); /* read first token */ |
| 510 | chunk(&lexstate); | 372 | chunk(&lexstate); |
| 511 | if (lexstate.token != EOS) | 373 | if (lexstate.token != EOS) |
| 512 | luaY_error(&lexstate, "<eof> expected"); | 374 | luaK_error(&lexstate, "<eof> expected"); |
| 513 | close_func(&lexstate); | 375 | close_func(&lexstate); |
| 514 | return funcstate.f; | 376 | return funcstate.f; |
| 515 | } | 377 | } |
| @@ -522,21 +384,18 @@ TProtoFunc *luaY_parser (lua_State *L, ZIO *z) { | |||
| 522 | 384 | ||
| 523 | 385 | ||
| 524 | static void explist1 (LexState *ls, listdesc *d) { | 386 | static void explist1 (LexState *ls, listdesc *d) { |
| 525 | vardesc v; | 387 | expdesc v; |
| 526 | expr(ls, &v); | 388 | expr(ls, &v); |
| 527 | d->n = 1; | 389 | d->n = 1; |
| 528 | while (ls->token == ',') { | 390 | while (ls->token == ',') { |
| 529 | d->n++; | 391 | d->n++; |
| 530 | close_exp(ls, &v); | 392 | luaK_2stack(ls, &v); |
| 531 | next(ls); | 393 | next(ls); |
| 532 | expr(ls, &v); | 394 | expr(ls, &v); |
| 533 | } | 395 | } |
| 534 | if (v.k == VEXP) | 396 | luaK_2stack(ls, &v); |
| 535 | d->pc = v.info; | 397 | luaK_setcallreturns(ls, v.info, MULT_RET); /* default for explists */ |
| 536 | else { | 398 | d->pc = v.info; |
| 537 | close_exp(ls, &v); | ||
| 538 | d->pc = 0; | ||
| 539 | } | ||
| 540 | } | 399 | } |
| 541 | 400 | ||
| 542 | 401 | ||
| @@ -544,7 +403,6 @@ static void explist (LexState *ls, listdesc *d) { | |||
| 544 | switch (ls->token) { | 403 | switch (ls->token) { |
| 545 | case ELSE: case ELSEIF: case END: case UNTIL: | 404 | case ELSE: case ELSEIF: case END: case UNTIL: |
| 546 | case EOS: case ';': case ')': | 405 | case EOS: case ';': case ')': |
| 547 | d->pc = 0; | ||
| 548 | d->n = 0; | 406 | d->n = 0; |
| 549 | break; | 407 | break; |
| 550 | 408 | ||
| @@ -564,7 +422,10 @@ static int funcparams (LexState *ls, int slf) { | |||
| 564 | next(ls); | 422 | next(ls); |
| 565 | explist(ls, &e); | 423 | explist(ls, &e); |
| 566 | check_match(ls, ')', '(', line); | 424 | check_match(ls, ')', '(', line); |
| 567 | close_call(ls, e.pc, MULT_RET); /* close 1 for old semantics */ | 425 | #ifdef LUA_COMPAT_ARGRET |
| 426 | if (e.n > 0) /* arg list is not empty? */ | ||
| 427 | luaK_setcallreturns(ls, e.pc, 1); /* last call returns only 1 value */ | ||
| 428 | #endif | ||
| 568 | break; | 429 | break; |
| 569 | } | 430 | } |
| 570 | 431 | ||
| @@ -578,27 +439,27 @@ static int funcparams (LexState *ls, int slf) { | |||
| 578 | break; | 439 | break; |
| 579 | 440 | ||
| 580 | default: | 441 | default: |
| 581 | luaY_error(ls, "function arguments expected"); | 442 | luaK_error(ls, "function arguments expected"); |
| 582 | break; | 443 | break; |
| 583 | } | 444 | } |
| 584 | fs->stacksize = slevel; /* call will remove func and params */ | 445 | fs->stacksize = slevel; /* call will remove func and params */ |
| 585 | return code_AB(ls, CALL, slevel, 0, 0); | 446 | return luaK_AB(ls, CALL, slevel, 0, 0); |
| 586 | } | 447 | } |
| 587 | 448 | ||
| 588 | 449 | ||
| 589 | static void var_or_func_tail (LexState *ls, vardesc *v) { | 450 | static void var_or_func_tail (LexState *ls, expdesc *v) { |
| 590 | for (;;) { | 451 | for (;;) { |
| 591 | switch (ls->token) { | 452 | switch (ls->token) { |
| 592 | case '.': /* var_or_func_tail -> '.' NAME */ | 453 | case '.': /* var_or_func_tail -> '.' NAME */ |
| 593 | next(ls); | 454 | next(ls); |
| 594 | close_exp(ls, v); /* `v' must be on stack */ | 455 | luaK_2stack(ls, v); /* `v' must be on stack */ |
| 595 | code_kstr(ls, checkname(ls)); | 456 | luaK_kstr(ls, checkname(ls)); |
| 596 | v->k = VINDEXED; | 457 | v->k = VINDEXED; |
| 597 | break; | 458 | break; |
| 598 | 459 | ||
| 599 | case '[': /* var_or_func_tail -> '[' exp1 ']' */ | 460 | case '[': /* var_or_func_tail -> '[' exp1 ']' */ |
| 600 | next(ls); | 461 | next(ls); |
| 601 | close_exp(ls, v); /* `v' must be on stack */ | 462 | luaK_2stack(ls, v); /* `v' must be on stack */ |
| 602 | exp1(ls); | 463 | exp1(ls); |
| 603 | check(ls, ']'); | 464 | check(ls, ']'); |
| 604 | v->k = VINDEXED; | 465 | v->k = VINDEXED; |
| @@ -608,15 +469,15 @@ static void var_or_func_tail (LexState *ls, vardesc *v) { | |||
| 608 | int name; | 469 | int name; |
| 609 | next(ls); | 470 | next(ls); |
| 610 | name = checkname(ls); | 471 | name = checkname(ls); |
| 611 | close_exp(ls, v); /* `v' must be on stack */ | 472 | luaK_2stack(ls, v); /* `v' must be on stack */ |
| 612 | code_U(ls, PUSHSELF, name, 1); | 473 | luaK_U(ls, PUSHSELF, name, 1); |
| 613 | v->k = VEXP; | 474 | v->k = VEXP; |
| 614 | v->info = funcparams(ls, 1); | 475 | v->info = funcparams(ls, 1); |
| 615 | break; | 476 | break; |
| 616 | } | 477 | } |
| 617 | 478 | ||
| 618 | case '(': case STRING: case '{': /* var_or_func_tail -> funcparams */ | 479 | case '(': case STRING: case '{': /* var_or_func_tail -> funcparams */ |
| 619 | close_exp(ls, v); /* `v' must be on stack */ | 480 | luaK_2stack(ls, v); /* `v' must be on stack */ |
| 620 | v->k = VEXP; | 481 | v->k = VEXP; |
| 621 | v->info = funcparams(ls, 0); | 482 | v->info = funcparams(ls, 0); |
| 622 | break; | 483 | break; |
| @@ -627,12 +488,11 @@ static void var_or_func_tail (LexState *ls, vardesc *v) { | |||
| 627 | } | 488 | } |
| 628 | 489 | ||
| 629 | 490 | ||
| 630 | static void var_or_func (LexState *ls, vardesc *v) { | 491 | static void var_or_func (LexState *ls, expdesc *v) { |
| 631 | /* var_or_func -> ['%'] NAME var_or_func_tail */ | 492 | /* var_or_func -> ['%'] NAME var_or_func_tail */ |
| 632 | if (optional(ls, '%')) { /* upvalue? */ | 493 | if (optional(ls, '%')) { /* upvalue? */ |
| 633 | pushupvalue(ls, str_checkname(ls)); | ||
| 634 | v->k = VEXP; | 494 | v->k = VEXP; |
| 635 | v->info = 0; /* closed expression */ | 495 | v->info = pushupvalue(ls, str_checkname(ls)); |
| 636 | } | 496 | } |
| 637 | else /* variable name */ | 497 | else /* variable name */ |
| 638 | singlevar(ls, str_checkname(ls), v, 0); | 498 | singlevar(ls, str_checkname(ls), v, 0); |
| @@ -652,7 +512,7 @@ static void recfield (LexState *ls) { | |||
| 652 | /* recfield -> (NAME | '['exp1']') = exp1 */ | 512 | /* recfield -> (NAME | '['exp1']') = exp1 */ |
| 653 | switch (ls->token) { | 513 | switch (ls->token) { |
| 654 | case NAME: | 514 | case NAME: |
| 655 | code_kstr(ls, checkname(ls)); | 515 | luaK_kstr(ls, checkname(ls)); |
| 656 | break; | 516 | break; |
| 657 | 517 | ||
| 658 | case '[': | 518 | case '[': |
| @@ -661,7 +521,7 @@ static void recfield (LexState *ls) { | |||
| 661 | check(ls, ']'); | 521 | check(ls, ']'); |
| 662 | break; | 522 | break; |
| 663 | 523 | ||
| 664 | default: luaY_error(ls, "<name> or `[' expected"); | 524 | default: luaK_error(ls, "<name> or `[' expected"); |
| 665 | } | 525 | } |
| 666 | check(ls, '='); | 526 | check(ls, '='); |
| 667 | exp1(ls); | 527 | exp1(ls); |
| @@ -679,12 +539,12 @@ static int recfields (LexState *ls) { | |||
| 679 | recfield(ls); | 539 | recfield(ls); |
| 680 | n++; | 540 | n++; |
| 681 | if (++mod_n == RFIELDS_PER_FLUSH) { | 541 | if (++mod_n == RFIELDS_PER_FLUSH) { |
| 682 | code_U(ls, SETMAP, RFIELDS_PER_FLUSH-1, -2*RFIELDS_PER_FLUSH); | 542 | luaK_U(ls, SETMAP, RFIELDS_PER_FLUSH-1, -2*RFIELDS_PER_FLUSH); |
| 683 | mod_n = 0; | 543 | mod_n = 0; |
| 684 | } | 544 | } |
| 685 | } | 545 | } |
| 686 | if (mod_n) | 546 | if (mod_n) |
| 687 | code_U(ls, SETMAP, mod_n-1, -2*mod_n); | 547 | luaK_U(ls, SETMAP, mod_n-1, -2*mod_n); |
| 688 | return n; | 548 | return n; |
| 689 | } | 549 | } |
| 690 | 550 | ||
| @@ -702,13 +562,13 @@ static int listfields (LexState *ls) { | |||
| 702 | checklimit(ls, n, MAXARG_A*LFIELDS_PER_FLUSH, | 562 | checklimit(ls, n, MAXARG_A*LFIELDS_PER_FLUSH, |
| 703 | "items in a list initializer"); | 563 | "items in a list initializer"); |
| 704 | if (++mod_n == LFIELDS_PER_FLUSH) { | 564 | if (++mod_n == LFIELDS_PER_FLUSH) { |
| 705 | code_AB(ls, SETLIST, n/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH-1, | 565 | luaK_AB(ls, SETLIST, n/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH-1, |
| 706 | -LFIELDS_PER_FLUSH); | 566 | -LFIELDS_PER_FLUSH); |
| 707 | mod_n = 0; | 567 | mod_n = 0; |
| 708 | } | 568 | } |
| 709 | } | 569 | } |
| 710 | if (mod_n > 0) | 570 | if (mod_n > 0) |
| 711 | code_AB(ls, SETLIST, n/LFIELDS_PER_FLUSH, mod_n-1, -mod_n); | 571 | luaK_AB(ls, SETLIST, n/LFIELDS_PER_FLUSH, mod_n-1, -mod_n); |
| 712 | return n; | 572 | return n; |
| 713 | } | 573 | } |
| 714 | 574 | ||
| @@ -722,17 +582,17 @@ static void constructor_part (LexState *ls, constdesc *cd) { | |||
| 722 | return; | 582 | return; |
| 723 | 583 | ||
| 724 | case NAME: { | 584 | case NAME: { |
| 725 | vardesc v; | 585 | expdesc v; |
| 726 | expr(ls, &v); | 586 | expr(ls, &v); |
| 727 | if (ls->token == '=') { | 587 | if (ls->token == '=') { |
| 728 | code_kstr(ls, getvarname(ls, &v)); | 588 | luaK_kstr(ls, getvarname(ls, &v)); |
| 729 | next(ls); /* skip '=' */ | 589 | next(ls); /* skip '=' */ |
| 730 | exp1(ls); | 590 | exp1(ls); |
| 731 | cd->n = recfields(ls); | 591 | cd->n = recfields(ls); |
| 732 | cd->k = 1; /* record */ | 592 | cd->k = 1; /* record */ |
| 733 | } | 593 | } |
| 734 | else { | 594 | else { |
| 735 | close_exp(ls, &v); | 595 | luaK_2stack(ls, &v); |
| 736 | cd->n = listfields(ls); | 596 | cd->n = listfields(ls); |
| 737 | cd->k = 0; /* list */ | 597 | cd->k = 0; /* list */ |
| 738 | } | 598 | } |
| @@ -754,10 +614,10 @@ static void constructor_part (LexState *ls, constdesc *cd) { | |||
| 754 | } | 614 | } |
| 755 | 615 | ||
| 756 | 616 | ||
| 757 | static void constructor (LexState *ls) { | 617 | static int constructor (LexState *ls) { |
| 758 | /* constructor -> '{' constructor_part [';' constructor_part] '}' */ | 618 | /* constructor -> '{' constructor_part [';' constructor_part] '}' */ |
| 759 | int line = ls->linenumber; | 619 | int line = ls->linenumber; |
| 760 | int pc = code_U(ls, CREATETABLE, 0, 1); | 620 | int pc = luaK_U(ls, CREATETABLE, 0, 1); |
| 761 | int nelems; | 621 | int nelems; |
| 762 | constdesc cd; | 622 | constdesc cd; |
| 763 | check(ls, '{'); | 623 | check(ls, '{'); |
| @@ -768,12 +628,13 @@ static void constructor (LexState *ls) { | |||
| 768 | next(ls); | 628 | next(ls); |
| 769 | constructor_part(ls, &other_cd); | 629 | constructor_part(ls, &other_cd); |
| 770 | if (cd.k == other_cd.k) /* repeated parts? */ | 630 | if (cd.k == other_cd.k) /* repeated parts? */ |
| 771 | luaY_error(ls, "invalid constructor syntax"); | 631 | luaK_error(ls, "invalid constructor syntax"); |
| 772 | nelems += other_cd.n; | 632 | nelems += other_cd.n; |
| 773 | } | 633 | } |
| 774 | check_match(ls, '}', '{', line); | 634 | check_match(ls, '}', '{', line); |
| 775 | /* set initial table size */ | 635 | /* set initial table size */ |
| 776 | ls->fs->f->code[pc] = SETARG_U(ls->fs->f->code[pc], nelems); | 636 | ls->fs->f->code[pc] = SETARG_U(ls->fs->f->code[pc], nelems); |
| 637 | return pc; | ||
| 777 | } | 638 | } |
| 778 | 639 | ||
| 779 | /* }====================================================================== */ | 640 | /* }====================================================================== */ |
| @@ -783,101 +644,39 @@ static void constructor (LexState *ls) { | |||
| 783 | 644 | ||
| 784 | /* | 645 | /* |
| 785 | ** {====================================================================== | 646 | ** {====================================================================== |
| 786 | ** For parsing expressions, we use a classic stack with priorities. | 647 | ** Expression parsing |
| 787 | ** Each binary operator is represented by an index: EQ=2, NE=3, ... '^'=13. | ||
| 788 | ** The unary NOT is 0 and UNMINUS is 1. | ||
| 789 | ** ======================================================================= | 648 | ** ======================================================================= |
| 790 | */ | 649 | */ |
| 791 | 650 | ||
| 792 | #define INDNOT 0 | ||
| 793 | #define INDMINUS 1 | ||
| 794 | |||
| 795 | /* code of first binary operator */ | ||
| 796 | #define FIRSTBIN 2 | ||
| 797 | |||
| 798 | /* code for power operator (last operator) | ||
| 799 | ** '^' needs special treatment because it is right associative | ||
| 800 | */ | ||
| 801 | #define POW 13 | ||
| 802 | |||
| 803 | |||
| 804 | static const int priority [POW+1] = {5, 5, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 4, 6}; | ||
| 805 | |||
| 806 | static const OpCode opcodes [POW+1] = {NOTOP, MINUSOP, EQOP, NEQOP, GTOP, | ||
| 807 | LTOP, LEOP, GEOP, CONCOP, ADDOP, SUBOP, MULTOP, DIVOP, POWOP}; | ||
| 808 | |||
| 809 | #define MAXOPS 20 /* op's stack size (arbitrary limit) */ | ||
| 810 | |||
| 811 | typedef struct stack_op { | ||
| 812 | int ops[MAXOPS]; | ||
| 813 | int top; | ||
| 814 | } stack_op; | ||
| 815 | |||
| 816 | |||
| 817 | /* | ||
| 818 | ** returns the index of a binary operator | ||
| 819 | */ | ||
| 820 | static int binop (int op) { | ||
| 821 | switch (op) { | ||
| 822 | case EQ: return FIRSTBIN; | ||
| 823 | case NE: return FIRSTBIN+1; | ||
| 824 | case '>': return FIRSTBIN+2; | ||
| 825 | case '<': return FIRSTBIN+3; | ||
| 826 | case LE: return FIRSTBIN+4; | ||
| 827 | case GE: return FIRSTBIN+5; | ||
| 828 | case CONC: return FIRSTBIN+6; | ||
| 829 | case '+': return FIRSTBIN+7; | ||
| 830 | case '-': return FIRSTBIN+8; | ||
| 831 | case '*': return FIRSTBIN+9; | ||
| 832 | case '/': return FIRSTBIN+10; | ||
| 833 | case '^': return FIRSTBIN+11; | ||
| 834 | default: return -1; | ||
| 835 | } | ||
| 836 | } | ||
| 837 | |||
| 838 | |||
| 839 | static void push (LexState *ls, stack_op *s, int op) { | ||
| 840 | if (s->top >= MAXOPS) | ||
| 841 | luaY_error(ls, "expression too complex"); | ||
| 842 | s->ops[s->top++] = op; | ||
| 843 | } | ||
| 844 | |||
| 845 | |||
| 846 | static void pop_to (LexState *ls, stack_op *s, int prio) { | ||
| 847 | int op; | ||
| 848 | while (s->top > 0 && priority[(op=s->ops[s->top-1])] >= prio) { | ||
| 849 | code_0(ls, opcodes[op], op<FIRSTBIN?0:-1); | ||
| 850 | s->top--; | ||
| 851 | } | ||
| 852 | } | ||
| 853 | 651 | ||
| 854 | static void simpleexp (LexState *ls, vardesc *v) { | 652 | static void simpleexp (LexState *ls, expdesc *v) { |
| 855 | check_debugline(ls); | 653 | check_debugline(ls); |
| 856 | switch (ls->token) { | 654 | switch (ls->token) { |
| 857 | case NUMBER: { /* simpleexp -> NUMBER */ | 655 | case NUMBER: { /* simpleexp -> NUMBER */ |
| 858 | real r = ls->seminfo.r; | 656 | real r = ls->seminfo.r; |
| 859 | next(ls); | 657 | next(ls); |
| 860 | code_number(ls, r); | 658 | v->info = luaK_number(ls, r); |
| 861 | break; | 659 | break; |
| 862 | } | 660 | } |
| 863 | 661 | ||
| 864 | case STRING: /* simpleexp -> STRING */ | 662 | case STRING: /* simpleexp -> STRING */ |
| 865 | code_string(ls, ls->seminfo.ts); /* must use 'seminfo' before `next' */ | 663 | /* must use 'seminfo' before `next' */ |
| 664 | v->info = code_string(ls, ls->seminfo.ts); | ||
| 866 | next(ls); | 665 | next(ls); |
| 867 | break; | 666 | break; |
| 868 | 667 | ||
| 869 | case NIL: /* simpleexp -> NIL */ | 668 | case NIL: /* simpleexp -> NIL */ |
| 870 | adjuststack(ls, -1); | 669 | v->info = luaK_adjuststack(ls, -1); |
| 871 | next(ls); | 670 | next(ls); |
| 872 | break; | 671 | break; |
| 873 | 672 | ||
| 874 | case '{': /* simpleexp -> constructor */ | 673 | case '{': /* simpleexp -> constructor */ |
| 875 | constructor(ls); | 674 | v->info = constructor(ls); |
| 876 | break; | 675 | break; |
| 877 | 676 | ||
| 878 | case FUNCTION: /* simpleexp -> FUNCTION body */ | 677 | case FUNCTION: /* simpleexp -> FUNCTION body */ |
| 879 | next(ls); | 678 | next(ls); |
| 880 | body(ls, 0, ls->linenumber); | 679 | v->info = body(ls, 0, ls->linenumber); |
| 881 | break; | 680 | break; |
| 882 | 681 | ||
| 883 | case '(': /* simpleexp -> '(' expr ')' */ | 682 | case '(': /* simpleexp -> '(' expr ')' */ |
| @@ -891,67 +690,75 @@ static void simpleexp (LexState *ls, vardesc *v) { | |||
| 891 | return; | 690 | return; |
| 892 | 691 | ||
| 893 | default: | 692 | default: |
| 894 | luaY_error(ls, "<expression> expected"); | 693 | luaK_error(ls, "<expression> expected"); |
| 895 | return; | 694 | return; |
| 896 | } | 695 | } |
| 897 | v->k = VEXP; v->info = 0; | 696 | v->k = VEXP; |
| 898 | } | 697 | } |
| 899 | 698 | ||
| 900 | 699 | ||
| 901 | static void prefixexp (LexState *ls, vardesc *v, stack_op *s) { | 700 | static void exp1 (LexState *ls) { |
| 902 | /* prefixexp -> {NOT | '-'} simpleexp */ | 701 | expdesc v; |
| 903 | while (ls->token == NOT || ls->token == '-') { | 702 | expr(ls, &v); |
| 904 | push(ls, s, (ls->token==NOT)?INDNOT:INDMINUS); | 703 | luaK_2stack(ls, &v); |
| 905 | next(ls); | ||
| 906 | } | ||
| 907 | simpleexp(ls, v); | ||
| 908 | } | 704 | } |
| 909 | 705 | ||
| 910 | 706 | ||
| 911 | static void arith_exp (LexState *ls, vardesc *v) { | 707 | /* |
| 912 | stack_op s; | 708 | ** gets priorities of an operator. Returns the priority to the left, and |
| 913 | int op; | 709 | ** sets `rp' to the priority to the right. |
| 914 | s.top = 0; | 710 | */ |
| 915 | prefixexp(ls, v, &s); | 711 | static int get_priority (int op, int *rp) { |
| 916 | while ((op = binop(ls->token)) >= 0) { | 712 | switch (op) { |
| 917 | close_exp(ls, v); | 713 | case AND: case OR: |
| 918 | /* '^' is right associative, so must 'simulate' a higher priority */ | 714 | *rp = 1; return 1; |
| 919 | pop_to(ls, &s, (op == POW)?priority[op]+1:priority[op]); | 715 | case EQ: case NE: |
| 920 | push(ls, &s, op); | 716 | case '>': case '<': case LE: case GE: |
| 921 | next(ls); | 717 | *rp = 2; return 2; |
| 922 | prefixexp(ls, v, &s); | 718 | case CONC: |
| 923 | close_exp(ls, v); | 719 | *rp = 3; return 3; |
| 924 | } | 720 | case '+': case '-': |
| 925 | if (s.top > 0) { | 721 | *rp = 4; return 4; |
| 926 | close_exp(ls, v); | 722 | case '*': case '/': |
| 927 | pop_to(ls, &s, 0); | 723 | *rp = 5; return 5; |
| 724 | /* priority 6 is for unary operators */ | ||
| 725 | case '^': | ||
| 726 | *rp = 7; return 8; /* right associative */ | ||
| 727 | default: | ||
| 728 | *rp = -1; return -1; | ||
| 928 | } | 729 | } |
| 929 | } | 730 | } |
| 930 | 731 | ||
| 931 | 732 | ||
| 932 | static void exp1 (LexState *ls) { | 733 | /* |
| 933 | vardesc v; | 734 | ** expr -> simplexep | (NOT | '-') expr | expr binop expr |
| 934 | expr(ls, &v); | 735 | ** where `binop' is any binary operator with a priority higher than `limit' |
| 935 | close_exp(ls, &v); | 736 | */ |
| 936 | } | 737 | static void operator_expr (LexState *ls, expdesc *v, int limit) { |
| 937 | 738 | int rp; | |
| 938 | 739 | if (ls->token == '-' || ls->token == NOT) { | |
| 939 | static void expr (LexState *ls, vardesc *v) { | 740 | int op = ls->token; /* operator */ |
| 940 | /* expr -> arith_exp {(AND | OR) arith_exp} */ | ||
| 941 | arith_exp(ls, v); | ||
| 942 | while (ls->token == AND || ls->token == OR) { | ||
| 943 | OpCode op = (ls->token == AND) ? ONFJMP : ONTJMP; | ||
| 944 | int pc; | ||
| 945 | close_exp(ls, v); | ||
| 946 | next(ls); | 741 | next(ls); |
| 947 | pc = code_S(ls, op, 0, -1); | 742 | operator_expr(ls, v, 6); /* 6 == priority of NOT and unary `-' */ |
| 948 | arith_exp(ls, v); | 743 | luaK_prefix(ls, op, v); |
| 949 | close_exp(ls, v); | 744 | } |
| 950 | luaK_fixjump(ls, pc, ls->fs->pc); | 745 | else simpleexp(ls, v); |
| 746 | /* expand while following operators have a priority higher than `limit' */ | ||
| 747 | while (get_priority(ls->token, &rp) > limit) { | ||
| 748 | int op = ls->token; /* operator */ | ||
| 749 | expdesc v2; | ||
| 750 | luaK_infix(ls, v); | ||
| 751 | next(ls); | ||
| 752 | operator_expr(ls, &v2, rp); | ||
| 753 | luaK_posfix(ls, op, v, &v2); | ||
| 951 | } | 754 | } |
| 952 | } | 755 | } |
| 953 | 756 | ||
| 954 | 757 | ||
| 758 | static void expr (LexState *ls, expdesc *v) { | ||
| 759 | operator_expr(ls, v, -1); | ||
| 760 | } | ||
| 761 | |||
| 955 | /* }==================================================================== */ | 762 | /* }==================================================================== */ |
| 956 | 763 | ||
| 957 | 764 | ||
| @@ -967,21 +774,21 @@ static void block (LexState *ls) { | |||
| 967 | FuncState *fs = ls->fs; | 774 | FuncState *fs = ls->fs; |
| 968 | int nlocalvar = fs->nlocalvar; | 775 | int nlocalvar = fs->nlocalvar; |
| 969 | chunk(ls); | 776 | chunk(ls); |
| 970 | adjuststack(ls, fs->nlocalvar - nlocalvar); | 777 | luaK_adjuststack(ls, fs->nlocalvar - nlocalvar); |
| 971 | for (; fs->nlocalvar > nlocalvar; fs->nlocalvar--) | 778 | for (; fs->nlocalvar > nlocalvar; fs->nlocalvar--) |
| 972 | luaI_unregisterlocalvar(ls, fs->lastsetline); | 779 | luaI_unregisterlocalvar(ls, fs->lastsetline); |
| 973 | } | 780 | } |
| 974 | 781 | ||
| 975 | 782 | ||
| 976 | static int assignment (LexState *ls, vardesc *v, int nvars) { | 783 | static int assignment (LexState *ls, expdesc *v, int nvars) { |
| 977 | int left = 0; | 784 | int left = 0; |
| 978 | checklimit(ls, nvars, MAXVARSLH, "variables in a multiple assignment"); | 785 | checklimit(ls, nvars, MAXVARSLH, "variables in a multiple assignment"); |
| 979 | if (ls->token == ',') { /* assignment -> ',' NAME assignment */ | 786 | if (ls->token == ',') { /* assignment -> ',' NAME assignment */ |
| 980 | vardesc nv; | 787 | expdesc nv; |
| 981 | next(ls); | 788 | next(ls); |
| 982 | var_or_func(ls, &nv); | 789 | var_or_func(ls, &nv); |
| 983 | if (nv.k == VEXP) | 790 | if (nv.k == VEXP) |
| 984 | luaY_error(ls, "syntax error"); | 791 | luaK_error(ls, "syntax error"); |
| 985 | left = assignment(ls, &nv, nvars+1); | 792 | left = assignment(ls, &nv, nvars+1); |
| 986 | } | 793 | } |
| 987 | else { /* assignment -> '=' explist1 */ | 794 | else { /* assignment -> '=' explist1 */ |
| @@ -994,10 +801,10 @@ static int assignment (LexState *ls, vardesc *v, int nvars) { | |||
| 994 | } | 801 | } |
| 995 | if (v->k != VINDEXED || left+(nvars-1) == 0) { | 802 | if (v->k != VINDEXED || left+(nvars-1) == 0) { |
| 996 | /* global/local var or indexed var without values in between */ | 803 | /* global/local var or indexed var without values in between */ |
| 997 | storevar(ls, v); | 804 | luaK_storevar(ls, v); |
| 998 | } | 805 | } |
| 999 | else { /* indexed var with values in between*/ | 806 | else { /* indexed var with values in between*/ |
| 1000 | code_U(ls, SETTABLE, left+(nvars-1), -1); | 807 | luaK_U(ls, SETTABLE, left+(nvars-1), -1); |
| 1001 | left += 2; /* table&index are not popped, because they aren't on top */ | 808 | left += 2; /* table&index are not popped, because they aren't on top */ |
| 1002 | } | 809 | } |
| 1003 | return left; | 810 | return left; |
| @@ -1021,20 +828,20 @@ static void whilestat (LexState *ls, int line) { | |||
| 1021 | cond_size = fs->pc - while_init; | 828 | cond_size = fs->pc - while_init; |
| 1022 | /* save condition (to move it to after body) */ | 829 | /* save condition (to move it to after body) */ |
| 1023 | if (cond_size > MAX_WHILE_EXP) | 830 | if (cond_size > MAX_WHILE_EXP) |
| 1024 | luaY_error(ls, "while condition too complex"); | 831 | luaK_error(ls, "while condition too complex"); |
| 1025 | for (i=0; i<cond_size; i++) buffer[i] = fs->f->code[while_init+i]; | 832 | for (i=0; i<cond_size; i++) buffer[i] = fs->f->code[while_init+i]; |
| 1026 | /* go back to state prior condition */ | 833 | /* go back to state prior condition */ |
| 1027 | fs->pc = while_init; | 834 | fs->pc = while_init; |
| 1028 | deltastack(ls, -1); | 835 | luaK_deltastack(ls, -1); |
| 1029 | code_S(ls, JMP, 0, 0); /* initial jump to condition */ | 836 | luaK_S(ls, JMP, 0, 0); /* initial jump to condition */ |
| 1030 | check(ls, DO); | 837 | check(ls, DO); |
| 1031 | block(ls); | 838 | block(ls); |
| 1032 | check_match(ls, END, WHILE, line); | 839 | check_match(ls, END, WHILE, line); |
| 1033 | luaK_fixjump(ls, while_init, fs->pc); | 840 | luaK_fixjump(ls, while_init, fs->pc); |
| 1034 | /* copy condition to new position, and correct stack */ | 841 | /* copy condition to new position, and correct stack */ |
| 1035 | for (i=0; i<cond_size; i++) luaK_primitivecode(ls, buffer[i]); | 842 | for (i=0; i<cond_size; i++) luaK_primitivecode(ls, buffer[i]); |
| 1036 | deltastack(ls, 1); | 843 | luaK_deltastack(ls, 1); |
| 1037 | luaK_fixjump(ls, code_S(ls, IFTJMP, 0, -1), while_init+1); | 844 | luaK_fixjump(ls, luaK_S(ls, IFTJMP, 0, -1), while_init+1); |
| 1038 | } | 845 | } |
| 1039 | 846 | ||
| 1040 | 847 | ||
| @@ -1046,7 +853,7 @@ static void repeatstat (LexState *ls, int line) { | |||
| 1046 | block(ls); | 853 | block(ls); |
| 1047 | check_match(ls, UNTIL, REPEAT, line); | 854 | check_match(ls, UNTIL, REPEAT, line); |
| 1048 | exp1(ls); | 855 | exp1(ls); |
| 1049 | luaK_fixjump(ls, code_S(ls, IFFJMP, 0, -1), repeat_init); | 856 | luaK_fixjump(ls, luaK_S(ls, IFFJMP, 0, -1), repeat_init); |
| 1050 | } | 857 | } |
| 1051 | 858 | ||
| 1052 | 859 | ||
| @@ -1068,10 +875,8 @@ static void decinit (LexState *ls, listdesc *d) { | |||
| 1068 | next(ls); | 875 | next(ls); |
| 1069 | explist1(ls, d); | 876 | explist1(ls, d); |
| 1070 | } | 877 | } |
| 1071 | else { | 878 | else |
| 1072 | d->n = 0; | 879 | d->n = 0; |
| 1073 | d->pc = 0; | ||
| 1074 | } | ||
| 1075 | } | 880 | } |
| 1076 | 881 | ||
| 1077 | 882 | ||
| @@ -1089,15 +894,15 @@ static void localstat (LexState *ls) { | |||
| 1089 | } | 894 | } |
| 1090 | 895 | ||
| 1091 | 896 | ||
| 1092 | static int funcname (LexState *ls, vardesc *v) { | 897 | static int funcname (LexState *ls, expdesc *v) { |
| 1093 | /* funcname -> NAME [':' NAME | '.' NAME] */ | 898 | /* funcname -> NAME [':' NAME | '.' NAME] */ |
| 1094 | int needself = 0; | 899 | int needself = 0; |
| 1095 | singlevar(ls, str_checkname(ls), v, 0); | 900 | singlevar(ls, str_checkname(ls), v, 0); |
| 1096 | if (ls->token == ':' || ls->token == '.') { | 901 | if (ls->token == ':' || ls->token == '.') { |
| 1097 | needself = (ls->token == ':'); | 902 | needself = (ls->token == ':'); |
| 1098 | next(ls); | 903 | next(ls); |
| 1099 | close_exp(ls, v); | 904 | luaK_2stack(ls, v); |
| 1100 | code_kstr(ls, checkname(ls)); | 905 | luaK_kstr(ls, checkname(ls)); |
| 1101 | v->k = VINDEXED; | 906 | v->k = VINDEXED; |
| 1102 | } | 907 | } |
| 1103 | return needself; | 908 | return needself; |
| @@ -1107,31 +912,31 @@ static int funcname (LexState *ls, vardesc *v) { | |||
| 1107 | static int funcstat (LexState *ls, int line) { | 912 | static int funcstat (LexState *ls, int line) { |
| 1108 | /* funcstat -> FUNCTION funcname body */ | 913 | /* funcstat -> FUNCTION funcname body */ |
| 1109 | int needself; | 914 | int needself; |
| 1110 | vardesc v; | 915 | expdesc v; |
| 1111 | if (ls->fs->prev) /* inside other function? */ | 916 | if (ls->fs->prev) /* inside other function? */ |
| 1112 | return 0; | 917 | return 0; |
| 1113 | check_debugline(ls); | 918 | check_debugline(ls); |
| 1114 | next(ls); | 919 | next(ls); |
| 1115 | needself = funcname(ls, &v); | 920 | needself = funcname(ls, &v); |
| 1116 | body(ls, needself, line); | 921 | body(ls, needself, line); |
| 1117 | storevar(ls, &v); | 922 | luaK_storevar(ls, &v); |
| 1118 | return 1; | 923 | return 1; |
| 1119 | } | 924 | } |
| 1120 | 925 | ||
| 1121 | 926 | ||
| 1122 | static void namestat (LexState *ls) { | 927 | static void namestat (LexState *ls) { |
| 1123 | /* stat -> func | ['%'] NAME assignment */ | 928 | /* stat -> func | ['%'] NAME assignment */ |
| 1124 | vardesc v; | 929 | expdesc v; |
| 1125 | check_debugline(ls); | 930 | check_debugline(ls); |
| 1126 | var_or_func(ls, &v); | 931 | var_or_func(ls, &v); |
| 1127 | if (v.k == VEXP) { /* stat -> func */ | 932 | if (v.k == VEXP) { /* stat -> func */ |
| 1128 | if (v.info == 0) /* is just an upper value? */ | 933 | if (!luaK_iscall(ls, v.info)) /* is just an upper value? */ |
| 1129 | luaY_error(ls, "syntax error"); | 934 | luaK_error(ls, "syntax error"); |
| 1130 | close_call(ls, v.info, 0); /* call statement uses no results */ | 935 | luaK_setcallreturns(ls, v.info, 0); /* call statement uses no results */ |
| 1131 | } | 936 | } |
| 1132 | else { /* stat -> ['%'] NAME assignment */ | 937 | else { /* stat -> ['%'] NAME assignment */ |
| 1133 | int left = assignment(ls, &v, 1); | 938 | int left = assignment(ls, &v, 1); |
| 1134 | adjuststack(ls, left); /* remove eventual garbage left on stack */ | 939 | luaK_adjuststack(ls, left); /* remove eventual garbage left on stack */ |
| 1135 | } | 940 | } |
| 1136 | } | 941 | } |
| 1137 | 942 | ||
| @@ -1144,10 +949,10 @@ static void ifpart (LexState *ls, int line) { | |||
| 1144 | int elseinit; | 949 | int elseinit; |
| 1145 | next(ls); /* skip IF or ELSEIF */ | 950 | next(ls); /* skip IF or ELSEIF */ |
| 1146 | exp1(ls); /* cond */ | 951 | exp1(ls); /* cond */ |
| 1147 | c = code_S(ls, IFFJMP, 0, -1); /* jump `then' if `cond' is false */ | 952 | c = luaK_S(ls, IFFJMP, 0, -1); /* jump `then' if `cond' is false */ |
| 1148 | check(ls, THEN); | 953 | check(ls, THEN); |
| 1149 | block(ls); /* `then' part */ | 954 | block(ls); /* `then' part */ |
| 1150 | je = code_S(ls, JMP, 0, 0); /* jump `else' part after `then' */ | 955 | je = luaK_S(ls, JMP, 0, 0); /* jump `else' part after `then' */ |
| 1151 | elseinit = fs->pc; | 956 | elseinit = fs->pc; |
| 1152 | if (ls->token == ELSEIF) | 957 | if (ls->token == ELSEIF) |
| 1153 | ifpart(ls, line); | 958 | ifpart(ls, line); |
| @@ -1234,20 +1039,20 @@ static void parlist (LexState *ls) { | |||
| 1234 | case NAME: /* tailparlist -> NAME [',' tailparlist] */ | 1039 | case NAME: /* tailparlist -> NAME [',' tailparlist] */ |
| 1235 | goto init; | 1040 | goto init; |
| 1236 | 1041 | ||
| 1237 | default: luaY_error(ls, "<name> or `...' expected"); | 1042 | default: luaK_error(ls, "<name> or `...' expected"); |
| 1238 | } | 1043 | } |
| 1239 | } | 1044 | } |
| 1240 | break; | 1045 | break; |
| 1241 | 1046 | ||
| 1242 | case ')': break; /* parlist -> empty */ | 1047 | case ')': break; /* parlist -> empty */ |
| 1243 | 1048 | ||
| 1244 | default: luaY_error(ls, "<name> or `...' expected"); | 1049 | default: luaK_error(ls, "<name> or `...' expected"); |
| 1245 | } | 1050 | } |
| 1246 | code_args(ls, nparams, dots); | 1051 | code_args(ls, nparams, dots); |
| 1247 | } | 1052 | } |
| 1248 | 1053 | ||
| 1249 | 1054 | ||
| 1250 | static void body (LexState *ls, int needself, int line) { | 1055 | static int body (LexState *ls, int needself, int line) { |
| 1251 | /* body -> '(' parlist ')' chunk END */ | 1056 | /* body -> '(' parlist ')' chunk END */ |
| 1252 | FuncState new_fs; | 1057 | FuncState new_fs; |
| 1253 | init_state(ls, &new_fs, ls->fs->f->source); | 1058 | init_state(ls, &new_fs, ls->fs->f->source); |
| @@ -1260,7 +1065,7 @@ static void body (LexState *ls, int needself, int line) { | |||
| 1260 | chunk(ls); | 1065 | chunk(ls); |
| 1261 | check_match(ls, END, FUNCTION, line); | 1066 | check_match(ls, END, FUNCTION, line); |
| 1262 | close_func(ls); | 1067 | close_func(ls); |
| 1263 | func_onstack(ls, &new_fs); | 1068 | return func_onstack(ls, &new_fs); |
| 1264 | } | 1069 | } |
| 1265 | 1070 | ||
| 1266 | 1071 | ||
| @@ -1271,8 +1076,7 @@ static void ret (LexState *ls) { | |||
| 1271 | check_debugline(ls); | 1076 | check_debugline(ls); |
| 1272 | next(ls); | 1077 | next(ls); |
| 1273 | explist(ls, &e); | 1078 | explist(ls, &e); |
| 1274 | close_call(ls, e.pc, MULT_RET); | 1079 | luaK_U(ls, RETCODE, ls->fs->nlocalvar, 0); |
| 1275 | code_U(ls, RETCODE, ls->fs->nlocalvar, 0); | ||
| 1276 | ls->fs->stacksize = ls->fs->nlocalvar; /* removes all temp values */ | 1080 | ls->fs->stacksize = ls->fs->nlocalvar; /* removes all temp values */ |
| 1277 | optional(ls, ';'); | 1081 | optional(ls, ';'); |
| 1278 | } | 1082 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.h,v 1.5 1999/11/22 13:12:07 roberto Exp roberto $ | 2 | ** $Id: lparser.h,v 1.6 2000/02/22 13:30:11 roberto Exp roberto $ |
| 3 | ** LL(1) Parser and code generator for Lua | 3 | ** LL(1) Parser and code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -50,21 +50,19 @@ | |||
| 50 | 50 | ||
| 51 | 51 | ||
| 52 | /* | 52 | /* |
| 53 | ** Variable descriptor: | 53 | ** Expression descriptor |
| 54 | ** must include an `exp' option because LL(1) cannot distinguish | ||
| 55 | ** between variables, upvalues and function calls on first sight. | ||
| 56 | */ | 54 | */ |
| 57 | typedef enum { | 55 | typedef enum { |
| 58 | VGLOBAL, /* info is constant index of global name */ | 56 | VGLOBAL, /* info is constant index of global name */ |
| 59 | VLOCAL, /* info is stack index */ | 57 | VLOCAL, /* info is stack index */ |
| 60 | VINDEXED, /* no info (table and index are on the stack) */ | 58 | VINDEXED, /* no info (table and index are on the stack) */ |
| 61 | VEXP /* info is pc index of a call (or 0 if exp is closed) */ | 59 | VEXP /* info is pc index of exp main operator */ |
| 62 | } varkind; | 60 | } expkind; |
| 63 | 61 | ||
| 64 | typedef struct vardesc { | 62 | typedef struct expdesc { |
| 65 | varkind k; | 63 | expkind k; |
| 66 | int info; | 64 | int info; |
| 67 | } vardesc; | 65 | } expdesc; |
| 68 | 66 | ||
| 69 | 67 | ||
| 70 | /* state needed to generate code for a given function */ | 68 | /* state needed to generate code for a given function */ |
| @@ -78,7 +76,7 @@ typedef struct FuncState { | |||
| 78 | int nupvalues; /* number of upvalues */ | 76 | int nupvalues; /* number of upvalues */ |
| 79 | int nvars; /* number of entries in f->locvars (-1 if no debug information) */ | 77 | int nvars; /* number of entries in f->locvars (-1 if no debug information) */ |
| 80 | int lastsetline; /* line where last SETLINE was issued */ | 78 | int lastsetline; /* line where last SETLINE was issued */ |
| 81 | vardesc upvalues[MAXUPVALUES]; /* upvalues */ | 79 | expdesc upvalues[MAXUPVALUES]; /* upvalues */ |
| 82 | TaggedString *localvar[MAXLOCALS]; /* store local variable names */ | 80 | TaggedString *localvar[MAXLOCALS]; /* store local variable names */ |
| 83 | } FuncState; | 81 | } FuncState; |
| 84 | 82 | ||
