diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1997-10-13 20:12:04 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1997-10-13 20:12:04 -0200 |
| commit | 7c261a13b572fb0f7449f6cdf2b495d0e5bd57d5 (patch) | |
| tree | 026cbe3e25e1929f171d0f30ac7a588bfb29f573 /lua.stx | |
| parent | 2bb94d9e22f1f8ab2c00c9296a3920bebe4862bd (diff) | |
| download | lua-7c261a13b572fb0f7449f6cdf2b495d0e5bd57d5.tar.gz lua-7c261a13b572fb0f7449f6cdf2b495d0e5bd57d5.tar.bz2 lua-7c261a13b572fb0f7449f6cdf2b495d0e5bd57d5.zip | |
more uniform treatment to opcode variants.
Diffstat (limited to 'lua.stx')
| -rw-r--r-- | lua.stx | 208 |
1 files changed, 91 insertions, 117 deletions
| @@ -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 */ |
| 25 | int luaY_parse (void); | 25 | int 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 | ||
| 121 | static 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 | |||
| 130 | static 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 | |||
| 138 | static void deltastack (int delta) | 118 | static 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 | ||
| 149 | static void code_opcode (OpCode op, int delta) | 129 | static 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 | ||
| 156 | static void code_opb (OpCode opbyte, int arg, int delta) | 152 | static 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 | } | |
| 162 | static 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 | ||
| 169 | static void code_opborw (OpCode opbyte, int arg, int delta) | 167 | static 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 | ||
| 178 | static void code_oparg (OpCode firstop, OpCode opbyte, int arg, int delta) | 174 | static 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) | 190 | static 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 | ||
| 202 | static void code_constant (int c) | 199 | static 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 |
| 241 | static int real_constant (real r) | 238 | static 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) | |||
| 270 | static void flush_record (int n) | 267 | static 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 | ||
| 276 | static void flush_list (int m, int n) | 273 | static 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) | |||
| 392 | static void adjuststack (int n) | 384 | static 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 | ||
| 401 | static long adjust_functioncall (long exp, int i) | 393 | static 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) | |||
| 430 | static void code_args (int dots) | 425 | static 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) | |||
| 441 | static void lua_pushvar (vardesc number) | 436 | static 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 | ||
| 479 | static 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 | |||
| 497 | static int fix_jump (int pc, OpCode op, int n) | 473 | static 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 | ||
| 525 | static void code_shortcircuit (OpCode op, int pos) | 501 | static 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 | ||
| 535 | static void codereturn (void) | 507 | static 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 | |||
| 589 | static TProtoFunc *close_func (void) | 559 | static 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 */ | |||
| 757 | GetPC : /* empty */ { $$ = currState->pc; } | 727 | GetPC : /* empty */ { $$ = currState->pc; } |
| 758 | ; | 728 | ; |
| 759 | 729 | ||
| 760 | SaveWord : GetPC { $$ = $1; code_word(0); /* open space */ } | 730 | SaveWord : /* empty */ |
| 731 | { $$ = currState->pc; | ||
| 732 | check_pc(JMPSIZE); | ||
| 733 | currState->pc += JMPSIZE; /* open space */ | ||
| 734 | } | ||
| 761 | ; | 735 | ; |
| 762 | 736 | ||
| 763 | SaveWordPop : SaveWord { $$ = $1; deltastack(-1); /* pop condition */ } | 737 | SaveWordPop : 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 | ||
| 801 | table : '{' SaveWordPush fieldlist '}' { fix_opcode($2, CREATEARRAYB, $3); } | 775 | table : '{' SaveWordPush fieldlist '}' { fix_opcode($2, CREATEARRAY, 2, $3); } |
| 802 | ; | 776 | ; |
| 803 | 777 | ||
| 804 | functioncall : funcvalue funcParams | 778 | functioncall : 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 | ||
| 813 | funcvalue : varexp { $$ = 0; } | 787 | funcvalue : 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 | ; |
