aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1998-05-27 10:08:34 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1998-05-27 10:08:34 -0300
commit7e59a8901d063dbea4eb0693c9c2d85bda1fc5f6 (patch)
tree1834168cd16e821a017e3d8408978f89e6c2ddaf
parentabc6eac404da8181ad945ac6950f61a65ba7dfa5 (diff)
downloadlua-7e59a8901d063dbea4eb0693c9c2d85bda1fc5f6.tar.gz
lua-7e59a8901d063dbea4eb0693c9c2d85bda1fc5f6.tar.bz2
lua-7e59a8901d063dbea4eb0693c9c2d85bda1fc5f6.zip
NEW LL(1) PARSER
-rw-r--r--llex.c138
-rw-r--r--llex.h31
-rw-r--r--lparser.c1332
-rw-r--r--lstate.h4
-rw-r--r--lua.stx940
-rw-r--r--makefile22
6 files changed, 1442 insertions, 1025 deletions
diff --git a/llex.c b/llex.c
index d1301463..7a19eb7e 100644
--- a/llex.c
+++ b/llex.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: llex.c,v 1.17 1998/03/09 17:22:49 roberto Exp roberto $ 2** $Id: llex.c,v 1.18 1998/03/20 14:18:18 roberto Exp roberto $
3** Lexical Analizer 3** Lexical Analizer
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -15,7 +15,6 @@
15#include "lparser.h" 15#include "lparser.h"
16#include "lstate.h" 16#include "lstate.h"
17#include "lstring.h" 17#include "lstring.h"
18#include "lstx.h"
19#include "luadebug.h" 18#include "luadebug.h"
20#include "lzio.h" 19#include "lzio.h"
21 20
@@ -27,23 +26,53 @@ int lua_debug=0;
27#define next(LS) (LS->current = zgetc(LS->lex_z)) 26#define next(LS) (LS->current = zgetc(LS->lex_z))
28 27
29 28
30static struct { 29#define save(c) luaL_addchar(c)
31 char *name; 30#define save_and_next(LS) (save(LS->current), next(LS))
32 int token; 31
33} reserved [] = { 32
34 {"and", AND}, {"do", DO}, {"else", ELSE}, {"elseif", ELSEIF}, 33char *reserved [] = {"and", "do", "else", "elseif", "end", "function",
35 {"end", END}, {"function", FUNCTION}, {"if", IF}, {"local", LOCAL}, 34 "if", "local", "nil", "not", "or", "repeat", "return", "then",
36 {"nil", NIL}, {"not", NOT}, {"or", OR}, {"repeat", REPEAT}, 35 "until", "while"};
37 {"return", RETURN}, {"then", THEN}, {"until", UNTIL}, {"while", WHILE} 36
38};
39 37
40void luaX_init (void) 38void luaX_init (void)
41{ 39{
42 int i; 40 int i;
43 for (i=0; i<(sizeof(reserved)/sizeof(reserved[0])); i++) { 41 for (i=0; i<(sizeof(reserved)/sizeof(reserved[0])); i++) {
44 TaggedString *ts = luaS_new(reserved[i].name); 42 TaggedString *ts = luaS_new(reserved[i]);
45 ts->head.marked = reserved[i].token; /* reserved word (always > 255) */ 43 ts->head.marked = FIRST_RESERVED+i; /* reserved word (always > 255) */
44 }
45}
46
47
48void luaX_syntaxerror (LexState *ls, char *s, char *token) {
49 if (token[0] == 0)
50 token = "<eof>";
51 luaL_verror("%.100s;\n last token read: `%.50s' at line %d in file %.50s",
52 s, token, ls->linenumber, zname(ls->lex_z));
53}
54
55
56void luaX_error (LexState *ls, char *s) {
57 save(0);
58 luaX_syntaxerror(ls, s, luaL_buffer());
59}
60
61
62void luaX_token2str (LexState *ls, int token, char *s) {
63 if (token < 255) {
64 s[0] = token;
65 s[1] = 0;
46 } 66 }
67 else
68 strcpy(s, reserved[token-FIRST_RESERVED]);
69}
70
71
72static void luaX_invalidchar (LexState *ls, int c) {
73 char buff[10];
74 sprintf(buff, "0x%X", c);
75 luaX_syntaxerror(ls, "invalid control char", buff);
47} 76}
48 77
49 78
@@ -56,16 +85,15 @@ static void firstline (LexState *LS)
56} 85}
57 86
58 87
59void luaX_setinput (ZIO *z) 88void luaX_setinput (LexState *LS, ZIO *z)
60{ 89{
61 LexState *LS = L->lexstate;
62 LS->current = '\n'; 90 LS->current = '\n';
63 LS->linelasttoken = 0;
64 LS->linenumber = 0; 91 LS->linenumber = 0;
65 LS->iflevel = 0; 92 LS->iflevel = 0;
66 LS->ifstate[0].skip = 0; 93 LS->ifstate[0].skip = 0;
67 LS->ifstate[0].elsepart = 1; /* to avoid a free $else */ 94 LS->ifstate[0].elsepart = 1; /* to avoid a free $else */
68 LS->lex_z = z; 95 LS->lex_z = z;
96 LS->fs = NULL;
69 firstline(LS); 97 firstline(LS);
70 luaL_resetbuffer(); 98 luaL_resetbuffer();
71} 99}
@@ -87,7 +115,7 @@ static void skipspace (LexState *LS)
87} 115}
88 116
89 117
90static int checkcond (char *buff) 118static int checkcond (LexState *LS, char *buff)
91{ 119{
92 static char *opts[] = {"nil", "1", NULL}; 120 static char *opts[] = {"nil", "1", NULL};
93 int i = luaO_findstring(buff, opts); 121 int i = luaO_findstring(buff, opts);
@@ -95,7 +123,7 @@ static int checkcond (char *buff)
95 else if (isalpha((unsigned char)buff[0]) || buff[0] == '_') 123 else if (isalpha((unsigned char)buff[0]) || buff[0] == '_')
96 return luaS_globaldefined(buff); 124 return luaS_globaldefined(buff);
97 else { 125 else {
98 luaY_syntaxerror("invalid $if condition", buff); 126 luaX_syntaxerror(LS, "invalid $if condition", buff);
99 return 0; /* to avoid warnings */ 127 return 0; /* to avoid warnings */
100 } 128 }
101} 129}
@@ -108,7 +136,7 @@ static void readname (LexState *LS, char *buff)
108 while (isalnum(LS->current) || LS->current == '_') { 136 while (isalnum(LS->current) || LS->current == '_') {
109 if (i >= PRAGMASIZE) { 137 if (i >= PRAGMASIZE) {
110 buff[PRAGMASIZE] = 0; 138 buff[PRAGMASIZE] = 0;
111 luaY_syntaxerror("pragma too long", buff); 139 luaX_syntaxerror(LS, "pragma too long", buff);
112 } 140 }
113 buff[i++] = LS->current; 141 buff[i++] = LS->current;
114 next(LS); 142 next(LS);
@@ -126,7 +154,7 @@ static void ifskip (LexState *LS)
126 if (LS->current == '\n') 154 if (LS->current == '\n')
127 inclinenumber(LS); 155 inclinenumber(LS);
128 else if (LS->current == EOZ) 156 else if (LS->current == EOZ)
129 luaY_error("input ends inside a $if"); 157 luaX_error(LS, "input ends inside a $if");
130 else next(LS); 158 else next(LS);
131 } 159 }
132} 160}
@@ -159,35 +187,35 @@ static void inclinenumber (LexState *LS)
159 break; 187 break;
160 case 3: /* end */ 188 case 3: /* end */
161 if (LS->iflevel-- == 0) 189 if (LS->iflevel-- == 0)
162 luaY_syntaxerror("unmatched $end", "$end"); 190 luaX_syntaxerror(LS, "unmatched $end", "$end");
163 break; 191 break;
164 case 4: /* ifnot */ 192 case 4: /* ifnot */
165 ifnot = 1; 193 ifnot = 1;
166 /* go through */ 194 /* go through */
167 case 5: /* if */ 195 case 5: /* if */
168 if (LS->iflevel == MAX_IFS-1) 196 if (LS->iflevel == MAX_IFS-1)
169 luaY_syntaxerror("too many nested $ifs", "$if"); 197 luaX_syntaxerror(LS, "too many nested $ifs", "$if");
170 readname(LS, buff); 198 readname(LS, buff);
171 LS->iflevel++; 199 LS->iflevel++;
172 LS->ifstate[LS->iflevel].elsepart = 0; 200 LS->ifstate[LS->iflevel].elsepart = 0;
173 LS->ifstate[LS->iflevel].condition = checkcond(buff) ? !ifnot : ifnot; 201 LS->ifstate[LS->iflevel].condition = checkcond(LS, buff) ? !ifnot : ifnot;
174 LS->ifstate[LS->iflevel].skip = skip || !LS->ifstate[LS->iflevel].condition; 202 LS->ifstate[LS->iflevel].skip = skip || !LS->ifstate[LS->iflevel].condition;
175 break; 203 break;
176 case 6: /* else */ 204 case 6: /* else */
177 if (LS->ifstate[LS->iflevel].elsepart) 205 if (LS->ifstate[LS->iflevel].elsepart)
178 luaY_syntaxerror("unmatched $else", "$else"); 206 luaX_syntaxerror(LS, "unmatched $else", "$else");
179 LS->ifstate[LS->iflevel].elsepart = 1; 207 LS->ifstate[LS->iflevel].elsepart = 1;
180 LS->ifstate[LS->iflevel].skip = LS->ifstate[LS->iflevel-1].skip || 208 LS->ifstate[LS->iflevel].skip = LS->ifstate[LS->iflevel-1].skip ||
181 LS->ifstate[LS->iflevel].condition; 209 LS->ifstate[LS->iflevel].condition;
182 break; 210 break;
183 default: 211 default:
184 luaY_syntaxerror("unknown pragma", buff); 212 luaX_syntaxerror(LS, "unknown pragma", buff);
185 } 213 }
186 skipspace(LS); 214 skipspace(LS);
187 if (LS->current == '\n') /* pragma must end with a '\n' ... */ 215 if (LS->current == '\n') /* pragma must end with a '\n' ... */
188 inclinenumber(LS); 216 inclinenumber(LS);
189 else if (LS->current != EOZ) /* or eof */ 217 else if (LS->current != EOZ) /* or eof */
190 luaY_syntaxerror("invalid pragma format", buff); 218 luaX_syntaxerror(LS, "invalid pragma format", buff);
191 ifskip(LS); 219 ifskip(LS);
192 } 220 }
193} 221}
@@ -201,25 +229,16 @@ static void inclinenumber (LexState *LS)
201 229
202 230
203 231
204#define save(c) luaL_addchar(c)
205#define save_and_next(LS) (save(LS->current), next(LS))
206
207
208char *luaX_lasttoken (void)
209{
210 save(0);
211 return luaL_buffer();
212}
213 232
214 233
215static int read_long_string (LexState *LS, YYSTYPE *l) 234static int read_long_string (LexState *LS)
216{ 235{
217 int cont = 0; 236 int cont = 0;
218 while (1) { 237 while (1) {
219 switch (LS->current) { 238 switch (LS->current) {
220 case EOZ: 239 case EOZ:
221 luaY_error("unfinished long string"); 240 luaX_error(LS, "unfinished long string");
222 return 0; /* to avoid warnings */ 241 return EOS; /* to avoid warnings */
223 case '[': 242 case '[':
224 save_and_next(LS); 243 save_and_next(LS);
225 if (LS->current == '[') { 244 if (LS->current == '[') {
@@ -244,25 +263,15 @@ static int read_long_string (LexState *LS, YYSTYPE *l)
244 } 263 }
245 } endloop: 264 } endloop:
246 save_and_next(LS); /* pass the second ']' */ 265 save_and_next(LS); /* pass the second ']' */
247 l->pTStr = luaS_newlstr(L->Mbuffbase+2, 266 LS->seminfo.ts = luaS_newlstr(L->Mbuffbase+2,
248 L->Mbuffnext-(L->Mbuffbase-L->Mbuffer)-4); 267 L->Mbuffnext-(L->Mbuffbase-L->Mbuffer)-4);
249 return STRING; 268 return STRING;
250} 269}
251 270
252 271
253/* to avoid warnings; this declaration cannot be public since YYSTYPE 272int luaX_lex (LexState *LS) {
254** cannot be visible in llex.h (otherwise there is an error, since
255** the parser body redefines it!)
256*/
257int luaY_lex (YYSTYPE *l);
258int luaY_lex (YYSTYPE *l)
259{
260 LexState *LS = L->lexstate;
261 double a; 273 double a;
262 luaL_resetbuffer(); 274 luaL_resetbuffer();
263 if (lua_debug)
264 luaY_codedebugline(LS->linelasttoken);
265 LS->linelasttoken = LS->linenumber;
266 while (1) { 275 while (1) {
267 switch (LS->current) { 276 switch (LS->current) {
268 277
@@ -272,7 +281,6 @@ int luaY_lex (YYSTYPE *l)
272 281
273 case '\n': 282 case '\n':
274 inclinenumber(LS); 283 inclinenumber(LS);
275 LS->linelasttoken = LS->linenumber;
276 continue; 284 continue;
277 285
278 case '-': 286 case '-':
@@ -287,7 +295,7 @@ int luaY_lex (YYSTYPE *l)
287 if (LS->current != '[') return '['; 295 if (LS->current != '[') return '[';
288 else { 296 else {
289 save_and_next(LS); /* pass the second '[' */ 297 save_and_next(LS); /* pass the second '[' */
290 return read_long_string(LS, l); 298 return read_long_string(LS);
291 } 299 }
292 300
293 case '=': 301 case '=':
@@ -318,8 +326,8 @@ int luaY_lex (YYSTYPE *l)
318 switch (LS->current) { 326 switch (LS->current) {
319 case EOZ: 327 case EOZ:
320 case '\n': 328 case '\n':
321 luaY_error("unfinished string"); 329 luaX_error(LS, "unfinished string");
322 return 0; /* to avoid warnings */ 330 return EOS; /* to avoid warnings */
323 case '\\': 331 case '\\':
324 next(LS); /* do not save the '\' */ 332 next(LS); /* do not save the '\' */
325 switch (LS->current) { 333 switch (LS->current) {
@@ -345,13 +353,13 @@ int luaY_lex (YYSTYPE *l)
345 next(LS); 353 next(LS);
346 } while (++i<3 && isdigit(LS->current)); 354 } while (++i<3 && isdigit(LS->current));
347 if (c >= 256) 355 if (c >= 256)
348 luaY_error("escape sequence too large"); 356 luaX_error(LS, "escape sequence too large");
349 save(c); 357 save(c);
350 } 358 }
351 else { 359 else {
352 save('\\'); 360 save('\\');
353 save(LS->current); 361 save(LS->current);
354 luaY_error("invalid escape sequence"); 362 luaX_error(LS, "invalid escape sequence");
355 } 363 }
356 break; 364 break;
357 } 365 }
@@ -362,7 +370,7 @@ int luaY_lex (YYSTYPE *l)
362 } 370 }
363 } 371 }
364 save_and_next(LS); /* skip delimiter */ 372 save_and_next(LS); /* skip delimiter */
365 l->pTStr = luaS_newlstr(L->Mbuffbase+1, 373 LS->seminfo.ts = luaS_newlstr(L->Mbuffbase+1,
366 L->Mbuffnext-(L->Mbuffbase-L->Mbuffer)-2); 374 L->Mbuffnext-(L->Mbuffbase-L->Mbuffer)-2);
367 return STRING; 375 return STRING;
368 } 376 }
@@ -395,7 +403,7 @@ int luaY_lex (YYSTYPE *l)
395 save_and_next(LS); 403 save_and_next(LS);
396 if (LS->current == '.') { 404 if (LS->current == '.') {
397 save('.'); 405 save('.');
398 luaY_error( 406 luaX_error(LS,
399 "ambiguous syntax (decimal point x string concatenation)"); 407 "ambiguous syntax (decimal point x string concatenation)");
400 } 408 }
401 } 409 }
@@ -415,7 +423,7 @@ int luaY_lex (YYSTYPE *l)
415 neg = (LS->current=='-'); 423 neg = (LS->current=='-');
416 if (LS->current == '+' || LS->current == '-') save_and_next(LS); 424 if (LS->current == '+' || LS->current == '-') save_and_next(LS);
417 if (!isdigit(LS->current)) 425 if (!isdigit(LS->current))
418 luaY_error("invalid numeral format"); 426 luaX_error(LS, "invalid numeral format");
419 do { 427 do {
420 e = 10.0*e + (LS->current-'0'); 428 e = 10.0*e + (LS->current-'0');
421 save_and_next(LS); 429 save_and_next(LS);
@@ -426,18 +434,20 @@ int luaY_lex (YYSTYPE *l)
426 ea *= ea; 434 ea *= ea;
427 } 435 }
428 } 436 }
429 l->vReal = a; 437 LS->seminfo.r = a;
430 return NUMBER; 438 return NUMBER;
431 } 439 }
432 440
433 case EOZ: 441 case EOZ:
434 if (LS->iflevel > 0) 442 if (LS->iflevel > 0)
435 luaY_error("input ends inside a $if"); 443 luaX_error(LS, "input ends inside a $if");
436 return 0; 444 return EOS;
437 445
438 default: 446 default:
439 if (LS->current != '_' && !isalpha(LS->current)) { 447 if (LS->current != '_' && !isalpha(LS->current)) {
440 int c = LS->current; 448 int c = LS->current;
449 if (iscntrl(c))
450 luaX_invalidchar(LS, c);
441 save_and_next(LS); 451 save_and_next(LS);
442 return c; 452 return c;
443 } 453 }
@@ -448,9 +458,9 @@ int luaY_lex (YYSTYPE *l)
448 } while (isalnum(LS->current) || LS->current == '_'); 458 } while (isalnum(LS->current) || LS->current == '_');
449 save(0); 459 save(0);
450 ts = luaS_new(L->Mbuffbase); 460 ts = luaS_new(L->Mbuffbase);
451 if (ts->head.marked > 255) 461 if (ts->head.marked >= 'A')
452 return ts->head.marked; /* reserved word */ 462 return ts->head.marked; /* reserved word */
453 l->pTStr = ts; 463 LS->seminfo.ts = ts;
454 return NAME; 464 return NAME;
455 } 465 }
456 } 466 }
diff --git a/llex.h b/llex.h
index dcce5149..3947bf5d 100644
--- a/llex.h
+++ b/llex.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: llex.h,v 1.6 1997/12/17 20:48:58 roberto Exp roberto $ 2** $Id: llex.h,v 1.7 1998/01/09 14:57:43 roberto Exp $
3** Lexical Analizer 3** Lexical Analizer
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -11,6 +11,20 @@
11#include "lzio.h" 11#include "lzio.h"
12 12
13 13
14#define FIRST_RESERVED 260
15
16/* maximum length of a reserved word (+1 for terminal 0) */
17#define TOKEN_LEN 15
18
19enum RESERVED {
20 /* terminal symbols denoted by reserved words */
21 AND = FIRST_RESERVED,
22 DO, ELSE, ELSEIF, END, FUNCTION, IF, LOCAL, NIL, NOT, OR,
23 REPEAT, RETURN, THEN, UNTIL, WHILE,
24 /* other terminal symbols */
25 NAME, CONC, DOTS, EQ, GE, LE, NE, NUMBER, STRING, EOS};
26
27
14#define MAX_IFS 5 28#define MAX_IFS 5
15 29
16/* "ifstate" keeps the state of each nested $if the lexical is dealing with. */ 30/* "ifstate" keeps the state of each nested $if the lexical is dealing with. */
@@ -24,18 +38,25 @@ struct ifState {
24 38
25typedef struct LexState { 39typedef struct LexState {
26 int current; /* look ahead character */ 40 int current; /* look ahead character */
41 int token; /* look ahead token */
42 struct FuncState *fs; /* 'FuncState' is private for the parser */
43 union {
44 real r;
45 TaggedString *ts;
46 } seminfo; /* semantics information */
27 struct zio *lex_z; /* input stream */ 47 struct zio *lex_z; /* input stream */
28 int linenumber; /* input line counter */ 48 int linenumber; /* input line counter */
29 int linelasttoken; /* line where last token was read */
30 int lastline; /* last line wherein a SETLINE was generated */
31 int iflevel; /* level of nested $if's (for lexical analysis) */ 49 int iflevel; /* level of nested $if's (for lexical analysis) */
32 struct ifState ifstate[MAX_IFS]; 50 struct ifState ifstate[MAX_IFS];
33} LexState; 51} LexState;
34 52
35 53
36void luaX_init (void); 54void luaX_init (void);
37void luaX_setinput (ZIO *z); 55void luaX_setinput (LexState *LS, ZIO *z);
38char *luaX_lasttoken (void); 56int luaX_lex (LexState *LS);
57void luaX_syntaxerror (LexState *ls, char *s, char *token);
58void luaX_error (LexState *ls, char *s);
59void luaX_token2str (LexState *ls, int token, char *s);
39 60
40 61
41#endif 62#endif
diff --git a/lparser.c b/lparser.c
new file mode 100644
index 00000000..0eefb204
--- /dev/null
+++ b/lparser.c
@@ -0,0 +1,1332 @@
1/*
2** $Id: $
3** LL(1) Parser and code generator for Lua
4** See Copyright Notice in lua.h
5*/
6
7
8#include <stdio.h>
9
10#include "lauxlib.h"
11#include "ldo.h"
12#include "lfunc.h"
13#include "llex.h"
14#include "lmem.h"
15#include "lopcodes.h"
16#include "lparser.h"
17#include "lstate.h"
18#include "lstring.h"
19#include "lua.h"
20#include "luadebug.h"
21#include "lzio.h"
22
23
24/* for limit numbers in error messages */
25#define MES_LIM(x) "(limit=" x ")"
26
27
28/* size of a "normal" jump instruction: OpCode + 1 byte */
29#define JMPSIZE 2
30
31/* maximum number of local variables */
32#define MAXLOCALS 32
33#define SMAXLOCALS "32"
34
35
36/* maximum number of upvalues */
37#define MAXUPVALUES 16
38#define SMAXUPVALUES "16"
39
40
41/*
42** Variable descriptor:
43** must include a "exp" option because LL(1) cannot distinguish
44** between variables, upvalues and function calls on first sight.
45** VGLOBAL: info is constant index of global name
46** VLOCAL: info is stack index
47** VDOT: info is constant index of index name
48** VEXP: info is pc index of "nparam" of function call (or 0 if exp is closed)
49*/
50typedef enum {VGLOBAL, VLOCAL, VDOT, VINDEXED, VEXP} varkind;
51
52typedef struct {
53 varkind k;
54 int info;
55} vardesc;
56
57
58/*
59** Expression List descriptor:
60** tells number of expressions in the list,
61** and, if last expression is open (a function call),
62** where is its pc index of "nparam"
63*/
64typedef struct {
65 int n;
66 int pc; /* 0 if last expression is closed */
67} listdesc;
68
69
70/*
71** Constructors descriptor:
72** "n" indicates number of elements, and "k" signals whether
73** it is a list constructor (k = 0) or a record constructor (k = 1)
74** or empty (k = ';' or '}')
75*/
76typedef struct {
77 int n;
78 int k;
79} constdesc;
80
81
82/* state needed to generate code for a given function */
83typedef struct FuncState {
84 TProtoFunc *f; /* current function header */
85 struct FuncState *prev; /* enclosuring function */
86 int pc; /* next position to code */
87 int stacksize; /* number of values on activation register */
88 int maxstacksize; /* maximum number of values on activation register */
89 int nlocalvar; /* number of active local variables */
90 int nupvalues; /* number of upvalues */
91 int nvars; /* number of entries in f->locvars */
92 int maxcode; /* size of f->code */
93 int maxvars; /* size of f->locvars (-1 if no debug information) */
94 int maxconsts; /* size of f->consts */
95 int lastsetline; /* line where last SETLINE was issued */
96 vardesc upvalues[MAXUPVALUES]; /* upvalues */
97 TaggedString *localvar[MAXLOCALS]; /* store local variable names */
98} FuncState;
99
100
101static int assignment (LexState *ls, vardesc *v, int nvars);
102static int cond (LexState *ls);
103static int funcname (LexState *ls, vardesc *v);
104static int funcparams (LexState *ls, int slf);
105static int listfields (LexState *ls);
106static int localnamelist (LexState *ls);
107static int optional (LexState *ls, int c);
108static int recfields (LexState *ls);
109static int stat (LexState *ls);
110static void block (LexState *ls);
111static void body (LexState *ls, int needself, int line);
112static void chunk (LexState *ls);
113static void constructor (LexState *ls);
114static void decinit (LexState *ls, listdesc *d);
115static void exp (LexState *ls, vardesc *v);
116static void exp1 (LexState *ls);
117static void exp2 (LexState *ls, vardesc *v);
118static void explist (LexState *ls, listdesc *e);
119static void explist1 (LexState *ls, listdesc *e);
120static void ifpart (LexState *ls);
121static void parlist (LexState *ls);
122static void part (LexState *ls, constdesc *cd);
123static void recfield (LexState *ls);
124static void ret (LexState *ls);
125static void simpleexp (LexState *ls, vardesc *v);
126static void statlist (LexState *ls);
127static void var_or_func (LexState *ls, vardesc *v);
128static void var_or_func_tail (LexState *ls, vardesc *v);
129
130
131
132static void check_pc (FuncState *fs, int n) {
133 if (fs->pc+n > fs->maxcode)
134 fs->maxcode = luaM_growvector(&fs->f->code, fs->maxcode,
135 Byte, codeEM, MAX_INT);
136}
137
138
139static void code_byte (FuncState *fs, Byte c) {
140 check_pc(fs, 1);
141 fs->f->code[fs->pc++] = c;
142}
143
144
145static void deltastack (LexState *ls, int delta) {
146 FuncState *fs = ls->fs;
147 fs->stacksize += delta;
148 if (fs->stacksize > fs->maxstacksize) {
149 if (fs->stacksize > 255)
150 luaX_error(ls, "function/expression too complex");
151 fs->maxstacksize = fs->stacksize;
152 }
153}
154
155
156static int code_oparg_at (LexState *ls, int pc, OpCode op, int builtin,
157 int arg, int delta) {
158 Byte *code = ls->fs->f->code;
159 deltastack(ls, delta);
160 if (arg < builtin) {
161 code[pc] = op+1+arg;
162 return 1;
163 }
164 else if (arg <= 255) {
165 code[pc] = op;
166 code[pc+1] = arg;
167 return 2;
168 }
169 else if (arg <= MAX_WORD) {
170 code[pc] = op+1+builtin;
171 code[pc+1] = arg>>8;
172 code[pc+2] = arg&0xFF;
173 return 3;
174 }
175 else luaX_error(ls, "code too long " MES_LIM("64K"));
176 return 0; /* to avoid warnings */
177}
178
179
180static int fix_opcode (LexState *ls, int pc, OpCode op, int builtin, int arg) {
181 FuncState *fs = ls->fs;
182 TProtoFunc *f = fs->f;
183 if (arg < builtin) { /* close space */
184 luaO_memdown(f->code+pc+1, f->code+pc+2, fs->pc-(pc+2));
185 fs->pc--;
186 }
187 else if (arg > 255) { /* open space */
188 check_pc(fs, 1);
189 luaO_memup(f->code+pc+1, f->code+pc, fs->pc-pc);
190 fs->pc++;
191 }
192 return code_oparg_at(ls, pc, op, builtin, arg, 0) - 2;
193}
194
195static void code_oparg (LexState *ls, OpCode op, int builtin, int arg,
196 int delta) {
197 check_pc(ls->fs, 3); /* maximum code size */
198 ls->fs->pc += code_oparg_at(ls, ls->fs->pc, op, builtin, arg, delta);
199}
200
201
202static void code_opcode (LexState *ls, OpCode op, int delta) {
203 deltastack(ls, delta);
204 code_byte(ls->fs, op);
205}
206
207
208static void code_constant (LexState *ls, int c) {
209 code_oparg(ls, PUSHCONSTANT, 8, c, 1);
210}
211
212
213static int next_constant (FuncState *fs) {
214 TProtoFunc *f = fs->f;
215 if (f->nconsts >= fs->maxconsts) {
216 fs->maxconsts = luaM_growvector(&f->consts, fs->maxconsts, TObject,
217 constantEM, MAX_WORD);
218 }
219 return f->nconsts++;
220}
221
222
223static int string_constant (FuncState *fs, TaggedString *s) {
224 TProtoFunc *f = fs->f;
225 int c = s->constindex;
226 if (!(c < f->nconsts &&
227 ttype(&f->consts[c]) == LUA_T_STRING && tsvalue(&f->consts[c]) == s)) {
228 c = next_constant(fs);
229 ttype(&f->consts[c]) = LUA_T_STRING;
230 tsvalue(&f->consts[c]) = s;
231 s->constindex = c; /* hint for next time */
232 }
233 return c;
234}
235
236
237static void code_string (LexState *ls, TaggedString *s) {
238 code_constant(ls, string_constant(ls->fs, s));
239}
240
241
242#define LIM 20
243static int real_constant (FuncState *fs, real r) {
244 /* check whether 'r' has appeared within the last LIM entries */
245 TObject *cnt = fs->f->consts;
246 int c = fs->f->nconsts;
247 int lim = c < LIM ? 0 : c-LIM;
248 while (--c >= lim) {
249 if (ttype(&cnt[c]) == LUA_T_NUMBER && nvalue(&cnt[c]) == r)
250 return c;
251 }
252 /* not found; create a luaM_new entry */
253 c = next_constant(fs);
254 cnt = fs->f->consts; /* 'next_constant' may reallocate this vector */
255 ttype(&cnt[c]) = LUA_T_NUMBER;
256 nvalue(&cnt[c]) = r;
257 return c;
258}
259
260
261static void code_number (LexState *ls, real f) {
262 int i;
263 if (f >= 0 && f <= (real)MAX_WORD && (real)(i=(int)f) == f)
264 code_oparg(ls, PUSHNUMBER, 3, i, 1); /* f has a short integer value */
265 else
266 code_constant(ls, real_constant(ls->fs, f));
267}
268
269
270static void flush_record (LexState *ls, int n) {
271 if (n > 0)
272 code_oparg(ls, SETMAP, 1, n-1, -2*n);
273}
274
275
276static void flush_list (LexState *ls, int m, int n) {
277 if (n == 0) return;
278 code_oparg(ls, SETLIST, 1, m, -n);
279 code_byte(ls->fs, n);
280}
281
282
283static void luaI_registerlocalvar (FuncState *fs, TaggedString *varname,
284 int line) {
285 if (fs->maxvars != -1) { /* debug information? */
286 TProtoFunc *f = fs->f;
287 if (fs->nvars >= fs->maxvars)
288 fs->maxvars = luaM_growvector(&f->locvars, fs->maxvars,
289 LocVar, "", MAX_WORD);
290 f->locvars[fs->nvars].varname = varname;
291 f->locvars[fs->nvars].line = line;
292 fs->nvars++;
293 }
294}
295
296
297static void luaI_unregisterlocalvar (FuncState *fs, int line) {
298 luaI_registerlocalvar(fs, NULL, line);
299}
300
301
302static void store_localvar (LexState *ls, TaggedString *name, int n) {
303 FuncState *fs = ls->fs;
304 if (fs->nlocalvar+n < MAXLOCALS)
305 fs->localvar[fs->nlocalvar+n] = name;
306 else
307 luaX_error(ls, "too many local variables " MES_LIM(SMAXLOCALS));
308 luaI_registerlocalvar(fs, name, ls->linenumber);
309}
310
311
312static void add_localvar (LexState *ls, TaggedString *name) {
313 store_localvar(ls, name, 0);
314 ls->fs->nlocalvar++;
315}
316
317
318static int aux_localname (FuncState *fs, TaggedString *n) {
319 int i;
320 for (i=fs->nlocalvar-1; i >= 0; i--)
321 if (n == fs->localvar[i]) return i; /* local var index */
322 return -1; /* not found */
323}
324
325
326static void singlevar (LexState *ls, TaggedString *n, vardesc *var, int prev) {
327 FuncState *fs = prev ? ls->fs->prev : ls->fs;
328 int i = aux_localname(fs, n);
329 if (i >= 0) { /* local value */
330 var->k = VLOCAL;
331 var->info = i;
332 }
333 else { /* check shadowing */
334 FuncState *level = fs;
335 while ((level = level->prev) != NULL)
336 if (aux_localname(level, n) >= 0)
337 luaX_syntaxerror(ls, "cannot access a variable in outer scope", n->str);
338 var->k = VGLOBAL;
339 var->info = string_constant(fs, n);
340 }
341}
342
343
344static int indexupvalue (LexState *ls, TaggedString *n) {
345 FuncState *fs = ls->fs;
346 vardesc v;
347 int i;
348 singlevar(ls, n, &v, 1);
349 for (i=0; i<fs->nupvalues; i++) {
350 if (fs->upvalues[i].k == v.k && fs->upvalues[i].info == v.info)
351 return i;
352 }
353 /* new one */
354 if (++(fs->nupvalues) > MAXUPVALUES)
355 luaX_error(ls, "too many upvalues in a single function "
356 MES_LIM(SMAXUPVALUES));
357 fs->upvalues[i] = v; /* i = fs->nupvalues - 1 */
358 return i;
359}
360
361
362static void pushupvalue (LexState *ls, TaggedString *n) {
363 int i;
364 if (ls->fs->prev == NULL)
365 luaX_syntaxerror(ls, "cannot access upvalue in main", n->str);
366 if (aux_localname(ls->fs, n) >= 0)
367 luaX_syntaxerror(ls, "cannot access an upvalue in current scope", n->str);
368 i = indexupvalue(ls, n);
369 code_oparg(ls, PUSHUPVALUE, 2, i, 1);
370}
371
372
373
374static void check_debugline (LexState *ls) {
375 if (lua_debug && ls->linenumber != ls->fs->lastsetline) {
376 code_oparg(ls, SETLINE, 0, ls->linenumber, 0);
377 ls->fs->lastsetline = ls->linenumber;
378 }
379}
380
381
382static void adjuststack (LexState *ls, int n) {
383 if (n > 0)
384 code_oparg(ls, POP, 2, n-1, -n);
385 else if (n < 0)
386 code_oparg(ls, PUSHNIL, 1, (-n)-1, -n);
387}
388
389
390static void close_exp (LexState *ls, int pc, int nresults) {
391 if (pc > 0) { /* expression is an open function call */
392 Byte *code = ls->fs->f->code;
393 int nparams = code[pc]; /* save nparams */
394 pc += fix_opcode(ls, pc-2, CALLFUNC, 2, nresults);
395 code[pc] = nparams; /* restore nparams */
396 if (nresults != MULT_RET)
397 deltastack(ls, nresults); /* "push" results */
398 deltastack(ls, -(nparams+1)); /* "pop" params and function */
399 }
400}
401
402
403static void adjust_mult_assign (LexState *ls, int nvars, listdesc *d) {
404 int diff = d->n - nvars;
405 if (d->pc == 0) { /* list is closed */
406 /* push or pop eventual difference between list lengths */
407 adjuststack(ls, diff);
408 }
409 else { /* must correct function call */
410 diff--; /* do not count function call itself */
411 if (diff < 0) { /* more variables than values */
412 /* function call must provide extra values */
413 close_exp(ls, d->pc, -diff);
414 }
415 else { /* more values than variables */
416 close_exp(ls, d->pc, 0); /* call should provide no value */
417 adjuststack(ls, diff); /* pop eventual extra values */
418 }
419 }
420}
421
422
423static void code_args (LexState *ls, int nparams, int dots) {
424 FuncState *fs = ls->fs;
425 fs->nlocalvar += nparams; /* "self" may already be there */
426 nparams = fs->nlocalvar;
427 if (!dots) {
428 fs->f->code[1] = nparams; /* fill-in arg information */
429 deltastack(ls, nparams);
430 }
431 else {
432 fs->f->code[1] = nparams+ZEROVARARG;
433 deltastack(ls, nparams+1);
434 add_localvar(ls, luaS_new("arg"));
435 }
436}
437
438
439static void lua_pushvar (LexState *ls, vardesc *var) {
440 switch (var->k) {
441 case VLOCAL:
442 code_oparg(ls, PUSHLOCAL, 8, var->info, 1);
443 break;
444 case VGLOBAL:
445 code_oparg(ls, GETGLOBAL, 8, var->info, 1);
446 break;
447 case VDOT:
448 code_oparg(ls, GETDOTTED, 8, var->info, 0);
449 break;
450 case VINDEXED:
451 code_opcode(ls, GETTABLE, -1);
452 break;
453 case VEXP:
454 close_exp(ls, var->info, 1); /* function must return 1 value */
455 break;
456 }
457 var->k = VEXP;
458 var->info = 0; /* now this is a closed expression */
459}
460
461
462static void storevar (LexState *ls, vardesc *var) {
463 switch (var->k) {
464 case VLOCAL:
465 code_oparg(ls, SETLOCAL, 8, var->info, -1);
466 break;
467 case VGLOBAL:
468 code_oparg(ls, SETGLOBAL, 8, var->info, -1);
469 break;
470 case VINDEXED:
471 code_opcode(ls, SETTABLE0, -3);
472 break;
473 default:
474 LUA_INTERNALERROR("invalid var kind to store");
475 }
476}
477
478
479static int fix_jump (LexState *ls, int pc, OpCode op, int n) {
480 /* jump is relative to position following jump instruction */
481 return fix_opcode(ls, pc, op, 0, n-(pc+JMPSIZE));
482}
483
484
485static void fix_upjmp (LexState *ls, OpCode op, int pos) {
486 int delta = ls->fs->pc+JMPSIZE - pos; /* jump is relative */
487 if (delta > 255) delta++;
488 code_oparg(ls, op, 0, delta, 0);
489}
490
491
492static void codeIf (LexState *ls, int thenAdd, int elseAdd) {
493 FuncState *fs = ls->fs;
494 int elseinit = elseAdd+JMPSIZE;
495 if (fs->pc == elseinit) { /* no else part */
496 fs->pc -= JMPSIZE;
497 elseinit = fs->pc;
498 }
499 else
500 elseinit += fix_jump(ls, elseAdd, JMP, fs->pc);
501 fix_jump(ls, thenAdd, IFFJMP, elseinit);
502}
503
504
505static void func_onstack (LexState *ls, FuncState *func) {
506 FuncState *fs = ls->fs;
507 int i;
508 int c = next_constant(fs);
509 ttype(&fs->f->consts[c]) = LUA_T_PROTO;
510 fs->f->consts[c].value.tf = func->f;
511 if (func->nupvalues == 0)
512 code_constant(ls, c);
513 else {
514 for (i=0; i<func->nupvalues; i++)
515 lua_pushvar(ls, &func->upvalues[i]);
516 code_oparg(ls, CLOSURE, 0, c, -func->nupvalues+1);
517 code_byte(fs, func->nupvalues);
518 }
519}
520
521
522static void init_state (LexState *ls, FuncState *fs, TaggedString *filename) {
523 TProtoFunc *f = luaF_newproto();
524 fs->prev = ls->fs; /* linked list of funcstates */
525 ls->fs = fs;
526 fs->stacksize = 0;
527 fs->maxstacksize = 0;
528 fs->nlocalvar = 0;
529 fs->nupvalues = 0;
530 fs->lastsetline = 0;
531 fs->f = f;
532 f->fileName = filename;
533 fs->pc = 0;
534 fs->maxcode = 0;
535 f->code = NULL;
536 fs->maxconsts = 0;
537 if (lua_debug)
538 fs->nvars = fs->maxvars = 0;
539 else
540 fs->maxvars = -1; /* flag no debug information */
541 code_byte(fs, 0); /* to be filled with stacksize */
542 code_byte(fs, 0); /* to be filled with arg information */
543}
544
545
546static void close_func (LexState *ls) {
547 FuncState *fs = ls->fs;
548 TProtoFunc *f = fs->f;
549 code_opcode(ls, ENDCODE, 0);
550 f->code[0] = fs->maxstacksize;
551 f->code = luaM_reallocvector(f->code, fs->pc, Byte);
552 f->consts = luaM_reallocvector(f->consts, f->nconsts, TObject);
553 if (fs->maxvars != -1) { /* debug information? */
554 luaI_registerlocalvar(fs, NULL, -1); /* flag end of vector */
555 f->locvars = luaM_reallocvector(f->locvars, fs->nvars, LocVar);
556 }
557 ls->fs = fs->prev;
558}
559
560
561
562static int expfollow [] = {ELSE, ELSEIF, THEN, IF, WHILE, REPEAT, DO, NAME,
563 LOCAL, FUNCTION, END, UNTIL, RETURN, ')', ']', '}', ';', EOS, ',', 0};
564
565static int is_in (int tok, int *toks) {
566 int *t = toks;
567 while (*t) {
568 if (*t == tok)
569 return t-toks;
570 t++;
571 }
572 return -1;
573}
574
575
576static void next (LexState *ls) {
577 ls->token = luaX_lex(ls);
578}
579
580
581static void error_expected (LexState *ls, int token) {
582 char buff[100], t[TOKEN_LEN];
583 luaX_token2str(ls, token, t);
584 sprintf(buff, "`%s' expected", t);
585 luaX_error(ls, buff);
586}
587
588static void error_unmatched (LexState *ls, int what, int who, int where) {
589 if (where == ls->linenumber)
590 error_expected(ls, what);
591 else {
592 char buff[100];
593 char t_what[TOKEN_LEN], t_who[TOKEN_LEN];
594 luaX_token2str(ls, what, t_what);
595 luaX_token2str(ls, who, t_who);
596 sprintf(buff, "`%s' expected (to close `%s' at line %d)",
597 t_what, t_who, where);
598 luaX_error(ls, buff);
599 }
600}
601
602static void check (LexState *ls, int c) {
603 if (ls->token != c)
604 error_expected(ls, c);
605 next(ls);
606}
607
608static void check_match (LexState *ls, int what, int who, int where) {
609 if (ls->token != what)
610 error_unmatched(ls, what, who, where);
611 check_debugline(ls); /* to 'mark' the 'what' */
612 next(ls);
613}
614
615static TaggedString *checkname (LexState *ls) {
616 TaggedString *ts;
617 if (ls->token != NAME)
618 luaX_error(ls, "`NAME' expected");
619 ts = ls->seminfo.ts;
620 next(ls);
621 return ts;
622}
623
624
625static int optional (LexState *ls, int c) {
626 if (ls->token == c) {
627 next(ls);
628 return 1;
629 }
630 else return 0;
631}
632
633
634TProtoFunc *luaY_parser (ZIO *z) {
635 struct LexState lexstate;
636 struct FuncState funcstate;
637 luaX_setinput(&lexstate, z);
638 init_state(&lexstate, &funcstate, luaS_new(zname(z)));
639 next(&lexstate); /* read first token */
640 chunk(&lexstate);
641 if (lexstate.token != EOS)
642 luaX_error(&lexstate, "<eof> expected");
643 close_func(&lexstate);
644 return funcstate.f;
645}
646
647
648
649/*============================================================*/
650/* GRAMAR RULES */
651/*============================================================*/
652
653static void chunk (LexState *ls) {
654 /* chunk -> statlist ret */
655 statlist(ls);
656 ret(ls);
657}
658
659static void statlist (LexState *ls) {
660 /* statlist -> { stat [;] } */
661 while (stat(ls)) {
662 LUA_ASSERT(ls->fs->stacksize == ls->fs->nlocalvar,
663 "stack size != # local vars");
664 optional(ls, ';');
665 }
666}
667
668static int stat (LexState *ls) {
669 int line = ls->linenumber; /* may be needed for error messages */
670 FuncState *fs = ls->fs;
671 switch (ls->token) {
672 case IF: { /* stat -> IF ifpart END */
673 next(ls);
674 ifpart(ls);
675 check_match(ls, END, IF, line);
676 return 1;
677 }
678
679 case WHILE: { /* stat -> WHILE cond DO block END */
680 TProtoFunc *f = fs->f;
681 int while_init = fs->pc;
682 int cond_end, cond_size;
683 next(ls);
684 cond_end = cond(ls);
685 check(ls, DO);
686 block(ls);
687 check_match(ls, END, WHILE, line);
688 cond_size = cond_end-while_init;
689 check_pc(fs, cond_size);
690 memcpy(f->code+fs->pc, f->code+while_init, cond_size);
691 luaO_memdown(f->code+while_init, f->code+cond_end, fs->pc-while_init);
692 while_init += JMPSIZE + fix_jump(ls, while_init, JMP, fs->pc-cond_size);
693 fix_upjmp(ls, IFTUPJMP, while_init);
694 return 1;
695 }
696
697 case DO: { /* stat -> DO block END */
698 next(ls);
699 block(ls);
700 check_match(ls, END, DO, line);
701 return 1;
702 }
703
704 case REPEAT: { /* stat -> REPEAT block UNTIL exp1 */
705 int repeat_init = fs->pc;
706 next(ls);
707 block(ls);
708 check_match(ls, UNTIL, REPEAT, line);
709 exp1(ls);
710 fix_upjmp(ls, IFFUPJMP, repeat_init);
711 deltastack(ls, -1); /* pops condition */
712 return 1;
713 }
714
715 case FUNCTION: { /* stat -> FUNCTION funcname body */
716 int needself;
717 vardesc v;
718 if (ls->fs->prev) /* inside other function? */
719 return 0;
720 check_debugline(ls);
721 next(ls);
722 needself = funcname(ls, &v);
723 body(ls, needself, line);
724 storevar(ls, &v);
725 return 1;
726 }
727
728 case LOCAL: { /* stat -> LOCAL localnamelist decinit */
729 listdesc d;
730 int nvars;
731 check_debugline(ls);
732 next(ls);
733 nvars = localnamelist(ls);
734 decinit(ls, &d);
735 ls->fs->nlocalvar += nvars;
736 adjust_mult_assign(ls, nvars, &d);
737 return 1;
738 }
739
740 case NAME: case '%': { /* stat -> func | ['%'] NAME assignment */
741 vardesc v;
742 check_debugline(ls);
743 var_or_func(ls, &v);
744 if (v.k == VEXP) { /* stat -> func */
745 if (v.info == 0) /* is just an upper value? */
746 luaX_error(ls, "syntax error");
747 close_exp(ls, v.info, 0);
748 }
749 else {
750 int left = assignment(ls, &v, 1); /* stat -> ['%'] NAME assignment */
751 adjuststack(ls, left); /* remove eventual 'garbage' left on stack */
752 }
753 return 1;
754 }
755
756 case RETURN: case ';': case ELSE: case ELSEIF:
757 case END: case UNTIL: case EOS: /* 'stat' follow */
758 return 0;
759
760 default:
761 luaX_error(ls, "<statement> expected");
762 return 0; /* to avoid warnings */
763 }
764}
765
766static int SaveWord (LexState *ls) {
767 int res = ls->fs->pc;
768 check_pc(ls->fs, JMPSIZE);
769 ls->fs->pc += JMPSIZE; /* open space */
770 return res;
771}
772
773static int SaveWordPop (LexState *ls) {
774 deltastack(ls, -1); /* pop condition */
775 return SaveWord(ls);
776}
777
778static int cond (LexState *ls) {
779 /* cond -> exp1 */
780 exp1(ls);
781 return SaveWordPop(ls);
782}
783
784static void block (LexState *ls) {
785 /* block -> chunk */
786 FuncState *fs = ls->fs;
787 int nlocalvar = fs->nlocalvar;
788 chunk(ls);
789 adjuststack(ls, fs->nlocalvar - nlocalvar);
790 for (; fs->nlocalvar > nlocalvar; fs->nlocalvar--)
791 luaI_unregisterlocalvar(fs, ls->linenumber);
792}
793
794static int funcname (LexState *ls, vardesc *v) {
795 /* funcname -> NAME [':' NAME | '.' NAME] */
796 int needself = 0;
797 singlevar(ls, checkname(ls), v, 0);
798 if (ls->token == ':' || ls->token == '.') {
799 needself = (ls->token == ':');
800 next(ls);
801 lua_pushvar(ls, v);
802 code_string(ls, checkname(ls));
803 v->k = VINDEXED;
804 }
805 return needself;
806}
807
808static void body (LexState *ls, int needself, int line) {
809 /* body -> '(' parlist ')' chunk END */
810 FuncState newfs;
811 init_state(ls, &newfs, ls->fs->f->fileName);
812 newfs.f->lineDefined = line;
813 check(ls, '(');
814 if (needself)
815 add_localvar(ls, luaS_new("self"));
816 parlist(ls);
817 check(ls, ')');
818 chunk(ls);
819 check_match(ls, END, FUNCTION, line);
820 close_func(ls);
821 func_onstack(ls, &newfs);
822}
823
824static void ifpart (LexState *ls) {
825 /* ifpart -> cond THEN block [ELSE block | ELSEIF ifpart] */
826 int c = cond(ls);
827 int e;
828 check(ls, THEN);
829 block(ls);
830 e = SaveWord(ls);
831 switch (ls->token) {
832 case ELSE:
833 next(ls);
834 block(ls);
835 break;
836
837 case ELSEIF:
838 next(ls);
839 ifpart(ls);
840 break;
841 }
842 codeIf(ls, c, e);
843}
844
845static void ret (LexState *ls) {
846 /* ret -> [RETURN explist sc] */
847 if (ls->token == RETURN) {
848 listdesc e;
849 check_debugline(ls);
850 next(ls);
851 explist(ls, &e);
852 close_exp(ls, e.pc, MULT_RET);
853 code_oparg(ls, RETCODE, 0, ls->fs->nlocalvar, 0);
854 ls->fs->stacksize = ls->fs->nlocalvar; /* removes all temp values */
855 optional(ls, ';');
856 }
857}
858
859
860/*
861** For parsing expressions, we use a classic stack with priorities.
862** Each binary operator is represented by its index in "binop" + FIRSTBIN
863** (EQ=2, NE=3, ... '^'=13). The unary NOT is 0 and UNMINUS is 1.
864*/
865
866/* code of first binary operator */
867#define FIRSTBIN 2
868
869/* code for power operator (last operator)
870** '^' needs special treatment because it is right associative
871*/
872#define POW 13
873
874static int binop [] = {EQ, NE, '>', '<', LE, GE, CONC,
875 '+', '-', '*', '/', '^', 0};
876
877static int priority [POW+1] = {5, 5, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 4, 6};
878
879static OpCode opcodes [POW+1] = {NOTOP, MINUSOP, EQOP, NEQOP, GTOP, LTOP,
880 LEOP, GEOP, CONCOP, ADDOP, SUBOP, MULTOP, DIVOP, POWOP};
881
882#define MAXOPS 20
883
884typedef struct {
885 int ops[MAXOPS];
886 int top;
887} stack_op;
888
889
890static void exp1 (LexState *ls) {
891 vardesc v;
892 exp(ls, &v);
893 lua_pushvar(ls, &v);
894 if (is_in(ls->token, expfollow) < 0)
895 luaX_error(ls, "ill formed expression");
896}
897
898
899static void exp (LexState *ls, vardesc *v) {
900 exp2(ls, v);
901 while (ls->token == AND || ls->token == OR) {
902 int is_and = (ls->token == AND);
903 int pc;
904 lua_pushvar(ls, v);
905 next(ls);
906 pc = SaveWordPop(ls);
907 exp2(ls, v);
908 lua_pushvar(ls, v);
909 fix_jump(ls, pc, (is_and?ONFJMP:ONTJMP), ls->fs->pc);
910 }
911}
912
913
914static void push (LexState *ls, stack_op *s, int op) {
915 if (s->top == MAXOPS)
916 luaX_error(ls, "expression too complex");
917 s->ops[s->top++] = op;
918}
919
920
921static void prefix (LexState *ls, stack_op *s) {
922 while (ls->token == NOT || ls->token == '-') {
923 push(ls, s, ls->token==NOT?0:1);
924 next(ls);
925 }
926}
927
928static void pop_to (LexState *ls, stack_op *s, int prio) {
929 int op;
930 while (s->top > 0 && priority[(op=s->ops[s->top-1])] >= prio) {
931 code_opcode(ls, opcodes[op], op<FIRSTBIN?0:-1);
932 s->top--;
933 }
934}
935
936static void exp2 (LexState *ls, vardesc *v) {
937 stack_op s;
938 int op;
939 s.top = 0;
940 prefix(ls, &s);
941 simpleexp(ls, v);
942 while ((op = is_in(ls->token, binop)) >= 0) {
943 op += FIRSTBIN;
944 lua_pushvar(ls, v);
945 /* '^' is right associative, so must 'simulate' a higher priority */
946 pop_to(ls, &s, (op == POW)?priority[op]+1:priority[op]);
947 push(ls, &s, op);
948 next(ls);
949 prefix(ls, &s);
950 simpleexp(ls, v);
951 lua_pushvar(ls, v);
952 }
953 if (s.top > 0) {
954 lua_pushvar(ls, v);
955 pop_to(ls, &s, 0);
956 }
957}
958
959
960static void simpleexp (LexState *ls, vardesc *v) {
961 check_debugline(ls);
962 switch (ls->token) {
963 case '(': /* simpleexp -> '(' exp ')' */
964 next(ls);
965 exp(ls, v);
966 check(ls, ')');
967 break;
968
969 case NUMBER: /* simpleexp -> NUMBER */
970 code_number(ls, ls->seminfo.r);
971 next(ls);
972 v->k = VEXP; v->info = 0;
973 break;
974
975 case STRING: /* simpleexp -> STRING */
976 code_string(ls, ls->seminfo.ts);
977 next(ls);
978 v->k = VEXP; v->info = 0;
979 break;
980
981 case NIL: /* simpleexp -> NIL */
982 adjuststack(ls, -1);
983 next(ls);
984 v->k = VEXP; v->info = 0;
985 break;
986
987 case '{': /* simpleexp -> constructor */
988 constructor(ls);
989 v->k = VEXP; v->info = 0;
990 break;
991
992 case FUNCTION: { /* simpleexp -> FUNCTION body */
993 int line = ls->linenumber;
994 next(ls);
995 body(ls, 0, line);
996 v->k = VEXP; v->info = 0;
997 break;
998 }
999
1000 case NAME: case '%':
1001 var_or_func(ls, v);
1002 break;
1003
1004 default:
1005 luaX_error(ls, "<expression> expected");
1006 break;
1007 }
1008}
1009
1010static void var_or_func (LexState *ls, vardesc *v) {
1011 /* var_or_func -> ['%'] NAME var_or_func_tail */
1012 if (optional(ls, '%')) { /* upvalue? */
1013 pushupvalue(ls, checkname(ls));
1014 v->k = VEXP;
1015 v->info = 0; /* closed expression */
1016 }
1017 else /* variable name */
1018 singlevar(ls, checkname(ls), v, 0);
1019 var_or_func_tail(ls, v);
1020}
1021
1022static void var_or_func_tail (LexState *ls, vardesc *v) {
1023 for (;;) {
1024 switch (ls->token) {
1025 case '.': /* var_or_func_tail -> '.' NAME */
1026 next(ls);
1027 lua_pushvar(ls, v); /* 'v' must be on stack */
1028 v->k = VDOT;
1029 v->info = string_constant(ls->fs, checkname(ls));
1030 break;
1031
1032 case '[': /* var_or_func_tail -> '[' exp1 ']' */
1033 next(ls);
1034 lua_pushvar(ls, v); /* 'v' must be on stack */
1035 exp1(ls);
1036 check(ls, ']');
1037 v->k = VINDEXED;
1038 break;
1039
1040 case ':': /* var_or_func_tail -> ':' NAME funcparams */
1041 next(ls);
1042 lua_pushvar(ls, v); /* 'v' must be on stack */
1043 code_oparg(ls, PUSHSELF, 8, string_constant(ls->fs, checkname(ls)), 1);
1044 v->k = VEXP;
1045 v->info = funcparams(ls, 1);
1046 break;
1047
1048 case '(': case STRING: case '{': /* var_or_func_tail -> funcparams */
1049 lua_pushvar(ls, v); /* 'v' must be on stack */
1050 v->k = VEXP;
1051 v->info = funcparams(ls, 0);
1052 break;
1053
1054 default: return; /* should be follow... */
1055 }
1056 }
1057}
1058
1059static int funcparams (LexState *ls, int slf) {
1060 FuncState *fs = ls->fs;
1061 int nparams = 1; /* default value */
1062 switch (ls->token) {
1063 case '(': { /* funcparams -> '(' explist ')' */
1064 listdesc e;
1065 next(ls);
1066 explist(ls, &e);
1067 check(ls, ')');
1068 close_exp(ls, e.pc, 1);
1069 nparams = e.n;
1070 break;
1071 }
1072
1073 case '{': /* funcparams -> constructor */
1074 constructor(ls);
1075 break;
1076
1077 case STRING: /* funcparams -> STRING */
1078 next(ls);
1079 break;
1080
1081 default:
1082 luaX_error(ls, "function arguments expected");
1083 break;
1084 }
1085 code_byte(fs, 0); /* save space for opcode */
1086 code_byte(fs, 0); /* and nresult */
1087 code_byte(fs, nparams+slf);
1088 return fs->pc-1;
1089}
1090
1091static void explist (LexState *ls, listdesc *d) {
1092 switch (ls->token) {
1093 case ELSE: case ELSEIF: case END: case UNTIL:
1094 case EOS: case ';': case ')':
1095 d->pc = 0;
1096 d->n = 0;
1097 break;
1098
1099 default:
1100 explist1(ls, d);
1101 }
1102}
1103
1104static void explist1 (LexState *ls, listdesc *d) {
1105 vardesc v;
1106 exp(ls, &v);
1107 d->n = 1;
1108 while (ls->token == ',') {
1109 d->n++;
1110 lua_pushvar(ls, &v);
1111 next(ls);
1112 exp(ls, &v);
1113 }
1114 if (v.k == VEXP)
1115 d->pc = v.info;
1116 else {
1117 lua_pushvar(ls, &v);
1118 d->pc = 0;
1119 }
1120}
1121
1122static void parlist (LexState *ls) {
1123 int nparams = 0;
1124 int dots = 0;
1125 switch (ls->token) {
1126 case DOTS: /* parlist -> DOTS */
1127 next(ls);
1128 dots = 1;
1129 break;
1130
1131 case NAME: /* parlist, tailparlist -> NAME [',' tailparlist] */
1132 init:
1133 store_localvar(ls, checkname(ls), nparams++);
1134 if (ls->token == ',') {
1135 next(ls);
1136 switch (ls->token) {
1137 case DOTS: /* tailparlist -> DOTS */
1138 next(ls);
1139 dots = 1;
1140 break;
1141
1142 case NAME: /* tailparlist -> NAME [',' tailparlist] */
1143 goto init;
1144
1145 default: luaX_error(ls, "NAME or `...' expected");
1146 }
1147 }
1148 break;
1149
1150 case ')': break; /* parlist -> empty */
1151
1152 default: luaX_error(ls, "NAME or `...' expected");
1153 }
1154 code_args(ls, nparams, dots);
1155}
1156
1157static int localnamelist (LexState *ls) {
1158 /* localnamelist -> NAME {',' NAME} */
1159 int i = 1;
1160 store_localvar(ls, checkname(ls), 0);
1161 while (ls->token == ',') {
1162 next(ls);
1163 store_localvar(ls, checkname(ls), i++);
1164 }
1165 return i;
1166}
1167
1168static void decinit (LexState *ls, listdesc *d) {
1169 /* decinit -> ['=' explist1] */
1170 if (ls->token == '=') {
1171 next(ls);
1172 explist1(ls, d);
1173 }
1174 else {
1175 d->n = 0;
1176 d->pc = 0;
1177 }
1178}
1179
1180static int assignment (LexState *ls, vardesc *v, int nvars) {
1181 int left = 0;
1182 /* dotted variables <a.x> must be stored like regular indexed vars <a["x"]> */
1183 if (v->k == VDOT) {
1184 code_constant(ls, v->info);
1185 v->k = VINDEXED;
1186 }
1187 if (ls->token == ',') { /* assignment -> ',' NAME assignment */
1188 vardesc nv;
1189 next(ls);
1190 var_or_func(ls, &nv);
1191 if (nv.k == VEXP)
1192 luaX_error(ls, "syntax error");
1193 left = assignment(ls, &nv, nvars+1);
1194 }
1195 else { /* assignment -> '=' explist1 */
1196 listdesc d;
1197 check(ls, '=');
1198 explist1(ls, &d);
1199 adjust_mult_assign(ls, nvars, &d);
1200 }
1201 if (v->k != VINDEXED || left+(nvars-1) == 0) {
1202 /* global/local var or indexed var without values in between */
1203 storevar(ls, v);
1204 }
1205 else { /* indexed var with values in between*/
1206 code_oparg(ls, SETTABLE, 0, left+(nvars-1), -1);
1207 left += 2; /* table/index are not popped, because they aren't on top */
1208 }
1209 return left;
1210}
1211
1212static void constructor (LexState *ls) {
1213 /* constructor -> '{' part [';' part] '}' */
1214 int line = ls->linenumber;
1215 int pc = SaveWord(ls);
1216 int nelems;
1217 constdesc cd;
1218 deltastack(ls, 1);
1219 check(ls, '{');
1220 part(ls, &cd);
1221 nelems = cd.n;
1222 if (ls->token == ';') {
1223 constdesc other_cd;
1224 next(ls);
1225 part(ls, &other_cd);
1226 if (cd.k == other_cd.k) /* repeated parts? */
1227 luaX_error(ls, "invalid constructor syntax");
1228 nelems += other_cd.n;
1229 }
1230 check_match(ls, '}', '{', line);
1231 fix_opcode(ls, pc, CREATEARRAY, 2, nelems);
1232}
1233
1234static void part (LexState *ls, constdesc *cd) {
1235 switch (ls->token) {
1236 case ';': case '}': /* part -> empty */
1237 cd->n = 0;
1238 cd->k = ls->token;
1239 return;
1240
1241 case NAME: {
1242 vardesc v;
1243 exp(ls, &v);
1244 if (ls->token == '=') {
1245 switch (v.k) {
1246 case VGLOBAL:
1247 code_constant(ls, v.info);
1248 break;
1249 case VLOCAL:
1250 code_string(ls, ls->fs->localvar[v.info]);
1251 break;
1252 default:
1253 luaX_error(ls, "`=' unexpected");
1254 }
1255 next(ls);
1256 exp1(ls);
1257 cd->n = recfields(ls);
1258 cd->k = 1; /* record */
1259 }
1260 else {
1261 lua_pushvar(ls, &v);
1262 cd->n = listfields(ls);
1263 cd->k = 0; /* list */
1264 }
1265 break;
1266 }
1267
1268 case '[': /* part -> recfield recfields */
1269 recfield(ls);
1270 cd->n = recfields(ls);
1271 cd->k = 1; /* record */
1272 break;
1273
1274 default: /* part -> exp1 listfields */
1275 exp1(ls);
1276 cd->n = listfields(ls);
1277 cd->k = 0; /* list */
1278 break;
1279 }
1280}
1281
1282static int recfields (LexState *ls) {
1283 /* recfields -> { ',' recfield } [','] */
1284 int n = 1; /* one has been read before */
1285 while (ls->token == ',') {
1286 next(ls);
1287 if (ls->token == ';' || ls->token == '}')
1288 break;
1289 recfield(ls);
1290 n++;
1291 if (n%RFIELDS_PER_FLUSH == 0)
1292 flush_record(ls, RFIELDS_PER_FLUSH);
1293 }
1294 flush_record(ls, n%RFIELDS_PER_FLUSH);
1295 return n;
1296}
1297
1298static int listfields (LexState *ls) {
1299 /* listfields -> { ',' exp1 } [','] */
1300 int n = 1; /* one has been read before */
1301 while (ls->token == ',') {
1302 next(ls);
1303 if (ls->token == ';' || ls->token == '}')
1304 break;
1305 exp1(ls);
1306 n++;
1307 if (n%LFIELDS_PER_FLUSH == 0)
1308 flush_list(ls, n/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH);
1309 }
1310 flush_list(ls, n/LFIELDS_PER_FLUSH, n%LFIELDS_PER_FLUSH);
1311 return n;
1312}
1313
1314static void recfield (LexState *ls) {
1315 /* recfield -> (NAME | '['exp1']') = exp1 */
1316 switch (ls->token) {
1317 case NAME:
1318 code_string(ls, checkname(ls));
1319 break;
1320
1321 case '[':
1322 next(ls);
1323 exp1(ls);
1324 check(ls, ']');
1325 break;
1326
1327 default: luaX_error(ls, "NAME or `[' expected");
1328 }
1329 check(ls, '=');
1330 exp1(ls);
1331}
1332
diff --git a/lstate.h b/lstate.h
index 06b4aced..21cbef59 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.h,v 1.6 1997/12/17 20:48:58 roberto Exp roberto $ 2** $Id: lstate.h,v 1.7 1998/01/09 14:57:43 roberto Exp $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -57,8 +57,6 @@ typedef struct LState {
57 struct IM *IMtable; /* table for tag methods */ 57 struct IM *IMtable; /* table for tag methods */
58 int IMtable_size; /* size of IMtable */ 58 int IMtable_size; /* size of IMtable */
59 int last_tag; /* last used tag in IMtable */ 59 int last_tag; /* last used tag in IMtable */
60 struct FuncState *mainState, *currState; /* point to local structs in yacc */
61 struct LexState *lexstate; /* point to local struct in yacc */
62 struct ref *refArray; /* locked objects */ 60 struct ref *refArray; /* locked objects */
63 int refSize; /* size of refArray */ 61 int refSize; /* size of refArray */
64 unsigned long GCthreshold; 62 unsigned long GCthreshold;
diff --git a/lua.stx b/lua.stx
deleted file mode 100644
index 41aff108..00000000
--- a/lua.stx
+++ /dev/null
@@ -1,940 +0,0 @@
1%{
2/*
3** $Id: lua.stx,v 1.36 1998/03/25 18:52:29 roberto Exp roberto $
4** Syntax analizer and code generator
5** See Copyright Notice in lua.h
6*/
7
8
9#include <stdlib.h>
10#include <string.h>
11
12#include "lauxlib.h"
13#include "ldo.h"
14#include "lfunc.h"
15#include "llex.h"
16#include "lmem.h"
17#include "lopcodes.h"
18#include "lparser.h"
19#include "lstate.h"
20#include "lstring.h"
21#include "lua.h"
22#include "luadebug.h"
23#include "lzio.h"
24
25
26int luaY_parse (void);
27
28
29#define MES_LIM(x) "(limit=" x ")"
30
31
32/* size of a "normal" jump instruction: OpCode + 1 byte */
33#define JMPSIZE 2
34
35/* maximum number of local variables */
36#define MAXLOCALS 32
37#define SMAXLOCALS "32"
38
39#define MINGLOBAL (MAXLOCALS+1)
40
41/* maximum number of variables in a multiple assignment */
42#define MAXVAR 32
43#define SMAXVAR "32"
44
45/* maximum number of nested functions */
46#define MAXSTATES 6
47#define SMAXSTATES "6"
48
49/* maximum number of upvalues */
50#define MAXUPVALUES 16
51#define SMAXUPVALUES "16"
52
53
54
55/*
56** Variable descriptor:
57** if 0<n<MINGLOBAL, represents local variable indexed by (n-1);
58** if MINGLOBAL<=n, represents global variable at position (n-MINGLOBAL);
59** if n<0, indexed variable with index (-n)-1 (table on top of stack);
60** if n==0, an indexed variable (table and index on top of stack)
61** Must be long to store negative Word values.
62*/
63typedef long vardesc;
64
65#define isglobal(v) (MINGLOBAL<=(v))
66#define globalindex(v) ((v)-MINGLOBAL)
67#define islocal(v) (0<(v) && (v)<MINGLOBAL)
68#define localindex(v) ((v)-1)
69#define isdot(v) (v<0)
70#define dotindex(v) ((-(v))-1)
71
72/* state needed to generate code for a given function */
73typedef struct FuncState {
74 TProtoFunc *f; /* current function header */
75 int pc; /* next position to code */
76 TaggedString *localvar[MAXLOCALS]; /* store local variable names */
77 int stacksize; /* number of values on activation register */
78 int maxstacksize; /* maximum number of values on activation register */
79 int nlocalvar; /* number of active local variables */
80 int nupvalues; /* number of upvalues */
81 int nvars; /* number of entries in f->locvars */
82 int maxcode; /* size of f->code */
83 int maxvars; /* size of f->locvars (-1 if no debug information) */
84 int maxconsts; /* size of f->consts */
85 vardesc varbuffer[MAXVAR]; /* variables in an assignment list */
86 vardesc upvalues[MAXUPVALUES]; /* upvalues */
87} FuncState;
88
89
90
91#define YYPURE 1
92
93
94void luaY_syntaxerror (char *s, char *token)
95{
96 if (token[0] == 0)
97 token = "<eof>";
98 luaL_verror("%.100s;\n last token read: \"%.50s\" at line %d in file %.50s",
99 s, token, L->lexstate->linenumber, L->mainState->f->fileName->str);
100}
101
102
103void luaY_error (char *s)
104{
105 luaY_syntaxerror(s, luaX_lasttoken());
106}
107
108
109static void check_pc (int n)
110{
111 FuncState *fs = L->currState;
112 if (fs->pc+n > fs->maxcode)
113 fs->maxcode = luaM_growvector(&fs->f->code, fs->maxcode,
114 Byte, codeEM, MAX_INT);
115}
116
117
118static void code_byte (Byte c)
119{
120 check_pc(1);
121 L->currState->f->code[L->currState->pc++] = c;
122}
123
124
125static void deltastack (int delta)
126{
127 FuncState *fs = L->currState;
128 fs->stacksize += delta;
129 if (fs->stacksize > fs->maxstacksize) {
130 if (fs->stacksize > 255)
131 luaY_error("function/expression too complex");
132 fs->maxstacksize = fs->stacksize;
133 }
134}
135
136
137static int code_oparg_at (int pc, OpCode op, int builtin, int arg, int delta)
138{
139 Byte *code = L->currState->f->code;
140 deltastack(delta);
141 if (arg < builtin) {
142 code[pc] = op+1+arg;
143 return 1;
144 }
145 else if (arg <= 255) {
146 code[pc] = op;
147 code[pc+1] = arg;
148 return 2;
149 }
150 else if (arg <= MAX_WORD) {
151 code[pc] = op+1+builtin;
152 code[pc+1] = arg>>8;
153 code[pc+2] = arg&0xFF;
154 return 3;
155 }
156 else luaY_error("code too long " MES_LIM("64K"));
157 return 0; /* to avoid warnings */
158}
159
160
161static int fix_opcode (int pc, OpCode op, int builtin, int arg)
162{
163 FuncState *fs = L->currState;
164 if (arg < builtin) { /* close space */
165 luaO_memdown(fs->f->code+pc+1, fs->f->code+pc+2, fs->pc-(pc+2));
166 fs->pc--;
167 }
168 else if (arg > 255) { /* open space */
169 check_pc(1);
170 luaO_memup(fs->f->code+pc+1, fs->f->code+pc, fs->pc-pc);
171 fs->pc++;
172 }
173 return code_oparg_at(pc, op, builtin, arg, 0) - 2;
174}
175
176
177static void code_oparg (OpCode op, int builtin, int arg, int delta)
178{
179 check_pc(3); /* maximum code size */
180 L->currState->pc += code_oparg_at(L->currState->pc, op, builtin, arg, delta);
181}
182
183
184static void code_opcode (OpCode op, int delta)
185{
186 deltastack(delta);
187 code_byte(op);
188}
189
190
191static void code_pop (OpCode op)
192{
193 code_opcode(op, -1);
194}
195
196/* binary operations get 2 arguments and leave one, so they pop one */
197#define code_binop(op) code_pop(op)
198
199
200static void code_neutralop (OpCode op)
201{
202 code_opcode(op, 0);
203}
204
205/* unary operations get 1 argument and leave one, so they are neutral */
206#define code_unop(op) code_neutralop(op)
207
208
209static void code_constant (int c)
210{
211 code_oparg(PUSHCONSTANT, 8, c, 1);
212}
213
214
215static int next_constant (FuncState *cs)
216{
217 TProtoFunc *f = cs->f;
218 if (f->nconsts >= cs->maxconsts) {
219 cs->maxconsts = luaM_growvector(&f->consts, cs->maxconsts, TObject,
220 constantEM, MAX_WORD);
221 }
222 return f->nconsts++;
223}
224
225
226static int string_constant (TaggedString *s, FuncState *cs)
227{
228 TProtoFunc *f = cs->f;
229 int c = s->constindex;
230 if (!(c < f->nconsts &&
231 ttype(&f->consts[c]) == LUA_T_STRING && tsvalue(&f->consts[c]) == s)) {
232 c = next_constant(cs);
233 ttype(&f->consts[c]) = LUA_T_STRING;
234 tsvalue(&f->consts[c]) = s;
235 s->constindex = c; /* hint for next time */
236 }
237 return c;
238}
239
240
241static void code_string (TaggedString *s)
242{
243 code_constant(string_constant(s, L->currState));
244}
245
246
247#define LIM 20
248static int real_constant (real r)
249{
250 /* check whether 'r' has appeared within the last LIM entries */
251 TObject *cnt = L->currState->f->consts;
252 int c = L->currState->f->nconsts;
253 int lim = c < LIM ? 0 : c-LIM;
254 while (--c >= lim) {
255 if (ttype(&cnt[c]) == LUA_T_NUMBER && nvalue(&cnt[c]) == r)
256 return c;
257 }
258 /* not found; create a luaM_new entry */
259 c = next_constant(L->currState);
260 cnt = L->currState->f->consts; /* 'next_constant' may reallocate this vector */
261 ttype(&cnt[c]) = LUA_T_NUMBER;
262 nvalue(&cnt[c]) = r;
263 return c;
264}
265
266
267static void code_number (real f)
268{
269 int i;
270 if (f >= 0 && f <= (real)MAX_WORD && (real)(i=(int)f) == f)
271 code_oparg(PUSHNUMBER, 3, i, 1); /* f has an (short) integer value */
272 else
273 code_constant(real_constant(f));
274}
275
276
277static void flush_record (int n)
278{
279 if (n > 0)
280 code_oparg(SETMAP, 1, n-1, -2*n);
281}
282
283static void flush_list (int m, int n)
284{
285 if (n == 0) return;
286 code_oparg(SETLIST, 1, m, -n);
287 code_byte(n);
288}
289
290
291static void luaI_registerlocalvar (TaggedString *varname, int line)
292{
293 FuncState *fs = L->currState;
294 if (fs->maxvars != -1) { /* debug information? */
295 if (fs->nvars >= fs->maxvars)
296 fs->maxvars = luaM_growvector(&fs->f->locvars, fs->maxvars,
297 LocVar, "", MAX_WORD);
298 fs->f->locvars[fs->nvars].varname = varname;
299 fs->f->locvars[fs->nvars].line = line;
300 fs->nvars++;
301 }
302}
303
304
305static void luaI_unregisterlocalvar (int line)
306{
307 luaI_registerlocalvar(NULL, line);
308}
309
310
311static void store_localvar (TaggedString *name, int n)
312{
313 if (L->currState->nlocalvar+n < MAXLOCALS)
314 L->currState->localvar[L->currState->nlocalvar+n] = name;
315 else
316 luaY_error("too many local variables " MES_LIM(SMAXLOCALS));
317 luaI_registerlocalvar(name, L->lexstate->linenumber);
318}
319
320static void add_localvar (TaggedString *name)
321{
322 store_localvar(name, 0);
323 L->currState->nlocalvar++;
324}
325
326
327/*
328** dotted variables <a.x> must be stored like regular indexed vars <a["x"]>
329*/
330static vardesc var2store (vardesc var)
331{
332 if (isdot(var)) {
333 code_constant(dotindex(var));
334 var = 0;
335 }
336 return var;
337}
338
339
340static void add_varbuffer (vardesc var, int n)
341{
342 if (n >= MAXVAR)
343 luaY_error("variable buffer overflow " MES_LIM(SMAXVAR));
344 L->currState->varbuffer[n] = var2store(var);
345}
346
347
348static int aux_localname (TaggedString *n, FuncState *st)
349{
350 int i;
351 for (i=st->nlocalvar-1; i >= 0; i--)
352 if (n == st->localvar[i]) return i; /* local var index */
353 return -1; /* not found */
354}
355
356
357static vardesc singlevar (TaggedString *n, FuncState *st)
358{
359 int i = aux_localname(n, st);
360 if (i == -1) { /* check shadowing */
361 int l;
362 for (l=1; l<=(st-L->mainState); l++)
363 if (aux_localname(n, st-l) >= 0)
364 luaY_syntaxerror("cannot access a variable in outer scope", n->str);
365 return string_constant(n, st)+MINGLOBAL; /* global value */
366 }
367 else return i+1; /* local value */
368}
369
370
371static int indexupvalue (TaggedString *n)
372{
373 vardesc v = singlevar(n, L->currState-1);
374 int i;
375 for (i=0; i<L->currState->nupvalues; i++) {
376 if (L->currState->upvalues[i] == v)
377 return i;
378 }
379 /* new one */
380 if (++(L->currState->nupvalues) > MAXUPVALUES)
381 luaY_error("too many upvalues in a single function " MES_LIM(SMAXUPVALUES));
382 L->currState->upvalues[i] = v; /* i = L->currState->nupvalues - 1 */
383 return i;
384}
385
386
387static void pushupvalue (TaggedString *n)
388{
389 int i;
390 if (L->currState == L->mainState)
391 luaY_error("cannot access upvalue in main");
392 if (aux_localname(n, L->currState) >= 0)
393 luaY_syntaxerror("cannot access an upvalue in current scope", n->str);
394 i = indexupvalue(n);
395 code_oparg(PUSHUPVALUE, 2, i, 1);
396}
397
398
399void luaY_codedebugline (int line)
400{
401 if (lua_debug && line != L->lexstate->lastline) {
402 code_oparg(SETLINE, 0, line, 0);
403 L->lexstate->lastline = line;
404 }
405}
406
407
408static void adjuststack (int n)
409{
410 if (n > 0)
411 code_oparg(POP, 2, n-1, -n);
412 else if (n < 0)
413 code_oparg(PUSHNIL, 1, (-n)-1, -n);
414}
415
416
417static long adjust_functioncall (long exp, int nresults)
418{
419 if (exp <= 0)
420 return -exp; /* exp is -list length */
421 else {
422 int temp = L->currState->f->code[exp];
423 int nparams = L->currState->f->code[exp-1];
424 exp += fix_opcode(exp-2, CALLFUNC, 2, nresults);
425 L->currState->f->code[exp] = nparams;
426 if (nresults != MULT_RET)
427 deltastack(nresults);
428 deltastack(-(nparams+1));
429 return temp+nresults;
430 }
431}
432
433
434static void adjust_mult_assign (int vars, long exps)
435{
436 if (exps > 0) { /* must correct function call */
437 int diff = L->currState->f->code[exps] - vars;
438 if (diff < 0)
439 adjust_functioncall(exps, -diff);
440 else {
441 adjust_functioncall(exps, 0);
442 adjuststack(diff);
443 }
444 }
445 else adjuststack((-exps)-vars);
446}
447
448
449static void code_args (int nparams, int dots)
450{
451 L->currState->nlocalvar += nparams; /* "self" may already be there */
452 nparams = L->currState->nlocalvar;
453 if (!dots) {
454 L->currState->f->code[1] = nparams; /* fill-in arg information */
455 deltastack(nparams);
456 }
457 else {
458 L->currState->f->code[1] = nparams+ZEROVARARG;
459 deltastack(nparams+1);
460 add_localvar(luaS_new("arg"));
461 }
462}
463
464
465static void lua_pushvar (vardesc var)
466{
467 if (isglobal(var))
468 code_oparg(GETGLOBAL, 8, globalindex(var), 1);
469 else if (islocal(var))
470 code_oparg(PUSHLOCAL, 8, localindex(var), 1);
471 else if (isdot(var))
472 code_oparg(GETDOTTED, 8, dotindex(var), 0);
473 else
474 code_pop(GETTABLE);
475}
476
477
478static void storevar (vardesc var)
479{
480 if (var == 0) /* indexed var */
481 code_opcode(SETTABLE0, -3);
482 else if (isglobal(var))
483 code_oparg(SETGLOBAL, 8, globalindex(var), -1);
484 else /* local var */
485 code_oparg(SETLOCAL, 8, localindex(var), -1);
486}
487
488
489/* returns how many elements are left as 'garbage' on the stack */
490static int lua_codestore (int i, int left)
491{
492 if (L->currState->varbuffer[i] != 0 || /* global or local var or */
493 left+i == 0) { /* indexed var without values in between */
494 storevar(L->currState->varbuffer[i]);
495 return left;
496 }
497 else { /* indexed var with values in between*/
498 code_oparg(SETTABLE, 0, left+i, -1);
499 return left+2; /* table/index are not popped, since they are not on top */
500 }
501}
502
503
504static int fix_jump (int pc, OpCode op, int n)
505{
506 /* jump is relative to position following jump instruction */
507 return fix_opcode(pc, op, 0, n-(pc+JMPSIZE));
508}
509
510
511static void fix_upjmp (OpCode op, int pos)
512{
513 int delta = L->currState->pc+JMPSIZE - pos; /* jump is relative */
514 if (delta > 255) delta++;
515 code_oparg(op, 0, delta, 0);
516}
517
518
519static void codeIf (int thenAdd, int elseAdd)
520{
521 int elseinit = elseAdd+JMPSIZE;
522 if (L->currState->pc == elseinit) { /* no else part */
523 L->currState->pc -= JMPSIZE;
524 elseinit = L->currState->pc;
525 }
526 else
527 elseinit += fix_jump(elseAdd, JMP, L->currState->pc);
528 fix_jump(thenAdd, IFFJMP, elseinit);
529}
530
531
532static void code_shortcircuit (int pc, OpCode op)
533{
534 fix_jump(pc, op, L->currState->pc);
535}
536
537
538static void codereturn (void)
539{
540 code_oparg(RETCODE, 0, L->currState->nlocalvar, 0);
541 L->currState->stacksize = L->currState->nlocalvar;
542}
543
544
545static void func_onstack (TProtoFunc *f)
546{
547 int i;
548 int nupvalues = (L->currState+1)->nupvalues;
549 int c = next_constant(L->currState);
550 ttype(&L->currState->f->consts[c]) = LUA_T_PROTO;
551 L->currState->f->consts[c].value.tf = (L->currState+1)->f;
552 if (nupvalues == 0)
553 code_constant(c);
554 else {
555 for (i=0; i<nupvalues; i++)
556 lua_pushvar((L->currState+1)->upvalues[i]);
557 code_oparg(CLOSURE, 0, c, -nupvalues+1);
558 code_byte(nupvalues);
559 }
560}
561
562
563static void init_state (TaggedString *filename)
564{
565 TProtoFunc *f = luaF_newproto();
566 FuncState *fs = L->currState;
567 fs->stacksize = 0;
568 fs->maxstacksize = 0;
569 fs->nlocalvar = 0;
570 fs->nupvalues = 0;
571 fs->f = f;
572 f->fileName = filename;
573 fs->pc = 0;
574 fs->maxcode = 0;
575 f->code = NULL;
576 fs->maxconsts = 0;
577 if (lua_debug) {
578 fs->nvars = 0;
579 fs->maxvars = 0;
580 }
581 else
582 fs->maxvars = -1; /* flag no debug information */
583 code_byte(0); /* to be filled with stacksize */
584 code_byte(0); /* to be filled with arg information */
585 L->lexstate->lastline = 0; /* invalidate it */
586}
587
588
589static void init_func (void)
590{
591 if (L->currState-L->mainState >= MAXSTATES-1)
592 luaY_error("too many nested functions " MES_LIM(SMAXSTATES));
593 L->currState++;
594 init_state(L->mainState->f->fileName);
595 luaY_codedebugline(L->lexstate->linenumber);
596 L->currState->f->lineDefined = L->lexstate->linenumber;
597}
598
599static TProtoFunc *close_func (void)
600{
601 TProtoFunc *f = L->currState->f;
602 code_neutralop(ENDCODE);
603 f->code[0] = L->currState->maxstacksize;
604 f->code = luaM_reallocvector(f->code, L->currState->pc, Byte);
605 f->consts = luaM_reallocvector(f->consts, f->nconsts, TObject);
606 if (L->currState->maxvars != -1) { /* debug information? */
607 luaI_registerlocalvar(NULL, -1); /* flag end of vector */
608 f->locvars = luaM_reallocvector(f->locvars, L->currState->nvars, LocVar);
609 }
610 L->currState--;
611 return f;
612}
613
614
615/*
616** Parse Lua code.
617*/
618TProtoFunc *luaY_parser (ZIO *z)
619{
620 struct LexState lexstate;
621 FuncState state[MAXSTATES];
622 L->currState = L->mainState = &state[0];
623 L->lexstate = &lexstate;
624 luaX_setinput(z);
625 init_state(luaS_new(zname(z)));
626 if (luaY_parse()) lua_error("parse error");
627 return close_func();
628}
629
630
631%}
632
633
634%union
635{
636 int vInt;
637 real vReal;
638 char *pChar;
639 long vLong;
640 TaggedString *pTStr;
641 TProtoFunc *pFunc;
642}
643
644%start chunk
645
646%token NIL
647%token IF THEN ELSE ELSEIF WHILE DO REPEAT UNTIL END
648%token RETURN
649%token LOCAL
650%token FUNCTION
651%token DOTS
652%token <vReal> NUMBER
653%token <pTStr> NAME STRING
654
655%type <vInt> SaveWord, cond, GetPC, SaveWordPop, SaveWordPush
656%type <vLong> exprlist, exprlist1 /* if > 0, points to function return
657 counter (which has list length); if <= 0, -list lenght */
658%type <vLong> functioncall, expr, sexp /* if != 0, points to function return
659 counter */
660%type <vInt> varlist1, funcParams, funcvalue
661%type <vInt> fieldlist, localnamelist, decinit
662%type <vInt> ffieldlist1, lfieldlist1, ffieldlist, lfieldlist, part
663%type <vLong> var, varname, funcname /* vardesc */
664
665
666%left AND OR
667%left EQ NE '>' '<' LE GE
668%left CONC
669%left '+' '-'
670%left '*' '/'
671%left UNARY NOT
672%right '^'
673
674
675%% /* beginning of rules section */
676
677
678chunk : statlist ret ;
679
680statlist : /* empty */
681 | statlist stat sc
682 { LUA_ASSERT(L->currState->stacksize == L->currState->nlocalvar,
683 "stack size != # local vars"); }
684 ;
685
686sc : /* empty */ | ';' ;
687
688stat : IF cond THEN block SaveWord elsepart END { codeIf($2, $5); }
689
690 | DO block END
691
692 | WHILE GetPC cond DO block END
693 {{
694 FuncState *fs = L->currState;
695 int expsize = $3-$2;
696 int newpos = $2+JMPSIZE;
697 check_pc(expsize);
698 memcpy(fs->f->code+fs->pc, fs->f->code+$2, expsize);
699 luaO_memdown(fs->f->code+$2, fs->f->code+$3, fs->pc-$2);
700 newpos += fix_jump($2, JMP, fs->pc-expsize);
701 fix_upjmp(IFTUPJMP, newpos);
702 }}
703
704 | REPEAT GetPC block UNTIL expr1
705 {
706 fix_upjmp(IFFUPJMP, $2);
707 deltastack(-1); /* pops condition */
708 }
709
710 | varlist1 '=' exprlist1
711 {{
712 int i;
713 int left = 0;
714 adjust_mult_assign($1, $3);
715 for (i=$1-1; i>=0; i--)
716 left = lua_codestore(i, left);
717 adjuststack(left); /* remove eventual 'garbage' left on stack */
718 }}
719
720 | functioncall { adjust_functioncall($1, 0); }
721
722 | LOCAL localnamelist decinit
723 {
724 L->currState->nlocalvar += $2;
725 adjust_mult_assign($2, $3);
726 }
727
728 | FUNCTION funcname body { storevar($2); }
729 ;
730
731block : {$<vInt>$ = L->currState->nlocalvar;} chunk
732 {
733 adjuststack(L->currState->nlocalvar - $<vInt>1);
734 for (; L->currState->nlocalvar > $<vInt>1; L->currState->nlocalvar--)
735 luaI_unregisterlocalvar(L->lexstate->linenumber);
736 }
737 ;
738
739funcname : varname { $$ = $1; init_func(); }
740 | fvarname '.' fname
741 {
742 $$ = 0; /* flag indexed variable */
743 init_func();
744 }
745 | fvarname ':' fname
746 {
747 $$ = 0; /* flag indexed variable */
748 init_func();
749 add_localvar(luaS_new("self"));
750 }
751 ;
752
753fvarname : varname { lua_pushvar($1); } ;
754
755fname : NAME { code_string($1); } ;
756
757body : '(' parlist ')' chunk END { func_onstack(close_func()); } ;
758
759elsepart : /* empty */
760 | ELSE block
761 | ELSEIF cond THEN block SaveWord elsepart { codeIf($2, $5); }
762 ;
763
764ret : /* empty */
765 | RETURN exprlist sc
766 {
767 adjust_functioncall($2, MULT_RET);
768 codereturn();
769 }
770 ;
771
772GetPC : /* empty */ { $$ = L->currState->pc; } ;
773
774SaveWord : /* empty */
775 { $$ = L->currState->pc;
776 check_pc(JMPSIZE);
777 L->currState->pc += JMPSIZE; /* open space */
778 }
779 ;
780
781SaveWordPop : SaveWord { $$ = $1; deltastack(-1); /* pop condition */ } ;
782
783SaveWordPush : SaveWord { $$ = $1; deltastack(1); /* push a value */ } ;
784
785cond : expr1 SaveWordPop { $$ = $2; } ;
786
787expr1 : expr { adjust_functioncall($1, 1); } ;
788
789expr : '(' expr ')' { $$ = $2; }
790 | expr1 EQ expr1 { code_binop(EQOP); $$ = 0; }
791 | expr1 '<' expr1 { code_binop(LTOP); $$ = 0; }
792 | expr1 '>' expr1 { code_binop(GTOP); $$ = 0; }
793 | expr1 NE expr1 { code_binop(NEQOP); $$ = 0; }
794 | expr1 LE expr1 { code_binop(LEOP); $$ = 0; }
795 | expr1 GE expr1 { code_binop(GEOP); $$ = 0; }
796 | expr1 '+' expr1 { code_binop(ADDOP); $$ = 0; }
797 | expr1 '-' expr1 { code_binop(SUBOP); $$ = 0; }
798 | expr1 '*' expr1 { code_binop(MULTOP); $$ = 0; }
799 | expr1 '/' expr1 { code_binop(DIVOP); $$ = 0; }
800 | expr1 '^' expr1 { code_binop(POWOP); $$ = 0; }
801 | expr1 CONC expr1 { code_binop(CONCOP); $$ = 0; }
802 | '-' expr1 %prec UNARY { code_unop(MINUSOP); $$ = 0;}
803 | NOT expr1 { code_unop(NOTOP); $$ = 0;}
804 | sexp { $$ = $1; /* simple expressions */ }
805 | table { $$ = 0; }
806 | NUMBER { code_number($1); $$ = 0; }
807 | STRING { code_string($1); $$ = 0; }
808 | NIL { adjuststack(-1); $$ = 0; }
809 | FUNCTION { init_func(); } body { $$ = 0; }
810 | expr1 AND SaveWordPop expr1 { code_shortcircuit($3, ONFJMP); $$ = 0; }
811 | expr1 OR SaveWordPop expr1 { code_shortcircuit($3, ONTJMP); $$ = 0; }
812 ;
813
814sexp1 : sexp { adjust_functioncall($1, 1); } ;
815
816sexp : var { lua_pushvar($1); $$ = 0; }
817 | '%' NAME { pushupvalue($2); $$ = 0; }
818 | functioncall { $$ = $1; }
819 ;
820
821var : varname { $$ = $1; }
822 | sexp1 '[' expr1 ']' { $$ = 0; } /* indexed variable */
823 | sexp1 '.' NAME { $$ = (-string_constant($3, L->currState))-1; }
824 ;
825
826varname : NAME { $$ = singlevar($1, L->currState); } ;
827
828table : '{' SaveWordPush fieldlist '}' { fix_opcode($2, CREATEARRAY, 2, $3); } ;
829
830functioncall : funcvalue funcParams
831 {
832 code_byte(0); /* save space for opcode */
833 code_byte($1+$2); /* number of parameters */
834 $$ = L->currState->pc;
835 code_byte(0); /* must be adjusted by other rules */
836 }
837 ;
838
839funcvalue : sexp1 { $$ = 0; }
840 | sexp1 ':' NAME
841 {
842 code_oparg(PUSHSELF, 8, string_constant($3, L->currState), 1);
843 $$ = 1;
844 }
845 ;
846
847funcParams : '(' exprlist ')' { $$ = adjust_functioncall($2, 1); }
848 | table { $$ = 1; }
849 | STRING { code_string($1); $$ = 1; }
850 ;
851
852exprlist : /* empty */ { $$ = 0; }
853 | exprlist1 { $$ = $1; }
854 ;
855
856exprlist1 : expr { if ($1 != 0) $$ = $1; else $$ = -1; }
857 | exprlist1 ',' { $<vLong>$ = adjust_functioncall($1, 1); } expr
858 {
859 if ($4 == 0) $$ = -($<vLong>3 + 1); /* -length */
860 else {
861 L->currState->f->code[$4] = $<vLong>3; /* store list length */
862 $$ = $4;
863 }
864 }
865 ;
866
867parlist : /* empty */ { code_args(0, 0); }
868 | DOTS { code_args(0, 1); }
869 | localnamelist { code_args($1, 0); }
870 | localnamelist ',' DOTS { code_args($1, 1); }
871 ;
872
873fieldlist : part { $$ = abs($1); }
874 | part ';' part
875 {
876 if ($1*$3 > 0) /* repeated parts? */
877 luaY_error("invalid constructor syntax");
878 $$ = abs($1)+abs($3);
879 }
880 ;
881
882part : /* empty */ { $$ = 0; }
883 | ffieldlist { $$ = $1; }
884 | lfieldlist { $$ = $1; }
885 ;
886
887lastcomma : /* empty */ | ',' ;
888
889ffieldlist : ffieldlist1 lastcomma
890 {
891 flush_record($1%RFIELDS_PER_FLUSH);
892 $$ = -$1; /* negative signals a "record" part */
893 }
894 ;
895
896lfieldlist : lfieldlist1 lastcomma
897 {
898 flush_list($1/LFIELDS_PER_FLUSH, $1%LFIELDS_PER_FLUSH);
899 $$ = $1;
900 }
901 ;
902
903ffieldlist1 : ffield {$$=1;}
904 | ffieldlist1 ',' ffield
905 {
906 $$=$1+1;
907 if ($$%RFIELDS_PER_FLUSH == 0)
908 flush_record(RFIELDS_PER_FLUSH);
909 }
910 ;
911
912ffield : ffieldkey '=' expr1 ;
913
914ffieldkey : '[' expr1 ']'
915 | fname
916 ;
917
918lfieldlist1 : expr1 {$$=1;}
919 | lfieldlist1 ',' expr1
920 {
921 $$=$1+1;
922 if ($$%LFIELDS_PER_FLUSH == 0)
923 flush_list($$/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH);
924 }
925 ;
926
927varlist1 : var { $$ = 1; add_varbuffer($1, 0); }
928 | varlist1 ',' var { add_varbuffer($3, $1); $$ = $1+1; }
929 ;
930
931localnamelist : NAME {store_localvar($1, 0); $$ = 1;}
932 | localnamelist ',' NAME { store_localvar($3, $1); $$ = $1+1; }
933 ;
934
935decinit : /* empty */ { $$ = 0; }
936 | '=' exprlist1 { $$ = $2; }
937 ;
938
939%%
940
diff --git a/makefile b/makefile
index f5b426b4..c9a76afd 100644
--- a/makefile
+++ b/makefile
@@ -1,5 +1,5 @@
1# 1#
2## $Id: makefile,v 1.10 1998/01/05 17:12:54 roberto Exp roberto $ 2## $Id: makefile,v 1.11 1998/05/18 22:26:03 roberto Exp roberto $
3## Makefile 3## Makefile
4## See Copyright Notice in lua.h 4## See Copyright Notice in lua.h
5# 5#
@@ -18,7 +18,7 @@
18# define LUA_COMPAT2_5 if yous system does need to be compatible with 18# define LUA_COMPAT2_5 if yous system does need to be compatible with
19# version 2.5 (or older) 19# version 2.5 (or older)
20# 20#
21#define LUA_NUM_TYPE if you need numbers to be different from double 21# define LUA_NUM_TYPE if you need numbers to be different from double
22 22
23CONFIG = -DPOPEN -D_POSIX_SOURCE 23CONFIG = -DPOPEN -D_POSIX_SOURCE
24#CONFIG = -DLUA_COMPAT2_5 -DOLD_ANSI -DDEBUG 24#CONFIG = -DLUA_COMPAT2_5 -DOLD_ANSI -DDEBUG
@@ -46,8 +46,8 @@ LUAOBJS = \
46 llex.o \ 46 llex.o \
47 lmem.o \ 47 lmem.o \
48 lobject.o \ 48 lobject.o \
49 lparser.o \
49 lstate.o \ 50 lstate.o \
50 lstx.o \
51 lstring.o \ 51 lstring.o \
52 ltable.o \ 52 ltable.o \
53 ltm.o \ 53 ltm.o \
@@ -75,16 +75,11 @@ liblualib.a : $(LIBOBJS)
75liblua.so.1.0 : lua.o 75liblua.so.1.0 : lua.o
76 ld -o liblua.so.1.0 $(LUAOBJS) 76 ld -o liblua.so.1.0 $(LUAOBJS)
77 77
78lstx.c lstx.h : lua.stx
79 bison -o lstx.c -p luaY_ -d lua.stx
80# yacc -d lua.stx
81# sed -e 's/yy/luaY_/g' -e 's/malloc\.h/stdlib\.h/g' y.tab.c > lstx.c
82# sed -e 's/yy/luaY_/g' y.tab.h > lstx.h
83 78
84clear : 79clear :
85 rcsclean 80 rcsclean
86 rm -f *.o 81 rm -f *.o
87 rm -f lstx.c lstx.h 82 rm -f
88 co lua.h lualib.h luadebug.h 83 co lua.h lualib.h luadebug.h
89 84
90 85
@@ -94,6 +89,7 @@ clear :
94%.c : RCS/%.c,v 89%.c : RCS/%.c,v
95 co $@ 90 co $@
96 91
92
97lapi.o: lapi.c lapi.h lua.h lobject.h lauxlib.h ldo.h lstate.h lfunc.h \ 93lapi.o: lapi.c lapi.h lua.h lobject.h lauxlib.h ldo.h lstate.h lfunc.h \
98 lgc.h lmem.h lstring.h ltable.h ltm.h luadebug.h lvm.h 94 lgc.h lmem.h lstring.h ltable.h ltm.h luadebug.h lvm.h
99lauxlib.o: lauxlib.c lauxlib.h lua.h luadebug.h 95lauxlib.o: lauxlib.c lauxlib.h lua.h luadebug.h
@@ -107,18 +103,18 @@ lgc.o: lgc.c ldo.h lobject.h lua.h lstate.h lfunc.h lgc.h lmem.h \
107 lstring.h ltable.h ltm.h 103 lstring.h ltable.h ltm.h
108liolib.o: liolib.c lauxlib.h lua.h luadebug.h lualib.h 104liolib.o: liolib.c lauxlib.h lua.h luadebug.h lualib.h
109llex.o: llex.c lauxlib.h lua.h llex.h lobject.h lzio.h lmem.h \ 105llex.o: llex.c lauxlib.h lua.h llex.h lobject.h lzio.h lmem.h \
110 lparser.h lstate.h lstring.h lstx.h luadebug.h 106 lparser.h lstate.h lstring.h luadebug.h
111lmathlib.o: lmathlib.c lauxlib.h lua.h lualib.h 107lmathlib.o: lmathlib.c lauxlib.h lua.h lualib.h
112lmem.o: lmem.c lmem.h lstate.h lobject.h lua.h 108lmem.o: lmem.c lmem.h lstate.h lobject.h lua.h
113lobject.o: lobject.c lobject.h lua.h 109lobject.o: lobject.c lobject.h lua.h
110lparser.o: lparser.c lauxlib.h lua.h ldo.h lobject.h lstate.h lfunc.h \
111 llex.h lzio.h lmem.h lopcodes.h lparser.h lstring.h luadebug.h
114lstate.o: lstate.c lbuiltin.h ldo.h lobject.h lua.h lstate.h lfunc.h \ 112lstate.o: lstate.c lbuiltin.h ldo.h lobject.h lua.h lstate.h lfunc.h \
115 lgc.h llex.h lzio.h lmem.h lstring.h ltable.h ltm.h 113 lgc.h llex.h lzio.h lmem.h lstring.h ltable.h ltm.h
116lstring.o: lstring.c lmem.h lobject.h lua.h lstate.h lstring.h 114lstring.o: lstring.c lmem.h lobject.h lua.h lstate.h lstring.h
117lstrlib.o: lstrlib.c lauxlib.h lua.h lualib.h 115lstrlib.o: lstrlib.c lauxlib.h lua.h lualib.h
118lstx.o: lstx.c lauxlib.h lua.h ldo.h lobject.h lstate.h lfunc.h llex.h \
119 lzio.h lmem.h lopcodes.h lparser.h lstring.h luadebug.h
120ltable.o: ltable.c lauxlib.h lua.h lmem.h lobject.h lstate.h ltable.h 116ltable.o: ltable.c lauxlib.h lua.h lmem.h lobject.h lstate.h ltable.h
121ltm.o: ltm.c lauxlib.h lua.h lmem.h lobject.h lstate.h ltm.h lapi.h 117ltm.o: ltm.c lauxlib.h lua.h lmem.h lobject.h lstate.h ltm.h
122lua.o: lua.c lua.h luadebug.h lualib.h 118lua.o: lua.c lua.h luadebug.h lualib.h
123lundump.o: lundump.c lauxlib.h lua.h lfunc.h lobject.h lmem.h \ 119lundump.o: lundump.c lauxlib.h lua.h lfunc.h lobject.h lmem.h \
124 lstring.h lundump.h lzio.h 120 lstring.h lundump.h lzio.h