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 | ; |
