diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1995-10-25 11:05:51 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1995-10-25 11:05:51 -0200 |
| commit | 9efc257d9d774501af4538a289729f3e8e5e3d7e (patch) | |
| tree | c4113f56f9bdcf6e1e66ac11f2cf5483387f3bc8 | |
| parent | fa71304e54f304ceceddef3a4b97b38228822e94 (diff) | |
| download | lua-9efc257d9d774501af4538a289729f3e8e5e3d7e.tar.gz lua-9efc257d9d774501af4538a289729f3e8e5e3d7e.tar.bz2 lua-9efc257d9d774501af4538a289729f3e8e5e3d7e.zip | |
new method to keep debug line information: current line is stored on the
Lua stack, just below (new) base, with tag LUA_T_LINE.
SETLINE opcodes are generated by lex.
| -rw-r--r-- | inout.c | 5 | ||||
| -rw-r--r-- | lex.c | 8 | ||||
| -rw-r--r-- | lua.h | 3 | ||||
| -rw-r--r-- | lua.stx | 214 | ||||
| -rw-r--r-- | opcode.c | 60 | ||||
| -rw-r--r-- | opcode.h | 6 |
6 files changed, 169 insertions, 127 deletions
| @@ -5,7 +5,7 @@ | |||
| 5 | ** Also provides some predefined lua functions. | 5 | ** Also provides some predefined lua functions. |
| 6 | */ | 6 | */ |
| 7 | 7 | ||
| 8 | char *rcs_inout="$Id: inout.c,v 2.23 1995/10/17 11:58:41 roberto Exp roberto $"; | 8 | char *rcs_inout="$Id: inout.c,v 2.24 1995/10/23 13:54:11 roberto Exp roberto $"; |
| 9 | 9 | ||
| 10 | #include <stdio.h> | 10 | #include <stdio.h> |
| 11 | #include <stdlib.h> | 11 | #include <stdlib.h> |
| @@ -29,8 +29,7 @@ char *rcs_inout="$Id: inout.c,v 2.23 1995/10/17 11:58:41 roberto Exp roberto $"; | |||
| 29 | 29 | ||
| 30 | /* Exported variables */ | 30 | /* Exported variables */ |
| 31 | Word lua_linenumber; | 31 | Word lua_linenumber; |
| 32 | Bool lua_debug; | 32 | Bool lua_debug = 0; |
| 33 | Word lua_debugline = 0; | ||
| 34 | char *lua_parsedfile; | 33 | char *lua_parsedfile; |
| 35 | 34 | ||
| 36 | 35 | ||
| @@ -1,4 +1,4 @@ | |||
| 1 | char *rcs_lex = "$Id: lex.c,v 2.18 1995/10/06 13:10:53 roberto Exp roberto $"; | 1 | char *rcs_lex = "$Id: lex.c,v 2.19 1995/10/13 15:16:25 roberto Exp roberto $"; |
| 2 | 2 | ||
| 3 | 3 | ||
| 4 | #include <ctype.h> | 4 | #include <ctype.h> |
| @@ -148,6 +148,10 @@ static int read_long_string (void) | |||
| 148 | int yylex (void) | 148 | int yylex (void) |
| 149 | { | 149 | { |
| 150 | float a; | 150 | float a; |
| 151 | static int linelasttoken = 0; | ||
| 152 | if (lua_debug) | ||
| 153 | luaI_codedebugline(linelasttoken); | ||
| 154 | linelasttoken = lua_linenumber; | ||
| 151 | while (1) | 155 | while (1) |
| 152 | { | 156 | { |
| 153 | yytextLast = yytext; | 157 | yytextLast = yytext; |
| @@ -159,7 +163,7 @@ int yylex (void) | |||
| 159 | case EOF: | 163 | case EOF: |
| 160 | case 0: | 164 | case 0: |
| 161 | return 0; | 165 | return 0; |
| 162 | case '\n': lua_linenumber++; | 166 | case '\n': linelasttoken = ++lua_linenumber; |
| 163 | case ' ': | 167 | case ' ': |
| 164 | case '\r': /* CR: to avoid problems with DOS/Windows */ | 168 | case '\r': /* CR: to avoid problems with DOS/Windows */ |
| 165 | case '\t': | 169 | case '\t': |
| @@ -2,7 +2,7 @@ | |||
| 2 | ** LUA - Linguagem para Usuarios de Aplicacao | 2 | ** LUA - Linguagem para Usuarios de Aplicacao |
| 3 | ** Grupo de Tecnologia em Computacao Grafica | 3 | ** Grupo de Tecnologia em Computacao Grafica |
| 4 | ** TeCGraf - PUC-Rio | 4 | ** TeCGraf - PUC-Rio |
| 5 | ** $Id: lua.h,v 3.17 1995/10/06 14:11:10 roberto Exp roberto $ | 5 | ** $Id: lua.h,v 3.18 1995/10/17 14:12:45 roberto Exp roberto $ |
| 6 | */ | 6 | */ |
| 7 | 7 | ||
| 8 | 8 | ||
| @@ -26,6 +26,7 @@ typedef enum | |||
| 26 | LUA_T_CFUNCTION= -6, | 26 | LUA_T_CFUNCTION= -6, |
| 27 | LUA_T_MARK = -7, | 27 | LUA_T_MARK = -7, |
| 28 | LUA_T_CMARK = -8, | 28 | LUA_T_CMARK = -8, |
| 29 | LUA_T_LINE = -9, | ||
| 29 | LUA_T_USERDATA = 0 | 30 | LUA_T_USERDATA = 0 |
| 30 | } lua_Type; | 31 | } lua_Type; |
| 31 | 32 | ||
| @@ -1,6 +1,6 @@ | |||
| 1 | %{ | 1 | %{ |
| 2 | 2 | ||
| 3 | char *rcs_luastx = "$Id: lua.stx,v 3.20 1995/10/04 14:20:26 roberto Exp roberto $"; | 3 | char *rcs_luastx = "$Id: lua.stx,v 3.21 1995/10/17 11:58:41 roberto Exp roberto $"; |
| 4 | 4 | ||
| 5 | #include <stdio.h> | 5 | #include <stdio.h> |
| 6 | #include <stdlib.h> | 6 | #include <stdlib.h> |
| @@ -37,6 +37,7 @@ static Byte *basepc; | |||
| 37 | static int maincode; | 37 | static int maincode; |
| 38 | static int pc; | 38 | static int pc; |
| 39 | 39 | ||
| 40 | |||
| 40 | #define MAXVAR 32 | 41 | #define MAXVAR 32 |
| 41 | static Long varbuffer[MAXVAR]; /* variables in an assignment list; | 42 | static Long varbuffer[MAXVAR]; /* variables in an assignment list; |
| 42 | it's long to store negative Word values */ | 43 | it's long to store negative Word values */ |
| @@ -235,15 +236,17 @@ static void lua_codeadjust (int n) | |||
| 235 | } | 236 | } |
| 236 | } | 237 | } |
| 237 | 238 | ||
| 238 | static void init_function (TreeNode *func) | 239 | static void change2main (void) |
| 239 | { | 240 | { |
| 240 | if (funcCode == NULL) /* first function */ | 241 | /* (re)store main values */ |
| 241 | { | 242 | pc=maincode; basepc=*initcode; maxcurr=maxmain; |
| 242 | funcCode = newvector(CODE_BLOCK, Byte); | 243 | nlocalvar=0; |
| 243 | maxcode = CODE_BLOCK; | 244 | } |
| 244 | } | 245 | |
| 245 | pc=0; basepc=funcCode; maxcurr=maxcode; | 246 | static void savemain (void) |
| 246 | nlocalvar=0; | 247 | { |
| 248 | /* save main values */ | ||
| 249 | maincode=pc; *initcode=basepc; maxmain=maxcurr; | ||
| 247 | } | 250 | } |
| 248 | 251 | ||
| 249 | static void codereturn (void) | 252 | static void codereturn (void) |
| @@ -257,29 +260,43 @@ static void codereturn (void) | |||
| 257 | } | 260 | } |
| 258 | } | 261 | } |
| 259 | 262 | ||
| 260 | static void codedebugline (void) | 263 | void luaI_codedebugline (int line) |
| 261 | { | 264 | { |
| 262 | if (lua_debug) | 265 | static int lastline = 0; |
| 266 | if (lua_debug && line != lastline) | ||
| 263 | { | 267 | { |
| 264 | code_byte(SETLINE); | 268 | code_byte(SETLINE); |
| 265 | code_word(lua_linenumber); | 269 | code_word(line); |
| 270 | lastline = line; | ||
| 266 | } | 271 | } |
| 267 | } | 272 | } |
| 268 | 273 | ||
| 269 | static void adjust_mult_assign (int vars, int exps, int temps) | 274 | static int adjust_functioncall (Long exp, int i) |
| 270 | { | 275 | { |
| 271 | if (exps < 0) | 276 | if (exp <= 0) |
| 277 | return -exp; /* exp is -list length */ | ||
| 278 | else | ||
| 272 | { | 279 | { |
| 273 | int r = vars - (-exps-1); | 280 | int temp = basepc[exp]; |
| 274 | if (r >= 0) | 281 | basepc[exp] = i; |
| 275 | code_byte(r); | 282 | return temp+i; |
| 283 | } | ||
| 284 | } | ||
| 285 | |||
| 286 | static void adjust_mult_assign (int vars, Long exps, int temps) | ||
| 287 | { | ||
| 288 | if (exps > 0) | ||
| 289 | { /* must correct function call */ | ||
| 290 | int diff = vars - basepc[exps]; | ||
| 291 | if (diff >= 0) | ||
| 292 | adjust_functioncall(exps, diff); | ||
| 276 | else | 293 | else |
| 277 | { | 294 | { |
| 278 | code_byte(0); | 295 | adjust_functioncall(exps, 0); |
| 279 | lua_codeadjust(temps); | 296 | lua_codeadjust(temps); |
| 280 | } | 297 | } |
| 281 | } | 298 | } |
| 282 | else if (vars != exps) | 299 | else if (vars != -exps) |
| 283 | lua_codeadjust(temps); | 300 | lua_codeadjust(temps); |
| 284 | } | 301 | } |
| 285 | 302 | ||
| @@ -349,11 +366,14 @@ static void yyerror (char *s) | |||
| 349 | */ | 366 | */ |
| 350 | void lua_parse (TFunc *tf) | 367 | void lua_parse (TFunc *tf) |
| 351 | { | 368 | { |
| 369 | lua_debug = 0; | ||
| 352 | initcode = &(tf->code); | 370 | initcode = &(tf->code); |
| 353 | *initcode = newvector(CODE_BLOCK, Byte); | 371 | *initcode = newvector(CODE_BLOCK, Byte); |
| 354 | maincode = 0; | 372 | maincode = 0; |
| 355 | maxmain = CODE_BLOCK; | 373 | maxmain = CODE_BLOCK; |
| 374 | change2main(); | ||
| 356 | if (yyparse ()) lua_error("parse error"); | 375 | if (yyparse ()) lua_error("parse error"); |
| 376 | savemain(); | ||
| 357 | (*initcode)[maincode++] = RETCODE0; | 377 | (*initcode)[maincode++] = RETCODE0; |
| 358 | tf->size = maincode; | 378 | tf->size = maincode; |
| 359 | #if LISTING | 379 | #if LISTING |
| @@ -391,10 +411,15 @@ void lua_parse (TFunc *tf) | |||
| 391 | %token <vInt> DEBUG | 411 | %token <vInt> DEBUG |
| 392 | 412 | ||
| 393 | %type <vLong> PrepJump | 413 | %type <vLong> PrepJump |
| 394 | %type <vInt> expr, exprlist, exprlist1, varlist1, funcParams, funcvalue | 414 | %type <vLong> exprlist, exprlist1 /* if > 0, points to function return |
| 415 | counter (which has list length); if <= 0, -list lenght */ | ||
| 416 | %type <vLong> functioncall, expr /* if != 0, points to function return | ||
| 417 | counter */ | ||
| 418 | %type <vInt> varlist1, funcParams, funcvalue | ||
| 395 | %type <vInt> fieldlist, localdeclist, decinit | 419 | %type <vInt> fieldlist, localdeclist, decinit |
| 396 | %type <vInt> ffieldlist, ffieldlist1, semicolonpart | 420 | %type <vInt> ffieldlist, ffieldlist1, semicolonpart |
| 397 | %type <vInt> lfieldlist, lfieldlist1 | 421 | %type <vInt> lfieldlist, lfieldlist1 |
| 422 | %type <vInt> functiontoken | ||
| 398 | %type <vLong> var, singlevar | 423 | %type <vLong> var, singlevar |
| 399 | %type <pFunc> body | 424 | %type <pFunc> body |
| 400 | 425 | ||
| @@ -411,63 +436,63 @@ void lua_parse (TFunc *tf) | |||
| 411 | 436 | ||
| 412 | 437 | ||
| 413 | functionlist : /* empty */ | 438 | functionlist : /* empty */ |
| 414 | | functionlist | 439 | | functionlist globalstat |
| 415 | { | ||
| 416 | pc=maincode; basepc=*initcode; maxcurr=maxmain; | ||
| 417 | nlocalvar=0; | ||
| 418 | } | ||
| 419 | stat sc | ||
| 420 | { | ||
| 421 | maincode=pc; *initcode=basepc; maxmain=maxcurr; | ||
| 422 | } | ||
| 423 | | functionlist function | 440 | | functionlist function |
| 424 | | functionlist method | 441 | | functionlist method |
| 425 | | functionlist setdebug | ||
| 426 | ; | 442 | ; |
| 427 | 443 | ||
| 428 | function : FUNCTION NAME | 444 | globalstat : stat sc |
| 429 | { | 445 | | setdebug |
| 430 | init_function($2); | 446 | ; |
| 431 | $<vInt>$ = lua_linenumber; | 447 | |
| 432 | } | 448 | function : functiontoken NAME body |
| 433 | body | ||
| 434 | { | 449 | { |
| 435 | Word func = luaI_findsymbol($2); | 450 | Word func = luaI_findsymbol($2); |
| 436 | luaI_insertfunction($4); /* may take part in GC */ | 451 | luaI_insertfunction($3); /* may take part in GC */ |
| 437 | s_tag(func) = LUA_T_FUNCTION; | 452 | s_tag(func) = LUA_T_FUNCTION; |
| 438 | lua_table[func].object.value.tf = $4; | 453 | lua_table[func].object.value.tf = $3; |
| 439 | $4->lineDefined = $<vInt>3; | 454 | $3->lineDefined = $1; |
| 440 | $4->name1 = $2->ts.str; | 455 | $3->name1 = $2->ts.str; |
| 441 | $4->name2 = NULL; | 456 | $3->name2 = NULL; |
| 442 | $4->fileName = lua_parsedfile; | 457 | $3->fileName = lua_parsedfile; |
| 443 | } | 458 | } |
| 444 | ; | 459 | ; |
| 445 | 460 | ||
| 446 | method : FUNCTION NAME ':' NAME | 461 | method : functiontoken NAME ':' NAME |
| 447 | { | 462 | { |
| 448 | init_function($4); | ||
| 449 | add_localvar(luaI_findsymbolbyname("self")); | 463 | add_localvar(luaI_findsymbolbyname("self")); |
| 450 | $<vInt>$ = lua_linenumber; | ||
| 451 | } | 464 | } |
| 452 | body | 465 | body |
| 453 | { | 466 | { |
| 454 | /* assign function to table field */ | 467 | /* assign function to table field */ |
| 455 | pc=maincode; basepc=*initcode; maxcurr=maxmain; | ||
| 456 | nlocalvar=0; | ||
| 457 | lua_pushvar(luaI_findsymbol($2)+1); | 468 | lua_pushvar(luaI_findsymbol($2)+1); |
| 458 | code_byte(PUSHSTRING); | 469 | code_byte(PUSHSTRING); |
| 459 | code_word(luaI_findconstant($4)); | 470 | code_word(luaI_findconstant($4)); |
| 460 | code_byte(PUSHFUNCTION); | 471 | code_byte(PUSHFUNCTION); |
| 461 | code_code($6); | 472 | code_code($6); |
| 462 | code_byte(STOREINDEXED0); | 473 | code_byte(STOREINDEXED0); |
| 463 | maincode=pc; *initcode=basepc; maxmain=maxcurr; | 474 | $6->lineDefined = $1; |
| 464 | $6->lineDefined = $<vInt>5; | ||
| 465 | $6->name1 = $4->ts.str; | 475 | $6->name1 = $4->ts.str; |
| 466 | $6->name2 = $2->ts.str; | 476 | $6->name2 = $2->ts.str; |
| 467 | $6->fileName = lua_parsedfile; | 477 | $6->fileName = lua_parsedfile; |
| 468 | } | 478 | } |
| 469 | ; | 479 | ; |
| 470 | 480 | ||
| 481 | functiontoken : FUNCTION | ||
| 482 | { | ||
| 483 | if (funcCode == NULL) /* first function */ | ||
| 484 | { | ||
| 485 | funcCode = newvector(CODE_BLOCK, Byte); | ||
| 486 | maxcode = CODE_BLOCK; | ||
| 487 | } | ||
| 488 | savemain(); /* save main values */ | ||
| 489 | /* set func values */ | ||
| 490 | pc=0; basepc=funcCode; maxcurr=maxcode; | ||
| 491 | nlocalvar=0; | ||
| 492 | $$ = lua_linenumber; | ||
| 493 | } | ||
| 494 | ; | ||
| 495 | |||
| 471 | body : '(' parlist ')' block END | 496 | body : '(' parlist ')' block END |
| 472 | { | 497 | { |
| 473 | codereturn(); | 498 | codereturn(); |
| @@ -475,10 +500,12 @@ body : '(' parlist ')' block END | |||
| 475 | $$->size = pc; | 500 | $$->size = pc; |
| 476 | $$->code = newvector(pc, Byte); | 501 | $$->code = newvector(pc, Byte); |
| 477 | memcpy($$->code, basepc, pc*sizeof(Byte)); | 502 | memcpy($$->code, basepc, pc*sizeof(Byte)); |
| 503 | /* save func values */ | ||
| 478 | funcCode = basepc; maxcode=maxcurr; | 504 | funcCode = basepc; maxcode=maxcurr; |
| 479 | #if LISTING | 505 | #if LISTING |
| 480 | PrintCode(funcCode,funcCode+pc); | 506 | PrintCode(funcCode,funcCode+pc); |
| 481 | #endif | 507 | #endif |
| 508 | change2main(); /* change back to main code */ | ||
| 482 | } | 509 | } |
| 483 | ; | 510 | ; |
| 484 | 511 | ||
| @@ -488,11 +515,7 @@ statlist : /* empty */ | |||
| 488 | 515 | ||
| 489 | sc : /* empty */ | ';' ; | 516 | sc : /* empty */ | ';' ; |
| 490 | 517 | ||
| 491 | stat : { codedebugline(); } stat1 ; | 518 | stat : IF expr1 THEN PrepJump block PrepJump elsepart END |
| 492 | |||
| 493 | cond : { codedebugline(); } expr1 ; | ||
| 494 | |||
| 495 | stat1 : IF expr1 THEN PrepJump block PrepJump elsepart END | ||
| 496 | { codeIf($4, $6); } | 519 | { codeIf($4, $6); } |
| 497 | 520 | ||
| 498 | | WHILE {$<vLong>$=pc;} expr1 DO PrepJump block PrepJump END | 521 | | WHILE {$<vLong>$=pc;} expr1 DO PrepJump block PrepJump END |
| @@ -503,7 +526,7 @@ stat1 : IF expr1 THEN PrepJump block PrepJump elsepart END | |||
| 503 | code_word_at(basepc+$7+1, pc - ($<vLong>2)); | 526 | code_word_at(basepc+$7+1, pc - ($<vLong>2)); |
| 504 | } | 527 | } |
| 505 | 528 | ||
| 506 | | REPEAT {$<vLong>$=pc;} block UNTIL cond PrepJump | 529 | | REPEAT {$<vLong>$=pc;} block UNTIL expr1 PrepJump |
| 507 | { | 530 | { |
| 508 | basepc[$6] = IFFUPJMP; | 531 | basepc[$6] = IFFUPJMP; |
| 509 | code_word_at(basepc+$6+1, pc - ($<vLong>2)); | 532 | code_word_at(basepc+$6+1, pc - ($<vLong>2)); |
| @@ -520,7 +543,7 @@ stat1 : IF expr1 THEN PrepJump block PrepJump elsepart END | |||
| 520 | lua_codeadjust (0); | 543 | lua_codeadjust (0); |
| 521 | } | 544 | } |
| 522 | } | 545 | } |
| 523 | | functioncall { code_byte(0); } | 546 | | functioncall |
| 524 | | LOCAL localdeclist decinit | 547 | | LOCAL localdeclist decinit |
| 525 | { nlocalvar += $2; | 548 | { nlocalvar += $2; |
| 526 | adjust_mult_assign($2, $3, 0); | 549 | adjust_mult_assign($2, $3, 0); |
| @@ -529,7 +552,7 @@ stat1 : IF expr1 THEN PrepJump block PrepJump elsepart END | |||
| 529 | 552 | ||
| 530 | elsepart : /* empty */ | 553 | elsepart : /* empty */ |
| 531 | | ELSE block | 554 | | ELSE block |
| 532 | | ELSEIF cond THEN PrepJump block PrepJump elsepart | 555 | | ELSEIF expr1 THEN PrepJump block PrepJump elsepart |
| 533 | { codeIf($4, $6); } | 556 | { codeIf($4, $6); } |
| 534 | ; | 557 | ; |
| 535 | 558 | ||
| @@ -544,9 +567,9 @@ block : {$<vInt>$ = nlocalvar;} statlist ret | |||
| 544 | ; | 567 | ; |
| 545 | 568 | ||
| 546 | ret : /* empty */ | 569 | ret : /* empty */ |
| 547 | | RETURN { codedebugline(); } exprlist sc | 570 | | RETURN exprlist sc |
| 548 | { | 571 | { |
| 549 | if ($3 < 0) code_byte(MULT_RET); | 572 | adjust_functioncall($2, MULT_RET); |
| 550 | codereturn(); | 573 | codereturn(); |
| 551 | } | 574 | } |
| 552 | ; | 575 | ; |
| @@ -558,46 +581,49 @@ PrepJump : /* empty */ | |||
| 558 | code_word (0); | 581 | code_word (0); |
| 559 | } | 582 | } |
| 560 | 583 | ||
| 561 | expr1 : expr { if ($1 == 0) code_byte(1); } | 584 | expr1 : expr |
| 585 | { | ||
| 586 | adjust_functioncall($1, 1); | ||
| 587 | } | ||
| 562 | ; | 588 | ; |
| 563 | 589 | ||
| 564 | expr : '(' expr ')' { $$ = $2; } | 590 | expr : '(' expr ')' { $$ = $2; } |
| 565 | | expr1 EQ expr1 { code_byte(EQOP); $$ = 1; } | 591 | | expr1 EQ expr1 { code_byte(EQOP); $$ = 0; } |
| 566 | | expr1 '<' expr1 { code_byte(LTOP); $$ = 1; } | 592 | | expr1 '<' expr1 { code_byte(LTOP); $$ = 0; } |
| 567 | | expr1 '>' expr1 { code_byte(GTOP); $$ = 1; } | 593 | | expr1 '>' expr1 { code_byte(GTOP); $$ = 0; } |
| 568 | | expr1 NE expr1 { code_byte(EQOP); code_byte(NOTOP); $$ = 1; } | 594 | | expr1 NE expr1 { code_byte(EQOP); code_byte(NOTOP); $$ = 0; } |
| 569 | | expr1 LE expr1 { code_byte(LEOP); $$ = 1; } | 595 | | expr1 LE expr1 { code_byte(LEOP); $$ = 0; } |
| 570 | | expr1 GE expr1 { code_byte(GEOP); $$ = 1; } | 596 | | expr1 GE expr1 { code_byte(GEOP); $$ = 0; } |
| 571 | | expr1 '+' expr1 { code_byte(ADDOP); $$ = 1; } | 597 | | expr1 '+' expr1 { code_byte(ADDOP); $$ = 0; } |
| 572 | | expr1 '-' expr1 { code_byte(SUBOP); $$ = 1; } | 598 | | expr1 '-' expr1 { code_byte(SUBOP); $$ = 0; } |
| 573 | | expr1 '*' expr1 { code_byte(MULTOP); $$ = 1; } | 599 | | expr1 '*' expr1 { code_byte(MULTOP); $$ = 0; } |
| 574 | | expr1 '/' expr1 { code_byte(DIVOP); $$ = 1; } | 600 | | expr1 '/' expr1 { code_byte(DIVOP); $$ = 0; } |
| 575 | | expr1 '^' expr1 { code_byte(POWOP); $$ = 1; } | 601 | | expr1 '^' expr1 { code_byte(POWOP); $$ = 0; } |
| 576 | | expr1 CONC expr1 { code_byte(CONCOP); $$ = 1; } | 602 | | expr1 CONC expr1 { code_byte(CONCOP); $$ = 0; } |
| 577 | | '-' expr1 %prec UNARY { code_byte(MINUSOP); $$ = 1;} | 603 | | '-' expr1 %prec UNARY { code_byte(MINUSOP); $$ = 0;} |
| 578 | | table { $$ = 1; } | 604 | | table { $$ = 0; } |
| 579 | | varexp { $$ = 1;} | 605 | | varexp { $$ = 0;} |
| 580 | | NUMBER { code_number($1); $$ = 1; } | 606 | | NUMBER { code_number($1); $$ = 0; } |
| 581 | | STRING | 607 | | STRING |
| 582 | { | 608 | { |
| 583 | code_byte(PUSHSTRING); | 609 | code_byte(PUSHSTRING); |
| 584 | code_word($1); | 610 | code_word($1); |
| 585 | $$ = 1; | 611 | $$ = 0; |
| 586 | } | 612 | } |
| 587 | | NIL {code_byte(PUSHNIL); $$ = 1; } | 613 | | NIL {code_byte(PUSHNIL); $$ = 0; } |
| 588 | | functioncall { $$ = 0; } | 614 | | functioncall { $$ = $1; } |
| 589 | | NOT expr1 { code_byte(NOTOP); $$ = 1;} | 615 | | NOT expr1 { code_byte(NOTOP); $$ = 0;} |
| 590 | | expr1 AND PrepJump {code_byte(POP); } expr1 | 616 | | expr1 AND PrepJump {code_byte(POP); } expr1 |
| 591 | { | 617 | { |
| 592 | basepc[$3] = ONFJMP; | 618 | basepc[$3] = ONFJMP; |
| 593 | code_word_at(basepc+$3+1, pc - ($3 + sizeof(Word)+1)); | 619 | code_word_at(basepc+$3+1, pc - ($3 + sizeof(Word)+1)); |
| 594 | $$ = 1; | 620 | $$ = 0; |
| 595 | } | 621 | } |
| 596 | | expr1 OR PrepJump {code_byte(POP); } expr1 | 622 | | expr1 OR PrepJump {code_byte(POP); } expr1 |
| 597 | { | 623 | { |
| 598 | basepc[$3] = ONTJMP; | 624 | basepc[$3] = ONTJMP; |
| 599 | code_word_at(basepc+$3+1, pc - ($3 + sizeof(Word)+1)); | 625 | code_word_at(basepc+$3+1, pc - ($3 + sizeof(Word)+1)); |
| 600 | $$ = 1; | 626 | $$ = 0; |
| 601 | } | 627 | } |
| 602 | ; | 628 | ; |
| 603 | 629 | ||
| @@ -613,7 +639,12 @@ table : | |||
| 613 | ; | 639 | ; |
| 614 | 640 | ||
| 615 | functioncall : funcvalue funcParams | 641 | functioncall : funcvalue funcParams |
| 616 | { code_byte(CALLFUNC); code_byte($1+$2); } | 642 | { |
| 643 | code_byte(CALLFUNC); | ||
| 644 | code_byte($1+$2); | ||
| 645 | $$ = pc; | ||
| 646 | code_byte(0); /* may be modified by other rules */ | ||
| 647 | } | ||
| 617 | ; | 648 | ; |
| 618 | 649 | ||
| 619 | funcvalue : varexp { $$ = 0; } | 650 | funcvalue : varexp { $$ = 0; } |
| @@ -626,7 +657,7 @@ funcvalue : varexp { $$ = 0; } | |||
| 626 | ; | 657 | ; |
| 627 | 658 | ||
| 628 | funcParams : '(' exprlist ')' | 659 | funcParams : '(' exprlist ')' |
| 629 | { if ($2<0) { code_byte(1); $$ = -$2; } else $$ = $2; } | 660 | { $$ = adjust_functioncall($2, 1); } |
| 630 | | table { $$ = 1; } | 661 | | table { $$ = 1; } |
| 631 | ; | 662 | ; |
| 632 | 663 | ||
| @@ -634,11 +665,15 @@ exprlist : /* empty */ { $$ = 0; } | |||
| 634 | | exprlist1 { $$ = $1; } | 665 | | exprlist1 { $$ = $1; } |
| 635 | ; | 666 | ; |
| 636 | 667 | ||
| 637 | exprlist1 : expr { if ($1 == 0) $$ = -1; else $$ = 1; } | 668 | exprlist1 : expr { if ($1 != 0) $$ = $1; else $$ = -1; } |
| 638 | | exprlist1 ',' { if ($1 < 0) code_byte(1); } expr | 669 | | exprlist1 ',' { $<vLong>$ = adjust_functioncall($1, 1); } expr |
| 639 | { | 670 | { |
| 640 | int r = $1 < 0 ? -$1 : $1; | 671 | if ($4 == 0) $$ = -($<vLong>3 + 1); /* -length */ |
| 641 | $$ = ($4 == 0) ? -(r+1) : r+1; | 672 | else |
| 673 | { | ||
| 674 | adjust_functioncall($4, $<vLong>3); | ||
| 675 | $$ = $4; | ||
| 676 | } | ||
| 642 | } | 677 | } |
| 643 | ; | 678 | ; |
| 644 | 679 | ||
| @@ -757,7 +792,8 @@ decinit : /* empty */ { $$ = 0; } | |||
| 757 | | '=' exprlist1 { $$ = $2; } | 792 | | '=' exprlist1 { $$ = $2; } |
| 758 | ; | 793 | ; |
| 759 | 794 | ||
| 760 | setdebug : DEBUG {lua_debug = $1;} | 795 | setdebug : DEBUG { lua_debug = $1; } |
| 796 | ; | ||
| 761 | 797 | ||
| 762 | %% | 798 | %% |
| 763 | 799 | ||
| @@ -3,7 +3,7 @@ | |||
| 3 | ** TecCGraf - PUC-Rio | 3 | ** TecCGraf - PUC-Rio |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | char *rcs_opcode="$Id: opcode.c,v 3.45 1995/10/17 14:12:45 roberto Exp $"; | 6 | char *rcs_opcode="$Id: opcode.c,v 3.46 1995/10/17 14:30:05 roberto Exp roberto $"; |
| 7 | 7 | ||
| 8 | #include <setjmp.h> | 8 | #include <setjmp.h> |
| 9 | #include <stdlib.h> | 9 | #include <stdlib.h> |
| @@ -75,7 +75,7 @@ static void lua_initstack (void) | |||
| 75 | stack = newvector(maxstack, Object); | 75 | stack = newvector(maxstack, Object); |
| 76 | stackLimit = stack+maxstack; | 76 | stackLimit = stack+maxstack; |
| 77 | top = stack; | 77 | top = stack; |
| 78 | *top = initial_stack; | 78 | *(top++) = initial_stack; |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | 81 | ||
| @@ -86,19 +86,19 @@ static void lua_initstack (void) | |||
| 86 | 86 | ||
| 87 | static void growstack (void) | 87 | static void growstack (void) |
| 88 | { | 88 | { |
| 89 | StkId t = top-stack; | ||
| 90 | if (stack == &initial_stack) | 89 | if (stack == &initial_stack) |
| 91 | lua_initstack(); | 90 | lua_initstack(); |
| 92 | else | 91 | else |
| 93 | { | 92 | { |
| 93 | StkId t = top-stack; | ||
| 94 | Long maxstack = stackLimit - stack; | 94 | Long maxstack = stackLimit - stack; |
| 95 | maxstack *= 2; | 95 | maxstack *= 2; |
| 96 | stack = growvector(stack, maxstack, Object); | 96 | stack = growvector(stack, maxstack, Object); |
| 97 | stackLimit = stack+maxstack; | 97 | stackLimit = stack+maxstack; |
| 98 | top = stack + t; | ||
| 98 | if (maxstack >= MAX_WORD/2) | 99 | if (maxstack >= MAX_WORD/2) |
| 99 | lua_error("stack size overflow"); | 100 | lua_error("stack size overflow"); |
| 100 | } | 101 | } |
| 101 | top = stack + t; | ||
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | 104 | ||
| @@ -227,16 +227,6 @@ static void callFB (int fb) | |||
| 227 | do_call((top-stack)-nParams, luaI_fallBacks[fb].nResults); | 227 | do_call((top-stack)-nParams, luaI_fallBacks[fb].nResults); |
| 228 | } | 228 | } |
| 229 | 229 | ||
| 230 | /* | ||
| 231 | ** Call the fallback for invalid functions (see do_call) | ||
| 232 | */ | ||
| 233 | static void call_funcFB (StkId base, int nResults) | ||
| 234 | { | ||
| 235 | open_stack((top-stack)-(base-1)); | ||
| 236 | stack[base-1] = luaI_fallBacks[FB_FUNCTION].function; | ||
| 237 | do_call(base, nResults); | ||
| 238 | } | ||
| 239 | |||
| 240 | 230 | ||
| 241 | /* | 231 | /* |
| 242 | ** Call a function (C or Lua). The parameters must be on the stack, | 232 | ** Call a function (C or Lua). The parameters must be on the stack, |
| @@ -248,6 +238,7 @@ static void do_call (StkId base, int nResults) | |||
| 248 | { | 238 | { |
| 249 | StkId firstResult; | 239 | StkId firstResult; |
| 250 | Object *func = stack+base-1; | 240 | Object *func = stack+base-1; |
| 241 | int i; | ||
| 251 | if (tag(func) == LUA_T_CFUNCTION) | 242 | if (tag(func) == LUA_T_CFUNCTION) |
| 252 | { | 243 | { |
| 253 | tag(func) = LUA_T_CMARK; | 244 | tag(func) = LUA_T_CMARK; |
| @@ -260,7 +251,10 @@ static void do_call (StkId base, int nResults) | |||
| 260 | } | 251 | } |
| 261 | else | 252 | else |
| 262 | { /* func is not a function */ | 253 | { /* func is not a function */ |
| 263 | call_funcFB(base, nResults); | 254 | /* Call the fallback for invalid functions */ |
| 255 | open_stack((top-stack)-(base-1)); | ||
| 256 | stack[base-1] = luaI_fallBacks[FB_FUNCTION].function; | ||
| 257 | do_call(base, nResults); | ||
| 264 | return; | 258 | return; |
| 265 | } | 259 | } |
| 266 | /* adjust the number of results */ | 260 | /* adjust the number of results */ |
| @@ -268,14 +262,10 @@ static void do_call (StkId base, int nResults) | |||
| 268 | adjust_top(firstResult+nResults); | 262 | adjust_top(firstResult+nResults); |
| 269 | /* move results to base-1 (to erase parameters and function) */ | 263 | /* move results to base-1 (to erase parameters and function) */ |
| 270 | base--; | 264 | base--; |
| 271 | if (firstResult != base) | 265 | nResults = top - (stack+firstResult); /* actual number of results */ |
| 272 | { | 266 | for (i=0; i<nResults; i++) |
| 273 | int i; | 267 | *(stack+base+i) = *(stack+firstResult+i); |
| 274 | nResults = top - (stack+firstResult); /* actual number of results */ | 268 | top -= firstResult-base; |
| 275 | for (i=0; i<nResults; i++) | ||
| 276 | *(stack+base+i) = *(stack+firstResult+i); | ||
| 277 | top -= firstResult-base; | ||
| 278 | } | ||
| 279 | } | 269 | } |
| 280 | 270 | ||
| 281 | 271 | ||
| @@ -366,9 +356,12 @@ lua_Object lua_stackedfunction (int level) | |||
| 366 | 356 | ||
| 367 | 357 | ||
| 368 | void lua_funcinfo (lua_Object func, char **filename, char **funcname, | 358 | void lua_funcinfo (lua_Object func, char **filename, char **funcname, |
| 369 | char **objname, int *linedefined) | 359 | char **objname, int *line) |
| 370 | { | 360 | { |
| 371 | return luaI_funcInfo(Address(func), filename, funcname, objname, linedefined); | 361 | Object *f = Address(func); |
| 362 | luaI_funcInfo(f, filename, funcname, objname, line); | ||
| 363 | *line = (f+1 < top && (f+1)->tag == LUA_T_LINE) ? | ||
| 364 | (f+1)->value.i : -1; | ||
| 372 | } | 365 | } |
| 373 | 366 | ||
| 374 | 367 | ||
| @@ -587,9 +580,9 @@ lua_Object lua_getparam (int number) | |||
| 587 | */ | 580 | */ |
| 588 | real lua_getnumber (lua_Object object) | 581 | real lua_getnumber (lua_Object object) |
| 589 | { | 582 | { |
| 590 | if (object == LUA_NOOBJECT || tag(Address(object)) == LUA_T_NIL) return 0.0; | 583 | if (object == LUA_NOOBJECT) return 0.0; |
| 591 | if (tonumber (Address(object))) return 0.0; | 584 | if (tonumber (Address(object))) return 0.0; |
| 592 | else return (nvalue(Address(object))); | 585 | else return (nvalue(Address(object))); |
| 593 | } | 586 | } |
| 594 | 587 | ||
| 595 | /* | 588 | /* |
| @@ -597,7 +590,7 @@ real lua_getnumber (lua_Object object) | |||
| 597 | */ | 590 | */ |
| 598 | char *lua_getstring (lua_Object object) | 591 | char *lua_getstring (lua_Object object) |
| 599 | { | 592 | { |
| 600 | if (object == LUA_NOOBJECT || tag(Address(object)) == LUA_T_NIL) return NULL; | 593 | if (object == LUA_NOOBJECT) return NULL; |
| 601 | if (tostring (Address(object))) return NULL; | 594 | if (tostring (Address(object))) return NULL; |
| 602 | else return (svalue(Address(object))); | 595 | else return (svalue(Address(object))); |
| 603 | } | 596 | } |
| @@ -1168,9 +1161,16 @@ static StkId lua_execute (Byte *pc, StkId base) | |||
| 1168 | { | 1161 | { |
| 1169 | CodeWord code; | 1162 | CodeWord code; |
| 1170 | get_word(code,pc); | 1163 | get_word(code,pc); |
| 1171 | lua_debugline = code.w; | 1164 | if ((stack+base-1)->tag != LUA_T_LINE) |
| 1165 | { | ||
| 1166 | /* open space for LINE value */ | ||
| 1167 | open_stack((top-stack)-base); | ||
| 1168 | base++; | ||
| 1169 | (stack+base-1)->tag = LUA_T_LINE; | ||
| 1170 | } | ||
| 1171 | (stack+base-1)->value.i = code.w; | ||
| 1172 | break; | ||
| 1172 | } | 1173 | } |
| 1173 | break; | ||
| 1174 | 1174 | ||
| 1175 | default: | 1175 | default: |
| 1176 | lua_error ("internal error - opcode doesn't match"); | 1176 | lua_error ("internal error - opcode doesn't match"); |
| @@ -1,6 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** TeCGraf - PUC-Rio | 2 | ** TeCGraf - PUC-Rio |
| 3 | ** $Id: opcode.h,v 3.12 1995/10/04 17:13:02 roberto Exp roberto $ | 3 | ** $Id: opcode.h,v 3.13 1995/10/17 11:58:41 roberto Exp roberto $ |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | #ifndef opcode_h | 6 | #ifndef opcode_h |
| @@ -68,7 +68,7 @@ typedef enum | |||
| 68 | CALLFUNC, | 68 | CALLFUNC, |
| 69 | RETCODE0, | 69 | RETCODE0, |
| 70 | RETCODE, | 70 | RETCODE, |
| 71 | SETLINE, | 71 | SETLINE |
| 72 | } OpCode; | 72 | } OpCode; |
| 73 | 73 | ||
| 74 | #define MULT_RET 255 | 74 | #define MULT_RET 255 |
| @@ -85,6 +85,7 @@ typedef union | |||
| 85 | TFunc *tf; | 85 | TFunc *tf; |
| 86 | struct Hash *a; | 86 | struct Hash *a; |
| 87 | void *u; | 87 | void *u; |
| 88 | int i; | ||
| 88 | } Value; | 89 | } Value; |
| 89 | 90 | ||
| 90 | typedef struct Object | 91 | typedef struct Object |
| @@ -147,6 +148,7 @@ void lua_setinput (Input fn); /* from "lex.c" module */ | |||
| 147 | char *lua_lasttext (void); /* from "lex.c" module */ | 148 | char *lua_lasttext (void); /* from "lex.c" module */ |
| 148 | int yylex (void); /* from "lex.c" module */ | 149 | int yylex (void); /* from "lex.c" module */ |
| 149 | void lua_parse (TFunc *tf); /* from "lua.stx" module */ | 150 | void lua_parse (TFunc *tf); /* from "lua.stx" module */ |
| 151 | void luaI_codedebugline (int line); /* from "lua.stx" module */ | ||
| 150 | void lua_travstack (int (*fn)(Object *)); | 152 | void lua_travstack (int (*fn)(Object *)); |
| 151 | Object *luaI_Address (lua_Object o); | 153 | Object *luaI_Address (lua_Object o); |
| 152 | void luaI_pushobject (Object *o); | 154 | void luaI_pushobject (Object *o); |
