diff options
Diffstat (limited to 'lua.stx')
-rw-r--r-- | lua.stx | 245 |
1 files changed, 123 insertions, 122 deletions
@@ -1,6 +1,6 @@ | |||
1 | %{ | 1 | %{ |
2 | /* | 2 | /* |
3 | ** $Id: lua.stx,v 1.16 1997/10/30 18:47:19 roberto Exp roberto $ | 3 | ** $Id: lua.stx,v 1.17 1997/11/07 15:09:49 roberto Exp roberto $ |
4 | ** Syntax analizer and code generator | 4 | ** Syntax analizer and code generator |
5 | ** See Copyright Notice in lua.h | 5 | ** See Copyright Notice in lua.h |
6 | */ | 6 | */ |
@@ -16,13 +16,13 @@ | |||
16 | #include "lmem.h" | 16 | #include "lmem.h" |
17 | #include "lopcodes.h" | 17 | #include "lopcodes.h" |
18 | #include "lparser.h" | 18 | #include "lparser.h" |
19 | #include "lstate.h" | ||
19 | #include "lstring.h" | 20 | #include "lstring.h" |
20 | #include "lua.h" | 21 | #include "lua.h" |
21 | #include "luadebug.h" | 22 | #include "luadebug.h" |
22 | #include "lzio.h" | 23 | #include "lzio.h" |
23 | 24 | ||
24 | 25 | ||
25 | /* to avoid warnings generated by yacc */ | ||
26 | int luaY_parse (void); | 26 | int luaY_parse (void); |
27 | 27 | ||
28 | 28 | ||
@@ -61,7 +61,7 @@ typedef long vardesc; | |||
61 | #define dotindex(v) ((-(v))-1) | 61 | #define dotindex(v) ((-(v))-1) |
62 | 62 | ||
63 | /* state needed to generate code for a given function */ | 63 | /* state needed to generate code for a given function */ |
64 | typedef struct State { | 64 | typedef struct FuncState { |
65 | TProtoFunc *f; /* current function header */ | 65 | TProtoFunc *f; /* current function header */ |
66 | int pc; /* next position to code */ | 66 | int pc; /* next position to code */ |
67 | TaggedString *localvar[MAXLOCALS]; /* store local variable names */ | 67 | TaggedString *localvar[MAXLOCALS]; /* store local variable names */ |
@@ -75,11 +75,11 @@ typedef struct State { | |||
75 | int maxconsts; /* size of f->consts */ | 75 | int maxconsts; /* size of f->consts */ |
76 | vardesc varbuffer[MAXVAR]; /* variables in an assignment list */ | 76 | vardesc varbuffer[MAXVAR]; /* variables in an assignment list */ |
77 | vardesc upvalues[MAXUPVALUES]; /* upvalues */ | 77 | vardesc upvalues[MAXUPVALUES]; /* upvalues */ |
78 | } State; | 78 | } FuncState; |
79 | 79 | ||
80 | static State *mainState, *currState; | ||
81 | 80 | ||
82 | 81 | ||
82 | #define YYPURE 1 | ||
83 | 83 | ||
84 | 84 | ||
85 | void luaY_syntaxerror (char *s, char *token) | 85 | void luaY_syntaxerror (char *s, char *token) |
@@ -87,7 +87,7 @@ void luaY_syntaxerror (char *s, char *token) | |||
87 | if (token[0] == 0) | 87 | if (token[0] == 0) |
88 | token = "<eof>"; | 88 | token = "<eof>"; |
89 | luaL_verror("%.100s;\n> last token read: \"%.50s\" at line %d in file %.50s", | 89 | luaL_verror("%.100s;\n> last token read: \"%.50s\" at line %d in file %.50s", |
90 | s, token, luaX_linenumber, mainState->f->fileName->str); | 90 | s, token, L->lexstate->linenumber, L->mainState->f->fileName->str); |
91 | } | 91 | } |
92 | 92 | ||
93 | 93 | ||
@@ -99,16 +99,16 @@ void luaY_error (char *s) | |||
99 | 99 | ||
100 | static void check_pc (int n) | 100 | static void check_pc (int n) |
101 | { | 101 | { |
102 | if (currState->pc+n > currState->maxcode) | 102 | if (L->currState->pc+n > L->currState->maxcode) |
103 | currState->maxcode = luaM_growvector(&currState->f->code, | 103 | L->currState->maxcode = luaM_growvector(&L->currState->f->code, |
104 | currState->maxcode, Byte, codeEM, MAX_INT); | 104 | L->currState->maxcode, Byte, codeEM, MAX_INT); |
105 | } | 105 | } |
106 | 106 | ||
107 | 107 | ||
108 | static void movecode_up (int d, int s, int n) | 108 | static void movecode_up (int d, int s, int n) |
109 | { | 109 | { |
110 | while (n--) | 110 | while (n--) |
111 | currState->f->code[d+n] = currState->f->code[s+n]; | 111 | L->currState->f->code[d+n] = L->currState->f->code[s+n]; |
112 | } | 112 | } |
113 | 113 | ||
114 | 114 | ||
@@ -116,24 +116,24 @@ static void movecode_down (int d, int s, int n) | |||
116 | { | 116 | { |
117 | int i; | 117 | int i; |
118 | for (i=0; i<n; i++) | 118 | for (i=0; i<n; i++) |
119 | currState->f->code[d+i] = currState->f->code[s+i]; | 119 | L->currState->f->code[d+i] = L->currState->f->code[s+i]; |
120 | } | 120 | } |
121 | 121 | ||
122 | 122 | ||
123 | static void code_byte (Byte c) | 123 | static void code_byte (Byte c) |
124 | { | 124 | { |
125 | check_pc(1); | 125 | check_pc(1); |
126 | currState->f->code[currState->pc++] = c; | 126 | L->currState->f->code[L->currState->pc++] = c; |
127 | } | 127 | } |
128 | 128 | ||
129 | 129 | ||
130 | static void deltastack (int delta) | 130 | static void deltastack (int delta) |
131 | { | 131 | { |
132 | currState->stacksize += delta; | 132 | L->currState->stacksize += delta; |
133 | if (currState->stacksize > currState->maxstacksize) { | 133 | if (L->currState->stacksize > L->currState->maxstacksize) { |
134 | if (currState->stacksize > 255) | 134 | if (L->currState->stacksize > 255) |
135 | luaY_error("function/expression too complex (limit 256)"); | 135 | luaY_error("function/expression too complex (limit 256)"); |
136 | currState->maxstacksize = currState->stacksize; | 136 | L->currState->maxstacksize = L->currState->stacksize; |
137 | } | 137 | } |
138 | } | 138 | } |
139 | 139 | ||
@@ -142,18 +142,18 @@ static int code_oparg_at (int pc, OpCode op, int builtin, int arg, int delta) | |||
142 | { | 142 | { |
143 | deltastack(delta); | 143 | deltastack(delta); |
144 | if (arg < builtin) { | 144 | if (arg < builtin) { |
145 | currState->f->code[pc] = op+1+arg; | 145 | L->currState->f->code[pc] = op+1+arg; |
146 | return 1; | 146 | return 1; |
147 | } | 147 | } |
148 | else if (arg <= 255) { | 148 | else if (arg <= 255) { |
149 | currState->f->code[pc] = op; | 149 | L->currState->f->code[pc] = op; |
150 | currState->f->code[pc+1] = arg; | 150 | L->currState->f->code[pc+1] = arg; |
151 | return 2; | 151 | return 2; |
152 | } | 152 | } |
153 | else if (arg <= MAX_WORD) { | 153 | else if (arg <= MAX_WORD) { |
154 | currState->f->code[pc] = op+1+builtin; | 154 | L->currState->f->code[pc] = op+1+builtin; |
155 | currState->f->code[pc+1] = arg&0xFF; | 155 | L->currState->f->code[pc+1] = arg&0xFF; |
156 | currState->f->code[pc+2] = arg>>8; | 156 | L->currState->f->code[pc+2] = arg>>8; |
157 | return 3; | 157 | return 3; |
158 | } | 158 | } |
159 | else luaY_error("code too long (limit 64K)"); | 159 | else luaY_error("code too long (limit 64K)"); |
@@ -164,13 +164,13 @@ static int code_oparg_at (int pc, OpCode op, int builtin, int arg, int delta) | |||
164 | static int fix_opcode (int pc, OpCode op, int builtin, int arg) | 164 | static int fix_opcode (int pc, OpCode op, int builtin, int arg) |
165 | { | 165 | { |
166 | if (arg < builtin) { /* close space */ | 166 | if (arg < builtin) { /* close space */ |
167 | movecode_down(pc+1, pc+2, currState->pc-(pc+2)); | 167 | movecode_down(pc+1, pc+2, L->currState->pc-(pc+2)); |
168 | currState->pc--; | 168 | L->currState->pc--; |
169 | } | 169 | } |
170 | else if (arg > 255) { /* open space */ | 170 | else if (arg > 255) { /* open space */ |
171 | check_pc(1); | 171 | check_pc(1); |
172 | movecode_up(pc+1, pc, currState->pc-pc); | 172 | movecode_up(pc+1, pc, L->currState->pc-pc); |
173 | currState->pc++; | 173 | L->currState->pc++; |
174 | } | 174 | } |
175 | return code_oparg_at(pc, op, builtin, arg, 0) - 2; | 175 | return code_oparg_at(pc, op, builtin, arg, 0) - 2; |
176 | } | 176 | } |
@@ -179,7 +179,7 @@ static int fix_opcode (int pc, OpCode op, int builtin, int arg) | |||
179 | static void code_oparg (OpCode op, int builtin, int arg, int delta) | 179 | static void code_oparg (OpCode op, int builtin, int arg, int delta) |
180 | { | 180 | { |
181 | check_pc(3); /* maximum code size */ | 181 | check_pc(3); /* maximum code size */ |
182 | currState->pc += code_oparg_at(currState->pc, op, builtin, arg, delta); | 182 | L->currState->pc += code_oparg_at(L->currState->pc, op, builtin, arg, delta); |
183 | } | 183 | } |
184 | 184 | ||
185 | 185 | ||
@@ -214,7 +214,7 @@ static void code_constant (int c) | |||
214 | } | 214 | } |
215 | 215 | ||
216 | 216 | ||
217 | static int next_constant (State *cs) | 217 | static int next_constant (FuncState *cs) |
218 | { | 218 | { |
219 | TProtoFunc *f = cs->f; | 219 | TProtoFunc *f = cs->f; |
220 | if (f->nconsts >= cs->maxconsts) { | 220 | if (f->nconsts >= cs->maxconsts) { |
@@ -225,7 +225,7 @@ static int next_constant (State *cs) | |||
225 | } | 225 | } |
226 | 226 | ||
227 | 227 | ||
228 | static int string_constant (TaggedString *s, State *cs) | 228 | static int string_constant (TaggedString *s, FuncState *cs) |
229 | { | 229 | { |
230 | TProtoFunc *f = cs->f; | 230 | TProtoFunc *f = cs->f; |
231 | int c = s->constindex; | 231 | int c = s->constindex; |
@@ -242,7 +242,7 @@ static int string_constant (TaggedString *s, State *cs) | |||
242 | 242 | ||
243 | static void code_string (TaggedString *s) | 243 | static void code_string (TaggedString *s) |
244 | { | 244 | { |
245 | code_constant(string_constant(s, currState)); | 245 | code_constant(string_constant(s, L->currState)); |
246 | } | 246 | } |
247 | 247 | ||
248 | 248 | ||
@@ -250,16 +250,16 @@ static void code_string (TaggedString *s) | |||
250 | static int real_constant (real r) | 250 | static int real_constant (real r) |
251 | { | 251 | { |
252 | /* check whether 'r' has appeared within the last LIM entries */ | 252 | /* check whether 'r' has appeared within the last LIM entries */ |
253 | TObject *cnt = currState->f->consts; | 253 | TObject *cnt = L->currState->f->consts; |
254 | int c = currState->f->nconsts; | 254 | int c = L->currState->f->nconsts; |
255 | int lim = c < LIM ? 0 : c-LIM; | 255 | int lim = c < LIM ? 0 : c-LIM; |
256 | while (--c >= lim) { | 256 | while (--c >= lim) { |
257 | if (ttype(&cnt[c]) == LUA_T_NUMBER && nvalue(&cnt[c]) == r) | 257 | if (ttype(&cnt[c]) == LUA_T_NUMBER && nvalue(&cnt[c]) == r) |
258 | return c; | 258 | return c; |
259 | } | 259 | } |
260 | /* not found; create a luaM_new entry */ | 260 | /* not found; create a luaM_new entry */ |
261 | c = next_constant(currState); | 261 | c = next_constant(L->currState); |
262 | cnt = currState->f->consts; /* 'next_constant' may reallocate this vector */ | 262 | cnt = L->currState->f->consts; /* 'next_constant' may reallocate this vector */ |
263 | ttype(&cnt[c]) = LUA_T_NUMBER; | 263 | ttype(&cnt[c]) = LUA_T_NUMBER; |
264 | nvalue(&cnt[c]) = r; | 264 | nvalue(&cnt[c]) = r; |
265 | return c; | 265 | return c; |
@@ -292,13 +292,13 @@ static void flush_list (int m, int n) | |||
292 | 292 | ||
293 | static void luaI_registerlocalvar (TaggedString *varname, int line) | 293 | static void luaI_registerlocalvar (TaggedString *varname, int line) |
294 | { | 294 | { |
295 | if (currState->maxvars != -1) { /* debug information? */ | 295 | if (L->currState->maxvars != -1) { /* debug information? */ |
296 | if (currState->nvars >= currState->maxvars) | 296 | if (L->currState->nvars >= L->currState->maxvars) |
297 | currState->maxvars = luaM_growvector(&currState->f->locvars, | 297 | L->currState->maxvars = luaM_growvector(&L->currState->f->locvars, |
298 | currState->maxvars, LocVar, "", MAX_WORD); | 298 | L->currState->maxvars, LocVar, "", MAX_WORD); |
299 | currState->f->locvars[currState->nvars].varname = varname; | 299 | L->currState->f->locvars[L->currState->nvars].varname = varname; |
300 | currState->f->locvars[currState->nvars].line = line; | 300 | L->currState->f->locvars[L->currState->nvars].line = line; |
301 | currState->nvars++; | 301 | L->currState->nvars++; |
302 | } | 302 | } |
303 | } | 303 | } |
304 | 304 | ||
@@ -311,17 +311,17 @@ static void luaI_unregisterlocalvar (int line) | |||
311 | 311 | ||
312 | static void store_localvar (TaggedString *name, int n) | 312 | static void store_localvar (TaggedString *name, int n) |
313 | { | 313 | { |
314 | if (currState->nlocalvar+n < MAXLOCALS) | 314 | if (L->currState->nlocalvar+n < MAXLOCALS) |
315 | currState->localvar[currState->nlocalvar+n] = name; | 315 | L->currState->localvar[L->currState->nlocalvar+n] = name; |
316 | else | 316 | else |
317 | luaY_error("too many local variables (limit 32)"); | 317 | luaY_error("too many local variables (limit 32)"); |
318 | luaI_registerlocalvar(name, luaX_linenumber); | 318 | luaI_registerlocalvar(name, L->lexstate->linenumber); |
319 | } | 319 | } |
320 | 320 | ||
321 | static void add_localvar (TaggedString *name) | 321 | static void add_localvar (TaggedString *name) |
322 | { | 322 | { |
323 | store_localvar(name, 0); | 323 | store_localvar(name, 0); |
324 | currState->nlocalvar++; | 324 | L->currState->nlocalvar++; |
325 | } | 325 | } |
326 | 326 | ||
327 | 327 | ||
@@ -342,11 +342,11 @@ static void add_varbuffer (vardesc var, int n) | |||
342 | { | 342 | { |
343 | if (n >= MAXVAR) | 343 | if (n >= MAXVAR) |
344 | luaY_error("variable buffer overflow (limit 32)"); | 344 | luaY_error("variable buffer overflow (limit 32)"); |
345 | currState->varbuffer[n] = var2store(var); | 345 | L->currState->varbuffer[n] = var2store(var); |
346 | } | 346 | } |
347 | 347 | ||
348 | 348 | ||
349 | static int aux_localname (TaggedString *n, State *st) | 349 | static int aux_localname (TaggedString *n, FuncState *st) |
350 | { | 350 | { |
351 | int i; | 351 | int i; |
352 | for (i=st->nlocalvar-1; i >= 0; i--) | 352 | for (i=st->nlocalvar-1; i >= 0; i--) |
@@ -355,12 +355,12 @@ static int aux_localname (TaggedString *n, State *st) | |||
355 | } | 355 | } |
356 | 356 | ||
357 | 357 | ||
358 | static vardesc singlevar (TaggedString *n, State *st) | 358 | static vardesc singlevar (TaggedString *n, FuncState *st) |
359 | { | 359 | { |
360 | int i = aux_localname(n, st); | 360 | int i = aux_localname(n, st); |
361 | if (i == -1) { /* check shadowing */ | 361 | if (i == -1) { /* check shadowing */ |
362 | int l; | 362 | int l; |
363 | for (l=1; l<=(st-mainState); l++) | 363 | for (l=1; l<=(st-L->mainState); l++) |
364 | if (aux_localname(n, st-l) >= 0) | 364 | if (aux_localname(n, st-l) >= 0) |
365 | luaY_syntaxerror("cannot access a variable in outer scope", n->str); | 365 | luaY_syntaxerror("cannot access a variable in outer scope", n->str); |
366 | return string_constant(n, st)+MINGLOBAL; /* global value */ | 366 | return string_constant(n, st)+MINGLOBAL; /* global value */ |
@@ -371,16 +371,16 @@ static vardesc singlevar (TaggedString *n, State *st) | |||
371 | 371 | ||
372 | static int indexupvalue (TaggedString *n) | 372 | static int indexupvalue (TaggedString *n) |
373 | { | 373 | { |
374 | vardesc v = singlevar(n, currState-1); | 374 | vardesc v = singlevar(n, L->currState-1); |
375 | int i; | 375 | int i; |
376 | for (i=0; i<currState->nupvalues; i++) { | 376 | for (i=0; i<L->currState->nupvalues; i++) { |
377 | if (currState->upvalues[i] == v) | 377 | if (L->currState->upvalues[i] == v) |
378 | return i; | 378 | return i; |
379 | } | 379 | } |
380 | /* new one */ | 380 | /* new one */ |
381 | if (++(currState->nupvalues) > MAXUPVALUES) | 381 | if (++(L->currState->nupvalues) > MAXUPVALUES) |
382 | luaY_error("too many upvalues in a single function (limit 16)"); | 382 | luaY_error("too many upvalues in a single function (limit 16)"); |
383 | currState->upvalues[i] = v; /* i = currState->nupvalues - 1 */ | 383 | L->currState->upvalues[i] = v; /* i = L->currState->nupvalues - 1 */ |
384 | return i; | 384 | return i; |
385 | } | 385 | } |
386 | 386 | ||
@@ -388,9 +388,9 @@ static int indexupvalue (TaggedString *n) | |||
388 | static void pushupvalue (TaggedString *n) | 388 | static void pushupvalue (TaggedString *n) |
389 | { | 389 | { |
390 | int i; | 390 | int i; |
391 | if (currState == mainState) | 391 | if (L->currState == L->mainState) |
392 | luaY_error("cannot access upvalue in main"); | 392 | luaY_error("cannot access upvalue in main"); |
393 | if (aux_localname(n, currState) >= 0) | 393 | if (aux_localname(n, L->currState) >= 0) |
394 | luaY_syntaxerror("cannot access an upvalue in current scope", n->str); | 394 | luaY_syntaxerror("cannot access an upvalue in current scope", n->str); |
395 | i = indexupvalue(n); | 395 | i = indexupvalue(n); |
396 | code_oparg(PUSHUPVALUE, 2, i, 1); | 396 | code_oparg(PUSHUPVALUE, 2, i, 1); |
@@ -399,10 +399,9 @@ static void pushupvalue (TaggedString *n) | |||
399 | 399 | ||
400 | void luaY_codedebugline (int line) | 400 | void luaY_codedebugline (int line) |
401 | { | 401 | { |
402 | static int lastline = 0; | 402 | if (lua_debug && line != L->lexstate->lastline) { |
403 | if (lua_debug && line != lastline) { | ||
404 | code_oparg(SETLINE, 0, line, 0); | 403 | code_oparg(SETLINE, 0, line, 0); |
405 | lastline = line; | 404 | L->lexstate->lastline = line; |
406 | } | 405 | } |
407 | } | 406 | } |
408 | 407 | ||
@@ -421,10 +420,10 @@ static long adjust_functioncall (long exp, int nresults) | |||
421 | if (exp <= 0) | 420 | if (exp <= 0) |
422 | return -exp; /* exp is -list length */ | 421 | return -exp; /* exp is -list length */ |
423 | else { | 422 | else { |
424 | int temp = currState->f->code[exp]; | 423 | int temp = L->currState->f->code[exp]; |
425 | int nparams = currState->f->code[exp-1]; | 424 | int nparams = L->currState->f->code[exp-1]; |
426 | exp += fix_opcode(exp-2, CALLFUNC, 2, nresults); | 425 | exp += fix_opcode(exp-2, CALLFUNC, 2, nresults); |
427 | currState->f->code[exp] = nparams; | 426 | L->currState->f->code[exp] = nparams; |
428 | if (nresults != MULT_RET) | 427 | if (nresults != MULT_RET) |
429 | deltastack(nresults); | 428 | deltastack(nresults); |
430 | deltastack(-(nparams+1)); | 429 | deltastack(-(nparams+1)); |
@@ -436,7 +435,7 @@ static long adjust_functioncall (long exp, int nresults) | |||
436 | static void adjust_mult_assign (int vars, long exps) | 435 | static void adjust_mult_assign (int vars, long exps) |
437 | { | 436 | { |
438 | if (exps > 0) { /* must correct function call */ | 437 | if (exps > 0) { /* must correct function call */ |
439 | int diff = currState->f->code[exps] - vars; | 438 | int diff = L->currState->f->code[exps] - vars; |
440 | if (diff < 0) | 439 | if (diff < 0) |
441 | adjust_functioncall(exps, -diff); | 440 | adjust_functioncall(exps, -diff); |
442 | else { | 441 | else { |
@@ -450,11 +449,11 @@ static void adjust_mult_assign (int vars, long exps) | |||
450 | 449 | ||
451 | static void code_args (int nparams, int dots) | 450 | static void code_args (int nparams, int dots) |
452 | { | 451 | { |
453 | currState->nlocalvar += nparams; | 452 | L->currState->nlocalvar += nparams; |
454 | if (!dots) | 453 | if (!dots) |
455 | code_oparg(ARGS, 0, currState->nlocalvar, currState->nlocalvar); | 454 | code_oparg(ARGS, 0, L->currState->nlocalvar, L->currState->nlocalvar); |
456 | else { | 455 | else { |
457 | code_oparg(VARARGS, 0, currState->nlocalvar, currState->nlocalvar+1); | 456 | code_oparg(VARARGS, 0, L->currState->nlocalvar, L->currState->nlocalvar+1); |
458 | add_localvar(luaS_new("arg")); | 457 | add_localvar(luaS_new("arg")); |
459 | } | 458 | } |
460 | } | 459 | } |
@@ -487,9 +486,9 @@ static void storevar (vardesc var) | |||
487 | /* returns how many elements are left as 'garbage' on the stack */ | 486 | /* returns how many elements are left as 'garbage' on the stack */ |
488 | static int lua_codestore (int i, int left) | 487 | static int lua_codestore (int i, int left) |
489 | { | 488 | { |
490 | if (currState->varbuffer[i] != 0 || /* global or local var or */ | 489 | if (L->currState->varbuffer[i] != 0 || /* global or local var or */ |
491 | left+i == 0) { /* indexed var without values in between */ | 490 | left+i == 0) { /* indexed var without values in between */ |
492 | storevar(currState->varbuffer[i]); | 491 | storevar(L->currState->varbuffer[i]); |
493 | return left; | 492 | return left; |
494 | } | 493 | } |
495 | else { /* indexed var with values in between*/ | 494 | else { /* indexed var with values in between*/ |
@@ -508,7 +507,7 @@ static int fix_jump (int pc, OpCode op, int n) | |||
508 | 507 | ||
509 | static void fix_upjmp (OpCode op, int pos) | 508 | static void fix_upjmp (OpCode op, int pos) |
510 | { | 509 | { |
511 | int delta = currState->pc+JMPSIZE - pos; /* jump is relative */ | 510 | int delta = L->currState->pc+JMPSIZE - pos; /* jump is relative */ |
512 | if (delta > 255) delta++; | 511 | if (delta > 255) delta++; |
513 | code_oparg(op, 0, delta, 0); | 512 | code_oparg(op, 0, delta, 0); |
514 | } | 513 | } |
@@ -517,38 +516,38 @@ static void fix_upjmp (OpCode op, int pos) | |||
517 | static void codeIf (int thenAdd, int elseAdd) | 516 | static void codeIf (int thenAdd, int elseAdd) |
518 | { | 517 | { |
519 | int elseinit = elseAdd+JMPSIZE; | 518 | int elseinit = elseAdd+JMPSIZE; |
520 | if (currState->pc == elseinit) { /* no else part */ | 519 | if (L->currState->pc == elseinit) { /* no else part */ |
521 | currState->pc -= JMPSIZE; | 520 | L->currState->pc -= JMPSIZE; |
522 | elseinit = currState->pc; | 521 | elseinit = L->currState->pc; |
523 | } | 522 | } |
524 | else | 523 | else |
525 | elseinit += fix_jump(elseAdd, JMP, currState->pc); | 524 | elseinit += fix_jump(elseAdd, JMP, L->currState->pc); |
526 | fix_jump(thenAdd, IFFJMP, elseinit); | 525 | fix_jump(thenAdd, IFFJMP, elseinit); |
527 | } | 526 | } |
528 | 527 | ||
529 | 528 | ||
530 | static void code_shortcircuit (int pc, OpCode op) | 529 | static void code_shortcircuit (int pc, OpCode op) |
531 | { | 530 | { |
532 | fix_jump(pc, op, currState->pc); | 531 | fix_jump(pc, op, L->currState->pc); |
533 | } | 532 | } |
534 | 533 | ||
535 | 534 | ||
536 | static void codereturn (void) | 535 | static void codereturn (void) |
537 | { | 536 | { |
538 | code_oparg(RETCODE, 0, currState->nlocalvar, 0); | 537 | code_oparg(RETCODE, 0, L->currState->nlocalvar, 0); |
539 | currState->stacksize = currState->nlocalvar; | 538 | L->currState->stacksize = L->currState->nlocalvar; |
540 | } | 539 | } |
541 | 540 | ||
542 | 541 | ||
543 | static void func_onstack (TProtoFunc *f) | 542 | static void func_onstack (TProtoFunc *f) |
544 | { | 543 | { |
545 | int i; | 544 | int i; |
546 | int nupvalues = (currState+1)->nupvalues; | 545 | int nupvalues = (L->currState+1)->nupvalues; |
547 | int c = next_constant(currState); | 546 | int c = next_constant(L->currState); |
548 | ttype(&currState->f->consts[c]) = LUA_T_PROTO; | 547 | ttype(&L->currState->f->consts[c]) = LUA_T_PROTO; |
549 | currState->f->consts[c].value.tf = (currState+1)->f; | 548 | L->currState->f->consts[c].value.tf = (L->currState+1)->f; |
550 | for (i=0; i<nupvalues; i++) | 549 | for (i=0; i<nupvalues; i++) |
551 | lua_pushvar((currState+1)->upvalues[i]); | 550 | lua_pushvar((L->currState+1)->upvalues[i]); |
552 | code_constant(c); | 551 | code_constant(c); |
553 | code_oparg(CLOSURE, 2, nupvalues, -nupvalues); | 552 | code_oparg(CLOSURE, 2, nupvalues, -nupvalues); |
554 | } | 553 | } |
@@ -557,48 +556,48 @@ static void func_onstack (TProtoFunc *f) | |||
557 | static void init_state (TaggedString *filename) | 556 | static void init_state (TaggedString *filename) |
558 | { | 557 | { |
559 | TProtoFunc *f = luaF_newproto(); | 558 | TProtoFunc *f = luaF_newproto(); |
560 | currState->stacksize = 0; | 559 | L->currState->stacksize = 0; |
561 | currState->maxstacksize = 0; | 560 | L->currState->maxstacksize = 0; |
562 | currState->nlocalvar = 0; | 561 | L->currState->nlocalvar = 0; |
563 | currState->nupvalues = 0; | 562 | L->currState->nupvalues = 0; |
564 | currState->f = f; | 563 | L->currState->f = f; |
565 | f->fileName = filename; | 564 | f->fileName = filename; |
566 | currState->pc = 0; | 565 | L->currState->pc = 0; |
567 | currState->maxcode = 0; | 566 | L->currState->maxcode = 0; |
568 | f->code = NULL; | 567 | f->code = NULL; |
569 | currState->maxconsts = 0; | 568 | L->currState->maxconsts = 0; |
570 | if (lua_debug) { | 569 | if (lua_debug) { |
571 | currState->nvars = 0; | 570 | L->currState->nvars = 0; |
572 | currState->maxvars = 0; | 571 | L->currState->maxvars = 0; |
573 | } | 572 | } |
574 | else | 573 | else |
575 | currState->maxvars = -1; /* flag no debug information */ | 574 | L->currState->maxvars = -1; /* flag no debug information */ |
576 | code_byte(0); /* to be filled with stacksize */ | 575 | code_byte(0); /* to be filled with stacksize */ |
577 | } | 576 | } |
578 | 577 | ||
579 | 578 | ||
580 | static void init_func (void) | 579 | static void init_func (void) |
581 | { | 580 | { |
582 | if (currState-mainState >= MAXSTATES-1) | 581 | if (L->currState-L->mainState >= MAXSTATES-1) |
583 | luaY_error("too many nested functions (limit 6)"); | 582 | luaY_error("too many nested functions (limit 6)"); |
584 | currState++; | 583 | L->currState++; |
585 | init_state(mainState->f->fileName); | 584 | init_state(L->mainState->f->fileName); |
586 | luaY_codedebugline(luaX_linenumber); | 585 | luaY_codedebugline(L->lexstate->linenumber); |
587 | currState->f->lineDefined = luaX_linenumber; | 586 | L->currState->f->lineDefined = L->lexstate->linenumber; |
588 | } | 587 | } |
589 | 588 | ||
590 | static TProtoFunc *close_func (void) | 589 | static TProtoFunc *close_func (void) |
591 | { | 590 | { |
592 | TProtoFunc *f = currState->f; | 591 | TProtoFunc *f = L->currState->f; |
593 | code_neutralop(ENDCODE); | 592 | code_neutralop(ENDCODE); |
594 | f->code[0] = currState->maxstacksize; | 593 | f->code[0] = L->currState->maxstacksize; |
595 | f->code = luaM_reallocvector(f->code, currState->pc, Byte); | 594 | f->code = luaM_reallocvector(f->code, L->currState->pc, Byte); |
596 | f->consts = luaM_reallocvector(f->consts, f->nconsts, TObject); | 595 | f->consts = luaM_reallocvector(f->consts, f->nconsts, TObject); |
597 | if (currState->maxvars != -1) { /* debug information? */ | 596 | if (L->currState->maxvars != -1) { /* debug information? */ |
598 | luaI_registerlocalvar(NULL, -1); /* flag end of vector */ | 597 | luaI_registerlocalvar(NULL, -1); /* flag end of vector */ |
599 | f->locvars = luaM_reallocvector(f->locvars, currState->nvars, LocVar); | 598 | f->locvars = luaM_reallocvector(f->locvars, L->currState->nvars, LocVar); |
600 | } | 599 | } |
601 | currState--; | 600 | L->currState--; |
602 | return f; | 601 | return f; |
603 | } | 602 | } |
604 | 603 | ||
@@ -608,8 +607,10 @@ static TProtoFunc *close_func (void) | |||
608 | */ | 607 | */ |
609 | TProtoFunc *luaY_parser (ZIO *z, char *chunkname) | 608 | TProtoFunc *luaY_parser (ZIO *z, char *chunkname) |
610 | { | 609 | { |
611 | State state[MAXSTATES]; | 610 | struct LexState lexstate; |
612 | currState = mainState = &state[0]; | 611 | FuncState state[MAXSTATES]; |
612 | L->currState = L->mainState = &state[0]; | ||
613 | L->lexstate = &lexstate; | ||
613 | luaX_setinput(z); | 614 | luaX_setinput(z); |
614 | init_state(luaS_new(chunkname)); | 615 | init_state(luaS_new(chunkname)); |
615 | if (luaY_parse ()) lua_error("parse error"); | 616 | if (luaY_parse ()) lua_error("parse error"); |
@@ -685,10 +686,10 @@ stat : IF cond THEN block SaveWord elsepart END { codeIf($2, $5); } | |||
685 | int expsize = $3-$2; | 686 | int expsize = $3-$2; |
686 | int newpos = $2+JMPSIZE; | 687 | int newpos = $2+JMPSIZE; |
687 | check_pc(expsize); | 688 | check_pc(expsize); |
688 | memcpy(&currState->f->code[currState->pc], | 689 | memcpy(&L->currState->f->code[L->currState->pc], |
689 | &currState->f->code[$2], expsize); | 690 | &L->currState->f->code[$2], expsize); |
690 | movecode_down($2, $3, currState->pc-$2); | 691 | movecode_down($2, $3, L->currState->pc-$2); |
691 | newpos += fix_jump($2, JMP, currState->pc-expsize); | 692 | newpos += fix_jump($2, JMP, L->currState->pc-expsize); |
692 | fix_upjmp(IFTUPJMP, newpos); | 693 | fix_upjmp(IFTUPJMP, newpos); |
693 | }} | 694 | }} |
694 | 695 | ||
@@ -712,18 +713,18 @@ stat : IF cond THEN block SaveWord elsepart END { codeIf($2, $5); } | |||
712 | 713 | ||
713 | | LOCAL localnamelist decinit | 714 | | LOCAL localnamelist decinit |
714 | { | 715 | { |
715 | currState->nlocalvar += $2; | 716 | L->currState->nlocalvar += $2; |
716 | adjust_mult_assign($2, $3); | 717 | adjust_mult_assign($2, $3); |
717 | } | 718 | } |
718 | 719 | ||
719 | | FUNCTION funcname body { func_onstack($3); storevar($2); } | 720 | | FUNCTION funcname body { func_onstack($3); storevar($2); } |
720 | ; | 721 | ; |
721 | 722 | ||
722 | block : {$<vInt>$ = currState->nlocalvar;} chunk | 723 | block : {$<vInt>$ = L->currState->nlocalvar;} chunk |
723 | { | 724 | { |
724 | adjuststack(currState->nlocalvar - $<vInt>1); | 725 | adjuststack(L->currState->nlocalvar - $<vInt>1); |
725 | for (; currState->nlocalvar > $<vInt>1; currState->nlocalvar--) | 726 | for (; L->currState->nlocalvar > $<vInt>1; L->currState->nlocalvar--) |
726 | luaI_unregisterlocalvar(luaX_linenumber); | 727 | luaI_unregisterlocalvar(L->lexstate->linenumber); |
727 | } | 728 | } |
728 | ; | 729 | ; |
729 | 730 | ||
@@ -753,13 +754,13 @@ ret : /* empty */ | |||
753 | } | 754 | } |
754 | ; | 755 | ; |
755 | 756 | ||
756 | GetPC : /* empty */ { $$ = currState->pc; } | 757 | GetPC : /* empty */ { $$ = L->currState->pc; } |
757 | ; | 758 | ; |
758 | 759 | ||
759 | SaveWord : /* empty */ | 760 | SaveWord : /* empty */ |
760 | { $$ = currState->pc; | 761 | { $$ = L->currState->pc; |
761 | check_pc(JMPSIZE); | 762 | check_pc(JMPSIZE); |
762 | currState->pc += JMPSIZE; /* open space */ | 763 | L->currState->pc += JMPSIZE; /* open space */ |
763 | } | 764 | } |
764 | ; | 765 | ; |
765 | 766 | ||
@@ -808,7 +809,7 @@ functioncall : funcvalue funcParams | |||
808 | { | 809 | { |
809 | code_byte(0); /* save space for opcode */ | 810 | code_byte(0); /* save space for opcode */ |
810 | code_byte($1+$2); /* number of parameters */ | 811 | code_byte($1+$2); /* number of parameters */ |
811 | $$ = currState->pc; | 812 | $$ = L->currState->pc; |
812 | code_byte(0); /* must be adjusted by other rules */ | 813 | code_byte(0); /* must be adjusted by other rules */ |
813 | } | 814 | } |
814 | ; | 815 | ; |
@@ -816,7 +817,7 @@ functioncall : funcvalue funcParams | |||
816 | funcvalue : varexp { $$ = 0; } | 817 | funcvalue : varexp { $$ = 0; } |
817 | | varexp ':' NAME | 818 | | varexp ':' NAME |
818 | { | 819 | { |
819 | code_oparg(PUSHSELF, 0, string_constant($3, currState), 1); | 820 | code_oparg(PUSHSELF, 0, string_constant($3, L->currState), 1); |
820 | $$ = 1; | 821 | $$ = 1; |
821 | } | 822 | } |
822 | ; | 823 | ; |
@@ -834,7 +835,7 @@ exprlist1 : expr { if ($1 != 0) $$ = $1; else $$ = -1; } | |||
834 | { | 835 | { |
835 | if ($4 == 0) $$ = -($<vLong>3 + 1); /* -length */ | 836 | if ($4 == 0) $$ = -($<vLong>3 + 1); /* -length */ |
836 | else { | 837 | else { |
837 | currState->f->code[$4] = $<vLong>3; /* store list length */ | 838 | L->currState->f->code[$4] = $<vLong>3; /* store list length */ |
838 | $$ = $4; | 839 | $$ = $4; |
839 | } | 840 | } |
840 | } | 841 | } |
@@ -899,9 +900,9 @@ varlist1 : var { $$ = 1; add_varbuffer($1, 0); } | |||
899 | | varlist1 ',' var { add_varbuffer($3, $1); $$ = $1+1; } | 900 | | varlist1 ',' var { add_varbuffer($3, $1); $$ = $1+1; } |
900 | ; | 901 | ; |
901 | 902 | ||
902 | var : NAME { $$ = singlevar($1, currState); } | 903 | var : NAME { $$ = singlevar($1, L->currState); } |
903 | | varexp '[' expr1 ']' { $$ = 0; } /* indexed variable */ | 904 | | varexp '[' expr1 ']' { $$ = 0; } /* indexed variable */ |
904 | | varexp '.' NAME { $$ = (-string_constant($3, currState))-1; } | 905 | | varexp '.' NAME { $$ = (-string_constant($3, L->currState))-1; } |
905 | ; | 906 | ; |
906 | 907 | ||
907 | varexp : var { lua_pushvar($1); } | 908 | varexp : var { lua_pushvar($1); } |