aboutsummaryrefslogtreecommitdiff
path: root/lua.stx
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1997-07-30 19:00:50 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1997-07-30 19:00:50 -0300
commit0892f0e5b75c51f1fee07276a3ba13301b83409e (patch)
tree9f3b9ec92f26c05a85c826ffc5f803fda2f48867 /lua.stx
parent1d7857bc635c0bfe7c5b1f325d31feb7660e9a5a (diff)
downloadlua-0892f0e5b75c51f1fee07276a3ba13301b83409e.tar.gz
lua-0892f0e5b75c51f1fee07276a3ba13301b83409e.tar.bz2
lua-0892f0e5b75c51f1fee07276a3ba13301b83409e.zip
BIG CHANGE: functions have their own "constant table".
Diffstat (limited to 'lua.stx')
-rw-r--r--lua.stx281
1 files changed, 156 insertions, 125 deletions
diff --git a/lua.stx b/lua.stx
index 9f6e56f3..66b27e14 100644
--- a/lua.stx
+++ b/lua.stx
@@ -1,10 +1,8 @@
1%{ 1%{
2 2
3char *rcs_luastx = "$Id: lua.stx,v 3.47 1997/06/19 17:46:12 roberto Exp roberto $"; 3char *rcs_luastx = "$Id: lua.stx,v 3.48 1997/07/29 20:38:45 roberto Exp roberto $";
4 4
5#include <stdio.h>
6#include <stdlib.h> 5#include <stdlib.h>
7#include <string.h>
8 6
9#include "luadebug.h" 7#include "luadebug.h"
10#include "luamem.h" 8#include "luamem.h"
@@ -40,6 +38,7 @@ struct State {
40 int pc; /* next position to code */ 38 int pc; /* next position to code */
41 TaggedString *localvar[MAXLOCALS]; /* store local variable names */ 39 TaggedString *localvar[MAXLOCALS]; /* store local variable names */
42 int nlocalvar; /* number of active local variables */ 40 int nlocalvar; /* number of active local variables */
41 int maxconsts; /* size of consts vector */
43 int nvars; /* total number of local variables (for debugging information) */ 42 int nvars; /* total number of local variables (for debugging information) */
44 int maxvars; /* = -1 if no debug information */ 43 int maxvars; /* = -1 if no debug information */
45} stateMain, stateFunc, *currState; 44} stateMain, stateFunc, *currState;
@@ -69,41 +68,106 @@ static void check_space (int i)
69 Byte, codeEM, MAX_INT); 68 Byte, codeEM, MAX_INT);
70} 69}
71 70
71
72static void code_byte (Byte c) 72static void code_byte (Byte c)
73{ 73{
74 check_space(1); 74 check_space(1);
75 currState->f->code[currState->pc++] = c; 75 currState->f->code[currState->pc++] = c;
76} 76}
77 77
78static void code_float (real n) 78
79static void code_word_at (int pc, int n)
79{ 80{
80 check_space(sizeof(real)); 81 Word w = n;
81 memcpy(currState->f->code+currState->pc, &n, sizeof(real)); 82 if (w != n)
82 currState->pc += sizeof(real); 83 yyerror("block too big");
84 currState->f->code[pc] = n&0xFF;
85 currState->f->code[pc+1] = n>>8;
83} 86}
84 87
85static void code_code (TFunc *tf) 88static void code_word (int n)
86{ 89{
87 check_space(sizeof(TFunc *)); 90 code_byte(n&0xFF);
88 memcpy(currState->f->code+currState->pc, &tf, sizeof(TFunc *)); 91 code_byte(n>>8);
89 currState->pc += sizeof(TFunc *);
90} 92}
91 93
92static void code_word_at (int pc, int n) 94static void code_constant (int c)
93{ 95{
94 Word w = n; 96 if (c <= 255) {
95 if (w != n) 97 code_byte(PUSHCONSTANTB);
96 yyerror("block too big"); 98 code_byte(c);
97 memcpy(currState->f->code+pc, &w, sizeof(Word)); 99 }
100 else {
101 code_byte(PUSHCONSTANT);
102 code_word(c);
103 }
104}
105
106
107static int next_constant (void)
108{
109 if (currState->f->nconsts >= currState->maxconsts) {
110 currState->maxconsts =
111 growvector(&currState->f->consts, currState->maxconsts,
112 TObject, constantEM, MAX_WORD);
113 }
114 return currState->f->nconsts++;
115}
116
117
118static int string_constant (TaggedString *s)
119{
120 int c = s->u.s.constindex;
121 if (!(0 <= c && c < currState->f->nconsts &&
122 ttype(&currState->f->consts[c]) == LUA_T_STRING &&
123 tsvalue(&currState->f->consts[c]) == s)) {
124 c = next_constant();
125 ttype(&currState->f->consts[c]) = LUA_T_STRING;
126 tsvalue(&currState->f->consts[c]) = s;
127 s->u.s.constindex = c; /* hint for next time */
128 luaI_releasestring(s);
129 }
130 return c;
98} 131}
99 132
100static void code_word (Word n) 133
134static void code_string (TaggedString *s)
101{ 135{
102 check_space(sizeof(Word)); 136 int c = string_constant(s);
103 memcpy(currState->f->code+currState->pc, &n, sizeof(Word)); 137 code_constant(c);
104 currState->pc += sizeof(Word);
105} 138}
106 139
140static void code_float (real n)
141{
142 int c = next_constant();
143 ttype(&currState->f->consts[c]) = LUA_T_NUMBER;
144 nvalue(&currState->f->consts[c]) = n;
145 code_constant(c);
146}
147
148
149static void code_number (float f)
150{
151 Word i;
152 if (f >= 0 && f <= (float)MAX_WORD && (float)(i=(Word)f) == f) {
153 /* f has an (short) integer value */
154 if (i <= 2) code_byte(PUSH0 + i);
155 else if (i <= 255)
156 {
157 code_byte(PUSHBYTE);
158 code_byte(i);
159 }
160 else
161 {
162 code_byte(PUSHWORD);
163 code_word(i);
164 }
165 }
166 else
167 code_float(f);
168}
169
170
107static void flush_record (int n) 171static void flush_record (int n)
108{ 172{
109 if (n == 0) return; 173 if (n == 0) return;
@@ -149,6 +213,7 @@ static void luaI_unregisterlocalvar (int line)
149 213
150static void store_localvar (TaggedString *name, int n) 214static void store_localvar (TaggedString *name, int n)
151{ 215{
216 luaI_fixstring(name); /* local var names cannot be GC */
152 if (currState->nlocalvar+n < MAXLOCALS) 217 if (currState->nlocalvar+n < MAXLOCALS)
153 currState->localvar[currState->nlocalvar+n] = name; 218 currState->localvar[currState->nlocalvar+n] = name;
154 else 219 else
@@ -170,40 +235,6 @@ static void add_varbuffer (Long var)
170 yyerror ("variable buffer overflow"); 235 yyerror ("variable buffer overflow");
171} 236}
172 237
173static void code_string (Word w)
174{
175 code_byte(PUSHSTRING);
176 code_word(w);
177}
178
179static void code_constant (TaggedString *s)
180{
181 code_string(luaI_findconstant(s));
182}
183
184static void code_number (float f)
185{
186 Word i;
187 if (f >= 0 && f <= (float)MAX_WORD && (float)(i=(Word)f) == f) {
188 /* f has an (short) integer value */
189 if (i <= 2) code_byte(PUSH0 + i);
190 else if (i <= 255)
191 {
192 code_byte(PUSHBYTE);
193 code_byte(i);
194 }
195 else
196 {
197 code_byte(PUSHWORD);
198 code_word(i);
199 }
200 }
201 else
202 {
203 code_byte(PUSHFLOAT);
204 code_float(f);
205 }
206}
207 238
208/* 239/*
209** Search a local name and if find return its index. If do not find return -1 240** Search a local name and if find return its index. If do not find return -1
@@ -256,55 +287,6 @@ static void lua_codeadjust (int n)
256} 287}
257 288
258 289
259static void init_state (TFunc *f)
260{
261 luaI_initTFunc(f);
262 currState->nlocalvar = 0;
263 currState->f = f;
264 currState->pc = 0;
265 currState->codesize = CODE_BLOCK;
266 f->code = newvector(CODE_BLOCK, Byte);
267 if (lua_debug) {
268 currState->nvars = 0;
269 currState->maxvars = 0;
270 }
271 else
272 currState->maxvars = -1; /* flag no debug information */
273}
274
275
276static void init_func (void)
277{
278 currState = &stateFunc;
279 init_state(new(TFunc));
280 luaI_codedebugline(lua_linenumber);
281}
282
283
284static void codereturn (void)
285{
286 if (currState->nlocalvar == 0)
287 code_byte(RETCODE0);
288 else
289 {
290 code_byte(RETCODE);
291 code_byte(currState->nlocalvar);
292 }
293}
294
295
296static void close_func (void)
297{
298 codereturn();
299 code_byte(ENDCODE);
300 currState->f->code = shrinkvector(currState->f->code, currState->pc, Byte);
301 if (currState->maxvars != -1) { /* debug information? */
302 luaI_registerlocalvar(NULL, -1); /* flag end of vector */
303 currState->f->locvars = shrinkvector(currState->f->locvars,
304 currState->nvars, LocVar);
305 }
306}
307
308 290
309void luaI_codedebugline (int line) 291void luaI_codedebugline (int line)
310{ 292{
@@ -350,7 +332,7 @@ static int close_parlist (int dots)
350 else { 332 else {
351 code_byte(VARARGS); 333 code_byte(VARARGS);
352 code_byte(currState->nlocalvar); 334 code_byte(currState->nlocalvar);
353 add_localvar(luaI_createfixedstring("arg")); 335 add_localvar(luaI_createstring("arg"));
354 } 336 }
355 return lua_linenumber; 337 return lua_linenumber;
356} 338}
@@ -423,6 +405,65 @@ static void code_shortcircuit (int pc, Byte jmp)
423} 405}
424 406
425 407
408static void init_state (TFunc *f)
409{
410 currState->nlocalvar = 0;
411 currState->f = f;
412 currState->pc = 0;
413 currState->codesize = CODE_BLOCK;
414 f->code = newvector(CODE_BLOCK, Byte);
415 currState->maxconsts = 0;
416 if (lua_debug) {
417 currState->nvars = 0;
418 currState->maxvars = 0;
419 }
420 else
421 currState->maxvars = -1; /* flag no debug information */
422}
423
424
425static void init_func (Long v)
426{
427 TFunc *f = new(TFunc);
428 int c = next_constant();
429 ttype(&currState->f->consts[c]) = LUA_T_FUNCTION;
430 currState->f->consts[c].value.tf = f;
431 code_constant(c);
432 storesinglevar(v);
433 currState = &stateFunc;
434 luaI_initTFunc(f);
435 init_state(f);
436 luaI_codedebugline(lua_linenumber);
437}
438
439
440static void codereturn (void)
441{
442 if (currState->nlocalvar == 0)
443 code_byte(RETCODE0);
444 else
445 {
446 code_byte(RETCODE);
447 code_byte(currState->nlocalvar);
448 }
449}
450
451
452static void close_func (void)
453{
454 codereturn();
455 code_byte(ENDCODE);
456 currState->f->code = shrinkvector(currState->f->code, currState->pc, Byte);
457 currState->f->consts = shrinkvector(currState->f->consts,
458 currState->f->nconsts, TObject);
459 if (currState->maxvars != -1) { /* debug information? */
460 luaI_registerlocalvar(NULL, -1); /* flag end of vector */
461 currState->f->locvars = shrinkvector(currState->f->locvars,
462 currState->nvars, LocVar);
463 }
464}
465
466
426/* 467/*
427** Parse LUA code. 468** Parse LUA code.
428*/ 469*/
@@ -444,9 +485,7 @@ void lua_parse (TFunc *tf)
444 int vInt; 485 int vInt;
445 float vFloat; 486 float vFloat;
446 char *pChar; 487 char *pChar;
447 Word vWord;
448 Long vLong; 488 Long vLong;
449 TFunc *pFunc;
450 TaggedString *pTStr; 489 TaggedString *pTStr;
451} 490}
452 491
@@ -460,8 +499,7 @@ void lua_parse (TFunc *tf)
460%token FUNCTION 499%token FUNCTION
461%token DOTS 500%token DOTS
462%token <vFloat> NUMBER 501%token <vFloat> NUMBER
463%token <vWord> STRING 502%token <pTStr> NAME STRING
464%token <pTStr> NAME
465 503
466%type <vLong> PrepJump 504%type <vLong> PrepJump
467%type <vLong> exprlist, exprlist1 /* if > 0, points to function return 505%type <vLong> exprlist, exprlist1 /* if > 0, points to function return
@@ -473,8 +511,7 @@ void lua_parse (TFunc *tf)
473%type <vInt> ffieldlist, ffieldlist1, semicolonpart 511%type <vInt> ffieldlist, ffieldlist1, semicolonpart
474%type <vInt> lfieldlist, lfieldlist1 512%type <vInt> lfieldlist, lfieldlist1
475%type <vInt> parlist, parlist1, par 513%type <vInt> parlist, parlist1, par
476%type <vLong> var, singlevar, funcname 514%type <vLong> var, singlevar
477%type <pFunc> body
478 515
479%left AND OR 516%left AND OR
480%left EQ NE '>' '<' LE GE 517%left EQ NE '>' '<' LE GE
@@ -495,28 +532,21 @@ chunklist : /* empty */
495 ; 532 ;
496 533
497function : FUNCTION funcname body 534function : FUNCTION funcname body
498 {
499 code_byte(PUSHFUNCTION);
500 code_code($3);
501 storesinglevar($2);
502 }
503 ; 535 ;
504 536
505funcname : var { $$ =$1; init_func(); } 537funcname : var { init_func($1); }
506 | varexp ':' NAME 538 | varexp ':' NAME
507 { 539 {
508 code_constant($3); 540 code_string($3);
509 $$ = 0; /* indexed variable */ 541 init_func(0); /* indexed variable */
510 init_func(); 542 add_localvar(luaI_createstring("self"));
511 add_localvar(luaI_createfixedstring("self"));
512 } 543 }
513 ; 544 ;
514 545
515body : '(' parlist ')' block END 546body : '(' parlist ')' block END
516 { 547 {
517 close_func(); 548 close_func();
518 $$ = currState->f; 549 currState->f->lineDefined = $2;
519 $$->lineDefined = $2;
520 currState = &stateMain; /* change back to main code */ 550 currState = &stateMain; /* change back to main code */
521 } 551 }
522 ; 552 ;
@@ -658,7 +688,7 @@ funcvalue : varexp { $$ = 0; }
658 | varexp ':' NAME 688 | varexp ':' NAME
659 { 689 {
660 code_byte(PUSHSELF); 690 code_byte(PUSHSELF);
661 code_word(luaI_findconstant($3)); 691 code_word(string_constant($3));
662 $$ = 1; 692 $$ = 1;
663 } 693 }
664 ; 694 ;
@@ -735,7 +765,7 @@ ffield : ffieldkey '=' expr1
735 ; 765 ;
736 766
737ffieldkey : '[' expr1 ']' 767ffieldkey : '[' expr1 ']'
738 | NAME { code_constant($1); } 768 | NAME { code_string($1); }
739 ; 769 ;
740 770
741lfieldlist : /* empty */ { $$ = 0; } 771lfieldlist : /* empty */ { $$ = 0; }
@@ -771,7 +801,7 @@ var : singlevar { $$ = $1; }
771 } 801 }
772 | varexp '.' NAME 802 | varexp '.' NAME
773 { 803 {
774 code_constant($3); 804 code_string($3);
775 $$ = 0; /* indexed variable */ 805 $$ = 0; /* indexed variable */
776 } 806 }
777 ; 807 ;
@@ -783,6 +813,7 @@ singlevar : NAME
783 $$ = luaI_findsymbol($1)+1; /* return positive value */ 813 $$ = luaI_findsymbol($1)+1; /* return positive value */
784 else 814 else
785 $$ = -(local+1); /* return negative value */ 815 $$ = -(local+1); /* return negative value */
816 luaI_fixstring($1); /* cannot GC variable names */
786 } 817 }
787 ; 818 ;
788 819