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