diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1997-09-24 16:43:11 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1997-09-24 16:43:11 -0300 |
commit | 0dd6d1080e7f58eb17cb8a2ad3fc5801ed7c0532 (patch) | |
tree | 172953fb17b51eabde010564c86e27317f1bcc29 /lua.stx | |
parent | 3c820d622ec105815b6510015db8f9e6d81a05bc (diff) | |
download | lua-0dd6d1080e7f58eb17cb8a2ad3fc5801ed7c0532.tar.gz lua-0dd6d1080e7f58eb17cb8a2ad3fc5801ed7c0532.tar.bz2 lua-0dd6d1080e7f58eb17cb8a2ad3fc5801ed7c0532.zip |
new opcode variants.
Diffstat (limited to 'lua.stx')
-rw-r--r-- | lua.stx | 114 |
1 files changed, 63 insertions, 51 deletions
@@ -1,6 +1,6 @@ | |||
1 | %{ | 1 | %{ |
2 | /* | 2 | /* |
3 | ** $Id: lua.stx,v 1.3 1997/09/19 21:17:52 roberto Exp roberto $ | 3 | ** $Id: lua.stx,v 1.4 1997/09/22 20:53:20 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 | */ |
@@ -96,15 +96,24 @@ static void code_byte (Byte c) | |||
96 | 96 | ||
97 | static void code_word_at (int pc, int n) | 97 | static void code_word_at (int pc, int n) |
98 | { | 98 | { |
99 | Word w = n; | 99 | if (n > MAX_WORD) |
100 | if (w != n) | 100 | luaY_error("construction too big; unable to compile"); |
101 | luaY_error("block too big"); | ||
102 | currState->f->code[pc] = n&0xFF; | 101 | currState->f->code[pc] = n&0xFF; |
103 | currState->f->code[pc+1] = n>>8; | 102 | currState->f->code[pc+1] = n>>8; |
104 | } | 103 | } |
105 | 104 | ||
105 | |||
106 | static void fix_jump (int pc, OpCode op, int n) | ||
107 | { | ||
108 | currState->f->code[pc] = op; | ||
109 | code_word_at(pc+1, n); | ||
110 | } | ||
111 | |||
112 | |||
106 | static void code_word (int n) | 113 | static void code_word (int n) |
107 | { | 114 | { |
115 | if (n > MAX_WORD) | ||
116 | luaY_error("construction too big; unable to compile"); | ||
108 | code_byte(n&0xFF); | 117 | code_byte(n&0xFF); |
109 | code_byte(n>>8); | 118 | code_byte(n>>8); |
110 | } | 119 | } |
@@ -128,16 +137,25 @@ static void code_opcode (OpCode op, int delta) | |||
128 | } | 137 | } |
129 | 138 | ||
130 | 139 | ||
131 | static void code_opborw(OpCode opbyte, int arg, int delta) | 140 | static void code_opb (OpCode opbyte, int arg, int delta) |
132 | { | 141 | { |
133 | if (arg <= 255) { | 142 | code_opcode(opbyte, delta); |
134 | code_opcode(opbyte, delta); | 143 | code_byte(arg); |
135 | code_byte(arg); | 144 | } |
136 | } | 145 | |
137 | else { | 146 | static void code_opw (OpCode opbyte, int arg, int delta) |
138 | code_opcode(opbyte+1, delta); | 147 | { |
139 | code_word(arg); | 148 | code_opcode(opbyte, delta); |
140 | } | 149 | code_word(arg); |
150 | } | ||
151 | |||
152 | |||
153 | static void code_opborw (OpCode opbyte, int arg, int delta) | ||
154 | { | ||
155 | if (arg <= 255) | ||
156 | code_opb(opbyte, arg, delta); | ||
157 | else | ||
158 | code_opw(opbyte+1, arg, delta); | ||
141 | } | 159 | } |
142 | 160 | ||
143 | 161 | ||
@@ -167,7 +185,7 @@ static void code_pop (OpCode op) | |||
167 | 185 | ||
168 | static void code_constant (int c) | 186 | static void code_constant (int c) |
169 | { | 187 | { |
170 | code_opborw(PUSHCONSTANTB, c, 1); | 188 | code_oparg(PUSHCONSTANT0, PUSHCONSTANTB, c, 1); |
171 | } | 189 | } |
172 | 190 | ||
173 | 191 | ||
@@ -235,9 +253,8 @@ static void code_number (real f) | |||
235 | 253 | ||
236 | static void flush_record (int n) | 254 | static void flush_record (int n) |
237 | { | 255 | { |
238 | if (n == 0) return; | 256 | if (n > 0) |
239 | code_opcode(SETMAP, -2*n); | 257 | code_opb(SETMAP, n, -2*n); |
240 | code_byte(n); | ||
241 | } | 258 | } |
242 | 259 | ||
243 | static void flush_list (int m, int n) | 260 | static void flush_list (int m, int n) |
@@ -245,10 +262,8 @@ static void flush_list (int m, int n) | |||
245 | if (n == 0) return; | 262 | if (n == 0) return; |
246 | if (m == 0) | 263 | if (m == 0) |
247 | code_opcode(SETLIST0, -n); | 264 | code_opcode(SETLIST0, -n); |
248 | else if (m < 255) { | 265 | else if (m < 255) |
249 | code_opcode(SETLIST, -n); | 266 | code_opb(SETLIST, m, -n); |
250 | code_byte(m); | ||
251 | } | ||
252 | else | 267 | else |
253 | luaY_error("list constructor too long"); | 268 | luaY_error("list constructor too long"); |
254 | code_byte(n); | 269 | code_byte(n); |
@@ -352,8 +367,7 @@ void luaY_codedebugline (int line) | |||
352 | { | 367 | { |
353 | static int lastline = 0; | 368 | static int lastline = 0; |
354 | if (lua_debug && line != lastline) { | 369 | if (lua_debug && line != lastline) { |
355 | code_neutralop(SETLINE); | 370 | code_opw(SETLINE, line, 0); |
356 | code_word(line); | ||
357 | lastline = line; | 371 | lastline = line; |
358 | } | 372 | } |
359 | } | 373 | } |
@@ -399,13 +413,10 @@ static void adjust_mult_assign (int vars, long exps) | |||
399 | 413 | ||
400 | static void code_args (int dots) | 414 | static void code_args (int dots) |
401 | { | 415 | { |
402 | if (!dots) { | 416 | if (!dots) |
403 | code_opcode(ARGS, currState->nlocalvar); | 417 | code_opb(ARGS, currState->nlocalvar, currState->nlocalvar); |
404 | code_byte(currState->nlocalvar); | ||
405 | } | ||
406 | else { | 418 | else { |
407 | code_opcode(VARARGS, currState->nlocalvar+1); | 419 | code_opb(VARARGS, currState->nlocalvar, currState->nlocalvar+1); |
408 | code_byte(currState->nlocalvar); | ||
409 | add_localvar(luaS_new("arg")); | 420 | add_localvar(luaS_new("arg")); |
410 | } | 421 | } |
411 | } | 422 | } |
@@ -414,7 +425,7 @@ static void code_args (int dots) | |||
414 | static void lua_pushvar (vardesc number) | 425 | static void lua_pushvar (vardesc number) |
415 | { | 426 | { |
416 | if (number > 0) /* global var */ | 427 | if (number > 0) /* global var */ |
417 | code_opborw(GETGLOBALB, number-1, 1); | 428 | code_oparg(GETGLOBAL0, GETGLOBALB, number-1, 1); |
418 | else if (number < 0) /* local var */ | 429 | else if (number < 0) /* local var */ |
419 | code_oparg(PUSHLOCAL0, PUSHLOCAL, (-number)-1, 1); | 430 | code_oparg(PUSHLOCAL0, PUSHLOCAL, (-number)-1, 1); |
420 | else | 431 | else |
@@ -456,19 +467,19 @@ static void codeIf (int thenAdd, int elseAdd) | |||
456 | currState->pc -= sizeof(Word)+1; | 467 | currState->pc -= sizeof(Word)+1; |
457 | elseinit = currState->pc; | 468 | elseinit = currState->pc; |
458 | } | 469 | } |
459 | else { | 470 | else |
460 | currState->f->code[elseAdd] = JMP; | 471 | fix_jump(elseAdd, JMP, currState->pc-(elseAdd+1)); |
461 | code_word_at(elseAdd+1, currState->pc-elseinit); | 472 | fix_jump(thenAdd, IFFJMP, elseinit-(thenAdd+1)); |
462 | } | ||
463 | currState->f->code[thenAdd] = IFFJMP; | ||
464 | code_word_at(thenAdd+1, elseinit-(thenAdd+sizeof(Word)+1)); | ||
465 | } | 473 | } |
466 | 474 | ||
467 | 475 | ||
468 | static void code_shortcircuit (int pc, Byte jmp) | 476 | static void code_shortcircuit (OpCode op, int pos) |
469 | { | 477 | { |
470 | currState->f->code[pc] = jmp; | 478 | int dist = currState->pc - (pos+1); |
471 | code_word_at(pc+1, currState->pc - (pc + sizeof(Word)+1)); | 479 | if (dist > 255) |
480 | luaY_error("and/or expression too long"); | ||
481 | currState->f->code[pos] = op; | ||
482 | currState->f->code[pos+1] = dist; | ||
472 | } | 483 | } |
473 | 484 | ||
474 | 485 | ||
@@ -582,7 +593,7 @@ TProtoFunc *luaY_parser (ZIO *z, char *chunkname) | |||
582 | %token <vReal> NUMBER | 593 | %token <vReal> NUMBER |
583 | %token <pTStr> NAME STRING | 594 | %token <pTStr> NAME STRING |
584 | 595 | ||
585 | %type <vInt> PrepJump, PrepJumpPop | 596 | %type <vInt> PrepJump, PrepJumpPop, PrepJumpSC |
586 | %type <vLong> exprlist, exprlist1 /* if > 0, points to function return | 597 | %type <vLong> exprlist, exprlist1 /* if > 0, points to function return |
587 | counter (which has list length); if <= 0, -list lenght */ | 598 | counter (which has list length); if <= 0, -list lenght */ |
588 | %type <vLong> functioncall, expr /* if != 0, points to function return | 599 | %type <vLong> functioncall, expr /* if != 0, points to function return |
@@ -620,18 +631,15 @@ sc : /* empty */ | ';' ; | |||
620 | stat : IF expr1 THEN PrepJumpPop block PrepJump elsepart END | 631 | stat : IF expr1 THEN PrepJumpPop block PrepJump elsepart END |
621 | { codeIf($4, $6); } | 632 | { codeIf($4, $6); } |
622 | 633 | ||
623 | | WHILE {$<vInt>$=currState->pc;} expr1 DO PrepJumpPop block PrepJump END | 634 | | WHILE {$<vInt>$=currState->pc;} expr1 DO PrepJumpPop block END |
624 | { | 635 | { |
625 | currState->f->code[$5] = IFFJMP; | 636 | code_opborw(UPJMPB, currState->pc+1 - ($<vInt>2), 0); |
626 | code_word_at($5+1, currState->pc - ($5+sizeof(Word)+1)); | 637 | fix_jump($5, IFFJMP, currState->pc - ($5+1)); |
627 | currState->f->code[$7] = UPJMP; | ||
628 | code_word_at($7+1, currState->pc - ($<vInt>2)); | ||
629 | } | 638 | } |
630 | 639 | ||
631 | | REPEAT {$<vInt>$=currState->pc;} block UNTIL expr1 PrepJumpPop | 640 | | REPEAT {$<vInt>$=currState->pc;} block UNTIL expr1 |
632 | { | 641 | { |
633 | currState->f->code[$6] = IFFUPJMP; | 642 | code_opborw(IFFUPJMPB, currState->pc+1 - ($<vInt>2), -1); |
634 | code_word_at($6+1, currState->pc - ($<vInt>2)); | ||
635 | } | 643 | } |
636 | 644 | ||
637 | | varlist1 '=' exprlist1 | 645 | | varlist1 '=' exprlist1 |
@@ -699,6 +707,10 @@ PrepJump : /* empty */ | |||
699 | } | 707 | } |
700 | ; | 708 | ; |
701 | 709 | ||
710 | PrepJumpSC : /* empty */ | ||
711 | { $$ = currState->pc; code_opcode(0, -1); code_byte(0); } | ||
712 | ; | ||
713 | |||
702 | PrepJumpPop : PrepJump { $$ = $1; deltastack(-1); /* pop condition */ } | 714 | PrepJumpPop : PrepJump { $$ = $1; deltastack(-1); /* pop condition */ } |
703 | ; | 715 | ; |
704 | 716 | ||
@@ -726,13 +738,13 @@ expr : '(' expr ')' { $$ = $2; } | |||
726 | | STRING { code_string($1); $$ = 0; } | 738 | | STRING { code_string($1); $$ = 0; } |
727 | | NIL {code_opcode(PUSHNIL, 1); $$ = 0; } | 739 | | NIL {code_opcode(PUSHNIL, 1); $$ = 0; } |
728 | | functioncall { $$ = $1; } | 740 | | functioncall { $$ = $1; } |
729 | | expr1 AND PrepJumpPop expr1 { code_shortcircuit($3, ONFJMP); $$ = 0; } | ||
730 | | expr1 OR PrepJumpPop expr1 { code_shortcircuit($3, ONTJMP); $$ = 0; } | ||
731 | | FUNCTION { init_func(); } body { func_onstack($3); $$ = 0; } | 741 | | FUNCTION { init_func(); } body { func_onstack($3); $$ = 0; } |
742 | | expr1 AND PrepJumpSC expr1 { code_shortcircuit(ONFJMP, $3); $$ = 0; } | ||
743 | | expr1 OR PrepJumpSC expr1 { code_shortcircuit(ONTJMP, $3); $$ = 0; } | ||
732 | ; | 744 | ; |
733 | 745 | ||
734 | table : | 746 | table : |
735 | { code_opcode(CREATEARRAY, 1); $<vInt>$ = currState->pc; code_word(0); } | 747 | { $<vInt>$ = currState->pc+1; code_opw(CREATEARRAY, 0, 1); } |
736 | '{' fieldlist '}' | 748 | '{' fieldlist '}' |
737 | { code_word_at($<vInt>1, $3); } | 749 | { code_word_at($<vInt>1, $3); } |
738 | ; | 750 | ; |