aboutsummaryrefslogtreecommitdiff
path: root/lua.stx
diff options
context:
space:
mode:
Diffstat (limited to 'lua.stx')
-rw-r--r--lua.stx208
1 files changed, 91 insertions, 117 deletions
diff --git a/lua.stx b/lua.stx
index 28df6f36..fb85d18f 100644
--- a/lua.stx
+++ b/lua.stx
@@ -1,6 +1,6 @@
1%{ 1%{
2/* 2/*
3** $Id: lua.stx,v 1.7 1997/10/01 20:05:34 roberto Exp roberto $ 3** $Id: lua.stx,v 1.8 1997/10/06 14:51:11 roberto Exp roberto $
4** Syntax analizer and code generator 4** Syntax analizer and code generator
5** See Copyright Notice in lua.h 5** See Copyright Notice in lua.h
6*/ 6*/
@@ -23,9 +23,6 @@
23 23
24/* to avoid warnings generated by yacc */ 24/* to avoid warnings generated by yacc */
25int luaY_parse (void); 25int luaY_parse (void);
26#define malloc luaM_malloc
27#define realloc luaM_realloc
28#define free luaM_free
29 26
30 27
31/* size of a "normal" jump instruction: OpCode + 1 byte */ 28/* size of a "normal" jump instruction: OpCode + 1 byte */
@@ -118,23 +115,6 @@ static void code_byte (Byte c)
118} 115}
119 116
120 117
121static void code_word_at (int pc, int n)
122{
123 if (n > MAX_WORD)
124 luaY_error("construction too big; unable to compile");
125 currState->f->code[pc] = n&0xFF;
126 currState->f->code[pc+1] = n>>8;
127}
128
129
130static void code_word (int n)
131{
132 check_pc(2);
133 currState->pc += 2;
134 code_word_at(currState->pc-2, n);
135}
136
137
138static void deltastack (int delta) 118static void deltastack (int delta)
139{ 119{
140 currState->stacksize += delta; 120 currState->stacksize += delta;
@@ -146,41 +126,55 @@ static void deltastack (int delta)
146} 126}
147 127
148 128
149static void code_opcode (OpCode op, int delta) 129static int code_oparg_at (int pc, OpCode op, int builtin, int arg, int delta)
150{ 130{
151 code_byte(op);
152 deltastack(delta); 131 deltastack(delta);
132 if (arg < builtin) {
133 currState->f->code[pc] = op+1+arg;
134 return 1;
135 }
136 else if (arg <= 255) {
137 currState->f->code[pc] = op;
138 currState->f->code[pc+1] = arg;
139 return 2;
140 }
141 else if (arg <= MAX_WORD) {
142 currState->f->code[pc] = op+1+builtin;
143 currState->f->code[pc+1] = arg&0xFF;
144 currState->f->code[pc+2] = arg>>8;
145 return 3;
146 }
147 else luaY_error("construction too big - unable to compile");
148 return 0; /* to avoid warnings */
153} 149}
154 150
155 151
156static void code_opb (OpCode opbyte, int arg, int delta) 152static int fix_opcode (int pc, OpCode op, int builtin, int arg)
157{ 153{
158 code_opcode(opbyte, delta); 154 if (arg < builtin) { /* close space */
159 code_byte(arg); 155 movecode_down(pc+1, pc+2, currState->pc-(pc+2));
160} 156 currState->pc--;
161 157 }
162static void code_opw (OpCode opbyte, int arg, int delta) 158 else if (arg > 255) { /* open space */
163{ 159 check_pc(1);
164 code_opcode(opbyte, delta); 160 movecode_up(pc+1, pc, currState->pc-pc);
165 code_word(arg); 161 currState->pc++;
162 }
163 return code_oparg_at(pc, op, builtin, arg, 0) - 2;
166} 164}
167 165
168 166
169static void code_opborw (OpCode opbyte, int arg, int delta) 167static void code_oparg (OpCode op, int builtin, int arg, int delta)
170{ 168{
171 if (arg <= 255) 169 check_pc(3); /* maximum code size */
172 code_opb(opbyte, arg, delta); 170 currState->pc += code_oparg_at(currState->pc, op, builtin, arg, delta);
173 else
174 code_opw(opbyte+1, arg, delta);
175} 171}
176 172
177 173
178static void code_oparg (OpCode firstop, OpCode opbyte, int arg, int delta) 174static void code_opcode (OpCode op, int delta)
179{ 175{
180 if (firstop+arg < opbyte) 176 deltastack(delta);
181 code_opcode(firstop+arg, delta); 177 code_byte(op);
182 else
183 code_opborw(opbyte, arg, delta);
184} 178}
185 179
186 180
@@ -193,7 +187,10 @@ static void code_pop (OpCode op)
193#define code_binop(op) code_pop(op) 187#define code_binop(op) code_pop(op)
194 188
195 189
196#define code_neutralop(op) code_byte(op) 190static void code_neutralop (OpCode op)
191{
192 code_opcode(op, 0);
193}
197 194
198/* unary operations get 1 argument and leave one, so they are neutral */ 195/* unary operations get 1 argument and leave one, so they are neutral */
199#define code_unop(op) code_neutralop(op) 196#define code_unop(op) code_neutralop(op)
@@ -201,7 +198,7 @@ static void code_pop (OpCode op)
201 198
202static void code_constant (int c) 199static void code_constant (int c)
203{ 200{
204 code_oparg(PUSHCONSTANT0, PUSHCONSTANTB, c, 1); 201 code_oparg(PUSHCONSTANT, 8, c, 1);
205} 202}
206 203
207 204
@@ -237,7 +234,7 @@ static void code_string (TaggedString *s)
237} 234}
238 235
239 236
240#define LIM 13 237#define LIM 20
241static int real_constant (real r) 238static int real_constant (real r)
242{ 239{
243 /* check whether 'r' has appeared within the last LIM entries */ 240 /* check whether 'r' has appeared within the last LIM entries */
@@ -261,7 +258,7 @@ static void code_number (real f)
261{ 258{
262 Word i; 259 Word i;
263 if (f >= 0 && f <= (real)MAX_WORD && (real)(i=(Word)f) == f) 260 if (f >= 0 && f <= (real)MAX_WORD && (real)(i=(Word)f) == f)
264 code_oparg(PUSH0, PUSHBYTE, i, 1); /* f has an (short) integer value */ 261 code_oparg(PUSHNUMBER, 3, i, 1); /* f has an (short) integer value */
265 else 262 else
266 code_constant(real_constant(f)); 263 code_constant(real_constant(f));
267} 264}
@@ -270,18 +267,13 @@ static void code_number (real f)
270static void flush_record (int n) 267static void flush_record (int n)
271{ 268{
272 if (n > 0) 269 if (n > 0)
273 code_opb(SETMAP, n, -2*n); 270 code_oparg(SETMAP, 1, n-1, -2*n);
274} 271}
275 272
276static void flush_list (int m, int n) 273static void flush_list (int m, int n)
277{ 274{
278 if (n == 0) return; 275 if (n == 0) return;
279 if (m == 0) 276 code_oparg(SETLIST, 1, m, -n);
280 code_opcode(SETLIST0, -n);
281 else if (m < 255)
282 code_opb(SETLIST, m, -n);
283 else
284 luaY_error("list constructor too long");
285 code_byte(n); 277 code_byte(n);
286} 278}
287 279
@@ -375,7 +367,7 @@ static void pushupvalue (TaggedString *n)
375 if (aux_localname(n, currState) >= 0) 367 if (aux_localname(n, currState) >= 0)
376 luaY_syntaxerror("cannot access an upvalue in current scope", n->str); 368 luaY_syntaxerror("cannot access an upvalue in current scope", n->str);
377 i = indexupvalue(n); 369 i = indexupvalue(n);
378 code_oparg(PUSHUPVALUE0, PUSHUPVALUE, i, 1); 370 code_oparg(PUSHUPVALUE, 2, i, 1);
379} 371}
380 372
381 373
@@ -383,7 +375,7 @@ void luaY_codedebugline (int line)
383{ 375{
384 static int lastline = 0; 376 static int lastline = 0;
385 if (lua_debug && line != lastline) { 377 if (lua_debug && line != lastline) {
386 code_opw(SETLINE, line, 0); 378 code_oparg(SETLINE, 0, line, 0);
387 lastline = line; 379 lastline = line;
388 } 380 }
389} 381}
@@ -392,22 +384,25 @@ void luaY_codedebugline (int line)
392static void adjuststack (int n) 384static void adjuststack (int n)
393{ 385{
394 if (n > 0) 386 if (n > 0)
395 code_oparg(POP1-1, POPS, n, -n); /* POP1-1 = POP0 */ 387 code_oparg(POP, 2, n-1, -n);
396 else if (n < 0) 388 else if (n < 0)
397 code_oparg(PUSHNIL-1, PUSHNILS, -n, -n); /* PUSHNIL1-1 = PUSHNIL0 */ 389 code_oparg(PUSHNIL, 1, (-n)-1, -n);
398} 390}
399 391
400 392
401static long adjust_functioncall (long exp, int i) 393static long adjust_functioncall (long exp, int nresults)
402{ 394{
403 if (exp <= 0) 395 if (exp <= 0)
404 return -exp; /* exp is -list length */ 396 return -exp; /* exp is -list length */
405 else { 397 else {
406 int temp = currState->f->code[exp]; 398 int temp = currState->f->code[exp];
407 currState->f->code[exp] = i; 399 int nparams = currState->f->code[exp-1];
408 if (i != MULT_RET) 400 exp += fix_opcode(exp-2, CALLFUNC, 2, nresults);
409 deltastack(i); 401 currState->f->code[exp] = nparams;
410 return temp+i; 402 if (nresults != MULT_RET)
403 deltastack(nresults);
404 deltastack(-(nparams+1));
405 return temp+nresults;
411 } 406 }
412} 407}
413 408
@@ -430,9 +425,9 @@ static void adjust_mult_assign (int vars, long exps)
430static void code_args (int dots) 425static void code_args (int dots)
431{ 426{
432 if (!dots) 427 if (!dots)
433 code_opb(ARGS, currState->nlocalvar, currState->nlocalvar); 428 code_oparg(ARGS, 0, currState->nlocalvar, currState->nlocalvar);
434 else { 429 else {
435 code_opb(VARARGS, currState->nlocalvar, currState->nlocalvar+1); 430 code_oparg(VARARGS, 0, currState->nlocalvar, currState->nlocalvar+1);
436 add_localvar(luaS_new("arg")); 431 add_localvar(luaS_new("arg"));
437 } 432 }
438} 433}
@@ -441,9 +436,9 @@ static void code_args (int dots)
441static void lua_pushvar (vardesc number) 436static void lua_pushvar (vardesc number)
442{ 437{
443 if (number > 0) /* global var */ 438 if (number > 0) /* global var */
444 code_oparg(GETGLOBAL0, GETGLOBALB, number-1, 1); 439 code_oparg(GETGLOBAL, 8, number-1, 1);
445 else if (number < 0) /* local var */ 440 else if (number < 0) /* local var */
446 code_oparg(PUSHLOCAL0, PUSHLOCAL, (-number)-1, 1); 441 code_oparg(PUSHLOCAL, 8, (-number)-1, 1);
447 else 442 else
448 code_pop(GETTABLE); 443 code_pop(GETTABLE);
449} 444}
@@ -454,9 +449,9 @@ static void storevar (vardesc number)
454 if (number == 0) /* indexed var */ 449 if (number == 0) /* indexed var */
455 code_opcode(SETTABLE0, -3); 450 code_opcode(SETTABLE0, -3);
456 else if (number > 0) /* global var */ 451 else if (number > 0) /* global var */
457 code_opborw(SETGLOBALB, number-1, -1); 452 code_oparg(SETGLOBAL, 8, number-1, -1);
458 else /* number < 0 - local var */ 453 else /* number < 0 - local var */
459 code_oparg(SETLOCAL0, SETLOCAL, (-number)-1, -1); 454 code_oparg(SETLOCAL, 8, (-number)-1, -1);
460} 455}
461 456
462 457
@@ -469,35 +464,16 @@ static int lua_codestore (int i, int left)
469 return left; 464 return left;
470 } 465 }
471 else { /* indexed var with values in between*/ 466 else { /* indexed var with values in between*/
472 code_pop(SETTABLE); 467 code_oparg(SETTABLE, 0, left+i, -1);
473 code_byte(left+i); /* number of elements between table/index and value */
474 return left+2; /* table/index are not poped, since they are not on top */ 468 return left+2; /* table/index are not poped, since they are not on top */
475 } 469 }
476} 470}
477 471
478 472
479static int fix_opcode (int pc, OpCode op, int n)
480{
481 if (n <= 255) {
482 currState->f->code[pc] = op;
483 currState->f->code[pc+1] = n;
484 return 0;
485 }
486 else {
487 check_pc(1); /* open space */
488 movecode_up(pc+1, pc, currState->pc-pc);
489 currState->pc++;
490 currState->f->code[pc] = op+1; /* opcode must be word variant */
491 code_word_at(pc+1, n);
492 return 1;
493 }
494}
495
496
497static int fix_jump (int pc, OpCode op, int n) 473static int fix_jump (int pc, OpCode op, int n)
498{ 474{
499 /* jump is relative to position following jump instruction */ 475 /* jump is relative to position following jump instruction */
500 return fix_opcode(pc, op, n-(pc+JMPSIZE)); 476 return fix_opcode(pc, op, 0, n-(pc+JMPSIZE));
501} 477}
502 478
503 479
@@ -505,7 +481,7 @@ static void fix_upjmp (OpCode op, int pos)
505{ 481{
506 int delta = currState->pc+JMPSIZE - pos; /* jump is relative */ 482 int delta = currState->pc+JMPSIZE - pos; /* jump is relative */
507 if (delta > 255) delta++; 483 if (delta > 255) delta++;
508 code_opborw(op, delta, 0); 484 code_oparg(op, 0, delta, 0);
509} 485}
510 486
511 487
@@ -517,25 +493,20 @@ static void codeIf (int thenAdd, int elseAdd)
517 elseinit = currState->pc; 493 elseinit = currState->pc;
518 } 494 }
519 else 495 else
520 elseinit += fix_jump(elseAdd, JMPB, currState->pc); 496 elseinit += fix_jump(elseAdd, JMP, currState->pc);
521 fix_jump(thenAdd, IFFJMPB, elseinit); 497 fix_jump(thenAdd, IFFJMP, elseinit);
522} 498}
523 499
524 500
525static void code_shortcircuit (OpCode op, int pos) 501static void code_shortcircuit (int pc, OpCode op)
526{ 502{
527 int dist = currState->pc - (pos+JMPSIZE); 503 fix_jump(pc, op, currState->pc);
528 if (dist > 255)
529 luaY_error("and/or expression too long");
530 currState->f->code[pos] = op;
531 currState->f->code[pos+1] = dist;
532} 504}
533 505
534 506
535static void codereturn (void) 507static void codereturn (void)
536{ 508{
537 code_neutralop(RETCODE); 509 code_oparg(RETCODE, 0, currState->nlocalvar, 0);
538 code_byte(currState->nlocalvar);
539 currState->stacksize = currState->nlocalvar; 510 currState->stacksize = currState->nlocalvar;
540} 511}
541 512
@@ -549,7 +520,7 @@ static void func_onstack (TProtoFunc *f)
549 currState->f->consts[c].value.tf = (currState+1)->f; 520 currState->f->consts[c].value.tf = (currState+1)->f;
550 for (i=0; i<nupvalues; i++) 521 for (i=0; i<nupvalues; i++)
551 lua_pushvar((currState+1)->upvalues[i]); 522 lua_pushvar((currState+1)->upvalues[i]);
552 code_opborw(CLOSUREB, c, 1-nupvalues); 523 code_oparg(CLOSURE, 0, c, 1-nupvalues);
553} 524}
554 525
555 526
@@ -585,7 +556,6 @@ static void init_func (void)
585 currState->f->lineDefined = luaX_linenumber; 556 currState->f->lineDefined = luaX_linenumber;
586} 557}
587 558
588
589static TProtoFunc *close_func (void) 559static TProtoFunc *close_func (void)
590{ 560{
591 TProtoFunc *f = currState->f; 561 TProtoFunc *f = currState->f;
@@ -687,13 +657,13 @@ stat : IF cond THEN block SaveWord elsepart END
687 memcpy(&currState->f->code[currState->pc], 657 memcpy(&currState->f->code[currState->pc],
688 &currState->f->code[$2], expsize); 658 &currState->f->code[$2], expsize);
689 movecode_down($2, $3, currState->pc-$2); 659 movecode_down($2, $3, currState->pc-$2);
690 newpos += fix_jump($2, JMPB, currState->pc-expsize); 660 newpos += fix_jump($2, JMP, currState->pc-expsize);
691 fix_upjmp(IFTUPJMPB, newpos); 661 fix_upjmp(IFTUPJMP, newpos);
692 }} 662 }}
693 663
694 | REPEAT GetPC block UNTIL expr1 664 | REPEAT GetPC block UNTIL expr1
695 { 665 {
696 fix_upjmp(IFFUPJMPB, $2); 666 fix_upjmp(IFFUPJMP, $2);
697 deltastack(-1); /* pops condition */ 667 deltastack(-1); /* pops condition */
698 } 668 }
699 669
@@ -706,7 +676,7 @@ stat : IF cond THEN block SaveWord elsepart END
706 left = lua_codestore(i, left); 676 left = lua_codestore(i, left);
707 adjuststack(left); /* remove eventual 'garbage' left on stack */ 677 adjuststack(left); /* remove eventual 'garbage' left on stack */
708 }} 678 }}
709 | functioncall 679 | functioncall { adjust_functioncall($1, 0); }
710 | LOCAL localdeclist decinit 680 | LOCAL localdeclist decinit
711 { 681 {
712 currState->nlocalvar += $2; 682 currState->nlocalvar += $2;
@@ -757,7 +727,11 @@ ret : /* empty */
757GetPC : /* empty */ { $$ = currState->pc; } 727GetPC : /* empty */ { $$ = currState->pc; }
758 ; 728 ;
759 729
760SaveWord : GetPC { $$ = $1; code_word(0); /* open space */ } 730SaveWord : /* empty */
731 { $$ = currState->pc;
732 check_pc(JMPSIZE);
733 currState->pc += JMPSIZE; /* open space */
734 }
761 ; 735 ;
762 736
763SaveWordPop : SaveWord { $$ = $1; deltastack(-1); /* pop condition */ } 737SaveWordPop : SaveWord { $$ = $1; deltastack(-1); /* pop condition */ }
@@ -787,33 +761,33 @@ expr : '(' expr ')' { $$ = $2; }
787 | expr1 CONC expr1 { code_binop(CONCOP); $$ = 0; } 761 | expr1 CONC expr1 { code_binop(CONCOP); $$ = 0; }
788 | '-' expr1 %prec UNARY { code_unop(MINUSOP); $$ = 0;} 762 | '-' expr1 %prec UNARY { code_unop(MINUSOP); $$ = 0;}
789 | NOT expr1 { code_unop(NOTOP); $$ = 0;} 763 | NOT expr1 { code_unop(NOTOP); $$ = 0;}
790 | table { $$ = 0; } 764 | table { $$ = 0; }
791 | varexp { $$ = 0;} 765 | varexp { $$ = 0;}
792 | NUMBER { code_number($1); $$ = 0; } 766 | NUMBER { code_number($1); $$ = 0; }
793 | STRING { code_string($1); $$ = 0; } 767 | STRING { code_string($1); $$ = 0; }
794 | NIL {code_opcode(PUSHNIL, 1); $$ = 0; } 768 | NIL { adjuststack(-1); $$ = 0; }
795 | functioncall { $$ = $1; } 769 | functioncall { $$ = $1; }
796 | FUNCTION { init_func(); } body { func_onstack($3); $$ = 0; } 770 | FUNCTION { init_func(); } body { func_onstack($3); $$ = 0; }
797 | expr1 AND SaveWordPop expr1 { code_shortcircuit(ONFJMP, $3); $$ = 0; } 771 | expr1 AND SaveWordPop expr1 { code_shortcircuit($3, ONFJMP); $$ = 0; }
798 | expr1 OR SaveWordPop expr1 { code_shortcircuit(ONTJMP, $3); $$ = 0; } 772 | expr1 OR SaveWordPop expr1 { code_shortcircuit($3, ONTJMP); $$ = 0; }
799 ; 773 ;
800 774
801table : '{' SaveWordPush fieldlist '}' { fix_opcode($2, CREATEARRAYB, $3); } 775table : '{' SaveWordPush fieldlist '}' { fix_opcode($2, CREATEARRAY, 2, $3); }
802 ; 776 ;
803 777
804functioncall : funcvalue funcParams 778functioncall : funcvalue funcParams
805 { 779 {
806 code_opcode(CALLFUNC, -($1+$2+1)); /* ajdust counts results */ 780 code_byte(0); /* save space for opcode */
807 code_byte($1+$2); 781 code_byte($1+$2); /* number of parameters */
808 $$ = currState->pc; 782 $$ = currState->pc;
809 code_byte(0); /* may be adjusted by other rules */ 783 code_byte(0); /* must be adjusted by other rules */
810 } 784 }
811 ; 785 ;
812 786
813funcvalue : varexp { $$ = 0; } 787funcvalue : varexp { $$ = 0; }
814 | varexp ':' NAME 788 | varexp ':' NAME
815 { 789 {
816 code_opborw(PUSHSELFB, string_constant($3, currState), 1); 790 code_oparg(PUSHSELF, 0, string_constant($3, currState), 1);
817 $$ = 1; 791 $$ = 1;
818 } 792 }
819 ; 793 ;