diff options
| -rw-r--r-- | lua.stx | 369 |
1 files changed, 184 insertions, 185 deletions
| @@ -1,6 +1,6 @@ | |||
| 1 | %{ | 1 | %{ |
| 2 | 2 | ||
| 3 | char *rcs_luastx = "$Id: lua.stx,v 3.13 1994/12/06 14:27:18 roberto Exp roberto $"; | 3 | char *rcs_luastx = "$Id: lua.stx,v 3.14 1994/12/20 21:20:36 roberto Exp celes $"; |
| 4 | 4 | ||
| 5 | #include <stdio.h> | 5 | #include <stdio.h> |
| 6 | #include <stdlib.h> | 6 | #include <stdlib.h> |
| @@ -177,6 +177,189 @@ static void code_number (float f) | |||
| 177 | } | 177 | } |
| 178 | } | 178 | } |
| 179 | 179 | ||
| 180 | /* | ||
| 181 | ** Search a local name and if find return its index. If do not find return -1 | ||
| 182 | */ | ||
| 183 | static int lua_localname (Word n) | ||
| 184 | { | ||
| 185 | int i; | ||
| 186 | for (i=nlocalvar-1; i >= 0; i--) | ||
| 187 | if (n == localvar[i]) return i; /* local var */ | ||
| 188 | return -1; /* global var */ | ||
| 189 | } | ||
| 190 | |||
| 191 | /* | ||
| 192 | ** Push a variable given a number. If number is positive, push global variable | ||
| 193 | ** indexed by (number -1). If negative, push local indexed by ABS(number)-1. | ||
| 194 | ** Otherwise, if zero, push indexed variable (record). | ||
| 195 | */ | ||
| 196 | static void lua_pushvar (Long number) | ||
| 197 | { | ||
| 198 | if (number > 0) /* global var */ | ||
| 199 | { | ||
| 200 | code_byte(PUSHGLOBAL); | ||
| 201 | code_word(number-1); | ||
| 202 | } | ||
| 203 | else if (number < 0) /* local var */ | ||
| 204 | { | ||
| 205 | number = (-number) - 1; | ||
| 206 | if (number < 10) code_byte(PUSHLOCAL0 + number); | ||
| 207 | else | ||
| 208 | { | ||
| 209 | code_byte(PUSHLOCAL); | ||
| 210 | code_byte(number); | ||
| 211 | } | ||
| 212 | } | ||
| 213 | else | ||
| 214 | { | ||
| 215 | code_byte(PUSHINDEXED); | ||
| 216 | } | ||
| 217 | } | ||
| 218 | |||
| 219 | static void lua_codeadjust (int n) | ||
| 220 | { | ||
| 221 | if (n+nlocalvar == 0) | ||
| 222 | code_byte(ADJUST0); | ||
| 223 | else | ||
| 224 | { | ||
| 225 | code_byte(ADJUST); | ||
| 226 | code_byte(n+nlocalvar); | ||
| 227 | } | ||
| 228 | } | ||
| 229 | |||
| 230 | static void init_function (TreeNode *func) | ||
| 231 | { | ||
| 232 | if (funcCode == NULL) /* first function */ | ||
| 233 | { | ||
| 234 | funcCode = newvector(CODE_BLOCK, Byte); | ||
| 235 | maxcode = CODE_BLOCK; | ||
| 236 | } | ||
| 237 | pc=0; basepc=funcCode; maxcurr=maxcode; | ||
| 238 | nlocalvar=0; | ||
| 239 | if (lua_debug) | ||
| 240 | { | ||
| 241 | code_byte(SETFUNCTION); | ||
| 242 | code_code((Byte *)strdup(lua_file[lua_nfile-1])); | ||
| 243 | code_word(luaI_findconstant(func)); | ||
| 244 | } | ||
| 245 | } | ||
| 246 | |||
| 247 | static void codereturn (void) | ||
| 248 | { | ||
| 249 | if (lua_debug) code_byte(RESET); | ||
| 250 | if (nlocalvar == 0) | ||
| 251 | code_byte(RETCODE0); | ||
| 252 | else | ||
| 253 | { | ||
| 254 | code_byte(RETCODE); | ||
| 255 | code_byte(nlocalvar); | ||
| 256 | } | ||
| 257 | } | ||
| 258 | |||
| 259 | static void codedebugline (void) | ||
| 260 | { | ||
| 261 | if (lua_debug) | ||
| 262 | { | ||
| 263 | code_byte(SETLINE); | ||
| 264 | code_word(lua_linenumber); | ||
| 265 | } | ||
| 266 | } | ||
| 267 | |||
| 268 | static void adjust_mult_assign (int vars, int exps, int temps) | ||
| 269 | { | ||
| 270 | if (exps < 0) | ||
| 271 | { | ||
| 272 | int r = vars - (-exps-1); | ||
| 273 | if (r >= 0) | ||
| 274 | code_byte(r); | ||
| 275 | else | ||
| 276 | { | ||
| 277 | code_byte(0); | ||
| 278 | lua_codeadjust(temps); | ||
| 279 | } | ||
| 280 | } | ||
| 281 | else if (vars != exps) | ||
| 282 | lua_codeadjust(temps); | ||
| 283 | } | ||
| 284 | |||
| 285 | static void lua_codestore (int i) | ||
| 286 | { | ||
| 287 | if (varbuffer[i] > 0) /* global var */ | ||
| 288 | { | ||
| 289 | code_byte(STOREGLOBAL); | ||
| 290 | code_word(varbuffer[i]-1); | ||
| 291 | } | ||
| 292 | else if (varbuffer[i] < 0) /* local var */ | ||
| 293 | { | ||
| 294 | int number = (-varbuffer[i]) - 1; | ||
| 295 | if (number < 10) code_byte(STORELOCAL0 + number); | ||
| 296 | else | ||
| 297 | { | ||
| 298 | code_byte(STORELOCAL); | ||
| 299 | code_byte(number); | ||
| 300 | } | ||
| 301 | } | ||
| 302 | else /* indexed var */ | ||
| 303 | { | ||
| 304 | int j; | ||
| 305 | int upper=0; /* number of indexed variables upper */ | ||
| 306 | int param; /* number of itens until indexed expression */ | ||
| 307 | for (j=i+1; j <nvarbuffer; j++) | ||
| 308 | if (varbuffer[j] == 0) upper++; | ||
| 309 | param = upper*2 + i; | ||
| 310 | if (param == 0) | ||
| 311 | code_byte(STOREINDEXED0); | ||
| 312 | else | ||
| 313 | { | ||
| 314 | code_byte(STOREINDEXED); | ||
| 315 | code_byte(param); | ||
| 316 | } | ||
| 317 | } | ||
| 318 | } | ||
| 319 | |||
| 320 | static void codeIf (Long thenAdd, Long elseAdd) | ||
| 321 | { | ||
| 322 | Long elseinit = elseAdd+sizeof(Word)+1; | ||
| 323 | if (pc == elseinit) /* no else */ | ||
| 324 | { | ||
| 325 | pc -= sizeof(Word)+1; | ||
| 326 | elseinit = pc; | ||
| 327 | } | ||
| 328 | else | ||
| 329 | { | ||
| 330 | basepc[elseAdd] = JMP; | ||
| 331 | code_word_at(basepc+elseAdd+1, pc-elseinit); | ||
| 332 | } | ||
| 333 | basepc[thenAdd] = IFFJMP; | ||
| 334 | code_word_at(basepc+thenAdd+1,elseinit-(thenAdd+sizeof(Word)+1)); | ||
| 335 | } | ||
| 336 | |||
| 337 | static void yyerror (char *s) | ||
| 338 | { | ||
| 339 | static char msg[256]; | ||
| 340 | sprintf (msg,"%s near \"%s\" at line %d in file \"%s\"", | ||
| 341 | s, lua_lasttext (), lua_linenumber, lua_filename()); | ||
| 342 | lua_error (msg); | ||
| 343 | } | ||
| 344 | |||
| 345 | |||
| 346 | /* | ||
| 347 | ** Parse LUA code. | ||
| 348 | */ | ||
| 349 | void lua_parse (Byte **code) | ||
| 350 | { | ||
| 351 | initcode = code; | ||
| 352 | *initcode = newvector(CODE_BLOCK, Byte); | ||
| 353 | maincode = 0; | ||
| 354 | maxmain = CODE_BLOCK; | ||
| 355 | if (yyparse ()) lua_error("parse error"); | ||
| 356 | (*initcode)[maincode++] = RETCODE0; | ||
| 357 | #if LISTING | ||
| 358 | { static void PrintCode (Byte *c, Byte *end); | ||
| 359 | PrintCode(*initcode,*initcode+maincode); } | ||
| 360 | #endif | ||
| 361 | } | ||
| 362 | |||
| 180 | 363 | ||
| 181 | %} | 364 | %} |
| 182 | 365 | ||
| @@ -555,190 +738,6 @@ setdebug : DEBUG {lua_debug = $1;} | |||
| 555 | 738 | ||
| 556 | %% | 739 | %% |
| 557 | 740 | ||
| 558 | /* | ||
| 559 | ** Search a local name and if find return its index. If do not find return -1 | ||
| 560 | */ | ||
| 561 | static int lua_localname (Word n) | ||
| 562 | { | ||
| 563 | int i; | ||
| 564 | for (i=nlocalvar-1; i >= 0; i--) | ||
| 565 | if (n == localvar[i]) return i; /* local var */ | ||
| 566 | return -1; /* global var */ | ||
| 567 | } | ||
| 568 | |||
| 569 | /* | ||
| 570 | ** Push a variable given a number. If number is positive, push global variable | ||
| 571 | ** indexed by (number -1). If negative, push local indexed by ABS(number)-1. | ||
| 572 | ** Otherwise, if zero, push indexed variable (record). | ||
| 573 | */ | ||
| 574 | static void lua_pushvar (Long number) | ||
| 575 | { | ||
| 576 | if (number > 0) /* global var */ | ||
| 577 | { | ||
| 578 | code_byte(PUSHGLOBAL); | ||
| 579 | code_word(number-1); | ||
| 580 | } | ||
| 581 | else if (number < 0) /* local var */ | ||
| 582 | { | ||
| 583 | number = (-number) - 1; | ||
| 584 | if (number < 10) code_byte(PUSHLOCAL0 + number); | ||
| 585 | else | ||
| 586 | { | ||
| 587 | code_byte(PUSHLOCAL); | ||
| 588 | code_byte(number); | ||
| 589 | } | ||
| 590 | } | ||
| 591 | else | ||
| 592 | { | ||
| 593 | code_byte(PUSHINDEXED); | ||
| 594 | } | ||
| 595 | } | ||
| 596 | |||
| 597 | static void lua_codeadjust (int n) | ||
| 598 | { | ||
| 599 | if (n+nlocalvar == 0) | ||
| 600 | code_byte(ADJUST0); | ||
| 601 | else | ||
| 602 | { | ||
| 603 | code_byte(ADJUST); | ||
| 604 | code_byte(n+nlocalvar); | ||
| 605 | } | ||
| 606 | } | ||
| 607 | |||
| 608 | static void init_function (TreeNode *func) | ||
| 609 | { | ||
| 610 | if (funcCode == NULL) /* first function */ | ||
| 611 | { | ||
| 612 | funcCode = newvector(CODE_BLOCK, Byte); | ||
| 613 | maxcode = CODE_BLOCK; | ||
| 614 | } | ||
| 615 | pc=0; basepc=funcCode; maxcurr=maxcode; | ||
| 616 | nlocalvar=0; | ||
| 617 | if (lua_debug) | ||
| 618 | { | ||
| 619 | code_byte(SETFUNCTION); | ||
| 620 | code_code((Byte *)strdup(lua_file[lua_nfile-1])); | ||
| 621 | code_word(luaI_findconstant(func)); | ||
| 622 | } | ||
| 623 | } | ||
| 624 | |||
| 625 | static void codereturn (void) | ||
| 626 | { | ||
| 627 | if (lua_debug) code_byte(RESET); | ||
| 628 | if (nlocalvar == 0) | ||
| 629 | code_byte(RETCODE0); | ||
| 630 | else | ||
| 631 | { | ||
| 632 | code_byte(RETCODE); | ||
| 633 | code_byte(nlocalvar); | ||
| 634 | } | ||
| 635 | } | ||
| 636 | |||
| 637 | static void codedebugline (void) | ||
| 638 | { | ||
| 639 | if (lua_debug) | ||
| 640 | { | ||
| 641 | code_byte(SETLINE); | ||
| 642 | code_word(lua_linenumber); | ||
| 643 | } | ||
| 644 | } | ||
| 645 | |||
| 646 | static void adjust_mult_assign (int vars, int exps, int temps) | ||
| 647 | { | ||
| 648 | if (exps < 0) | ||
| 649 | { | ||
| 650 | int r = vars - (-exps-1); | ||
| 651 | if (r >= 0) | ||
| 652 | code_byte(r); | ||
| 653 | else | ||
| 654 | { | ||
| 655 | code_byte(0); | ||
| 656 | lua_codeadjust(temps); | ||
| 657 | } | ||
| 658 | } | ||
| 659 | else if (vars != exps) | ||
| 660 | lua_codeadjust(temps); | ||
| 661 | } | ||
| 662 | |||
| 663 | static void lua_codestore (int i) | ||
| 664 | { | ||
| 665 | if (varbuffer[i] > 0) /* global var */ | ||
| 666 | { | ||
| 667 | code_byte(STOREGLOBAL); | ||
| 668 | code_word(varbuffer[i]-1); | ||
| 669 | } | ||
| 670 | else if (varbuffer[i] < 0) /* local var */ | ||
| 671 | { | ||
| 672 | int number = (-varbuffer[i]) - 1; | ||
| 673 | if (number < 10) code_byte(STORELOCAL0 + number); | ||
| 674 | else | ||
| 675 | { | ||
| 676 | code_byte(STORELOCAL); | ||
| 677 | code_byte(number); | ||
| 678 | } | ||
| 679 | } | ||
| 680 | else /* indexed var */ | ||
| 681 | { | ||
| 682 | int j; | ||
| 683 | int upper=0; /* number of indexed variables upper */ | ||
| 684 | int param; /* number of itens until indexed expression */ | ||
| 685 | for (j=i+1; j <nvarbuffer; j++) | ||
| 686 | if (varbuffer[j] == 0) upper++; | ||
| 687 | param = upper*2 + i; | ||
| 688 | if (param == 0) | ||
| 689 | code_byte(STOREINDEXED0); | ||
| 690 | else | ||
| 691 | { | ||
| 692 | code_byte(STOREINDEXED); | ||
| 693 | code_byte(param); | ||
| 694 | } | ||
| 695 | } | ||
| 696 | } | ||
| 697 | |||
| 698 | static void codeIf (Long thenAdd, Long elseAdd) | ||
| 699 | { | ||
| 700 | Long elseinit = elseAdd+sizeof(Word)+1; | ||
| 701 | if (pc == elseinit) /* no else */ | ||
| 702 | { | ||
| 703 | pc -= sizeof(Word)+1; | ||
| 704 | elseinit = pc; | ||
| 705 | } | ||
| 706 | else | ||
| 707 | { | ||
| 708 | basepc[elseAdd] = JMP; | ||
| 709 | code_word_at(basepc+elseAdd+1, pc-elseinit); | ||
| 710 | } | ||
| 711 | basepc[thenAdd] = IFFJMP; | ||
| 712 | code_word_at(basepc+thenAdd+1,elseinit-(thenAdd+sizeof(Word)+1)); | ||
| 713 | } | ||
| 714 | |||
| 715 | static void yyerror (char *s) | ||
| 716 | { | ||
| 717 | static char msg[256]; | ||
| 718 | sprintf (msg,"%s near \"%s\" at line %d in file \"%s\"", | ||
| 719 | s, lua_lasttext (), lua_linenumber, lua_filename()); | ||
| 720 | lua_error (msg); | ||
| 721 | } | ||
| 722 | |||
| 723 | |||
| 724 | /* | ||
| 725 | ** Parse LUA code. | ||
| 726 | */ | ||
| 727 | void lua_parse (Byte **code) | ||
| 728 | { | ||
| 729 | initcode = code; | ||
| 730 | *initcode = newvector(CODE_BLOCK, Byte); | ||
| 731 | maincode = 0; | ||
| 732 | maxmain = CODE_BLOCK; | ||
| 733 | if (yyparse ()) lua_error("parse error"); | ||
| 734 | (*initcode)[maincode++] = RETCODE0; | ||
| 735 | #if LISTING | ||
| 736 | { static void PrintCode (Byte *c, Byte *end); | ||
| 737 | PrintCode(*initcode,*initcode+maincode); } | ||
| 738 | #endif | ||
| 739 | } | ||
| 740 | |||
| 741 | |||
| 742 | #if LISTING | 741 | #if LISTING |
| 743 | 742 | ||
| 744 | static void PrintCode (Byte *code, Byte *end) | 743 | static void PrintCode (Byte *code, Byte *end) |
