aboutsummaryrefslogtreecommitdiff
path: root/lua.stx
diff options
context:
space:
mode:
Diffstat (limited to 'lua.stx')
-rw-r--r--lua.stx129
1 files changed, 87 insertions, 42 deletions
diff --git a/lua.stx b/lua.stx
index 2f650f4e..8fd89517 100644
--- a/lua.stx
+++ b/lua.stx
@@ -1,6 +1,6 @@
1%{ 1%{
2/* 2/*
3** $Id: lua.stx,v 1.5 1997/09/24 19:43:11 roberto Exp roberto $ 3** $Id: lua.stx,v 1.6 1997/09/26 15:02:26 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*/
@@ -28,6 +28,9 @@ int luaY_parse (void);
28#define free luaM_free 28#define free luaM_free
29 29
30 30
31/* size of a "normal" jump instruction: OpCode + 1 byte */
32#define JMPSIZE 2
33
31/* maximum number of local variables */ 34/* maximum number of local variables */
32#define MAXLOCALS 32 35#define MAXLOCALS 32
33 36
@@ -85,11 +88,32 @@ void luaY_error (char *s)
85} 88}
86 89
87 90
88static void code_byte (Byte c) 91static void check_pc (int n)
89{ 92{
90 if (currState->pc >= currState->maxcode) 93 if (currState->pc+n > currState->maxcode)
91 currState->maxcode = luaM_growvector(&currState->f->code, 94 currState->maxcode = luaM_growvector(&currState->f->code,
92 currState->maxcode, Byte, codeEM, MAX_INT); 95 currState->maxcode, Byte, codeEM, MAX_INT);
96}
97
98
99static void movecode_up (int d, int s, int n)
100{
101 while (n--)
102 currState->f->code[d+n] = currState->f->code[s+n];
103}
104
105
106static void movecode_down (int d, int s, int n)
107{
108 int i;
109 for (i=0; i<n; i++)
110 currState->f->code[d+i] = currState->f->code[s+i];
111}
112
113
114static void code_byte (Byte c)
115{
116 check_pc(1);
93 currState->f->code[currState->pc++] = c; 117 currState->f->code[currState->pc++] = c;
94} 118}
95 119
@@ -103,19 +127,36 @@ static void code_word_at (int pc, int n)
103} 127}
104 128
105 129
106static void fix_jump (int pc, OpCode op, int n) 130static void code_word (int n)
107{ 131{
108 currState->f->code[pc] = op; 132 check_pc(2);
109 code_word_at(pc+1, n); 133 currState->pc += 2;
134 code_word_at(currState->pc-2, n);
110} 135}
111 136
112 137
113static void code_word (int n) 138static int fix_opcode (int pc, OpCode op, int n)
114{ 139{
115 if (n > MAX_WORD) 140 if (n <= 255) {
116 luaY_error("construction too big; unable to compile"); 141 currState->f->code[pc] = op;
117 code_byte(n&0xFF); 142 currState->f->code[pc+1] = n;
118 code_byte(n>>8); 143 return 0;
144 }
145 else {
146 check_pc(1); /* open space */
147 movecode_up(pc+1, pc, currState->pc-pc);
148 currState->pc++;
149 currState->f->code[pc] = op+1; /* opcode must be word variant */
150 code_word_at(pc+1, n);
151 return 1;
152 }
153}
154
155static int fix_jump (int pc, OpCode op, int n)
156{
157 n -= pc+1; /* jump is relative to position following jump opcode */
158 if (n > 255) n++; /* jump must be 1 bigger */
159 return fix_opcode(pc, op, n);
119} 160}
120 161
121 162
@@ -462,14 +503,14 @@ static int lua_codestore (int i, int left)
462 503
463static void codeIf (int thenAdd, int elseAdd) 504static void codeIf (int thenAdd, int elseAdd)
464{ 505{
465 int elseinit = elseAdd+sizeof(Word)+1; 506 int elseinit = elseAdd+JMPSIZE;
466 if (currState->pc == elseinit) { /* no else part */ 507 if (currState->pc == elseinit) { /* no else part */
467 currState->pc -= sizeof(Word)+1; 508 currState->pc -= JMPSIZE;
468 elseinit = currState->pc; 509 elseinit = currState->pc;
469 } 510 }
470 else 511 else
471 fix_jump(elseAdd, JMP, currState->pc-(elseAdd+1)); 512 elseinit += fix_jump(elseAdd, JMPB, currState->pc);
472 fix_jump(thenAdd, IFFJMP, elseinit-(thenAdd+1)); 513 fix_jump(thenAdd, IFFJMPB, elseinit);
473} 514}
474 515
475 516
@@ -593,7 +634,7 @@ TProtoFunc *luaY_parser (ZIO *z, char *chunkname)
593%token <vReal> NUMBER 634%token <vReal> NUMBER
594%token <pTStr> NAME STRING 635%token <pTStr> NAME STRING
595 636
596%type <vInt> PrepJump, PrepJumpPop, PrepJumpSC 637%type <vInt> SaveWord, cond, GetPC, SaveWordPop, SaveWordPush
597%type <vLong> exprlist, exprlist1 /* if > 0, points to function return 638%type <vLong> exprlist, exprlist1 /* if > 0, points to function return
598 counter (which has list length); if <= 0, -list lenght */ 639 counter (which has list length); if <= 0, -list lenght */
599%type <vLong> functioncall, expr /* if != 0, points to function return 640%type <vLong> functioncall, expr /* if != 0, points to function return
@@ -628,18 +669,24 @@ statlist : /* empty */
628 669
629sc : /* empty */ | ';' ; 670sc : /* empty */ | ';' ;
630 671
631stat : IF expr1 THEN PrepJumpPop block PrepJump elsepart END 672stat : IF cond THEN block SaveWord elsepart END
632 { codeIf($4, $6); } 673 { codeIf($2, $5); }
633 674
634 | WHILE {$<vInt>$=currState->pc;} expr1 DO PrepJumpPop block END 675 | WHILE GetPC cond DO block END
635 { 676 {{
636 code_opborw(UPJMPB, currState->pc+1 - ($<vInt>2), 0); 677 int expsize = $3-$2;
637 fix_jump($5, IFFJMP, currState->pc - ($5+1)); 678 int newpos = $2+JMPSIZE;
638 } 679 check_pc(expsize);
680 memcpy(&currState->f->code[currState->pc],
681 &currState->f->code[$2], expsize);
682 movecode_down($2, $3, currState->pc-$2);
683 newpos += fix_jump($2, JMPB, currState->pc-expsize);
684 code_opborw(IFTUPJMPB, currState->pc+1 - newpos, 0);
685 }}
639 686
640 | REPEAT {$<vInt>$=currState->pc;} block UNTIL expr1 687 | REPEAT GetPC block UNTIL expr1
641 { 688 {
642 code_opborw(IFFUPJMPB, currState->pc+1 - ($<vInt>2), -1); 689 code_opborw(IFFUPJMPB, currState->pc+1 - $2, -1);
643 } 690 }
644 691
645 | varlist1 '=' exprlist1 692 | varlist1 '=' exprlist1
@@ -687,8 +734,8 @@ body : '(' parlist ')' chunk END { $$ = close_func(); }
687 734
688elsepart : /* empty */ 735elsepart : /* empty */
689 | ELSE block 736 | ELSE block
690 | ELSEIF expr1 THEN PrepJumpPop block PrepJump elsepart 737 | ELSEIF cond THEN block SaveWord elsepart
691 { codeIf($4, $6); } 738 { codeIf($2, $5); }
692 ; 739 ;
693 740
694ret : /* empty */ 741ret : /* empty */
@@ -699,19 +746,19 @@ ret : /* empty */
699 } 746 }
700 ; 747 ;
701 748
702PrepJump : /* empty */ 749GetPC : /* empty */ { $$ = currState->pc; }
703 { 750 ;
704 $$ = currState->pc; 751
705 code_byte(0); /* open space */ 752SaveWord : GetPC { $$ = $1; code_word(0); /* open space */ }
706 code_word(0);
707 }
708 ; 753 ;
709 754
710PrepJumpSC : /* empty */ 755SaveWordPop : SaveWord { $$ = $1; deltastack(-1); /* pop condition */ }
711 { $$ = currState->pc; code_opcode(0, -1); code_byte(0); } 756 ;
757
758SaveWordPush : SaveWord { $$ = $1; deltastack(1); /* push a value */ }
712 ; 759 ;
713 760
714PrepJumpPop : PrepJump { $$ = $1; deltastack(-1); /* pop condition */ } 761cond : expr1 SaveWordPop { $$ = $2; }
715 ; 762 ;
716 763
717expr1 : expr { adjust_functioncall($1, 1); } 764expr1 : expr { adjust_functioncall($1, 1); }
@@ -739,14 +786,11 @@ expr : '(' expr ')' { $$ = $2; }
739 | NIL {code_opcode(PUSHNIL, 1); $$ = 0; } 786 | NIL {code_opcode(PUSHNIL, 1); $$ = 0; }
740 | functioncall { $$ = $1; } 787 | functioncall { $$ = $1; }
741 | FUNCTION { init_func(); } body { func_onstack($3); $$ = 0; } 788 | FUNCTION { init_func(); } body { func_onstack($3); $$ = 0; }
742 | expr1 AND PrepJumpSC expr1 { code_shortcircuit(ONFJMP, $3); $$ = 0; } 789 | expr1 AND SaveWordPop expr1 { code_shortcircuit(ONFJMP, $3); $$ = 0; }
743 | expr1 OR PrepJumpSC expr1 { code_shortcircuit(ONTJMP, $3); $$ = 0; } 790 | expr1 OR SaveWordPop expr1 { code_shortcircuit(ONTJMP, $3); $$ = 0; }
744 ; 791 ;
745 792
746table : 793table : '{' SaveWordPush fieldlist '}' { fix_opcode($2, CREATEARRAYB, $3); }
747 { $<vInt>$ = currState->pc+1; code_opw(CREATEARRAY, 0, 1); }
748 '{' fieldlist '}'
749 { code_word_at($<vInt>1, $3); }
750 ; 794 ;
751 795
752functioncall : funcvalue funcParams 796functioncall : funcvalue funcParams
@@ -892,3 +936,4 @@ decinit : /* empty */ { $$ = 0; }
892 ; 936 ;
893 937
894%% 938%%
939