aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1997-09-16 16:33:21 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1997-09-16 16:33:21 -0300
commit8cd67ac676fd7ff6c085e1ad6675ba6af0cb1fc3 (patch)
treea428bf2e179afe7d43f3f7c1850aec99234adaa2
parent9828893f7e73f39fa8ad268ca58a94929fa67d5c (diff)
downloadlua-8cd67ac676fd7ff6c085e1ad6675ba6af0cb1fc3.tar.gz
lua-8cd67ac676fd7ff6c085e1ad6675ba6af0cb1fc3.tar.bz2
lua-8cd67ac676fd7ff6c085e1ad6675ba6af0cb1fc3.zip
Syntax analizer and code generator
-rw-r--r--lparser.h20
-rw-r--r--lua.stx771
2 files changed, 444 insertions, 347 deletions
diff --git a/lparser.h b/lparser.h
new file mode 100644
index 00000000..5df77abc
--- /dev/null
+++ b/lparser.h
@@ -0,0 +1,20 @@
1/*
2** $Id: $
3** Syntax analizer and code generator
4** See Copyright Notice in lua.h
5*/
6
7#ifndef lparser_h
8#define lparser_h
9
10#include "lobject.h"
11#include "lzio.h"
12
13
14void luaY_codedebugline (int line);
15TProtoFunc *luaY_parser (ZIO *z, char *chunkname);
16void luaY_error (char *s);
17void luaY_syntaxerror (char *s, char *token);
18
19
20#endif
diff --git a/lua.stx b/lua.stx
index 7c1b748e..fcd8cb65 100644
--- a/lua.stx
+++ b/lua.stx
@@ -1,84 +1,121 @@
1%{ 1%{
2/*
3** $Id: $
4** Syntax analizer and code generator
5** See Copyright Notice in lua.h
6*/
2 7
3char *rcs_luastx = "$Id: lua.stx,v 3.50 1997/07/31 20:46:59 roberto Exp roberto $";
4 8
5#include <stdlib.h> 9#include <stdlib.h>
6 10
7#include "luadebug.h" 11#include "lauxlib.h"
8#include "luamem.h" 12#include "ldo.h"
9#include "lex.h" 13#include "lfunc.h"
10#include "opcode.h" 14#include "lglobal.h"
11#include "hash.h" 15#include "llex.h"
12#include "inout.h" 16#include "lmem.h"
13#include "tree.h" 17#include "lopcodes.h"
14#include "table.h" 18#include "lparser.h"
19#include "lstring.h"
15#include "lua.h" 20#include "lua.h"
16#include "func.h" 21#include "luadebug.h"
22#include "lzio.h"
17 23
18/* to avoid warnings generated by yacc */
19int yyparse (void);
20#define malloc luaI_malloc
21#define realloc luaI_realloc
22#define free luaI_free
23 24
24#ifndef LISTING 25/* to avoid warnings generated by yacc */
25#define LISTING 0 26int luaY_parse (void);
26#endif 27#define malloc luaM_malloc
28#define realloc luaM_realloc
29#define free luaM_free
27 30
28#ifndef CODE_BLOCK
29#define CODE_BLOCK 1000
30#endif
31 31
32/* maximum number of local variables */
32#define MAXLOCALS 32 33#define MAXLOCALS 32
33 34
35/* maximum number of variables in a multiple assignment */
36#define MAXVAR 32
37
38/* maximum number of nested functions */
39#define MAXSTATES 6
40
41/* maximum number of upvalues */
42#define MAXUPVALUES 8
43
44/*
45** Variable descriptor: if n>0, represents global variable indexed
46** by (n-1); if n<0, represents local variable index (-n)-1;
47** if n==0, represents an indexed variable (table and index on top of stack)
48** Must be long to store negative Word values.
49*/
50typedef long vardesc;
51
52
34/* state needed to generate code for a given function */ 53/* state needed to generate code for a given function */
35struct State { 54static struct State {
36 TFunc *f; /* current function header */ 55 TProtoFunc *f; /* current function header */
37 int codesize;
38 int pc; /* next position to code */ 56 int pc; /* next position to code */
39 TaggedString *localvar[MAXLOCALS]; /* store local variable names */ 57 TaggedString *localvar[MAXLOCALS]; /* store local variable names */
58 int stacksize; /* number of values on activation register */
59 int maxstacksize; /* maximum number of values on activation register */
40 int nlocalvar; /* number of active local variables */ 60 int nlocalvar; /* number of active local variables */
41 int maxconsts; /* size of consts vector */ 61 int nvars; /* number of entries in f->locvars */
42 int nvars; /* total number of local variables (for debugging information) */ 62 int maxcode; /* size of f->code */
43 int maxvars; /* = -1 if no debug information */ 63 int maxvars; /* size of f->locvars (-1 if no debug information) */
44} stateMain, stateFunc, *currState; 64 int maxconsts; /* size of f->consts */
45 65 vardesc varbuffer[MAXVAR]; /* variables in an assignment list */
46 66 vardesc upvalues[MAXUPVALUES]; /* upvalues */
47#define MAXVAR 32 67} *mainState, *currState;
48static Long varbuffer[MAXVAR]; /* variables in an assignment list;
49 it's long to store negative Word values */
50static int nvarbuffer=0; /* number of variables at a list */
51 68
52 69
53int lua_debug = 0;
54 70
55/* Internal functions */
56 71
57static void yyerror (char *s) 72void luaY_syntaxerror (char *s, char *token)
58{ 73{
59 luaI_syntaxerror(s); 74 if (token[0] == 0)
75 token = "<eof>";
76 luaL_verror("%.100s;\n> last token read: \"%.50s\" at line %d in file %.50s",
77 s, token, luaX_linenumber, mainState->f->fileName->str);
60} 78}
61 79
62static void check_space (int i) 80
81void luaY_error (char *s)
63{ 82{
64 if (currState->pc+i >= currState->codesize) 83 luaY_syntaxerror(s, luaX_lasttoken());
65 currState->codesize = growvector(&currState->f->code, currState->codesize,
66 Byte, codeEM, MAX_INT);
67} 84}
68 85
69 86
70static void code_byte (Byte c) 87static void code_byte (Byte c)
71{ 88{
72 check_space(1); 89 if (currState->pc >= currState->maxcode)
90 currState->maxcode = luaM_growvector(&currState->f->code,
91 currState->maxcode, Byte, codeEM, MAX_INT);
73 currState->f->code[currState->pc++] = c; 92 currState->f->code[currState->pc++] = c;
74} 93}
75 94
76 95
96static void deltastack (int delta)
97{
98 currState->stacksize += delta;
99 if (currState->stacksize > currState->maxstacksize) {
100 if (currState->stacksize > 255)
101 luaY_error("expression too complex");
102 currState->maxstacksize = currState->stacksize;
103 }
104}
105
106
107static void code_opcode (OpCode op, int delta)
108{
109 code_byte(op);
110 deltastack(delta);
111}
112
113
77static void code_word_at (int pc, int n) 114static void code_word_at (int pc, int n)
78{ 115{
79 Word w = n; 116 Word w = n;
80 if (w != n) 117 if (w != n)
81 yyerror("block too big"); 118 luaY_error("block too big");
82 currState->f->code[pc] = n&0xFF; 119 currState->f->code[pc] = n&0xFF;
83 currState->f->code[pc+1] = n>>8; 120 currState->f->code[pc+1] = n>>8;
84} 121}
@@ -92,11 +129,11 @@ static void code_word (int n)
92static void code_constant (int c) 129static void code_constant (int c)
93{ 130{
94 if (c <= 255) { 131 if (c <= 255) {
95 code_byte(PUSHCONSTANTB); 132 code_opcode(PUSHCONSTANTB, 1);
96 code_byte(c); 133 code_byte(c);
97 } 134 }
98 else { 135 else {
99 code_byte(PUSHCONSTANT); 136 code_opcode(PUSHCONSTANT, 1);
100 code_word(c); 137 code_word(c);
101 } 138 }
102} 139}
@@ -104,10 +141,10 @@ static void code_constant (int c)
104 141
105static int next_constant (void) 142static int next_constant (void)
106{ 143{
107 TFunc *f = currState->f; 144 TProtoFunc *f = currState->f;
108 if (f->nconsts >= currState->maxconsts) { 145 if (f->nconsts >= currState->maxconsts) {
109 currState->maxconsts = 146 currState->maxconsts =
110 growvector(&f->consts, currState->maxconsts, TObject, 147 luaM_growvector(&f->consts, currState->maxconsts, TObject,
111 constantEM, MAX_WORD); 148 constantEM, MAX_WORD);
112 } 149 }
113 return f->nconsts++; 150 return f->nconsts++;
@@ -116,7 +153,7 @@ static int next_constant (void)
116 153
117static int string_constant (TaggedString *s) 154static int string_constant (TaggedString *s)
118{ 155{
119 TFunc *f = currState->f; 156 TProtoFunc *f = currState->f;
120 int c = s->u.s.constindex; 157 int c = s->u.s.constindex;
121 if (!(0 <= c && c < f->nconsts && 158 if (!(0 <= c && c < f->nconsts &&
122 ttype(&f->consts[c]) == LUA_T_STRING && tsvalue(&f->consts[c]) == s)) { 159 ttype(&f->consts[c]) == LUA_T_STRING && tsvalue(&f->consts[c]) == s)) {
@@ -125,7 +162,6 @@ static int string_constant (TaggedString *s)
125 tsvalue(&f->consts[c]) = s; 162 tsvalue(&f->consts[c]) = s;
126 s->u.s.constindex = c; /* hint for next time */ 163 s->u.s.constindex = c; /* hint for next time */
127 } 164 }
128 luaI_releasestring(s);
129 return c; 165 return c;
130} 166}
131 167
@@ -136,7 +172,7 @@ static void code_string (TaggedString *s)
136} 172}
137 173
138 174
139#define LIM 10 175#define LIM 13
140static int real_constant (real r) 176static int real_constant (real r)
141{ 177{
142 /* check whether 'r' has appeared within the last LIM entries */ 178 /* check whether 'r' has appeared within the last LIM entries */
@@ -147,7 +183,7 @@ static int real_constant (real r)
147 if (ttype(&cnt[c]) == LUA_T_NUMBER && nvalue(&cnt[c]) == r) 183 if (ttype(&cnt[c]) == LUA_T_NUMBER && nvalue(&cnt[c]) == r)
148 return c; 184 return c;
149 } 185 }
150 /* not found; create a new entry */ 186 /* not found; create a luaM_new entry */
151 c = next_constant(); 187 c = next_constant();
152 cnt = currState->f->consts; /* 'next_constant' may reallocate this vector */ 188 cnt = currState->f->consts; /* 'next_constant' may reallocate this vector */
153 ttype(&cnt[c]) = LUA_T_NUMBER; 189 ttype(&cnt[c]) = LUA_T_NUMBER;
@@ -157,17 +193,17 @@ static int real_constant (real r)
157 193
158 194
159static void code_number (real f) 195static void code_number (real f)
160{ 196{
161 Word i; 197 Word i;
162 if (f >= 0 && f <= (real)MAX_WORD && (real)(i=(Word)f) == f) { 198 if (f >= 0 && f <= (real)MAX_WORD && (real)(i=(Word)f) == f) {
163 /* f has an (short) integer value */ 199 /* f has an (short) integer value */
164 if (i <= 2) code_byte(PUSH0 + i); 200 if (i <= 2) code_opcode(PUSH0 + i, 1);
165 else if (i <= 255) { 201 else if (i <= 255) {
166 code_byte(PUSHBYTE); 202 code_opcode(PUSHBYTE, 1);
167 code_byte(i); 203 code_byte(i);
168 } 204 }
169 else { 205 else {
170 code_byte(PUSHWORD); 206 code_opcode(PUSHWORD, 1);
171 code_word(i); 207 code_word(i);
172 } 208 }
173 } 209 }
@@ -179,7 +215,7 @@ static void code_number (real f)
179static void flush_record (int n) 215static void flush_record (int n)
180{ 216{
181 if (n == 0) return; 217 if (n == 0) return;
182 code_byte(STOREMAP); 218 code_opcode(SETMAP, -2*n);
183 code_byte(n); 219 code_byte(n);
184} 220}
185 221
@@ -187,15 +223,13 @@ static void flush_list (int m, int n)
187{ 223{
188 if (n == 0) return; 224 if (n == 0) return;
189 if (m == 0) 225 if (m == 0)
190 code_byte(STORELIST0); 226 code_opcode(SETLIST0, -n);
191 else 227 else if (m < 255) {
192 if (m < 255) 228 code_opcode(SETLIST, -n);
193 {
194 code_byte(STORELIST);
195 code_byte(m); 229 code_byte(m);
196 } 230 }
197 else 231 else
198 yyerror ("list constructor too long"); 232 luaY_error("list constructor too long");
199 code_byte(n); 233 code_byte(n);
200} 234}
201 235
@@ -204,7 +238,7 @@ static void luaI_registerlocalvar (TaggedString *varname, int line)
204{ 238{
205 if (currState->maxvars != -1) { /* debug information? */ 239 if (currState->maxvars != -1) { /* debug information? */
206 if (currState->nvars >= currState->maxvars) 240 if (currState->nvars >= currState->maxvars)
207 currState->maxvars = growvector(&currState->f->locvars, 241 currState->maxvars = luaM_growvector(&currState->f->locvars,
208 currState->maxvars, LocVar, "", MAX_WORD); 242 currState->maxvars, LocVar, "", MAX_WORD);
209 currState->f->locvars[currState->nvars].varname = varname; 243 currState->f->locvars[currState->nvars].varname = varname;
210 currState->f->locvars[currState->nvars].line = line; 244 currState->f->locvars[currState->nvars].line = line;
@@ -221,12 +255,11 @@ static void luaI_unregisterlocalvar (int line)
221 255
222static void store_localvar (TaggedString *name, int n) 256static void store_localvar (TaggedString *name, int n)
223{ 257{
224 luaI_fixstring(name); /* local var names cannot be GC */
225 if (currState->nlocalvar+n < MAXLOCALS) 258 if (currState->nlocalvar+n < MAXLOCALS)
226 currState->localvar[currState->nlocalvar+n] = name; 259 currState->localvar[currState->nlocalvar+n] = name;
227 else 260 else
228 yyerror ("too many local variables"); 261 luaY_error("too many local variables");
229 luaI_registerlocalvar(name, lua_linenumber); 262 luaI_registerlocalvar(name, luaX_linenumber);
230} 263}
231 264
232static void add_localvar (TaggedString *name) 265static void add_localvar (TaggedString *name)
@@ -235,165 +268,202 @@ static void add_localvar (TaggedString *name)
235 currState->nlocalvar++; 268 currState->nlocalvar++;
236} 269}
237 270
238static void add_varbuffer (Long var) 271static void add_varbuffer (vardesc var, int n)
239{ 272{
240 if (nvarbuffer < MAXVAR) 273 if (n >= MAXVAR)
241 varbuffer[nvarbuffer++] = var; 274 luaY_error("variable buffer overflow");
242 else 275 currState->varbuffer[n] = var;
243 yyerror ("variable buffer overflow");
244} 276}
245 277
246 278
247/* 279static int aux_localname (TaggedString *n, struct State *st)
248** Search a local name and if find return its index. If do not find return -1
249*/
250static int lua_localname (TaggedString *n)
251{ 280{
252 int i; 281 int i;
253 for (i=currState->nlocalvar-1; i >= 0; i--) 282 for (i=st->nlocalvar-1; i >= 0; i--)
254 if (n == currState->localvar[i]) return i; /* local var */ 283 if (n == st->localvar[i]) return i; /* local var index */
255 return -1; /* global var */ 284 return -1; /* not found */
256} 285}
257 286
258/* 287
259** Push a variable given a number. If number is positive, push global variable 288static vardesc singlevar (TaggedString *n, struct State *st)
260** indexed by (number -1). If negative, push local indexed by ABS(number)-1. 289{
261** Otherwise, if zero, push indexed variable (record). 290 int i = aux_localname(n, st);
262*/ 291 if (i == -1) { /* check shadowing */
263static void lua_pushvar (Long number) 292 int l;
264{ 293 for (l=1; l<=(st-mainState); l++)
265 if (number > 0) /* global var */ 294 if (aux_localname(n, st-l) >= 0)
266 { 295 luaY_syntaxerror("cannot access a variable in outer scope", n->str);
267 code_byte(PUSHGLOBAL); 296 return luaG_findsymbol(n)+1; /* positive value */
268 code_word(number-1);
269 }
270 else if (number < 0) /* local var */
271 {
272 number = (-number) - 1;
273 if (number < 10) code_byte(PUSHLOCAL0 + number);
274 else
275 {
276 code_byte(PUSHLOCAL);
277 code_byte(number);
278 } 297 }
279 } 298 else return -(i+1); /* negative value */
280 else
281 {
282 code_byte(PUSHINDEXED);
283 }
284} 299}
285 300
286static void lua_codeadjust (int n) 301
302static int indexupvalue (TaggedString *n)
287{ 303{
288 n += currState->nlocalvar; 304 vardesc v = singlevar(n, currState-1);
289 if (n == 0) 305 int i;
290 code_byte(ADJUST0); 306 for (i=0; i<currState->f->nupvalues; i++) {
291 else { 307 if (currState->upvalues[i] == v)
292 code_byte(ADJUST); 308 return i;
293 code_byte(n);
294 } 309 }
310 /* new one */
311 if (++currState->f->nupvalues > MAXUPVALUES)
312 luaY_error("too many upvalues in a single function");
313 currState->upvalues[i] = v; /* i = currState->f->nupvalues - 1 */
314 return i;
295} 315}
296 316
297 317
318static void pushupvalue (TaggedString *n)
319{
320 int i;
321 if (currState == mainState)
322 luaY_error("cannot access upvalue in main");
323 if (aux_localname(n, currState) >= 0)
324 luaY_syntaxerror("cannot access an upvalue in current scope", n->str);
325 i = indexupvalue(n);
326 if (i == 0)
327 code_opcode(PUSHUPVALUE0, 1);
328 else {
329 code_opcode(PUSHUPVALUE, 1);
330 code_byte(i);
331 }
332}
333
298 334
299void luaI_codedebugline (int line) 335void luaY_codedebugline (int line)
300{ 336{
301 static int lastline = 0; 337 static int lastline = 0;
302 if (lua_debug && line != lastline) 338 if (lua_debug && line != lastline) {
303 { 339 code_opcode(SETLINE, 0);
304 code_byte(SETLINE);
305 code_word(line); 340 code_word(line);
306 lastline = line; 341 lastline = line;
307 } 342 }
308} 343}
309 344
310static int adjust_functioncall (Long exp, int i) 345
346static void adjuststack (int n)
347{
348 if (n > 0) {
349 code_opcode(POPS, -n);
350 code_byte(n);
351 }
352 else if (n < 0) {
353 if (n == -1)
354 code_opcode(PUSHNIL, 1);
355 else {
356 code_opcode(PUSHNILS, -n);
357 code_byte(-n);
358 }
359 }
360}
361
362
363static long adjust_functioncall (long exp, int i)
311{ 364{
312 if (exp <= 0) 365 if (exp <= 0)
313 return -exp; /* exp is -list length */ 366 return -exp; /* exp is -list length */
314 else { 367 else {
315 int temp = currState->f->code[exp]; 368 int temp = currState->f->code[exp];
316 currState->f->code[exp] = i; 369 currState->f->code[exp] = i;
370 if (i != MULT_RET)
371 deltastack(i);
317 return temp+i; 372 return temp+i;
318 } 373 }
319} 374}
320 375
321static void adjust_mult_assign (int vars, Long exps, int temps) 376
377static void adjust_mult_assign (int vars, long exps)
322{ 378{
323 if (exps > 0) { /* must correct function call */ 379 if (exps > 0) { /* must correct function call */
324 int diff = vars - currState->f->code[exps]; 380 int diff = currState->f->code[exps] - vars;
325 if (diff >= 0) 381 if (diff < 0)
326 adjust_functioncall(exps, diff); 382 adjust_functioncall(exps, -diff);
327 else { 383 else {
328 adjust_functioncall(exps, 0); 384 adjust_functioncall(exps, 0);
329 lua_codeadjust(temps); 385 adjuststack(diff);
330 } 386 }
331 } 387 }
332 else if (vars != -exps) 388 else adjuststack((-exps)-vars);
333 lua_codeadjust(temps);
334} 389}
335 390
336static int close_parlist (int dots) 391
392static void code_args (int dots)
337{ 393{
338 if (!dots) 394 if (!dots) {
339 lua_codeadjust(0); 395 code_opcode(ARGS, currState->nlocalvar);
396 code_byte(currState->nlocalvar);
397 }
340 else { 398 else {
341 code_byte(VARARGS); 399 code_opcode(VARARGS, currState->nlocalvar+1);
342 code_byte(currState->nlocalvar); 400 code_byte(currState->nlocalvar);
343 add_localvar(luaI_createstring("arg")); 401 add_localvar(luaS_new("arg"));
344 } 402 }
345 return lua_linenumber; 403}
346} 404
347 405
348 406static void lua_pushvar (vardesc number)
349static void storesinglevar (Long v) 407{
350{ 408 if (number > 0) { /* global var */
351 if (v > 0) /* global var */ 409 code_opcode(PUSHGLOBAL, 1);
352 { 410 code_word(number-1);
353 code_byte(STOREGLOBAL); 411 }
354 code_word(v-1); 412 else if (number < 0) { /* local var */
355 } 413 number = (-number) - 1;
356 else if (v < 0) /* local var */ 414 if (number < 10)
357 { 415 code_opcode(PUSHLOCAL0 + number, 1);
358 int number = (-v) - 1; 416 else {
359 if (number < 10) code_byte(STORELOCAL0 + number); 417 code_opcode(PUSHLOCAL, 1);
360 else 418 code_byte(number);
361 { 419 }
362 code_byte(STORELOCAL); 420 }
363 code_byte(number); 421 else {
364 } 422 code_opcode(PUSHTABLE, -1);
365 }
366 else
367 code_byte(STOREINDEXED0);
368}
369
370
371static void lua_codestore (int i)
372{
373 if (varbuffer[i] != 0) /* global or local var */
374 storesinglevar(varbuffer[i]);
375 else /* indexed var */
376 {
377 int j;
378 int upper=0; /* number of indexed variables upper */
379 int param; /* number of itens until indexed expression */
380 for (j=i+1; j <nvarbuffer; j++)
381 if (varbuffer[j] == 0) upper++;
382 param = upper*2 + i;
383 if (param == 0)
384 code_byte(STOREINDEXED0);
385 else
386 {
387 code_byte(STOREINDEXED);
388 code_byte(param);
389 } 423 }
390 }
391} 424}
392 425
393static void codeIf (Long thenAdd, Long elseAdd) 426
427static void storevar (vardesc number)
428{
429 if (number == 0) /* indexed var */
430 code_opcode(SETTABLE0, -3);
431 else if (number > 0) { /* global var */
432 code_opcode(SETGLOBAL, -1);
433 code_word(number-1);
434 }
435 else { /* number < 0 - local var */
436 number = (-number) - 1;
437 if (number < 10)
438 code_opcode(SETLOCAL0 + number, -1);
439 else {
440 code_opcode(SETLOCAL, -1);
441 code_byte(number);
442 }
443 }
444}
445
446
447/* returns how many elements are left as 'garbage' on the stack */
448static int lua_codestore (int i, int left)
394{ 449{
395 Long elseinit = elseAdd+sizeof(Word)+1; 450 if (currState->varbuffer[i] != 0 || /* global or local var or */
396 if (currState->pc == elseinit) { /* no else */ 451 left+i == 0) { /* indexed var without values in between */
452 storevar(currState->varbuffer[i]);
453 return left;
454 }
455 else { /* indexed var with values in between*/
456 code_opcode(SETTABLE, -1);
457 code_byte(left+i); /* number of elements between table/index and value */
458 return left+2; /* table/index are not poped, since they are not on top */
459 }
460}
461
462
463static void codeIf (int thenAdd, int elseAdd)
464{
465 int elseinit = elseAdd+sizeof(Word)+1;
466 if (currState->pc == elseinit) { /* no else part */
397 currState->pc -= sizeof(Word)+1; 467 currState->pc -= sizeof(Word)+1;
398 elseinit = currState->pc; 468 elseinit = currState->pc;
399 } 469 }
@@ -413,13 +483,39 @@ static void code_shortcircuit (int pc, Byte jmp)
413} 483}
414 484
415 485
416static void init_state (TFunc *f) 486static void codereturn (void)
417{ 487{
488 code_opcode(RETCODE, 0);
489 code_byte(currState->nlocalvar);
490 currState->stacksize = currState->nlocalvar;
491}
492
493
494static void func_onstack (TProtoFunc *f)
495{
496 int i;
497 int nupvalues = (currState+1)->f->nupvalues;
498 int c = next_constant();
499 ttype(&currState->f->consts[c]) = LUA_T_PROTO;
500 currState->f->consts[c].value.tf = (currState+1)->f;
501 for (i=0; i<nupvalues; i++)
502 lua_pushvar((currState+1)->upvalues[i]);
503 code_constant(c);
504 code_opcode(CLOSURE, -nupvalues);
505}
506
507
508static void init_state (TaggedString *filename)
509{
510 TProtoFunc *f = luaF_newproto();
511 currState->stacksize = 0;
512 currState->maxstacksize = 0;
418 currState->nlocalvar = 0; 513 currState->nlocalvar = 0;
419 currState->f = f; 514 currState->f = f;
515 f->fileName = filename;
420 currState->pc = 0; 516 currState->pc = 0;
421 currState->codesize = CODE_BLOCK; 517 currState->maxcode = 0;
422 f->code = newvector(CODE_BLOCK, Byte); 518 f->code = NULL;
423 currState->maxconsts = 0; 519 currState->maxconsts = 0;
424 if (lua_debug) { 520 if (lua_debug) {
425 currState->nvars = 0; 521 currState->nvars = 0;
@@ -427,74 +523,63 @@ static void init_state (TFunc *f)
427 } 523 }
428 else 524 else
429 currState->maxvars = -1; /* flag no debug information */ 525 currState->maxvars = -1; /* flag no debug information */
526 code_byte(0); /* to be filled with stacksize */
430} 527}
431 528
432 529
433static void init_func (Long v) 530static void init_func (void)
434{ 531{
435 TFunc *f = new(TFunc); 532 if (currState-mainState >= MAXSTATES-1)
436 int c = next_constant(); 533 luaY_error("too many nested functions");
437 ttype(&currState->f->consts[c]) = LUA_T_FUNCTION; 534 currState++;
438 currState->f->consts[c].value.tf = f; 535 init_state(mainState->f->fileName);
439 code_constant(c); 536 luaY_codedebugline(luaX_linenumber);
440 storesinglevar(v); 537 currState->f->lineDefined = luaX_linenumber;
441 currState = &stateFunc;
442 luaI_initTFunc(f);
443 init_state(f);
444 luaI_codedebugline(lua_linenumber);
445} 538}
446 539
447 540
448static void codereturn (void)
449{
450 if (currState->nlocalvar == 0)
451 code_byte(RETCODE0);
452 else
453 {
454 code_byte(RETCODE);
455 code_byte(currState->nlocalvar);
456 }
457}
458
459 541
460static void close_func (void) 542static TProtoFunc *close_func (void)
461{ 543{
462 codereturn(); 544 TProtoFunc *f = currState->f;
463 code_byte(ENDCODE); 545 code_opcode(ENDCODE, 0);
464 currState->f->code = shrinkvector(currState->f->code, currState->pc, Byte); 546 f->code[0] = currState->maxstacksize;
465 currState->f->consts = shrinkvector(currState->f->consts, 547 f->code = luaM_reallocvector(f->code, currState->pc, Byte);
466 currState->f->nconsts, TObject); 548 f->consts = luaM_reallocvector(f->consts, f->nconsts, TObject);
467 if (currState->maxvars != -1) { /* debug information? */ 549 if (currState->maxvars != -1) { /* debug information? */
468 luaI_registerlocalvar(NULL, -1); /* flag end of vector */ 550 luaI_registerlocalvar(NULL, -1); /* flag end of vector */
469 currState->f->locvars = shrinkvector(currState->f->locvars, 551 f->locvars = luaM_reallocvector(f->locvars, currState->nvars, LocVar);
470 currState->nvars, LocVar);
471 } 552 }
553 currState--;
554 return f;
472} 555}
473 556
474 557
475/* 558/*
476** Parse LUA code. 559** Parse LUA code.
477*/ 560*/
478void lua_parse (TFunc *tf) 561TProtoFunc *luaY_parser (ZIO *z, char *chunkname)
479{ 562{
480 currState = &stateMain; 563 struct State state[MAXSTATES];
481 init_state(tf); 564 currState = mainState = &state[0];
482 if (yyparse ()) lua_error("parse error"); 565 luaX_setinput(z);
483 currState = &stateMain; 566 init_state(luaS_new(chunkname));
484 close_func(); 567 if (luaY_parse ()) lua_error("parse error");
568 return close_func();
485} 569}
486 570
487 571
488%} 572%}
489 573
490 574
491%union 575%union
492{ 576{
493 int vInt; 577 int vInt;
494 real vReal; 578 real vReal;
495 char *pChar; 579 char *pChar;
496 Long vLong; 580 long vLong;
497 TaggedString *pTStr; 581 TaggedString *pTStr;
582 TProtoFunc *pFunc;
498} 583}
499 584
500%start chunk 585%start chunk
@@ -509,7 +594,7 @@ void lua_parse (TFunc *tf)
509%token <vReal> NUMBER 594%token <vReal> NUMBER
510%token <pTStr> NAME STRING 595%token <pTStr> NAME STRING
511 596
512%type <vLong> PrepJump 597%type <vInt> PrepJump, PrepJumpPop
513%type <vLong> exprlist, exprlist1 /* if > 0, points to function return 598%type <vLong> exprlist, exprlist1 /* if > 0, points to function return
514 counter (which has list length); if <= 0, -list lenght */ 599 counter (which has list length); if <= 0, -list lenght */
515%type <vLong> functioncall, expr /* if != 0, points to function return 600%type <vLong> functioncall, expr /* if != 0, points to function return
@@ -518,8 +603,10 @@ void lua_parse (TFunc *tf)
518%type <vInt> fieldlist, localdeclist, decinit 603%type <vInt> fieldlist, localdeclist, decinit
519%type <vInt> ffieldlist, ffieldlist1, semicolonpart 604%type <vInt> ffieldlist, ffieldlist1, semicolonpart
520%type <vInt> lfieldlist, lfieldlist1 605%type <vInt> lfieldlist, lfieldlist1
521%type <vInt> parlist, parlist1, par 606%type <vInt> parlist1, par
522%type <vLong> var, singlevar 607%type <vLong> var, singlevar, funcname /* vardesc */
608%type <pFunc> body
609
523 610
524%left AND OR 611%left AND OR
525%left EQ NE '>' '<' LE GE 612%left EQ NE '>' '<' LE GE
@@ -532,89 +619,82 @@ void lua_parse (TFunc *tf)
532 619
533%% /* beginning of rules section */ 620%% /* beginning of rules section */
534 621
535chunk : chunklist ret ;
536
537chunklist : /* empty */
538 | chunklist stat sc
539 | chunklist function
540 ;
541 622
542function : FUNCTION funcname body 623chunk : statlist ret
543 ; 624 ;
544
545funcname : var { init_func($1); }
546 | varexp ':' NAME
547 {
548 code_string($3);
549 init_func(0); /* indexed variable */
550 add_localvar(luaI_createstring("self"));
551 }
552 ;
553
554body : '(' parlist ')' block END
555 {
556 close_func();
557 currState->f->lineDefined = $2;
558 currState = &stateMain; /* change back to main code */
559 }
560 ;
561 625
562statlist : /* empty */ 626statlist : /* empty */
563 | statlist stat sc 627 | statlist stat sc { if (currState->stacksize != currState->nlocalvar)
628 { luaY_error("contagem"); exit(1); }}
564 ; 629 ;
565 630
566sc : /* empty */ | ';' ; 631sc : /* empty */ | ';' ;
567 632
568stat : IF expr1 THEN PrepJump block PrepJump elsepart END 633stat : IF expr1 THEN PrepJumpPop block PrepJump elsepart END
569 { codeIf($4, $6); } 634 { codeIf($4, $6); }
570 635
571 | WHILE {$<vLong>$=currState->pc;} expr1 DO PrepJump block PrepJump END 636 | WHILE {$<vInt>$=currState->pc;} expr1 DO PrepJumpPop block PrepJump END
572 { 637 {
573 currState->f->code[$5] = IFFJMP; 638 currState->f->code[$5] = IFFJMP;
574 code_word_at($5+1, currState->pc - ($5+sizeof(Word)+1)); 639 code_word_at($5+1, currState->pc - ($5+sizeof(Word)+1));
575 currState->f->code[$7] = UPJMP; 640 currState->f->code[$7] = UPJMP;
576 code_word_at($7+1, currState->pc - ($<vLong>2)); 641 code_word_at($7+1, currState->pc - ($<vInt>2));
577 } 642 }
578 643
579 | REPEAT {$<vLong>$=currState->pc;} block UNTIL expr1 PrepJump 644 | REPEAT {$<vInt>$=currState->pc;} block UNTIL expr1 PrepJumpPop
580 { 645 {
581 currState->f->code[$6] = IFFUPJMP; 646 currState->f->code[$6] = IFFUPJMP;
582 code_word_at($6+1, currState->pc - ($<vLong>2)); 647 code_word_at($6+1, currState->pc - ($<vInt>2));
583 } 648 }
584 649
585 | varlist1 '=' exprlist1 650 | varlist1 '=' exprlist1
586 { 651 {{
587 { 652 int i;
588 int i; 653 int left = 0;
589 adjust_mult_assign(nvarbuffer, $3, $1 * 2 + nvarbuffer); 654 adjust_mult_assign($1, $3);
590 for (i=nvarbuffer-1; i>=0; i--) 655 for (i=$1-1; i>=0; i--)
591 lua_codestore(i); 656 left = lua_codestore(i, left);
592 if ($1 > 1 || ($1 == 1 && varbuffer[0] != 0)) 657 adjuststack(left); /* remove eventual 'garbage' left on stack */
593 lua_codeadjust(0); 658 }}
594 } 659 | functioncall
595 }
596 | functioncall {;}
597 | LOCAL localdeclist decinit 660 | LOCAL localdeclist decinit
598 { currState->nlocalvar += $2; 661 {
599 adjust_mult_assign($2, $3, 0); 662 currState->nlocalvar += $2;
600 } 663 adjust_mult_assign($2, $3);
664 }
665 | FUNCTION funcname body
666 {
667 func_onstack($3);
668 storevar($2);
669 }
601 ; 670 ;
602 671
672block : {$<vInt>$ = currState->nlocalvar;} chunk
673 {
674 adjuststack(currState->nlocalvar - $<vInt>1);
675 for (; currState->nlocalvar > $<vInt>1; currState->nlocalvar--)
676 luaI_unregisterlocalvar(luaX_linenumber);
677 }
678 ;
679
680funcname : var { init_func(); $$ = $1; }
681 | varexp ':' NAME
682 {
683 code_string($3);
684 $$ = 0; /* indexed variable */
685 init_func();
686 add_localvar(luaS_new("self"));
687 }
688 ;
689
690body : '(' parlist ')' chunk END { $$ = close_func(); }
691 ;
692
603elsepart : /* empty */ 693elsepart : /* empty */
604 | ELSE block 694 | ELSE block
605 | ELSEIF expr1 THEN PrepJump block PrepJump elsepart 695 | ELSEIF expr1 THEN PrepJumpPop block PrepJump elsepart
606 { codeIf($4, $6); } 696 { codeIf($4, $6); }
607 ; 697 ;
608
609block : {$<vInt>$ = currState->nlocalvar;} statlist ret
610 {
611 if (currState->nlocalvar != $<vInt>1) {
612 for (; currState->nlocalvar > $<vInt>1; currState->nlocalvar--)
613 luaI_unregisterlocalvar(lua_linenumber);
614 lua_codeadjust(0);
615 }
616 }
617 ;
618 698
619ret : /* empty */ 699ret : /* empty */
620 | RETURN exprlist sc 700 | RETURN exprlist sc
@@ -625,30 +705,33 @@ ret : /* empty */
625 ; 705 ;
626 706
627PrepJump : /* empty */ 707PrepJump : /* empty */
628 { 708 {
629 $$ = currState->pc; 709 $$ = currState->pc;
630 code_byte(0); /* open space */ 710 code_opcode(0, 0); /* open space */
631 code_word(0); 711 code_word(0);
632 } 712 }
633 ; 713 ;
634 714
715PrepJumpPop : PrepJump { $$ = $1; deltastack(-1); /* pop condition */ }
716 ;
717
635expr1 : expr { adjust_functioncall($1, 1); } 718expr1 : expr { adjust_functioncall($1, 1); }
636 ; 719 ;
637 720
638expr : '(' expr ')' { $$ = $2; } 721expr : '(' expr ')' { $$ = $2; }
639 | expr1 EQ expr1 { code_byte(EQOP); $$ = 0; } 722 | expr1 EQ expr1 { code_opcode(EQOP, -1); $$ = 0; }
640 | expr1 '<' expr1 { code_byte(LTOP); $$ = 0; } 723 | expr1 '<' expr1 { code_opcode(LTOP, -1); $$ = 0; }
641 | expr1 '>' expr1 { code_byte(GTOP); $$ = 0; } 724 | expr1 '>' expr1 { code_opcode(GTOP, -1); $$ = 0; }
642 | expr1 NE expr1 { code_byte(EQOP); code_byte(NOTOP); $$ = 0; } 725 | expr1 NE expr1 { code_opcode(NEQOP, -1); $$ = 0; }
643 | expr1 LE expr1 { code_byte(LEOP); $$ = 0; } 726 | expr1 LE expr1 { code_opcode(LEOP, -1); $$ = 0; }
644 | expr1 GE expr1 { code_byte(GEOP); $$ = 0; } 727 | expr1 GE expr1 { code_opcode(GEOP, -1); $$ = 0; }
645 | expr1 '+' expr1 { code_byte(ADDOP); $$ = 0; } 728 | expr1 '+' expr1 { code_opcode(ADDOP, -1); $$ = 0; }
646 | expr1 '-' expr1 { code_byte(SUBOP); $$ = 0; } 729 | expr1 '-' expr1 { code_opcode(SUBOP, -1); $$ = 0; }
647 | expr1 '*' expr1 { code_byte(MULTOP); $$ = 0; } 730 | expr1 '*' expr1 { code_opcode(MULTOP, -1); $$ = 0; }
648 | expr1 '/' expr1 { code_byte(DIVOP); $$ = 0; } 731 | expr1 '/' expr1 { code_opcode(DIVOP, -1); $$ = 0; }
649 | expr1 '^' expr1 { code_byte(POWOP); $$ = 0; } 732 | expr1 '^' expr1 { code_opcode(POWOP, -1); $$ = 0; }
650 | expr1 CONC expr1 { code_byte(CONCOP); $$ = 0; } 733 | expr1 CONC expr1 { code_opcode(CONCOP, -1); $$ = 0; }
651 | '-' expr1 %prec UNARY { code_byte(MINUSOP); $$ = 0;} 734 | '-' expr1 %prec UNARY { code_opcode(MINUSOP, 0); $$ = 0;}
652 | table { $$ = 0; } 735 | table { $$ = 0; }
653 | varexp { $$ = 0;} 736 | varexp { $$ = 0;}
654 | NUMBER { code_number($1); $$ = 0; } 737 | NUMBER { code_number($1); $$ = 0; }
@@ -657,45 +740,46 @@ expr : '(' expr ')' { $$ = $2; }
657 code_string($1); 740 code_string($1);
658 $$ = 0; 741 $$ = 0;
659 } 742 }
660 | NIL {code_byte(PUSHNIL); $$ = 0; } 743 | NIL {code_opcode(PUSHNIL, 1); $$ = 0; }
661 | functioncall { $$ = $1; } 744 | functioncall { $$ = $1; }
662 | NOT expr1 { code_byte(NOTOP); $$ = 0;} 745 | NOT expr1 { code_opcode(NOTOP, 0); $$ = 0;}
663 | expr1 AND PrepJump expr1 746 | expr1 AND PrepJumpPop expr1
664 { 747 {
665 code_shortcircuit($3, ONFJMP); 748 code_shortcircuit($3, ONFJMP);
666 $$ = 0; 749 $$ = 0;
667 } 750 }
668 | expr1 OR PrepJump expr1 751 | expr1 OR PrepJumpPop expr1
669 { 752 {
670 code_shortcircuit($3, ONTJMP); 753 code_shortcircuit($3, ONTJMP);
671 $$ = 0; 754 $$ = 0;
672 } 755 }
756 | FUNCTION { init_func(); } body { func_onstack($3); $$ = 0; }
673 ; 757 ;
674 758
675table : 759table :
676 { 760 {
677 code_byte(CREATEARRAY); 761 code_opcode(CREATEARRAY, 1);
678 $<vLong>$ = currState->pc; code_word(0); 762 $<vInt>$ = currState->pc; code_word(0);
679 } 763 }
680 '{' fieldlist '}' 764 '{' fieldlist '}'
681 { 765 {
682 code_word_at($<vLong>1, $3); 766 code_word_at($<vInt>1, $3);
683 } 767 }
684 ; 768 ;
685 769
686functioncall : funcvalue funcParams 770functioncall : funcvalue funcParams
687 { 771 {
688 code_byte(CALLFUNC); 772 code_opcode(CALLFUNC, -($1+$2+1)); /* ajdust counts results */
689 code_byte($1+$2); 773 code_byte($1+$2);
690 $$ = currState->pc; 774 $$ = currState->pc;
691 code_byte(0); /* may be modified by other rules */ 775 code_byte(0); /* may be adjusted by other rules */
692 } 776 }
693 ; 777 ;
694 778
695funcvalue : varexp { $$ = 0; } 779funcvalue : varexp { $$ = 0; }
696 | varexp ':' NAME 780 | varexp ':' NAME
697 { 781 {
698 code_byte(PUSHSELF); 782 code_opcode(PUSHSELF, 1);
699 code_word(string_constant($3)); 783 code_word(string_constant($3));
700 $$ = 1; 784 $$ = 1;
701 } 785 }
@@ -711,26 +795,26 @@ exprlist : /* empty */ { $$ = 0; }
711 ; 795 ;
712 796
713exprlist1 : expr { if ($1 != 0) $$ = $1; else $$ = -1; } 797exprlist1 : expr { if ($1 != 0) $$ = $1; else $$ = -1; }
714 | exprlist1 ',' { $<vLong>$ = adjust_functioncall($1, 1); } expr 798 | exprlist1 ',' { $<vLong>$ = adjust_functioncall($1, 1); } expr
715 { 799 {
716 if ($4 == 0) $$ = -($<vLong>3 + 1); /* -length */ 800 if ($4 == 0) $$ = -($<vLong>3 + 1); /* -length */
717 else 801 else
718 { 802 {
719 adjust_functioncall($4, $<vLong>3); 803 currState->f->code[$4] = $<vLong>3; /* store list length */
720 $$ = $4; 804 $$ = $4;
721 } 805 }
722 } 806 }
723 ; 807 ;
724 808
725parlist : /* empty */ { $$ = close_parlist(0); } 809parlist : /* empty */ { code_args(0); }
726 | parlist1 { $$ = close_parlist($1); } 810 | parlist1 { code_args($1); }
727 ; 811 ;
728 812
729parlist1 : par { $$ = $1; } 813parlist1 : par { $$ = $1; }
730 | parlist1 ',' par 814 | parlist1 ',' par
731 { 815 {
732 if ($1) 816 if ($1)
733 lua_error("invalid parameter list"); 817 luaY_error("invalid parameter list");
734 $$ = $3; 818 $$ = $3;
735 } 819 }
736 ; 820 ;
@@ -740,34 +824,35 @@ par : NAME { add_localvar($1); $$ = 0; }
740 ; 824 ;
741 825
742fieldlist : lfieldlist 826fieldlist : lfieldlist
743 { flush_list($1/FIELDS_PER_FLUSH, $1%FIELDS_PER_FLUSH); } 827 { flush_list($1/LFIELDS_PER_FLUSH, $1%LFIELDS_PER_FLUSH); }
744 semicolonpart 828 semicolonpart
745 { $$ = $1+$3; } 829 { $$ = $1+$3; }
746 | ffieldlist1 lastcomma 830 | ffieldlist1 lastcomma
747 { $$ = $1; flush_record($1%FIELDS_PER_FLUSH); } 831 { $$ = $1; flush_record($1%RFIELDS_PER_FLUSH); }
748 ; 832 ;
749 833
750semicolonpart : /* empty */ 834semicolonpart : /* empty */
751 { $$ = 0; } 835 { $$ = 0; }
752 | ';' ffieldlist 836 | ';' ffieldlist
753 { $$ = $2; flush_record($2%FIELDS_PER_FLUSH); } 837 { $$ = $2; flush_record($2%RFIELDS_PER_FLUSH); }
754 ; 838 ;
755 839
756lastcomma : /* empty */ 840lastcomma : /* empty */
757 | ',' 841 | ','
758 ; 842 ;
759 843
760ffieldlist : /* empty */ { $$ = 0; } 844ffieldlist : /* empty */ { $$ = 0; }
761 | ffieldlist1 lastcomma { $$ = $1; } 845 | ffieldlist1 lastcomma { $$ = $1; }
762 ; 846 ;
763 847
764ffieldlist1 : ffield {$$=1;} 848ffieldlist1 : ffield {$$=1;}
765 | ffieldlist1 ',' ffield 849 | ffieldlist1 ',' ffield
766 { 850 {
767 $$=$1+1; 851 $$=$1+1;
768 if ($$%FIELDS_PER_FLUSH == 0) flush_record(FIELDS_PER_FLUSH); 852 if ($$%RFIELDS_PER_FLUSH == 0)
853 flush_record(RFIELDS_PER_FLUSH);
769 } 854 }
770 ; 855 ;
771 856
772ffield : ffieldkey '=' expr1 857ffield : ffieldkey '=' expr1
773 ; 858 ;
@@ -784,26 +869,25 @@ lfieldlist1 : expr1 {$$=1;}
784 | lfieldlist1 ',' expr1 869 | lfieldlist1 ',' expr1
785 { 870 {
786 $$=$1+1; 871 $$=$1+1;
787 if ($$%FIELDS_PER_FLUSH == 0) 872 if ($$%LFIELDS_PER_FLUSH == 0)
788 flush_list($$/FIELDS_PER_FLUSH - 1, FIELDS_PER_FLUSH); 873 flush_list($$/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH);
789 } 874 }
790 ; 875 ;
791 876
792varlist1 : var 877varlist1 : var
793 { 878 {
794 nvarbuffer = 0; 879 $$ = 1;
795 add_varbuffer($1); 880 add_varbuffer($1, 0);
796 $$ = ($1 == 0) ? 1 : 0;
797 } 881 }
798 | varlist1 ',' var 882 | varlist1 ',' var
799 { 883 {
800 add_varbuffer($3); 884 add_varbuffer($3, $1);
801 $$ = ($3 == 0) ? $1 + 1 : $1; 885 $$ = $1+1;
802 } 886 }
803 ; 887 ;
804 888
805var : singlevar { $$ = $1; } 889var : singlevar { $$ = $1; }
806 | varexp '[' expr1 ']' 890 | varexp '[' expr1 ']'
807 { 891 {
808 $$ = 0; /* indexed variable */ 892 $$ = 0; /* indexed variable */
809 } 893 }
@@ -814,22 +898,15 @@ var : singlevar { $$ = $1; }
814 } 898 }
815 ; 899 ;
816 900
817singlevar : NAME 901singlevar : NAME { $$ = singlevar($1, currState); }
818 {
819 int local = lua_localname($1);
820 if (local == -1) /* global var */
821 $$ = luaI_findsymbol($1)+1; /* return positive value */
822 else
823 $$ = -(local+1); /* return negative value */
824 luaI_fixstring($1); /* cannot GC variable names */
825 }
826 ; 902 ;
827 903
828varexp : var { lua_pushvar($1); } 904varexp : var { lua_pushvar($1); }
905 | '%' NAME { pushupvalue($2); }
829 ; 906 ;
830 907
831localdeclist : NAME {store_localvar($1, 0); $$ = 1;} 908localdeclist : NAME {store_localvar($1, 0); $$ = 1;}
832 | localdeclist ',' NAME 909 | localdeclist ',' NAME
833 { 910 {
834 store_localvar($3, $1); 911 store_localvar($3, $1);
835 $$ = $1+1; 912 $$ = $1+1;
@@ -839,5 +916,5 @@ localdeclist : NAME {store_localvar($1, 0); $$ = 1;}
839decinit : /* empty */ { $$ = 0; } 916decinit : /* empty */ { $$ = 0; }
840 | '=' exprlist1 { $$ = $2; } 917 | '=' exprlist1 { $$ = $2; }
841 ; 918 ;
842 919
843%% 920%%