diff options
-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 | ||