diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1994-11-02 18:30:53 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1994-11-02 18:30:53 -0200 |
commit | fbf887ec2be8b293d6f3ffc88b42c5a9e87bf022 (patch) | |
tree | 030c6dd803fff11ae0c368e90b78a9fef2b8b731 | |
parent | ae77864844d6b933eb8be68694cbb8498af165dc (diff) | |
download | lua-fbf887ec2be8b293d6f3ffc88b42c5a9e87bf022.tar.gz lua-fbf887ec2be8b293d6f3ffc88b42c5a9e87bf022.tar.bz2 lua-fbf887ec2be8b293d6f3ffc88b42c5a9e87bf022.zip |
new way to call functions, plus several small changes. This is
a temporary version!
-rw-r--r-- | lua.h | 29 | ||||
-rw-r--r-- | lua.stx | 190 | ||||
-rw-r--r-- | opcode.c | 1298 | ||||
-rw-r--r-- | opcode.h | 41 |
4 files changed, 777 insertions, 781 deletions
@@ -2,13 +2,29 @@ | |||
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 1.4 1994/08/24 15:29:02 celes Exp roberto $ | 5 | ** $Id: lua.h,v 1.5 1994/11/01 17:54:31 roberto Exp $ |
6 | */ | 6 | */ |
7 | 7 | ||
8 | 8 | ||
9 | #ifndef lua_h | 9 | #ifndef lua_h |
10 | #define lua_h | 10 | #define lua_h |
11 | 11 | ||
12 | /* Private Part */ | ||
13 | |||
14 | typedef enum | ||
15 | { | ||
16 | LUA_T_MARK, | ||
17 | LUA_T_NIL, | ||
18 | LUA_T_NUMBER, | ||
19 | LUA_T_STRING, | ||
20 | LUA_T_ARRAY, | ||
21 | LUA_T_FUNCTION, | ||
22 | LUA_T_CFUNCTION, | ||
23 | LUA_T_USERDATA | ||
24 | } Type; | ||
25 | |||
26 | |||
27 | /* Public Part */ | ||
12 | 28 | ||
13 | typedef void (*lua_CFunction) (void); | 29 | typedef void (*lua_CFunction) (void); |
14 | typedef struct Object *lua_Object; | 30 | typedef struct Object *lua_Object; |
@@ -19,8 +35,7 @@ void lua_errorfunction (void (*fn) (char *s)); | |||
19 | void lua_error (char *s); | 35 | void lua_error (char *s); |
20 | int lua_dofile (char *filename); | 36 | int lua_dofile (char *filename); |
21 | int lua_dostring (char *string); | 37 | int lua_dostring (char *string); |
22 | int lua_call (char *functionname, int nparam); | 38 | int lua_callfunction (lua_Object function); |
23 | int lua_callfunction (lua_Object function, int nparam); | ||
24 | 39 | ||
25 | lua_Object lua_getparam (int number); | 40 | lua_Object lua_getparam (int number); |
26 | float lua_getnumber (lua_Object object); | 41 | float lua_getnumber (lua_Object object); |
@@ -33,8 +48,6 @@ lua_Object lua_getfield (lua_Object object, char *field); | |||
33 | lua_Object lua_getindexed (lua_Object object, float index); | 48 | lua_Object lua_getindexed (lua_Object object, float index); |
34 | lua_Object lua_getglobal (char *name); | 49 | lua_Object lua_getglobal (char *name); |
35 | 50 | ||
36 | lua_Object lua_pop (void); | ||
37 | |||
38 | int lua_pushnil (void); | 51 | int lua_pushnil (void); |
39 | int lua_pushnumber (float n); | 52 | int lua_pushnumber (float n); |
40 | int lua_pushstring (char *s); | 53 | int lua_pushstring (char *s); |
@@ -57,4 +70,10 @@ int lua_isfunction (lua_Object object); | |||
57 | int lua_iscfunction (lua_Object object); | 70 | int lua_iscfunction (lua_Object object); |
58 | int lua_isuserdata (lua_Object object); | 71 | int lua_isuserdata (lua_Object object); |
59 | 72 | ||
73 | |||
74 | /* for lua 1.1 */ | ||
75 | |||
76 | #define lua_call(f) lua_callfunction(lua_getglobal(f)) | ||
77 | |||
78 | |||
60 | #endif | 79 | #endif |
@@ -1,6 +1,6 @@ | |||
1 | %{ | 1 | %{ |
2 | 2 | ||
3 | char *rcs_luastx = "$Id: lua.stx,v 2.11 1994/10/21 19:00:12 roberto Exp roberto $"; | 3 | char *rcs_luastx = "$Id: lua.stx,v 2.12 1994/11/01 18:25:20 roberto Exp roberto $"; |
4 | 4 | ||
5 | #include <stdio.h> | 5 | #include <stdio.h> |
6 | #include <stdlib.h> | 6 | #include <stdlib.h> |
@@ -37,7 +37,6 @@ static int nlocalvar=0; /* number of local variables */ | |||
37 | #define MAXFIELDS FIELDS_PER_FLUSH*2 | 37 | #define MAXFIELDS FIELDS_PER_FLUSH*2 |
38 | static Word fields[MAXFIELDS]; /* fieldnames to be flushed */ | 38 | static Word fields[MAXFIELDS]; /* fieldnames to be flushed */ |
39 | static int nfields=0; | 39 | static int nfields=0; |
40 | static int ntemp; /* number of temporary var into stack */ | ||
41 | static int err; /* flag to indicate error */ | 40 | static int err; /* flag to indicate error */ |
42 | 41 | ||
43 | /* Internal functions */ | 42 | /* Internal functions */ |
@@ -112,7 +111,6 @@ static void flush_record (int n) | |||
112 | code_byte(n); | 111 | code_byte(n); |
113 | for (i=0; i<n; i++) | 112 | for (i=0; i<n; i++) |
114 | code_word(fields[--nfields]); | 113 | code_word(fields[--nfields]); |
115 | ntemp -= n; | ||
116 | } | 114 | } |
117 | 115 | ||
118 | static void flush_list (int m, int n) | 116 | static void flush_list (int m, int n) |
@@ -132,27 +130,15 @@ static void flush_list (int m, int n) | |||
132 | err = 1; | 130 | err = 1; |
133 | } | 131 | } |
134 | code_byte(n); | 132 | code_byte(n); |
135 | ntemp-=n; | ||
136 | } | ||
137 | |||
138 | static void incr_ntemp (void) | ||
139 | { | ||
140 | if (ntemp+nlocalvar+MAXVAR+1 < STACKGAP) | ||
141 | ntemp++; | ||
142 | else | ||
143 | { | ||
144 | lua_error ("stack overflow"); | ||
145 | err = 1; | ||
146 | } | ||
147 | } | 133 | } |
148 | 134 | ||
149 | static void add_nlocalvar (int n) | 135 | static void add_nlocalvar (int n) |
150 | { | 136 | { |
151 | if (ntemp+nlocalvar+MAXVAR+n < STACKGAP) | 137 | if (MAX_TEMPS+nlocalvar+MAXVAR+n < STACKGAP) |
152 | nlocalvar += n; | 138 | nlocalvar += n; |
153 | else | 139 | else |
154 | { | 140 | { |
155 | lua_error ("too many local variables or expression too complicate"); | 141 | lua_error ("too many local variables"); |
156 | err = 1; | 142 | err = 1; |
157 | } | 143 | } |
158 | } | 144 | } |
@@ -190,7 +176,6 @@ static void code_number (float f) | |||
190 | code_byte(PUSHFLOAT); | 176 | code_byte(PUSHFLOAT); |
191 | code_float(f); | 177 | code_float(f); |
192 | } | 178 | } |
193 | incr_ntemp(); | ||
194 | } | 179 | } |
195 | 180 | ||
196 | static void init_function (void) | 181 | static void init_function (void) |
@@ -235,8 +220,8 @@ static void init_function (void) | |||
235 | %token <vInt> DEBUG | 220 | %token <vInt> DEBUG |
236 | 221 | ||
237 | %type <vLong> PrepJump | 222 | %type <vLong> PrepJump |
238 | %type <vInt> expr, exprlist, exprlist1, varlist1, funcvalue | 223 | %type <vInt> expr, exprlist, exprlist1, varlist1, funcParams, funcvalue |
239 | %type <vInt> fieldlist, localdeclist | 224 | %type <vInt> fieldlist, localdeclist, decinit |
240 | %type <vInt> ffieldlist1 | 225 | %type <vInt> ffieldlist1 |
241 | %type <vInt> lfieldlist1 | 226 | %type <vInt> lfieldlist1 |
242 | %type <vLong> var, singlevar | 227 | %type <vLong> var, singlevar |
@@ -290,8 +275,8 @@ function : FUNCTION NAME | |||
290 | END | 275 | END |
291 | { | 276 | { |
292 | if (lua_debug) code_byte(RESET); | 277 | if (lua_debug) code_byte(RESET); |
293 | code_byte(RETCODE); code_byte(nlocalvar); | 278 | codereturn(); |
294 | s_tag($<vWord>3) = T_FUNCTION; | 279 | s_tag($<vWord>3) = LUA_T_FUNCTION; |
295 | s_bvalue($<vWord>3) = calloc (pc, sizeof(Byte)); | 280 | s_bvalue($<vWord>3) = calloc (pc, sizeof(Byte)); |
296 | if (s_bvalue($<vWord>3) == NULL) | 281 | if (s_bvalue($<vWord>3) == NULL) |
297 | { | 282 | { |
@@ -330,7 +315,7 @@ method : FUNCTION NAME { $<vWord>$ = lua_findsymbol($2); } ':' NAME | |||
330 | { | 315 | { |
331 | Byte *b; | 316 | Byte *b; |
332 | if (lua_debug) code_byte(RESET); | 317 | if (lua_debug) code_byte(RESET); |
333 | code_byte(RETCODE); code_byte(nlocalvar); | 318 | codereturn(); |
334 | b = calloc (pc, sizeof(Byte)); | 319 | b = calloc (pc, sizeof(Byte)); |
335 | if (b == NULL) | 320 | if (b == NULL) |
336 | { | 321 | { |
@@ -362,7 +347,6 @@ statlist : /* empty */ | |||
362 | ; | 347 | ; |
363 | 348 | ||
364 | stat : { | 349 | stat : { |
365 | ntemp = 0; | ||
366 | if (lua_debug) | 350 | if (lua_debug) |
367 | { | 351 | { |
368 | code_byte(SETLINE); code_word(lua_linenumber); | 352 | code_byte(SETLINE); code_word(lua_linenumber); |
@@ -414,16 +398,18 @@ stat1 : IF expr1 THEN PrepJump block PrepJump elsepart END | |||
414 | { | 398 | { |
415 | { | 399 | { |
416 | int i; | 400 | int i; |
417 | if ($3 == 0 || nvarbuffer != ntemp - $1 * 2) | 401 | adjust_mult_assign(nvarbuffer, $3, $1 * 2 + nvarbuffer); |
418 | lua_codeadjust ($1 * 2 + nvarbuffer); | ||
419 | for (i=nvarbuffer-1; i>=0; i--) | 402 | for (i=nvarbuffer-1; i>=0; i--) |
420 | lua_codestore (i); | 403 | lua_codestore (i); |
421 | if ($1 > 1 || ($1 == 1 && varbuffer[0] != 0)) | 404 | if ($1 > 1 || ($1 == 1 && varbuffer[0] != 0)) |
422 | lua_codeadjust (0); | 405 | lua_codeadjust (0); |
423 | } | 406 | } |
424 | } | 407 | } |
425 | | functioncall { lua_codeadjust (0); } | 408 | | functioncall { code_byte(0); } |
426 | | LOCAL localdeclist decinit { add_nlocalvar($2); lua_codeadjust (0); } | 409 | | LOCAL localdeclist decinit |
410 | { add_nlocalvar($2); | ||
411 | adjust_mult_assign($2, $3, 0); | ||
412 | } | ||
427 | ; | 413 | ; |
428 | 414 | ||
429 | elsepart : /* empty */ | 415 | elsepart : /* empty */ |
@@ -448,7 +434,7 @@ elsepart : /* empty */ | |||
448 | } | 434 | } |
449 | ; | 435 | ; |
450 | 436 | ||
451 | block : {$<vInt>$ = nlocalvar;} statlist {ntemp = 0;} ret | 437 | block : {$<vInt>$ = nlocalvar;} statlist ret |
452 | { | 438 | { |
453 | if (nlocalvar != $<vInt>1) | 439 | if (nlocalvar != $<vInt>1) |
454 | { | 440 | { |
@@ -462,8 +448,9 @@ ret : /* empty */ | |||
462 | | { if (lua_debug){code_byte(SETLINE);code_word(lua_linenumber);}} | 448 | | { if (lua_debug){code_byte(SETLINE);code_word(lua_linenumber);}} |
463 | RETURN exprlist sc | 449 | RETURN exprlist sc |
464 | { | 450 | { |
451 | if ($3 < 0) code_byte(MULT_RET); | ||
465 | if (lua_debug) code_byte(RESET); | 452 | if (lua_debug) code_byte(RESET); |
466 | code_byte(RETCODE); code_byte(nlocalvar); | 453 | codereturn(); |
467 | } | 454 | } |
468 | ; | 455 | ; |
469 | 456 | ||
@@ -474,22 +461,22 @@ PrepJump : /* empty */ | |||
474 | code_word (0); | 461 | code_word (0); |
475 | } | 462 | } |
476 | 463 | ||
477 | expr1 : expr { if ($1 == 0) {lua_codeadjust (ntemp+1); incr_ntemp();}} | 464 | expr1 : expr { if ($1 == 0) code_byte(1); } |
478 | ; | 465 | ; |
479 | 466 | ||
480 | expr : '(' expr ')' { $$ = $2; } | 467 | expr : '(' expr ')' { $$ = $2; } |
481 | | expr1 EQ expr1 { code_byte(EQOP); $$ = 1; ntemp--;} | 468 | | expr1 EQ expr1 { code_byte(EQOP); $$ = 1; } |
482 | | expr1 '<' expr1 { code_byte(LTOP); $$ = 1; ntemp--;} | 469 | | expr1 '<' expr1 { code_byte(LTOP); $$ = 1; } |
483 | | expr1 '>' expr1 { code_byte(LEOP); code_byte(NOTOP); $$ = 1; ntemp--;} | 470 | | expr1 '>' expr1 { code_byte(LEOP); code_byte(NOTOP); $$ = 1; } |
484 | | expr1 NE expr1 { code_byte(EQOP); code_byte(NOTOP); $$ = 1; ntemp--;} | 471 | | expr1 NE expr1 { code_byte(EQOP); code_byte(NOTOP); $$ = 1; } |
485 | | expr1 LE expr1 { code_byte(LEOP); $$ = 1; ntemp--;} | 472 | | expr1 LE expr1 { code_byte(LEOP); $$ = 1; } |
486 | | expr1 GE expr1 { code_byte(LTOP); code_byte(NOTOP); $$ = 1; ntemp--;} | 473 | | expr1 GE expr1 { code_byte(LTOP); code_byte(NOTOP); $$ = 1; } |
487 | | expr1 '+' expr1 { code_byte(ADDOP); $$ = 1; ntemp--;} | 474 | | expr1 '+' expr1 { code_byte(ADDOP); $$ = 1; } |
488 | | expr1 '-' expr1 { code_byte(SUBOP); $$ = 1; ntemp--;} | 475 | | expr1 '-' expr1 { code_byte(SUBOP); $$ = 1; } |
489 | | expr1 '*' expr1 { code_byte(MULTOP); $$ = 1; ntemp--;} | 476 | | expr1 '*' expr1 { code_byte(MULTOP); $$ = 1; } |
490 | | expr1 '/' expr1 { code_byte(DIVOP); $$ = 1; ntemp--;} | 477 | | expr1 '/' expr1 { code_byte(DIVOP); $$ = 1; } |
491 | | expr1 '^' expr1 { code_byte(POWOP); $$ = 1; ntemp--;} | 478 | | expr1 '^' expr1 { code_byte(POWOP); $$ = 1; } |
492 | | expr1 CONC expr1 { code_byte(CONCOP); $$ = 1; ntemp--;} | 479 | | expr1 CONC expr1 { code_byte(CONCOP); $$ = 1; } |
493 | | '+' expr1 %prec UNARY { $$ = 1; } | 480 | | '+' expr1 %prec UNARY { $$ = 1; } |
494 | | '-' expr1 %prec UNARY { code_byte(MINUSOP); $$ = 1;} | 481 | | '-' expr1 %prec UNARY { code_byte(MINUSOP); $$ = 1;} |
495 | | table { $$ = 1; } | 482 | | table { $$ = 1; } |
@@ -500,9 +487,8 @@ expr : '(' expr ')' { $$ = $2; } | |||
500 | code_byte(PUSHSTRING); | 487 | code_byte(PUSHSTRING); |
501 | code_word(lua_findconstant($1)); | 488 | code_word(lua_findconstant($1)); |
502 | $$ = 1; | 489 | $$ = 1; |
503 | incr_ntemp(); | ||
504 | } | 490 | } |
505 | | NIL {code_byte(PUSHNIL); $$ = 1; incr_ntemp();} | 491 | | NIL {code_byte(PUSHNIL); $$ = 1; } |
506 | | functioncall | 492 | | functioncall |
507 | { | 493 | { |
508 | $$ = 0; | 494 | $$ = 0; |
@@ -512,13 +498,13 @@ expr : '(' expr ')' { $$ = $2; } | |||
512 | } | 498 | } |
513 | } | 499 | } |
514 | | NOT expr1 { code_byte(NOTOP); $$ = 1;} | 500 | | NOT expr1 { code_byte(NOTOP); $$ = 1;} |
515 | | expr1 AND PrepJump {code_byte(POP); ntemp--;} expr1 | 501 | | expr1 AND PrepJump {code_byte(POP); } expr1 |
516 | { | 502 | { |
517 | basepc[$3] = ONFJMP; | 503 | basepc[$3] = ONFJMP; |
518 | code_word_at(basepc+$3+1, pc - ($3 + sizeof(Word)+1)); | 504 | code_word_at(basepc+$3+1, pc - ($3 + sizeof(Word)+1)); |
519 | $$ = 1; | 505 | $$ = 1; |
520 | } | 506 | } |
521 | | expr1 OR PrepJump {code_byte(POP); ntemp--;} expr1 | 507 | | expr1 OR PrepJump {code_byte(POP); } expr1 |
522 | { | 508 | { |
523 | basepc[$3] = ONTJMP; | 509 | basepc[$3] = ONTJMP; |
524 | code_word_at(basepc+$3+1, pc - ($3 + sizeof(Word)+1)); | 510 | code_word_at(basepc+$3+1, pc - ($3 + sizeof(Word)+1)); |
@@ -537,33 +523,35 @@ table : | |||
537 | } | 523 | } |
538 | ; | 524 | ; |
539 | 525 | ||
540 | functioncall : funcvalue funcParams { code_byte(CALLFUNC); ntemp = $1-1; } | 526 | functioncall : funcvalue funcParams |
527 | { code_byte(CALLFUNC); code_byte($1+$2); } | ||
541 | ; | 528 | ; |
542 | funcvalue : varexp | 529 | |
543 | { | 530 | funcvalue : varexp { $$ = 0; } |
544 | $$ = ntemp; code_byte(PUSHMARK); incr_ntemp(); | ||
545 | } | ||
546 | | varexp ':' NAME | 531 | | varexp ':' NAME |
547 | { | 532 | { |
548 | code_byte(PUSHSTRING); | 533 | code_byte(PUSHSTRING); |
549 | code_word(lua_findconstant($3)); | 534 | code_word(lua_findconstant($3)); |
550 | incr_ntemp(); | 535 | code_byte(PUSHSELF); |
551 | $$ = ntemp-1; | 536 | $$ = 1; |
552 | code_byte(PUSHMARKMET); | ||
553 | incr_ntemp(); | ||
554 | } | 537 | } |
555 | ; | 538 | ; |
539 | |||
556 | funcParams : '(' exprlist ')' | 540 | funcParams : '(' exprlist ')' |
557 | | table | 541 | { if ($2<0) { code_byte(1); $$ = -$2; } else $$ = $2; } |
542 | | table { $$ = 1; } | ||
558 | ; | 543 | ; |
559 | 544 | ||
560 | exprlist : /* empty */ { $$ = 1; } | 545 | exprlist : /* empty */ { $$ = 0; } |
561 | | exprlist1 { $$ = $1; } | 546 | | exprlist1 { $$ = $1; } |
562 | ; | 547 | ; |
563 | 548 | ||
564 | exprlist1 : expr { $$ = $1; } | 549 | exprlist1 : expr { if ($1 == 0) $$ = -1; else $$ = 1; } |
565 | | exprlist1 ',' {if (!$1){lua_codeadjust (ntemp+1); incr_ntemp();}} | 550 | | exprlist1 ',' { if ($1 < 0) code_byte(1); } expr |
566 | expr {$$ = $4;} | 551 | { |
552 | int r = $1 < 0 ? -$1 : $1; | ||
553 | $$ = ($4 == 0) ? -(r+1) : r+1; | ||
554 | } | ||
567 | ; | 555 | ; |
568 | 556 | ||
569 | parlist : /* empty */ | 557 | parlist : /* empty */ |
@@ -641,7 +629,7 @@ var : singlevar { $$ = $1; } | |||
641 | | varexp '.' NAME | 629 | | varexp '.' NAME |
642 | { | 630 | { |
643 | code_byte(PUSHSTRING); | 631 | code_byte(PUSHSTRING); |
644 | code_word(lua_findconstant($3)); incr_ntemp(); | 632 | code_word(lua_findconstant($3)); |
645 | $$ = 0; /* indexed variable */ | 633 | $$ = 0; /* indexed variable */ |
646 | } | 634 | } |
647 | ; | 635 | ; |
@@ -668,8 +656,8 @@ localdeclist : NAME {localvar[nlocalvar]=lua_findsymbol($1); $$ = 1;} | |||
668 | } | 656 | } |
669 | ; | 657 | ; |
670 | 658 | ||
671 | decinit : /* empty */ | 659 | decinit : /* empty */ { $$ = 0; } |
672 | | '=' exprlist1 | 660 | | '=' exprlist1 { $$ = $2; } |
673 | ; | 661 | ; |
674 | 662 | ||
675 | setdebug : DEBUG {lua_debug = $1;} | 663 | setdebug : DEBUG {lua_debug = $1;} |
@@ -698,7 +686,6 @@ static void lua_pushvar (long number) | |||
698 | { | 686 | { |
699 | code_byte(PUSHGLOBAL); | 687 | code_byte(PUSHGLOBAL); |
700 | code_word(number-1); | 688 | code_word(number-1); |
701 | incr_ntemp(); | ||
702 | } | 689 | } |
703 | else if (number < 0) /* local var */ | 690 | else if (number < 0) /* local var */ |
704 | { | 691 | { |
@@ -709,19 +696,50 @@ static void lua_pushvar (long number) | |||
709 | code_byte(PUSHLOCAL); | 696 | code_byte(PUSHLOCAL); |
710 | code_byte(number); | 697 | code_byte(number); |
711 | } | 698 | } |
712 | incr_ntemp(); | ||
713 | } | 699 | } |
714 | else | 700 | else |
715 | { | 701 | { |
716 | code_byte(PUSHINDEXED); | 702 | code_byte(PUSHINDEXED); |
717 | ntemp--; | ||
718 | } | 703 | } |
719 | } | 704 | } |
720 | 705 | ||
721 | static void lua_codeadjust (int n) | 706 | static void lua_codeadjust (int n) |
722 | { | 707 | { |
723 | code_byte(ADJUST); | 708 | if (n+nlocalvar == 0) |
724 | code_byte(n + nlocalvar); | 709 | code_byte(ADJUST0); |
710 | else | ||
711 | { | ||
712 | code_byte(ADJUST); | ||
713 | code_byte(n+nlocalvar); | ||
714 | } | ||
715 | } | ||
716 | |||
717 | static void codereturn (void) | ||
718 | { | ||
719 | if (nlocalvar == 0) | ||
720 | code_byte(RETCODE0); | ||
721 | else | ||
722 | { | ||
723 | code_byte(RETCODE); | ||
724 | code_byte(nlocalvar); | ||
725 | } | ||
726 | } | ||
727 | |||
728 | static void adjust_mult_assign (int vars, int exps, int temps) | ||
729 | { | ||
730 | if (exps < 0) | ||
731 | { | ||
732 | int r = vars - (-exps-1); | ||
733 | if (r >= 0) | ||
734 | code_byte(r); | ||
735 | else | ||
736 | { | ||
737 | code_byte(0); | ||
738 | lua_codeadjust(temps); | ||
739 | } | ||
740 | } | ||
741 | else if (vars != exps) | ||
742 | lua_codeadjust(temps); | ||
725 | } | 743 | } |
726 | 744 | ||
727 | static void lua_codestore (int i) | 745 | static void lua_codestore (int i) |
@@ -775,10 +793,9 @@ int yywrap (void) | |||
775 | 793 | ||
776 | 794 | ||
777 | /* | 795 | /* |
778 | ** Parse LUA code and execute global statement. | 796 | ** Parse LUA code and returns global statements. |
779 | ** Return 0 on success or 1 on error. | ||
780 | */ | 797 | */ |
781 | int lua_parse (void) | 798 | Byte *lua_parse (void) |
782 | { | 799 | { |
783 | Byte *init = initcode = (Byte *) calloc(CODE_BLOCK, sizeof(Byte)); | 800 | Byte *init = initcode = (Byte *) calloc(CODE_BLOCK, sizeof(Byte)); |
784 | maincode = 0; | 801 | maincode = 0; |
@@ -786,18 +803,17 @@ int lua_parse (void) | |||
786 | if (init == NULL) | 803 | if (init == NULL) |
787 | { | 804 | { |
788 | lua_error("not enough memory"); | 805 | lua_error("not enough memory"); |
789 | return 1; | 806 | return NULL; |
790 | } | 807 | } |
791 | err = 0; | 808 | err = 0; |
792 | if (yyparse () || (err==1)) return 1; | 809 | if (yyparse () || (err==1)) return NULL; |
793 | initcode[maincode++] = HALT; | 810 | initcode[maincode++] = RETCODE0; |
794 | init = initcode; | 811 | init = initcode; |
795 | #if LISTING | 812 | #if LISTING |
796 | PrintCode(init,init+maincode); | 813 | { static void PrintCode (Byte *code, Byte *end); |
814 | PrintCode(init,init+maincode); } | ||
797 | #endif | 815 | #endif |
798 | if (lua_execute (init)) return 1; | 816 | return init; |
799 | free(init); | ||
800 | return 0; | ||
801 | } | 817 | } |
802 | 818 | ||
803 | 819 | ||
@@ -876,7 +892,6 @@ static void PrintCode (Byte *code, Byte *end) | |||
876 | } | 892 | } |
877 | break; | 893 | break; |
878 | case PUSHINDEXED: printf ("%d PUSHINDEXED\n", (p++)-code); break; | 894 | case PUSHINDEXED: printf ("%d PUSHINDEXED\n", (p++)-code); break; |
879 | case PUSHMARK: printf ("%d PUSHMARK\n", (p++)-code); break; | ||
880 | case STORELOCAL0: case STORELOCAL1: case STORELOCAL2: case STORELOCAL3: | 895 | case STORELOCAL0: case STORELOCAL1: case STORELOCAL2: case STORELOCAL3: |
881 | case STORELOCAL4: case STORELOCAL5: case STORELOCAL6: case STORELOCAL7: | 896 | case STORELOCAL4: case STORELOCAL5: case STORELOCAL6: case STORELOCAL7: |
882 | case STORELOCAL8: case STORELOCAL9: | 897 | case STORELOCAL8: case STORELOCAL9: |
@@ -896,6 +911,7 @@ static void PrintCode (Byte *code, Byte *end) | |||
896 | printf ("%d STOREGLOBAL %d\n", n, c.w); | 911 | printf ("%d STOREGLOBAL %d\n", n, c.w); |
897 | } | 912 | } |
898 | break; | 913 | break; |
914 | case PUSHSELF: printf ("%d PUSHSELF\n", (p++)-code); break; | ||
899 | case STOREINDEXED0: printf ("%d STOREINDEXED0\n", (p++)-code); break; | 915 | case STOREINDEXED0: printf ("%d STOREINDEXED0\n", (p++)-code); break; |
900 | case STOREINDEXED: printf ("%d STOREINDEXED %d\n", p-code, *(++p)); | 916 | case STOREINDEXED: printf ("%d STOREINDEXED %d\n", p-code, *(++p)); |
901 | p++; | 917 | p++; |
@@ -912,6 +928,7 @@ static void PrintCode (Byte *code, Byte *end) | |||
912 | printf("%d STORERECORD %d\n", p-code, *(++p)); | 928 | printf("%d STORERECORD %d\n", p-code, *(++p)); |
913 | p += *p*sizeof(Word) + 1; | 929 | p += *p*sizeof(Word) + 1; |
914 | break; | 930 | break; |
931 | case ADJUST0: printf ("%d ADJUST0\n", (p++)-code); break; | ||
915 | case ADJUST: | 932 | case ADJUST: |
916 | printf ("%d ADJUST %d\n", p-code, *(++p)); | 933 | printf ("%d ADJUST %d\n", p-code, *(++p)); |
917 | p++; | 934 | p++; |
@@ -922,7 +939,7 @@ static void PrintCode (Byte *code, Byte *end) | |||
922 | int n = p-code; | 939 | int n = p-code; |
923 | p++; | 940 | p++; |
924 | get_word(c,p); | 941 | get_word(c,p); |
925 | printf ("%d CREATEARRAY\n", n, c.w); | 942 | printf ("%d CREATEARRAY %d\n", n, c.w); |
926 | break; | 943 | break; |
927 | } | 944 | } |
928 | case EQOP: printf ("%d EQOP\n", (p++)-code); break; | 945 | case EQOP: printf ("%d EQOP\n", (p++)-code); break; |
@@ -990,16 +1007,19 @@ static void PrintCode (Byte *code, Byte *end) | |||
990 | } | 1007 | } |
991 | break; | 1008 | break; |
992 | case POP: printf ("%d POP\n", (p++)-code); break; | 1009 | case POP: printf ("%d POP\n", (p++)-code); break; |
993 | case CALLFUNC: printf ("%d CALLFUNC\n", (p++)-code); break; | 1010 | case CALLFUNC: |
1011 | printf ("%d CALLFUNC %d %d\n", p-code, *(p+1), *(p+2)); | ||
1012 | p+=3; | ||
1013 | break; | ||
1014 | case RETCODE0: printf ("%d RETCODE0\n", (p++)-code); break; | ||
994 | case RETCODE: | 1015 | case RETCODE: |
995 | printf ("%d RETCODE %d\n", p-code, *(++p)); | 1016 | printf ("%d RETCODE %d\n", p-code, *(++p)); |
996 | p++; | 1017 | p++; |
997 | break; | 1018 | break; |
998 | case HALT: printf ("%d HALT\n", (p++)-code); break; | ||
999 | case SETFUNCTION: | 1019 | case SETFUNCTION: |
1000 | { | 1020 | { |
1001 | CodeCode c1; | 1021 | CodeCode c1; |
1002 | CodeWord c1; | 1022 | CodeWord c2; |
1003 | int n = p-code; | 1023 | int n = p-code; |
1004 | p++; | 1024 | p++; |
1005 | get_code(c1,p); | 1025 | get_code(c1,p); |
@@ -3,11 +3,12 @@ | |||
3 | ** TecCGraf - PUC-Rio | 3 | ** TecCGraf - PUC-Rio |
4 | */ | 4 | */ |
5 | 5 | ||
6 | char *rcs_opcode="$Id: opcode.c,v 2.11 1994/11/01 17:54:31 roberto Exp roberto $"; | 6 | char *rcs_opcode="$Id: opcode.c,v 2.12 1994/11/01 18:25:20 roberto Exp roberto $"; |
7 | 7 | ||
8 | #include <stdio.h> | 8 | #include <stdio.h> |
9 | #include <stdlib.h> | 9 | #include <stdlib.h> |
10 | #include <string.h> | 10 | #include <string.h> |
11 | #include <setjmp.h> | ||
11 | #include <math.h> | 12 | #include <math.h> |
12 | #ifdef __GNUC__ | 13 | #ifdef __GNUC__ |
13 | #include <floatingpoint.h> | 14 | #include <floatingpoint.h> |
@@ -19,57 +20,69 @@ char *rcs_opcode="$Id: opcode.c,v 2.11 1994/11/01 17:54:31 roberto Exp roberto $ | |||
19 | #include "table.h" | 20 | #include "table.h" |
20 | #include "lua.h" | 21 | #include "lua.h" |
21 | 22 | ||
22 | #define tonumber(o) ((tag(o) != T_NUMBER) && (lua_tonumber(o) != 0)) | 23 | #define tonumber(o) ((tag(o) != LUA_T_NUMBER) && (lua_tonumber(o) != 0)) |
23 | #define tostring(o) ((tag(o) != T_STRING) && (lua_tostring(o) != 0)) | 24 | #define tostring(o) ((tag(o) != LUA_T_STRING) && (lua_tostring(o) != 0)) |
24 | 25 | ||
25 | 26 | ||
26 | #define STACK_BUFFER (STACKGAP+128) | 27 | #define STACK_BUFFER (STACKGAP+128) |
27 | 28 | ||
28 | static Long maxstack; | 29 | static Long maxstack; |
29 | static Object *stack=NULL; | 30 | static Object *stack=NULL; |
30 | static Object *top, *base; | 31 | static Object *top; |
32 | |||
33 | static int CBase; /* when Lua calls C or C calls Lua, points to the */ | ||
34 | /* first slot after the last parameter. */ | ||
35 | static int CnResults = 0; /* when Lua calls C, has the number of parameters; */ | ||
36 | /* when C calls Lua, has the number of results. */ | ||
37 | |||
38 | static jmp_buf *errorJmp; | ||
39 | |||
40 | static int lua_execute (Byte *pc, int base); | ||
41 | |||
42 | |||
43 | |||
44 | /* | ||
45 | ** Reports an error, and jumps up to the available recover label | ||
46 | */ | ||
47 | void lua_error (char *s) | ||
48 | { | ||
49 | fprintf (stderr, "lua: %s\n", s); | ||
50 | if (errorJmp) | ||
51 | longjmp(*errorJmp, 1); | ||
52 | else | ||
53 | exit(1); | ||
54 | } | ||
31 | 55 | ||
32 | 56 | ||
33 | /* | 57 | /* |
34 | ** Init stack | 58 | ** Init stack |
35 | */ | 59 | */ |
36 | static int lua_initstack (void) | 60 | static void lua_initstack (void) |
37 | { | 61 | { |
38 | maxstack = STACK_BUFFER; | 62 | maxstack = STACK_BUFFER; |
39 | stack = (Object *)calloc(maxstack, sizeof(Object)); | 63 | stack = (Object *)calloc(maxstack, sizeof(Object)); |
40 | if (stack == NULL) | 64 | if (stack == NULL) |
41 | { | 65 | lua_error("stack - not enough memory"); |
42 | lua_error("stack - not enough memory"); | 66 | top = stack; |
43 | return 1; | ||
44 | } | ||
45 | tag(stack) = T_MARK; | ||
46 | top = base = stack+1; | ||
47 | return 0; | ||
48 | } | 67 | } |
49 | 68 | ||
50 | 69 | ||
51 | /* | 70 | /* |
52 | ** Check stack overflow and, if necessary, realloc vector | 71 | ** Check stack overflow and, if necessary, realloc vector |
53 | */ | 72 | */ |
54 | static int lua_checkstack (Word n) | 73 | static void lua_checkstack (Word n) |
55 | { | 74 | { |
56 | if (stack == NULL) | 75 | if (stack == NULL) |
57 | return lua_initstack(); | 76 | return lua_initstack(); |
58 | if (n > maxstack) | 77 | if (n > maxstack) |
59 | { | 78 | { |
60 | Word t = top-stack; | 79 | int t = top-stack; |
61 | Word b = base-stack; | ||
62 | maxstack *= 2; | 80 | maxstack *= 2; |
63 | stack = (Object *)realloc(stack, maxstack*sizeof(Object)); | 81 | stack = (Object *)realloc(stack, maxstack*sizeof(Object)); |
64 | if (stack == NULL) | 82 | if (stack == NULL) |
65 | { | 83 | lua_error("stack - not enough memory"); |
66 | lua_error("stack - not enough memory"); | ||
67 | return 1; | ||
68 | } | ||
69 | top = stack + t; | 84 | top = stack + t; |
70 | base = stack + b; | ||
71 | } | 85 | } |
72 | return 0; | ||
73 | } | 86 | } |
74 | 87 | ||
75 | 88 | ||
@@ -82,10 +95,7 @@ static char *lua_strconc (char *l, char *r) | |||
82 | static char buffer[1024]; | 95 | static char buffer[1024]; |
83 | int n = strlen(l)+strlen(r)+1; | 96 | int n = strlen(l)+strlen(r)+1; |
84 | if (n > 1024) | 97 | if (n > 1024) |
85 | { | 98 | lua_error ("string too large"); |
86 | lua_error ("string too large"); | ||
87 | return NULL; | ||
88 | } | ||
89 | return strcat(strcpy(buffer,l),r); | 99 | return strcat(strcpy(buffer,l),r); |
90 | } | 100 | } |
91 | 101 | ||
@@ -99,59 +109,46 @@ static int ToReal (char* s, float* f) | |||
99 | /* | 109 | /* |
100 | ** Convert, if possible, to a number object. | 110 | ** Convert, if possible, to a number object. |
101 | ** Return 0 if success, not 0 if error. | 111 | ** Return 0 if success, not 0 if error. |
102 | */ | 112 | */ |
103 | static int lua_tonumber (Object *obj) | 113 | static int lua_tonumber (Object *obj) |
104 | { | 114 | { |
105 | if (tag(obj) != T_STRING) | 115 | if (tag(obj) != LUA_T_STRING) |
106 | { | 116 | return 1;; |
107 | lua_reportbug ("unexpected type at conversion to number"); | ||
108 | return 1; | ||
109 | } | ||
110 | if (!ToReal(svalue(obj), &nvalue(obj))) | 117 | if (!ToReal(svalue(obj), &nvalue(obj))) |
111 | { | 118 | return 2; |
112 | lua_reportbug ("string to number convertion failed"); | 119 | tag(obj) = LUA_T_NUMBER; |
113 | return 2; | ||
114 | } | ||
115 | tag(obj) = T_NUMBER; | ||
116 | return 0; | 120 | return 0; |
117 | } | 121 | } |
118 | 122 | ||
119 | /* | 123 | /* |
120 | ** Test if it is possible to convert an object to a number object. | 124 | ** Test if it is possible to convert an object to a number object. |
121 | ** If possible, return the converted object, otherwise return nil object. | 125 | ** If possible, return the converted object, otherwise return nil object. |
122 | */ | 126 | */ |
123 | static Object *lua_convtonumber (Object *obj) | 127 | static Object *lua_convtonumber (Object *obj) |
124 | { | 128 | { |
125 | static Object cvt; | 129 | static Object cvt; |
126 | 130 | if (tag(obj) == LUA_T_NUMBER) | |
127 | if (tag(obj) == T_NUMBER) | ||
128 | { | 131 | { |
129 | cvt = *obj; | 132 | cvt = *obj; |
130 | return &cvt; | 133 | return &cvt; |
131 | } | 134 | } |
132 | 135 | if (tag(obj) == LUA_T_STRING && ToReal(svalue(obj), &nvalue(&cvt))) | |
133 | if (tag(obj) == T_STRING && ToReal(svalue(obj), &nvalue(&cvt))) | 136 | tag(&cvt) = LUA_T_NUMBER; |
134 | tag(&cvt) = T_NUMBER; | 137 | else |
135 | else | 138 | tag(&cvt) = LUA_T_NIL; |
136 | tag(&cvt) = T_NIL; | ||
137 | |||
138 | return &cvt; | 139 | return &cvt; |
139 | } | 140 | } |
140 | 141 | ||
141 | 142 | ||
142 | |||
143 | /* | 143 | /* |
144 | ** Convert, if possible, to a string tag | 144 | ** Convert, if possible, to a string tag |
145 | ** Return 0 in success or not 0 on error. | 145 | ** Return 0 in success or not 0 on error. |
146 | */ | 146 | */ |
147 | static int lua_tostring (Object *obj) | 147 | static int lua_tostring (Object *obj) |
148 | { | 148 | { |
149 | static char s[256]; | 149 | static char s[256]; |
150 | if (tag(obj) != T_NUMBER) | 150 | if (tag(obj) != LUA_T_NUMBER) |
151 | { | 151 | lua_reportbug ("unexpected type at conversion to string"); |
152 | lua_reportbug ("unexpected type at conversion to string"); | ||
153 | return 1; | ||
154 | } | ||
155 | if ((int) nvalue(obj) == nvalue(obj)) | 152 | if ((int) nvalue(obj) == nvalue(obj)) |
156 | sprintf (s, "%d", (int) nvalue(obj)); | 153 | sprintf (s, "%d", (int) nvalue(obj)); |
157 | else | 154 | else |
@@ -159,487 +156,67 @@ static int lua_tostring (Object *obj) | |||
159 | svalue(obj) = lua_createstring(s); | 156 | svalue(obj) = lua_createstring(s); |
160 | if (svalue(obj) == NULL) | 157 | if (svalue(obj) == NULL) |
161 | return 1; | 158 | return 1; |
162 | tag(obj) = T_STRING; | 159 | tag(obj) = LUA_T_STRING; |
163 | return 0; | 160 | return 0; |
164 | } | 161 | } |
165 | 162 | ||
166 | 163 | ||
167 | /* | 164 | /* |
168 | ** Execute the given opcode. Return 0 in success or 1 on error. | 165 | ** Adjust stack. Set top to the given value, pushing NILs if needed. |
169 | */ | 166 | */ |
170 | int lua_execute (Byte *pc) | 167 | static void adjust_top (Object *newtop) |
171 | { | 168 | { |
172 | Word oldbase; | 169 | while (top < newtop) tag(top++) = LUA_T_NIL; |
173 | 170 | top = newtop; /* top could be bigger than newtop */ | |
174 | if (stack == NULL) | 171 | } |
175 | lua_initstack(); | ||
176 | |||
177 | oldbase = base-stack; | ||
178 | base = top; | ||
179 | while (1) | ||
180 | { | ||
181 | OpCode opcode; | ||
182 | switch (opcode = (OpCode)*pc++) | ||
183 | { | ||
184 | case PUSHNIL: tag(top++) = T_NIL; break; | ||
185 | |||
186 | case PUSH0: tag(top) = T_NUMBER; nvalue(top++) = 0; break; | ||
187 | case PUSH1: tag(top) = T_NUMBER; nvalue(top++) = 1; break; | ||
188 | case PUSH2: tag(top) = T_NUMBER; nvalue(top++) = 2; break; | ||
189 | |||
190 | case PUSHBYTE: tag(top) = T_NUMBER; nvalue(top++) = *pc++; break; | ||
191 | |||
192 | case PUSHWORD: | ||
193 | { | ||
194 | CodeWord code; | ||
195 | get_word(code,pc); | ||
196 | tag(top) = T_NUMBER; nvalue(top++) = code.w; | ||
197 | } | ||
198 | break; | ||
199 | |||
200 | case PUSHFLOAT: | ||
201 | { | ||
202 | CodeFloat code; | ||
203 | get_float(code,pc); | ||
204 | tag(top) = T_NUMBER; nvalue(top++) = code.f; | ||
205 | } | ||
206 | break; | ||
207 | 172 | ||
208 | case PUSHSTRING: | ||
209 | { | ||
210 | CodeWord code; | ||
211 | get_word(code,pc); | ||
212 | tag(top) = T_STRING; svalue(top++) = lua_constant[code.w]; | ||
213 | } | ||
214 | break; | ||
215 | 173 | ||
216 | case PUSHFUNCTION: | 174 | /* |
217 | { | 175 | ** Call a C function. CBase will point to the top of the stack, |
218 | CodeCode code; | 176 | ** and CnResults is the number of parameters. Returns an index |
219 | get_code(code,pc); | 177 | ** to the first result from C. |
220 | tag(top) = T_FUNCTION; bvalue(top++) = code.b; | 178 | */ |
221 | } | 179 | static int callC (lua_CFunction func, int base) |
222 | break; | 180 | { |
223 | 181 | int oldBase = CBase; | |
224 | case PUSHLOCAL0: case PUSHLOCAL1: case PUSHLOCAL2: | 182 | int oldCnResults = CnResults; |
225 | case PUSHLOCAL3: case PUSHLOCAL4: case PUSHLOCAL5: | 183 | int firstResult; |
226 | case PUSHLOCAL6: case PUSHLOCAL7: case PUSHLOCAL8: | 184 | CnResults = (top-stack) - base; |
227 | case PUSHLOCAL9: *top++ = *(base + (int)(opcode-PUSHLOCAL0)); break; | 185 | CBase = base+CnResults; /* incorporate parameters on the stack */ |
228 | 186 | (*func)(); | |
229 | case PUSHLOCAL: *top++ = *(base + (*pc++)); break; | 187 | firstResult = CBase; |
230 | 188 | CBase = oldBase; | |
231 | case PUSHGLOBAL: | 189 | CnResults = oldCnResults; |
232 | { | 190 | return firstResult; |
233 | CodeWord code; | 191 | } |
234 | get_word(code,pc); | ||
235 | *top++ = s_object(code.w); | ||
236 | } | ||
237 | break; | ||
238 | |||
239 | case PUSHINDEXED: | ||
240 | { | ||
241 | int s = lua_pushsubscript(); | ||
242 | if (s == 1) return 1; | ||
243 | } | ||
244 | break; | ||
245 | |||
246 | case PUSHMARK: tag(top++) = T_MARK; break; | ||
247 | case PUSHMARKMET: | ||
248 | { | ||
249 | Object receiver = *(top-2); | ||
250 | if (lua_pushsubscript() == 1) return 1; | ||
251 | tag(top++) = T_MARK; | ||
252 | *(top++) = receiver; | ||
253 | break; | ||
254 | } | ||
255 | |||
256 | case STORELOCAL0: case STORELOCAL1: case STORELOCAL2: | ||
257 | case STORELOCAL3: case STORELOCAL4: case STORELOCAL5: | ||
258 | case STORELOCAL6: case STORELOCAL7: case STORELOCAL8: | ||
259 | case STORELOCAL9: *(base + (int)(opcode-STORELOCAL0)) = *(--top); break; | ||
260 | |||
261 | case STORELOCAL: *(base + (*pc++)) = *(--top); break; | ||
262 | |||
263 | case STOREGLOBAL: | ||
264 | { | ||
265 | CodeWord code; | ||
266 | get_word(code,pc); | ||
267 | s_object(code.w) = *(--top); | ||
268 | } | ||
269 | break; | ||
270 | |||
271 | case STOREINDEXED0: | ||
272 | { | ||
273 | int s = lua_storesubscript(); | ||
274 | if (s == 1) return 1; | ||
275 | } | ||
276 | break; | ||
277 | |||
278 | case STOREINDEXED: | ||
279 | { | ||
280 | int n = *pc++; | ||
281 | if (tag(top-3-n) != T_ARRAY) | ||
282 | { | ||
283 | lua_reportbug ("indexed expression not a table"); | ||
284 | return 1; | ||
285 | } | ||
286 | { | ||
287 | Object *h = lua_hashdefine (avalue(top-3-n), top-2-n); | ||
288 | if (h == NULL) return 1; | ||
289 | *h = *(top-1); | ||
290 | } | ||
291 | top--; | ||
292 | } | ||
293 | break; | ||
294 | |||
295 | case STORELIST0: | ||
296 | case STORELIST: | ||
297 | { | ||
298 | int m, n; | ||
299 | Object *arr; | ||
300 | if (opcode == STORELIST0) m = 0; | ||
301 | else m = *(pc++) * FIELDS_PER_FLUSH; | ||
302 | n = *(pc++); | ||
303 | arr = top-n-1; | ||
304 | if (tag(arr) != T_ARRAY) | ||
305 | { | ||
306 | lua_reportbug ("internal error - table expected"); | ||
307 | return 1; | ||
308 | } | ||
309 | while (n) | ||
310 | { | ||
311 | tag(top) = T_NUMBER; nvalue(top) = n+m; | ||
312 | *(lua_hashdefine (avalue(arr), top)) = *(top-1); | ||
313 | top--; | ||
314 | n--; | ||
315 | } | ||
316 | } | ||
317 | break; | ||
318 | |||
319 | case STORERECORD: | ||
320 | { | ||
321 | int n = *(pc++); | ||
322 | Object *arr = top-n-1; | ||
323 | if (tag(arr) != T_ARRAY) | ||
324 | { | ||
325 | lua_reportbug ("internal error - table expected"); | ||
326 | return 1; | ||
327 | } | ||
328 | while (n) | ||
329 | { | ||
330 | CodeWord code; | ||
331 | get_word(code,pc); | ||
332 | tag(top) = T_STRING; svalue(top) = lua_constant[code.w]; | ||
333 | *(lua_hashdefine (avalue(arr), top)) = *(top-1); | ||
334 | top--; | ||
335 | n--; | ||
336 | } | ||
337 | } | ||
338 | break; | ||
339 | |||
340 | case ADJUST: | ||
341 | { | ||
342 | Object *newtop = base + *(pc++); | ||
343 | while (top < newtop) tag(top++) = T_NIL; | ||
344 | top = newtop; /* top could be bigger than newtop */ | ||
345 | } | ||
346 | break; | ||
347 | |||
348 | case CREATEARRAY: | ||
349 | { | ||
350 | CodeWord size; | ||
351 | get_word(size,pc); | ||
352 | top++; | ||
353 | avalue(top-1) = lua_createarray(size.w); | ||
354 | if (avalue(top-1) == NULL) | ||
355 | return 1; | ||
356 | tag(top-1) = T_ARRAY; | ||
357 | } | ||
358 | break; | ||
359 | |||
360 | case EQOP: | ||
361 | { | ||
362 | Object *l = top-2; | ||
363 | Object *r = top-1; | ||
364 | --top; | ||
365 | if (tag(l) != tag(r)) | ||
366 | tag(top-1) = T_NIL; | ||
367 | else | ||
368 | { | ||
369 | switch (tag(l)) | ||
370 | { | ||
371 | case T_NIL: tag(top-1) = T_NUMBER; break; | ||
372 | case T_NUMBER: tag(top-1) = (nvalue(l) == nvalue(r)) ? T_NUMBER : T_NIL; break; | ||
373 | case T_ARRAY: tag(top-1) = (avalue(l) == avalue(r)) ? T_NUMBER : T_NIL; break; | ||
374 | case T_FUNCTION: tag(top-1) = (bvalue(l) == bvalue(r)) ? T_NUMBER : T_NIL; break; | ||
375 | case T_CFUNCTION: tag(top-1) = (fvalue(l) == fvalue(r)) ? T_NUMBER : T_NIL; break; | ||
376 | case T_USERDATA: tag(top-1) = (uvalue(l) == uvalue(r)) ? T_NUMBER : T_NIL; break; | ||
377 | case T_STRING: tag(top-1) = (strcmp (svalue(l), svalue(r)) == 0) ? T_NUMBER : T_NIL; break; | ||
378 | case T_MARK: return 1; | ||
379 | } | ||
380 | } | ||
381 | nvalue(top-1) = 1; | ||
382 | } | ||
383 | break; | ||
384 | |||
385 | case LTOP: | ||
386 | { | ||
387 | Object *l = top-2; | ||
388 | Object *r = top-1; | ||
389 | --top; | ||
390 | if (tag(l) == T_NUMBER && tag(r) == T_NUMBER) | ||
391 | tag(top-1) = (nvalue(l) < nvalue(r)) ? T_NUMBER : T_NIL; | ||
392 | else | ||
393 | { | ||
394 | if (tostring(l) || tostring(r)) | ||
395 | return 1; | ||
396 | tag(top-1) = (strcmp (svalue(l), svalue(r)) < 0) ? T_NUMBER : T_NIL; | ||
397 | } | ||
398 | nvalue(top-1) = 1; | ||
399 | } | ||
400 | break; | ||
401 | |||
402 | case LEOP: | ||
403 | { | ||
404 | Object *l = top-2; | ||
405 | Object *r = top-1; | ||
406 | --top; | ||
407 | if (tag(l) == T_NUMBER && tag(r) == T_NUMBER) | ||
408 | tag(top-1) = (nvalue(l) <= nvalue(r)) ? T_NUMBER : T_NIL; | ||
409 | else | ||
410 | { | ||
411 | if (tostring(l) || tostring(r)) | ||
412 | return 1; | ||
413 | tag(top-1) = (strcmp (svalue(l), svalue(r)) <= 0) ? T_NUMBER : T_NIL; | ||
414 | } | ||
415 | nvalue(top-1) = 1; | ||
416 | } | ||
417 | break; | ||
418 | |||
419 | case ADDOP: | ||
420 | { | ||
421 | Object *l = top-2; | ||
422 | Object *r = top-1; | ||
423 | if (tonumber(r) || tonumber(l)) | ||
424 | return 1; | ||
425 | nvalue(l) += nvalue(r); | ||
426 | --top; | ||
427 | } | ||
428 | break; | ||
429 | |||
430 | case SUBOP: | ||
431 | { | ||
432 | Object *l = top-2; | ||
433 | Object *r = top-1; | ||
434 | if (tonumber(r) || tonumber(l)) | ||
435 | return 1; | ||
436 | nvalue(l) -= nvalue(r); | ||
437 | --top; | ||
438 | } | ||
439 | break; | ||
440 | |||
441 | case MULTOP: | ||
442 | { | ||
443 | Object *l = top-2; | ||
444 | Object *r = top-1; | ||
445 | if (tonumber(r) || tonumber(l)) | ||
446 | return 1; | ||
447 | nvalue(l) *= nvalue(r); | ||
448 | --top; | ||
449 | } | ||
450 | break; | ||
451 | |||
452 | case DIVOP: | ||
453 | { | ||
454 | Object *l = top-2; | ||
455 | Object *r = top-1; | ||
456 | if (tonumber(r) || tonumber(l)) | ||
457 | return 1; | ||
458 | nvalue(l) /= nvalue(r); | ||
459 | --top; | ||
460 | } | ||
461 | break; | ||
462 | |||
463 | case POWOP: | ||
464 | { | ||
465 | Object *l = top-2; | ||
466 | Object *r = top-1; | ||
467 | if (tonumber(r) || tonumber(l)) | ||
468 | return 1; | ||
469 | nvalue(l) = pow(nvalue(l), nvalue(r)); | ||
470 | --top; | ||
471 | } | ||
472 | break; | ||
473 | |||
474 | case CONCOP: | ||
475 | { | ||
476 | Object *l = top-2; | ||
477 | Object *r = top-1; | ||
478 | if (tostring(r) || tostring(l)) | ||
479 | return 1; | ||
480 | svalue(l) = lua_createstring (lua_strconc(svalue(l),svalue(r))); | ||
481 | if (svalue(l) == NULL) | ||
482 | return 1; | ||
483 | --top; | ||
484 | } | ||
485 | break; | ||
486 | |||
487 | case MINUSOP: | ||
488 | if (tonumber(top-1)) | ||
489 | return 1; | ||
490 | nvalue(top-1) = - nvalue(top-1); | ||
491 | break; | ||
492 | |||
493 | case NOTOP: | ||
494 | tag(top-1) = tag(top-1) == T_NIL ? T_NUMBER : T_NIL; | ||
495 | break; | ||
496 | |||
497 | case ONTJMP: | ||
498 | { | ||
499 | CodeWord code; | ||
500 | get_word(code,pc); | ||
501 | if (tag(top-1) != T_NIL) pc += code.w; | ||
502 | } | ||
503 | break; | ||
504 | |||
505 | case ONFJMP: | ||
506 | { | ||
507 | CodeWord code; | ||
508 | get_word(code,pc); | ||
509 | if (tag(top-1) == T_NIL) pc += code.w; | ||
510 | } | ||
511 | break; | ||
512 | |||
513 | case JMP: | ||
514 | { | ||
515 | CodeWord code; | ||
516 | get_word(code,pc); | ||
517 | pc += code.w; | ||
518 | } | ||
519 | break; | ||
520 | |||
521 | case UPJMP: | ||
522 | { | ||
523 | CodeWord code; | ||
524 | get_word(code,pc); | ||
525 | pc -= code.w; | ||
526 | } | ||
527 | break; | ||
528 | |||
529 | case IFFJMP: | ||
530 | { | ||
531 | CodeWord code; | ||
532 | get_word(code,pc); | ||
533 | top--; | ||
534 | if (tag(top) == T_NIL) pc += code.w; | ||
535 | } | ||
536 | break; | ||
537 | 192 | ||
538 | case IFFUPJMP: | ||
539 | { | ||
540 | CodeWord code; | ||
541 | get_word(code,pc); | ||
542 | top--; | ||
543 | if (tag(top) == T_NIL) pc -= code.w; | ||
544 | } | ||
545 | break; | ||
546 | 193 | ||
547 | case POP: --top; break; | 194 | /* |
548 | 195 | ** Call a function (C or Lua). The parameters must be on the stack, | |
549 | case CALLFUNC: | 196 | ** between [stack+base,top). When returns, the results are on the stack, |
550 | { | 197 | ** between [stack+whereRes,top). The number of results is nResults, unless |
551 | Byte *newpc; | 198 | ** nResults=MULT_RET. |
552 | Object *b = top-1; | 199 | */ |
553 | while (tag(b) != T_MARK) b--; | 200 | static void do_call (Object *func, int base, int nResults, int whereRes) |
554 | if (tag(b-1) == T_FUNCTION) | 201 | { |
555 | { | 202 | int firstResult; |
556 | lua_debugline = 0; /* always reset debug flag */ | 203 | if (tag(func) == LUA_T_CFUNCTION) |
557 | newpc = bvalue(b-1); | 204 | firstResult = callC(fvalue(func), base); |
558 | bvalue(b-1) = pc; /* store return code */ | 205 | else if (tag(func) == LUA_T_FUNCTION) |
559 | nvalue(b) = (base-stack); /* store base value */ | 206 | firstResult = lua_execute(bvalue(func), base); |
560 | base = b+1; | 207 | else |
561 | pc = newpc; | 208 | lua_reportbug ("call expression not a function"); |
562 | if (lua_checkstack(STACKGAP+(base-stack))) | 209 | /* adjust the number of results */ |
563 | return 1; | 210 | if (nResults != MULT_RET && top - (stack+firstResult) != nResults) |
564 | } | 211 | adjust_top(stack+firstResult+nResults); |
565 | else if (tag(b-1) == T_CFUNCTION) | 212 | /* move results to the given position */ |
566 | { | 213 | if (firstResult != whereRes) |
567 | int nparam; | 214 | { |
568 | lua_debugline = 0; /* always reset debug flag */ | 215 | int i = top - (stack+firstResult); /* number of results */ |
569 | nvalue(b) = (base-stack); /* store base value */ | 216 | top -= firstResult-whereRes; |
570 | base = b+1; | 217 | while (i--) |
571 | nparam = top-base; /* number of parameters */ | 218 | *(stack+whereRes+i) = *(stack+firstResult+i); |
572 | (fvalue(b-1))(); /* call C function */ | ||
573 | |||
574 | /* shift returned values */ | ||
575 | { | ||
576 | int i; | ||
577 | int nretval = top - base - nparam; | ||
578 | top = base - 2; | ||
579 | base = stack + (int) nvalue(base-1); | ||
580 | for (i=0; i<nretval; i++) | ||
581 | { | ||
582 | *top = *(top+nparam+2); | ||
583 | ++top; | ||
584 | } | ||
585 | } | ||
586 | } | ||
587 | else | ||
588 | { | ||
589 | lua_reportbug ("call expression not a function"); | ||
590 | return 1; | ||
591 | } | ||
592 | } | ||
593 | break; | ||
594 | |||
595 | case RETCODE: | ||
596 | { | ||
597 | int i; | ||
598 | int shift = *pc++; | ||
599 | int nretval = top - base - shift; | ||
600 | top = base - 2; | ||
601 | pc = bvalue(base-2); | ||
602 | base = stack + (int) nvalue(base-1); | ||
603 | for (i=0; i<nretval; i++) | ||
604 | { | ||
605 | *top = *(top+shift+2); | ||
606 | ++top; | ||
607 | } | ||
608 | } | ||
609 | break; | ||
610 | |||
611 | case HALT: | ||
612 | base = stack+oldbase; | ||
613 | return 0; /* success */ | ||
614 | |||
615 | case SETFUNCTION: | ||
616 | { | ||
617 | CodeCode file; | ||
618 | CodeWord func; | ||
619 | get_code(file,pc); | ||
620 | get_word(func,pc); | ||
621 | if (lua_pushfunction ((char *)file.b, func.w)) | ||
622 | return 1; | ||
623 | } | ||
624 | break; | ||
625 | |||
626 | case SETLINE: | ||
627 | { | ||
628 | CodeWord code; | ||
629 | get_word(code,pc); | ||
630 | lua_debugline = code.w; | ||
631 | } | ||
632 | break; | ||
633 | |||
634 | case RESET: | ||
635 | lua_popfunction (); | ||
636 | break; | ||
637 | |||
638 | default: | ||
639 | lua_error ("internal error - opcode didn't match"); | ||
640 | return 1; | ||
641 | } | 219 | } |
642 | } | ||
643 | } | 220 | } |
644 | 221 | ||
645 | 222 | ||
@@ -649,7 +226,7 @@ int lua_execute (Byte *pc) | |||
649 | int lua_pushsubscript (void) | 226 | int lua_pushsubscript (void) |
650 | { | 227 | { |
651 | --top; | 228 | --top; |
652 | if (tag(top-1) != T_ARRAY) | 229 | if (tag(top-1) != LUA_T_ARRAY) |
653 | { | 230 | { |
654 | lua_reportbug ("indexed expression not a table"); | 231 | lua_reportbug ("indexed expression not a table"); |
655 | return 1; | 232 | return 1; |
@@ -668,7 +245,7 @@ int lua_pushsubscript (void) | |||
668 | */ | 245 | */ |
669 | int lua_storesubscript (void) | 246 | int lua_storesubscript (void) |
670 | { | 247 | { |
671 | if (tag(top-3) != T_ARRAY) | 248 | if (tag(top-3) != LUA_T_ARRAY) |
672 | { | 249 | { |
673 | lua_reportbug ("indexed expression not a table"); | 250 | lua_reportbug ("indexed expression not a table"); |
674 | return 1; | 251 | return 1; |
@@ -693,61 +270,89 @@ void lua_travstack (void (*fn)(Object *)) | |||
693 | fn (o); | 270 | fn (o); |
694 | } | 271 | } |
695 | 272 | ||
273 | |||
696 | /* | 274 | /* |
697 | ** Open file, generate opcode and execute global statement. Return 0 on | 275 | ** Executes a main procedure. Uses as Base the top of the stack, as it |
698 | ** success or 1 on error. | 276 | ** uses no parameters and left no results. |
699 | */ | 277 | */ |
700 | int lua_dofile (char *filename) | 278 | static void do_main (Byte *main) |
701 | { | 279 | { |
702 | if (lua_openfile (filename)) return 1; | 280 | if (main) |
703 | if (lua_parse ()) { lua_closefile (); return 1; } | 281 | { |
704 | lua_closefile (); | 282 | Object f; |
705 | return 0; | 283 | tag(&f) = LUA_T_FUNCTION; bvalue(&f) = main; |
284 | do_call(&f, top-stack, 0, top-stack); | ||
285 | free(main); | ||
286 | } | ||
706 | } | 287 | } |
707 | 288 | ||
289 | |||
708 | /* | 290 | /* |
709 | ** Generate opcode stored on string and execute global statement. Return 0 on | 291 | ** Open file, generate opcode and execute global statement. Return 0 on |
710 | ** success or 1 on error. | 292 | ** success or 1 on error. |
711 | */ | 293 | */ |
712 | int lua_dostring (char *string) | 294 | int lua_dofile (char *filename) |
713 | { | 295 | { |
714 | if (lua_openstring (string)) return 1; | 296 | jmp_buf myErrorJmp; |
715 | if (lua_parse ()) return 1; | 297 | int status; |
716 | lua_closestring(); | 298 | jmp_buf *oldErr = errorJmp; |
717 | return 0; | 299 | errorJmp = &myErrorJmp; |
300 | if (setjmp(myErrorJmp) == 0) | ||
301 | { | ||
302 | lua_openfile (filename); | ||
303 | do_main(lua_parse()); | ||
304 | status = 0; | ||
305 | } | ||
306 | else | ||
307 | status = 1; | ||
308 | lua_closefile(); | ||
309 | errorJmp = oldErr; | ||
310 | return status; | ||
718 | } | 311 | } |
719 | 312 | ||
720 | /* | 313 | /* |
721 | ** Execute the given function. Return 0 on success or 1 on error. | 314 | ** Generate opcode stored on string and execute global statement. Return 0 on |
315 | ** success or 1 on error. | ||
722 | */ | 316 | */ |
723 | int lua_call (char *functionname, int nparam) | 317 | int lua_dostring (char *string) |
724 | { | 318 | { |
725 | static Byte startcode[] = {CALLFUNC, HALT}; | 319 | jmp_buf myErrorJmp; |
726 | int i; | 320 | int status; |
727 | Object func = s_object(lua_findsymbol(functionname)); | 321 | jmp_buf *oldErr = errorJmp; |
728 | if (tag(&func) != T_FUNCTION) return 1; | 322 | errorJmp = &myErrorJmp; |
729 | for (i=1; i<=nparam; i++) | 323 | if (setjmp(myErrorJmp) == 0) |
730 | *(top-i+2) = *(top-i); | 324 | { |
731 | top += 2; | 325 | lua_openstring(string); |
732 | tag(top-nparam-1) = T_MARK; | 326 | do_main(lua_parse()); |
733 | *(top-nparam-2) = func; | 327 | status = 0; |
734 | return (lua_execute (startcode)); | 328 | } |
329 | else | ||
330 | status = 1; | ||
331 | lua_closestring(); | ||
332 | errorJmp = oldErr; | ||
333 | return status; | ||
735 | } | 334 | } |
736 | 335 | ||
737 | /* | 336 | /* |
738 | ** Execute the given lua function. Return 0 on success or 1 on error. | 337 | ** Execute the given lua function. Return 0 on success or 1 on error. |
739 | */ | 338 | */ |
740 | int lua_callfunction (Object *function, int nparam) | 339 | int lua_callfunction (Object *function) |
741 | { | 340 | { |
742 | static Byte startcode[] = {CALLFUNC, HALT}; | 341 | jmp_buf myErrorJmp; |
743 | int i; | 342 | int status; |
744 | if (tag(function) != T_FUNCTION) return 1; | 343 | jmp_buf *oldErr = errorJmp; |
745 | for (i=1; i<=nparam; i++) | 344 | errorJmp = &myErrorJmp; |
746 | *(top-i+2) = *(top-i); | 345 | if (setjmp(myErrorJmp) == 0) |
747 | top += 2; | 346 | { |
748 | tag(top-nparam-1) = T_MARK; | 347 | do_call(function, CBase, MULT_RET, CBase); |
749 | *(top-nparam-2) = *function; | 348 | CnResults = (top-stack) - CBase; /* number of results */ |
750 | return (lua_execute (startcode)); | 349 | CBase += CnResults; /* incorporate results on the stack */ |
350 | status = 0; | ||
351 | } | ||
352 | else | ||
353 | status = 1; | ||
354 | errorJmp = oldErr; | ||
355 | return status; | ||
751 | } | 356 | } |
752 | 357 | ||
753 | /* | 358 | /* |
@@ -756,8 +361,8 @@ int lua_callfunction (Object *function, int nparam) | |||
756 | */ | 361 | */ |
757 | Object *lua_getparam (int number) | 362 | Object *lua_getparam (int number) |
758 | { | 363 | { |
759 | if (number <= 0 || number > top-base) return NULL; | 364 | if (number <= 0 || number > CnResults) return NULL; |
760 | return (base+number-1); | 365 | return (stack+(CBase-CnResults+number-1)); |
761 | } | 366 | } |
762 | 367 | ||
763 | /* | 368 | /* |
@@ -765,7 +370,7 @@ Object *lua_getparam (int number) | |||
765 | */ | 370 | */ |
766 | real lua_getnumber (Object *object) | 371 | real lua_getnumber (Object *object) |
767 | { | 372 | { |
768 | if (object == NULL || tag(object) == T_NIL) return 0.0; | 373 | if (object == NULL || tag(object) == LUA_T_NIL) return 0.0; |
769 | if (tonumber (object)) return 0.0; | 374 | if (tonumber (object)) return 0.0; |
770 | else return (nvalue(object)); | 375 | else return (nvalue(object)); |
771 | } | 376 | } |
@@ -775,7 +380,7 @@ real lua_getnumber (Object *object) | |||
775 | */ | 380 | */ |
776 | char *lua_getstring (Object *object) | 381 | char *lua_getstring (Object *object) |
777 | { | 382 | { |
778 | if (object == NULL || tag(object) == T_NIL) return NULL; | 383 | if (object == NULL || tag(object) == LUA_T_NIL) return NULL; |
779 | if (tostring (object)) return NULL; | 384 | if (tostring (object)) return NULL; |
780 | else return (svalue(object)); | 385 | else return (svalue(object)); |
781 | } | 386 | } |
@@ -785,7 +390,7 @@ char *lua_getstring (Object *object) | |||
785 | */ | 390 | */ |
786 | char *lua_copystring (Object *object) | 391 | char *lua_copystring (Object *object) |
787 | { | 392 | { |
788 | if (object == NULL || tag(object) == T_NIL) return NULL; | 393 | if (object == NULL || tag(object) == LUA_T_NIL) return NULL; |
789 | if (tostring (object)) return NULL; | 394 | if (tostring (object)) return NULL; |
790 | else return (strdup(svalue(object))); | 395 | else return (strdup(svalue(object))); |
791 | } | 396 | } |
@@ -796,7 +401,7 @@ char *lua_copystring (Object *object) | |||
796 | lua_CFunction lua_getcfunction (Object *object) | 401 | lua_CFunction lua_getcfunction (Object *object) |
797 | { | 402 | { |
798 | if (object == NULL) return NULL; | 403 | if (object == NULL) return NULL; |
799 | if (tag(object) != T_CFUNCTION) return NULL; | 404 | if (tag(object) != LUA_T_CFUNCTION) return NULL; |
800 | else return (fvalue(object)); | 405 | else return (fvalue(object)); |
801 | } | 406 | } |
802 | 407 | ||
@@ -806,7 +411,7 @@ lua_CFunction lua_getcfunction (Object *object) | |||
806 | void *lua_getuserdata (Object *object) | 411 | void *lua_getuserdata (Object *object) |
807 | { | 412 | { |
808 | if (object == NULL) return NULL; | 413 | if (object == NULL) return NULL; |
809 | if (tag(object) != T_USERDATA) return NULL; | 414 | if (tag(object) != LUA_T_USERDATA) return NULL; |
810 | else return (uvalue(object)); | 415 | else return (uvalue(object)); |
811 | } | 416 | } |
812 | 417 | ||
@@ -816,7 +421,7 @@ void *lua_getuserdata (Object *object) | |||
816 | void *lua_gettable (Object *object) | 421 | void *lua_gettable (Object *object) |
817 | { | 422 | { |
818 | if (object == NULL) return NULL; | 423 | if (object == NULL) return NULL; |
819 | if (tag(object) != T_ARRAY) return NULL; | 424 | if (tag(object) != LUA_T_ARRAY) return NULL; |
820 | else return (avalue(object)); | 425 | else return (avalue(object)); |
821 | } | 426 | } |
822 | 427 | ||
@@ -827,12 +432,12 @@ void *lua_gettable (Object *object) | |||
827 | Object *lua_getfield (Object *object, char *field) | 432 | Object *lua_getfield (Object *object, char *field) |
828 | { | 433 | { |
829 | if (object == NULL) return NULL; | 434 | if (object == NULL) return NULL; |
830 | if (tag(object) != T_ARRAY) | 435 | if (tag(object) != LUA_T_ARRAY) |
831 | return NULL; | 436 | return NULL; |
832 | else | 437 | else |
833 | { | 438 | { |
834 | Object ref; | 439 | Object ref; |
835 | tag(&ref) = T_STRING; | 440 | tag(&ref) = LUA_T_STRING; |
836 | svalue(&ref) = lua_constant[lua_findconstant(field)]; | 441 | svalue(&ref) = lua_constant[lua_findconstant(field)]; |
837 | return (lua_hashget(avalue(object), &ref)); | 442 | return (lua_hashget(avalue(object), &ref)); |
838 | } | 443 | } |
@@ -845,12 +450,12 @@ Object *lua_getfield (Object *object, char *field) | |||
845 | Object *lua_getindexed (Object *object, float index) | 450 | Object *lua_getindexed (Object *object, float index) |
846 | { | 451 | { |
847 | if (object == NULL) return NULL; | 452 | if (object == NULL) return NULL; |
848 | if (tag(object) != T_ARRAY) | 453 | if (tag(object) != LUA_T_ARRAY) |
849 | return NULL; | 454 | return NULL; |
850 | else | 455 | else |
851 | { | 456 | { |
852 | Object ref; | 457 | Object ref; |
853 | tag(&ref) = T_NUMBER; | 458 | tag(&ref) = LUA_T_NUMBER; |
854 | nvalue(&ref) = index; | 459 | nvalue(&ref) = index; |
855 | return (lua_hashget(avalue(object), &ref)); | 460 | return (lua_hashget(avalue(object), &ref)); |
856 | } | 461 | } |
@@ -867,23 +472,12 @@ Object *lua_getglobal (char *name) | |||
867 | } | 472 | } |
868 | 473 | ||
869 | /* | 474 | /* |
870 | ** Pop and return an object | ||
871 | */ | ||
872 | Object *lua_pop (void) | ||
873 | { | ||
874 | if (top <= base) return NULL; | ||
875 | top--; | ||
876 | return top; | ||
877 | } | ||
878 | |||
879 | /* | ||
880 | ** Push a nil object | 475 | ** Push a nil object |
881 | */ | 476 | */ |
882 | int lua_pushnil (void) | 477 | int lua_pushnil (void) |
883 | { | 478 | { |
884 | if (lua_checkstack(top-stack+1) == 1) | 479 | lua_checkstack(top-stack+1); |
885 | return 1; | 480 | tag(top++) = LUA_T_NIL; |
886 | tag(top++) = T_NIL; | ||
887 | return 0; | 481 | return 0; |
888 | } | 482 | } |
889 | 483 | ||
@@ -892,9 +486,8 @@ int lua_pushnil (void) | |||
892 | */ | 486 | */ |
893 | int lua_pushnumber (real n) | 487 | int lua_pushnumber (real n) |
894 | { | 488 | { |
895 | if (lua_checkstack(top-stack+1) == 1) | 489 | lua_checkstack(top-stack+1); |
896 | return 1; | 490 | tag(top) = LUA_T_NUMBER; nvalue(top++) = n; |
897 | tag(top) = T_NUMBER; nvalue(top++) = n; | ||
898 | return 0; | 491 | return 0; |
899 | } | 492 | } |
900 | 493 | ||
@@ -903,9 +496,8 @@ int lua_pushnumber (real n) | |||
903 | */ | 496 | */ |
904 | int lua_pushstring (char *s) | 497 | int lua_pushstring (char *s) |
905 | { | 498 | { |
906 | if (lua_checkstack(top-stack+1) == 1) | 499 | lua_checkstack(top-stack+1); |
907 | return 1; | 500 | tag(top) = LUA_T_STRING; |
908 | tag(top) = T_STRING; | ||
909 | svalue(top++) = lua_createstring(s); | 501 | svalue(top++) = lua_createstring(s); |
910 | return 0; | 502 | return 0; |
911 | } | 503 | } |
@@ -915,9 +507,8 @@ int lua_pushstring (char *s) | |||
915 | */ | 507 | */ |
916 | int lua_pushcfunction (lua_CFunction fn) | 508 | int lua_pushcfunction (lua_CFunction fn) |
917 | { | 509 | { |
918 | if (lua_checkstack(top-stack+1) == 1) | 510 | lua_checkstack(top-stack+1); |
919 | return 1; | 511 | tag(top) = LUA_T_CFUNCTION; fvalue(top++) = fn; |
920 | tag(top) = T_CFUNCTION; fvalue(top++) = fn; | ||
921 | return 0; | 512 | return 0; |
922 | } | 513 | } |
923 | 514 | ||
@@ -926,9 +517,8 @@ int lua_pushcfunction (lua_CFunction fn) | |||
926 | */ | 517 | */ |
927 | int lua_pushuserdata (void *u) | 518 | int lua_pushuserdata (void *u) |
928 | { | 519 | { |
929 | if (lua_checkstack(top-stack+1) == 1) | 520 | lua_checkstack(top-stack+1); |
930 | return 1; | 521 | tag(top) = LUA_T_USERDATA; uvalue(top++) = u; |
931 | tag(top) = T_USERDATA; uvalue(top++) = u; | ||
932 | return 0; | 522 | return 0; |
933 | } | 523 | } |
934 | 524 | ||
@@ -937,9 +527,8 @@ int lua_pushuserdata (void *u) | |||
937 | */ | 527 | */ |
938 | int lua_pushtable (void *t) | 528 | int lua_pushtable (void *t) |
939 | { | 529 | { |
940 | if (lua_checkstack(top-stack+1) == 1) | 530 | lua_checkstack(top-stack+1); |
941 | return 1; | 531 | tag(top) = LUA_T_ARRAY; avalue(top++) = t; |
942 | tag(top) = T_ARRAY; avalue(top++) = t; | ||
943 | return 0; | 532 | return 0; |
944 | } | 533 | } |
945 | 534 | ||
@@ -948,21 +537,20 @@ int lua_pushtable (void *t) | |||
948 | */ | 537 | */ |
949 | int lua_pushobject (Object *o) | 538 | int lua_pushobject (Object *o) |
950 | { | 539 | { |
951 | if (lua_checkstack(top-stack+1) == 1) | 540 | lua_checkstack(top-stack+1); |
952 | return 1; | ||
953 | *top++ = *o; | 541 | *top++ = *o; |
954 | return 0; | 542 | return 0; |
955 | } | 543 | } |
956 | 544 | ||
957 | /* | 545 | /* |
958 | ** Store top of the stack at a global variable array field. | 546 | ** Store top of the stack at a global variable array field. |
959 | ** Return 1 on error, 0 on success. | 547 | ** Return 1 on error, 0 on success. |
960 | */ | 548 | */ |
961 | int lua_storeglobal (char *name) | 549 | int lua_storeglobal (char *name) |
962 | { | 550 | { |
963 | int n = lua_findsymbol (name); | 551 | int n = lua_findsymbol (name); |
964 | if (n < 0) return 1; | 552 | if (n < 0) return 1; |
965 | if (tag(top-1) == T_MARK) return 1; | 553 | if (tag(top-1) == LUA_T_MARK) return 1; |
966 | s_object(n) = *(--top); | 554 | s_object(n) = *(--top); |
967 | return 0; | 555 | return 0; |
968 | } | 556 | } |
@@ -973,16 +561,16 @@ int lua_storeglobal (char *name) | |||
973 | */ | 561 | */ |
974 | int lua_storefield (lua_Object object, char *field) | 562 | int lua_storefield (lua_Object object, char *field) |
975 | { | 563 | { |
976 | if (tag(object) != T_ARRAY) | 564 | if (tag(object) != LUA_T_ARRAY) |
977 | return 1; | 565 | return 1; |
978 | else | 566 | else |
979 | { | 567 | { |
980 | Object ref, *h; | 568 | Object ref, *h; |
981 | tag(&ref) = T_STRING; | 569 | tag(&ref) = LUA_T_STRING; |
982 | svalue(&ref) = lua_createstring(field); | 570 | svalue(&ref) = lua_createstring(field); |
983 | h = lua_hashdefine(avalue(object), &ref); | 571 | h = lua_hashdefine(avalue(object), &ref); |
984 | if (h == NULL) return 1; | 572 | if (h == NULL) return 1; |
985 | if (tag(top-1) == T_MARK) return 1; | 573 | if (tag(top-1) == LUA_T_MARK) return 1; |
986 | *h = *(--top); | 574 | *h = *(--top); |
987 | } | 575 | } |
988 | return 0; | 576 | return 0; |
@@ -994,16 +582,16 @@ int lua_storefield (lua_Object object, char *field) | |||
994 | */ | 582 | */ |
995 | int lua_storeindexed (lua_Object object, float index) | 583 | int lua_storeindexed (lua_Object object, float index) |
996 | { | 584 | { |
997 | if (tag(object) != T_ARRAY) | 585 | if (tag(object) != LUA_T_ARRAY) |
998 | return 1; | 586 | return 1; |
999 | else | 587 | else |
1000 | { | 588 | { |
1001 | Object ref, *h; | 589 | Object ref, *h; |
1002 | tag(&ref) = T_NUMBER; | 590 | tag(&ref) = LUA_T_NUMBER; |
1003 | nvalue(&ref) = index; | 591 | nvalue(&ref) = index; |
1004 | h = lua_hashdefine(avalue(object), &ref); | 592 | h = lua_hashdefine(avalue(object), &ref); |
1005 | if (h == NULL) return 1; | 593 | if (h == NULL) return 1; |
1006 | if (tag(top-1) == T_MARK) return 1; | 594 | if (tag(top-1) == LUA_T_MARK) return 1; |
1007 | *h = *(--top); | 595 | *h = *(--top); |
1008 | } | 596 | } |
1009 | return 0; | 597 | return 0; |
@@ -1015,7 +603,7 @@ int lua_storeindexed (lua_Object object, float index) | |||
1015 | */ | 603 | */ |
1016 | int lua_isnil (Object *object) | 604 | int lua_isnil (Object *object) |
1017 | { | 605 | { |
1018 | return (object != NULL && tag(object) == T_NIL); | 606 | return (object != NULL && tag(object) == LUA_T_NIL); |
1019 | } | 607 | } |
1020 | 608 | ||
1021 | /* | 609 | /* |
@@ -1023,7 +611,7 @@ int lua_isnil (Object *object) | |||
1023 | */ | 611 | */ |
1024 | int lua_isnumber (Object *object) | 612 | int lua_isnumber (Object *object) |
1025 | { | 613 | { |
1026 | return (object != NULL && tag(object) == T_NUMBER); | 614 | return (object != NULL && tag(object) == LUA_T_NUMBER); |
1027 | } | 615 | } |
1028 | 616 | ||
1029 | /* | 617 | /* |
@@ -1031,7 +619,7 @@ int lua_isnumber (Object *object) | |||
1031 | */ | 619 | */ |
1032 | int lua_isstring (Object *object) | 620 | int lua_isstring (Object *object) |
1033 | { | 621 | { |
1034 | return (object != NULL && tag(object) == T_STRING); | 622 | return (object != NULL && tag(object) == LUA_T_STRING); |
1035 | } | 623 | } |
1036 | 624 | ||
1037 | /* | 625 | /* |
@@ -1039,7 +627,7 @@ int lua_isstring (Object *object) | |||
1039 | */ | 627 | */ |
1040 | int lua_istable (Object *object) | 628 | int lua_istable (Object *object) |
1041 | { | 629 | { |
1042 | return (object != NULL && tag(object) == T_ARRAY); | 630 | return (object != NULL && tag(object) == LUA_T_ARRAY); |
1043 | } | 631 | } |
1044 | 632 | ||
1045 | /* | 633 | /* |
@@ -1047,15 +635,15 @@ int lua_istable (Object *object) | |||
1047 | */ | 635 | */ |
1048 | int lua_isfunction (Object *object) | 636 | int lua_isfunction (Object *object) |
1049 | { | 637 | { |
1050 | return (object != NULL && tag(object) == T_FUNCTION); | 638 | return (object != NULL && tag(object) == LUA_T_FUNCTION); |
1051 | } | 639 | } |
1052 | 640 | ||
1053 | /* | 641 | /* |
1054 | ** Given an object handle, return if it is a cfunction one. | 642 | ** Given an object handle, return if it is a cfunction one. |
1055 | */ | 643 | */ |
1056 | int lua_iscfunction (Object *object) | 644 | int lua_iscfunction (Object *object) |
1057 | { | 645 | { |
1058 | return (object != NULL && tag(object) == T_CFUNCTION); | 646 | return (object != NULL && tag(object) == LUA_T_CFUNCTION); |
1059 | } | 647 | } |
1060 | 648 | ||
1061 | /* | 649 | /* |
@@ -1063,21 +651,10 @@ int lua_iscfunction (Object *object) | |||
1063 | */ | 651 | */ |
1064 | int lua_isuserdata (Object *object) | 652 | int lua_isuserdata (Object *object) |
1065 | { | 653 | { |
1066 | return (object != NULL && tag(object) == T_USERDATA); | 654 | return (object != NULL && tag(object) == LUA_T_USERDATA); |
1067 | } | ||
1068 | |||
1069 | /* | ||
1070 | ** Internal function: return an object type. | ||
1071 | */ | ||
1072 | void lua_type (void) | ||
1073 | { | ||
1074 | Object *o = lua_getparam(1); | ||
1075 | |||
1076 | if (lua_constant == NULL) | ||
1077 | lua_initconstant(); | ||
1078 | lua_pushstring (lua_constant[tag(o)]); | ||
1079 | } | 655 | } |
1080 | 656 | ||
657 | |||
1081 | /* | 658 | /* |
1082 | ** Internal function: convert an object to a number | 659 | ** Internal function: convert an object to a number |
1083 | */ | 660 | */ |
@@ -1087,48 +664,439 @@ void lua_obj2number (void) | |||
1087 | lua_pushobject (lua_convtonumber(o)); | 664 | lua_pushobject (lua_convtonumber(o)); |
1088 | } | 665 | } |
1089 | 666 | ||
667 | |||
668 | |||
1090 | /* | 669 | /* |
1091 | ** Internal function: print object values | 670 | ** Execute the given opcode, until a RET. Parameters are between |
671 | ** [stack+base,top). Returns n such that the the results are between | ||
672 | ** [stack+n,top). | ||
1092 | */ | 673 | */ |
1093 | void lua_print (void) | 674 | static int lua_execute (Byte *pc, int base) |
1094 | { | 675 | { |
1095 | int i=1; | 676 | lua_debugline = 0; /* reset debug flag */ |
1096 | Object *obj; | 677 | if (stack == NULL) |
1097 | while ((obj=lua_getparam (i++)) != NULL) | 678 | lua_initstack(); |
679 | while (1) | ||
1098 | { | 680 | { |
1099 | if (lua_isnumber(obj)) printf("%g\n",lua_getnumber (obj)); | 681 | OpCode opcode; |
1100 | else if (lua_isstring(obj)) printf("%s\n",lua_getstring (obj)); | 682 | switch (opcode = (OpCode)*pc++) |
1101 | else if (lua_isfunction(obj)) printf("function: %p\n",bvalue(obj)); | 683 | { |
1102 | else if (lua_iscfunction(obj)) printf("cfunction: %p\n",lua_getcfunction (obj)); | 684 | case PUSHNIL: tag(top++) = LUA_T_NIL; break; |
1103 | else if (lua_isuserdata(obj)) printf("userdata: %p\n",lua_getuserdata (obj)); | ||
1104 | else if (lua_istable(obj)) printf("table: %p\n",obj); | ||
1105 | else if (lua_isnil(obj)) printf("nil\n"); | ||
1106 | else printf("invalid value to print\n"); | ||
1107 | } | ||
1108 | } | ||
1109 | 685 | ||
1110 | /* | 686 | case PUSH0: tag(top) = LUA_T_NUMBER; nvalue(top++) = 0; break; |
1111 | ** Internal function: do a file | 687 | case PUSH1: tag(top) = LUA_T_NUMBER; nvalue(top++) = 1; break; |
1112 | */ | 688 | case PUSH2: tag(top) = LUA_T_NUMBER; nvalue(top++) = 2; break; |
1113 | void lua_internaldofile (void) | ||
1114 | { | ||
1115 | lua_Object obj = lua_getparam (1); | ||
1116 | if (lua_isstring(obj) && !lua_dofile(lua_getstring(obj))) | ||
1117 | lua_pushnumber(1); | ||
1118 | else | ||
1119 | lua_pushnil(); | ||
1120 | } | ||
1121 | 689 | ||
1122 | /* | 690 | case PUSHBYTE: tag(top) = LUA_T_NUMBER; nvalue(top++) = *pc++; break; |
1123 | ** Internal function: do a string | 691 | |
1124 | */ | 692 | case PUSHWORD: |
1125 | void lua_internaldostring (void) | 693 | { |
1126 | { | 694 | CodeWord code; |
1127 | lua_Object obj = lua_getparam (1); | 695 | get_word(code,pc); |
1128 | if (lua_isstring(obj) && !lua_dostring(lua_getstring(obj))) | 696 | tag(top) = LUA_T_NUMBER; nvalue(top++) = code.w; |
1129 | lua_pushnumber(1); | 697 | } |
1130 | else | 698 | break; |
1131 | lua_pushnil(); | 699 | |
1132 | } | 700 | case PUSHFLOAT: |
701 | { | ||
702 | CodeFloat code; | ||
703 | get_float(code,pc); | ||
704 | tag(top) = LUA_T_NUMBER; nvalue(top++) = code.f; | ||
705 | } | ||
706 | break; | ||
707 | |||
708 | case PUSHSTRING: | ||
709 | { | ||
710 | CodeWord code; | ||
711 | get_word(code,pc); | ||
712 | tag(top) = LUA_T_STRING; svalue(top++) = lua_constant[code.w]; | ||
713 | } | ||
714 | break; | ||
715 | |||
716 | case PUSHFUNCTION: | ||
717 | { | ||
718 | CodeCode code; | ||
719 | get_code(code,pc); | ||
720 | tag(top) = LUA_T_FUNCTION; bvalue(top++) = code.b; | ||
721 | } | ||
722 | break; | ||
723 | |||
724 | case PUSHLOCAL0: case PUSHLOCAL1: case PUSHLOCAL2: | ||
725 | case PUSHLOCAL3: case PUSHLOCAL4: case PUSHLOCAL5: | ||
726 | case PUSHLOCAL6: case PUSHLOCAL7: case PUSHLOCAL8: | ||
727 | case PUSHLOCAL9: *top++ = *((stack+base) + (int)(opcode-PUSHLOCAL0)); break; | ||
728 | |||
729 | case PUSHLOCAL: *top++ = *((stack+base) + (*pc++)); break; | ||
730 | |||
731 | case PUSHGLOBAL: | ||
732 | { | ||
733 | CodeWord code; | ||
734 | get_word(code,pc); | ||
735 | *top++ = s_object(code.w); | ||
736 | } | ||
737 | break; | ||
738 | |||
739 | case PUSHINDEXED: | ||
740 | { | ||
741 | int s = lua_pushsubscript(); | ||
742 | if (s == 1) return 1; | ||
743 | } | ||
744 | break; | ||
745 | |||
746 | case PUSHSELF: | ||
747 | { | ||
748 | Object receiver = *(top-2); | ||
749 | if (lua_pushsubscript() == 1) return 1; | ||
750 | *(top++) = receiver; | ||
751 | break; | ||
752 | } | ||
753 | |||
754 | case STORELOCAL0: case STORELOCAL1: case STORELOCAL2: | ||
755 | case STORELOCAL3: case STORELOCAL4: case STORELOCAL5: | ||
756 | case STORELOCAL6: case STORELOCAL7: case STORELOCAL8: | ||
757 | case STORELOCAL9: | ||
758 | *((stack+base) + (int)(opcode-STORELOCAL0)) = *(--top); | ||
759 | break; | ||
760 | |||
761 | case STORELOCAL: *((stack+base) + (*pc++)) = *(--top); break; | ||
762 | |||
763 | case STOREGLOBAL: | ||
764 | { | ||
765 | CodeWord code; | ||
766 | get_word(code,pc); | ||
767 | s_object(code.w) = *(--top); | ||
768 | } | ||
769 | break; | ||
770 | |||
771 | case STOREINDEXED0: | ||
772 | { | ||
773 | int s = lua_storesubscript(); | ||
774 | if (s == 1) return 1; | ||
775 | } | ||
776 | break; | ||
777 | |||
778 | case STOREINDEXED: | ||
779 | { | ||
780 | int n = *pc++; | ||
781 | if (tag(top-3-n) != LUA_T_ARRAY) | ||
782 | { | ||
783 | lua_reportbug ("indexed expression not a table"); | ||
784 | return 1; | ||
785 | } | ||
786 | { | ||
787 | Object *h = lua_hashdefine (avalue(top-3-n), top-2-n); | ||
788 | if (h == NULL) return 1; | ||
789 | *h = *(top-1); | ||
790 | } | ||
791 | top--; | ||
792 | } | ||
793 | break; | ||
794 | |||
795 | case STORELIST0: | ||
796 | case STORELIST: | ||
797 | { | ||
798 | int m, n; | ||
799 | Object *arr; | ||
800 | if (opcode == STORELIST0) m = 0; | ||
801 | else m = *(pc++) * FIELDS_PER_FLUSH; | ||
802 | n = *(pc++); | ||
803 | arr = top-n-1; | ||
804 | if (tag(arr) != LUA_T_ARRAY) | ||
805 | { | ||
806 | lua_reportbug ("internal error - table expected"); | ||
807 | return 1; | ||
808 | } | ||
809 | while (n) | ||
810 | { | ||
811 | tag(top) = LUA_T_NUMBER; nvalue(top) = n+m; | ||
812 | *(lua_hashdefine (avalue(arr), top)) = *(top-1); | ||
813 | top--; | ||
814 | n--; | ||
815 | } | ||
816 | } | ||
817 | break; | ||
818 | |||
819 | case STORERECORD: | ||
820 | { | ||
821 | int n = *(pc++); | ||
822 | Object *arr = top-n-1; | ||
823 | if (tag(arr) != LUA_T_ARRAY) | ||
824 | { | ||
825 | lua_reportbug ("internal error - table expected"); | ||
826 | return 1; | ||
827 | } | ||
828 | while (n) | ||
829 | { | ||
830 | CodeWord code; | ||
831 | get_word(code,pc); | ||
832 | tag(top) = LUA_T_STRING; svalue(top) = lua_constant[code.w]; | ||
833 | *(lua_hashdefine (avalue(arr), top)) = *(top-1); | ||
834 | top--; | ||
835 | n--; | ||
836 | } | ||
837 | } | ||
838 | break; | ||
839 | |||
840 | case ADJUST0: | ||
841 | adjust_top((stack+base)); | ||
842 | break; | ||
843 | |||
844 | case ADJUST: | ||
845 | adjust_top((stack+base) + *(pc++)); | ||
846 | break; | ||
847 | |||
848 | case CREATEARRAY: | ||
849 | { | ||
850 | CodeWord size; | ||
851 | get_word(size,pc); | ||
852 | top++; | ||
853 | avalue(top-1) = lua_createarray(size.w); | ||
854 | if (avalue(top-1) == NULL) | ||
855 | return 1; | ||
856 | tag(top-1) = LUA_T_ARRAY; | ||
857 | } | ||
858 | break; | ||
859 | |||
860 | case EQOP: | ||
861 | { | ||
862 | int res; | ||
863 | Object *l = top-2; | ||
864 | Object *r = top-1; | ||
865 | --top; | ||
866 | if (tag(l) != tag(r)) | ||
867 | res = 0; | ||
868 | else | ||
869 | { | ||
870 | switch (tag(l)) | ||
871 | { | ||
872 | case LUA_T_NIL: | ||
873 | res = 0; break; | ||
874 | case LUA_T_NUMBER: | ||
875 | res = (nvalue(l) == nvalue(r)); break; | ||
876 | case LUA_T_ARRAY: | ||
877 | res = (avalue(l) == avalue(r)); break; | ||
878 | case LUA_T_FUNCTION: | ||
879 | res = (bvalue(l) == bvalue(r)); break; | ||
880 | case LUA_T_CFUNCTION: | ||
881 | res = (fvalue(l) == fvalue(r)); break; | ||
882 | case LUA_T_STRING: | ||
883 | res = (strcmp (svalue(l), svalue(r)) == 0); break; | ||
884 | default: | ||
885 | res = (uvalue(l) == uvalue(r)); break; | ||
886 | } | ||
887 | } | ||
888 | tag(top-1) = res ? LUA_T_NUMBER : LUA_T_NIL; | ||
889 | nvalue(top-1) = 1; | ||
890 | } | ||
891 | break; | ||
892 | |||
893 | case LTOP: | ||
894 | { | ||
895 | Object *l = top-2; | ||
896 | Object *r = top-1; | ||
897 | --top; | ||
898 | if (tag(l) == LUA_T_NUMBER && tag(r) == LUA_T_NUMBER) | ||
899 | tag(top-1) = (nvalue(l) < nvalue(r)) ? LUA_T_NUMBER : LUA_T_NIL; | ||
900 | else | ||
901 | { | ||
902 | if (tostring(l) || tostring(r)) | ||
903 | return 1; | ||
904 | tag(top-1) = (strcmp (svalue(l), svalue(r)) < 0) ? LUA_T_NUMBER : LUA_T_NIL; | ||
905 | } | ||
906 | nvalue(top-1) = 1; | ||
907 | } | ||
908 | break; | ||
909 | |||
910 | case LEOP: | ||
911 | { | ||
912 | Object *l = top-2; | ||
913 | Object *r = top-1; | ||
914 | --top; | ||
915 | if (tag(l) == LUA_T_NUMBER && tag(r) == LUA_T_NUMBER) | ||
916 | tag(top-1) = (nvalue(l) <= nvalue(r)) ? LUA_T_NUMBER : LUA_T_NIL; | ||
917 | else | ||
918 | { | ||
919 | if (tostring(l) || tostring(r)) | ||
920 | return 1; | ||
921 | tag(top-1) = (strcmp (svalue(l), svalue(r)) <= 0) ? LUA_T_NUMBER : LUA_T_NIL; | ||
922 | } | ||
923 | nvalue(top-1) = 1; | ||
924 | } | ||
925 | break; | ||
926 | |||
927 | case ADDOP: | ||
928 | { | ||
929 | Object *l = top-2; | ||
930 | Object *r = top-1; | ||
931 | if (tonumber(r) || tonumber(l)) | ||
932 | return 1; | ||
933 | nvalue(l) += nvalue(r); | ||
934 | --top; | ||
935 | } | ||
936 | break; | ||
937 | |||
938 | case SUBOP: | ||
939 | { | ||
940 | Object *l = top-2; | ||
941 | Object *r = top-1; | ||
942 | if (tonumber(r) || tonumber(l)) | ||
943 | return 1; | ||
944 | nvalue(l) -= nvalue(r); | ||
945 | --top; | ||
946 | } | ||
947 | break; | ||
1133 | 948 | ||
949 | case MULTOP: | ||
950 | { | ||
951 | Object *l = top-2; | ||
952 | Object *r = top-1; | ||
953 | if (tonumber(r) || tonumber(l)) | ||
954 | return 1; | ||
955 | nvalue(l) *= nvalue(r); | ||
956 | --top; | ||
957 | } | ||
958 | break; | ||
959 | |||
960 | case DIVOP: | ||
961 | { | ||
962 | Object *l = top-2; | ||
963 | Object *r = top-1; | ||
964 | if (tonumber(r) || tonumber(l)) | ||
965 | return 1; | ||
966 | nvalue(l) /= nvalue(r); | ||
967 | --top; | ||
968 | } | ||
969 | break; | ||
970 | |||
971 | case POWOP: | ||
972 | { | ||
973 | Object *l = top-2; | ||
974 | Object *r = top-1; | ||
975 | if (tonumber(r) || tonumber(l)) | ||
976 | return 1; | ||
977 | nvalue(l) = pow(nvalue(l), nvalue(r)); | ||
978 | --top; | ||
979 | } | ||
980 | break; | ||
981 | |||
982 | case CONCOP: | ||
983 | { | ||
984 | Object *l = top-2; | ||
985 | Object *r = top-1; | ||
986 | if (tostring(r) || tostring(l)) | ||
987 | return 1; | ||
988 | svalue(l) = lua_createstring (lua_strconc(svalue(l),svalue(r))); | ||
989 | if (svalue(l) == NULL) | ||
990 | return 1; | ||
991 | --top; | ||
992 | } | ||
993 | break; | ||
994 | |||
995 | case MINUSOP: | ||
996 | if (tonumber(top-1)) | ||
997 | return 1; | ||
998 | nvalue(top-1) = - nvalue(top-1); | ||
999 | break; | ||
1000 | |||
1001 | case NOTOP: | ||
1002 | tag(top-1) = tag(top-1) == LUA_T_NIL ? LUA_T_NUMBER : LUA_T_NIL; | ||
1003 | break; | ||
1004 | |||
1005 | case ONTJMP: | ||
1006 | { | ||
1007 | CodeWord code; | ||
1008 | get_word(code,pc); | ||
1009 | if (tag(top-1) != LUA_T_NIL) pc += code.w; | ||
1010 | } | ||
1011 | break; | ||
1012 | |||
1013 | case ONFJMP: | ||
1014 | { | ||
1015 | CodeWord code; | ||
1016 | get_word(code,pc); | ||
1017 | if (tag(top-1) == LUA_T_NIL) pc += code.w; | ||
1018 | } | ||
1019 | break; | ||
1020 | |||
1021 | case JMP: | ||
1022 | { | ||
1023 | CodeWord code; | ||
1024 | get_word(code,pc); | ||
1025 | pc += code.w; | ||
1026 | } | ||
1027 | break; | ||
1028 | |||
1029 | case UPJMP: | ||
1030 | { | ||
1031 | CodeWord code; | ||
1032 | get_word(code,pc); | ||
1033 | pc -= code.w; | ||
1034 | } | ||
1035 | break; | ||
1036 | |||
1037 | case IFFJMP: | ||
1038 | { | ||
1039 | CodeWord code; | ||
1040 | get_word(code,pc); | ||
1041 | top--; | ||
1042 | if (tag(top) == LUA_T_NIL) pc += code.w; | ||
1043 | } | ||
1044 | break; | ||
1045 | |||
1046 | case IFFUPJMP: | ||
1047 | { | ||
1048 | CodeWord code; | ||
1049 | get_word(code,pc); | ||
1050 | top--; | ||
1051 | if (tag(top) == LUA_T_NIL) pc -= code.w; | ||
1052 | } | ||
1053 | break; | ||
1054 | |||
1055 | case POP: --top; break; | ||
1056 | |||
1057 | case CALLFUNC: | ||
1058 | { | ||
1059 | int nParams = *(pc++); | ||
1060 | int nResults = *(pc++); | ||
1061 | Object *func = top-1-nParams; /* function is below parameters */ | ||
1062 | int newBase = (top-stack)-nParams; | ||
1063 | do_call(func, newBase, nResults, newBase-1); | ||
1064 | } | ||
1065 | break; | ||
1066 | |||
1067 | case RETCODE0: | ||
1068 | return base; | ||
1069 | |||
1070 | case RETCODE: | ||
1071 | return base+*pc; | ||
1072 | |||
1073 | case SETFUNCTION: | ||
1074 | { | ||
1075 | CodeCode file; | ||
1076 | CodeWord func; | ||
1077 | get_code(file,pc); | ||
1078 | get_word(func,pc); | ||
1079 | if (lua_pushfunction ((char *)file.b, func.w)) | ||
1080 | return 1; | ||
1081 | } | ||
1082 | break; | ||
1083 | |||
1084 | case SETLINE: | ||
1085 | { | ||
1086 | CodeWord code; | ||
1087 | get_word(code,pc); | ||
1088 | lua_debugline = code.w; | ||
1089 | } | ||
1090 | break; | ||
1091 | |||
1092 | case RESET: | ||
1093 | lua_popfunction (); | ||
1094 | break; | ||
1095 | |||
1096 | default: | ||
1097 | lua_error ("internal error - opcode doesn't match"); | ||
1098 | return 1; | ||
1099 | } | ||
1100 | } | ||
1101 | } | ||
1134 | 1102 | ||
@@ -1,11 +1,13 @@ | |||
1 | /* | 1 | /* |
2 | ** TeCGraf - PUC-Rio | 2 | ** TeCGraf - PUC-Rio |
3 | ** $Id: opcode.h,v 2.3 1994/08/05 19:31:09 celes Exp celes $ | 3 | ** $Id: opcode.h,v 2.4 1994/10/17 19:00:40 celes Exp roberto $ |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #ifndef opcode_h | 6 | #ifndef opcode_h |
7 | #define opcode_h | 7 | #define opcode_h |
8 | 8 | ||
9 | #include "lua.h" | ||
10 | |||
9 | #ifndef STACKGAP | 11 | #ifndef STACKGAP |
10 | #define STACKGAP 128 | 12 | #define STACKGAP 128 |
11 | #endif | 13 | #endif |
@@ -16,6 +18,8 @@ | |||
16 | 18 | ||
17 | #define FIELDS_PER_FLUSH 40 | 19 | #define FIELDS_PER_FLUSH 40 |
18 | 20 | ||
21 | #define MAX_TEMPS 20 | ||
22 | |||
19 | typedef unsigned char Byte; | 23 | typedef unsigned char Byte; |
20 | 24 | ||
21 | typedef unsigned short Word; | 25 | typedef unsigned short Word; |
@@ -54,8 +58,7 @@ typedef enum | |||
54 | PUSHLOCAL, | 58 | PUSHLOCAL, |
55 | PUSHGLOBAL, | 59 | PUSHGLOBAL, |
56 | PUSHINDEXED, | 60 | PUSHINDEXED, |
57 | PUSHMARK, | 61 | PUSHSELF, |
58 | PUSHMARKMET, | ||
59 | STORELOCAL0, STORELOCAL1, STORELOCAL2, STORELOCAL3, STORELOCAL4, | 62 | STORELOCAL0, STORELOCAL1, STORELOCAL2, STORELOCAL3, STORELOCAL4, |
60 | STORELOCAL5, STORELOCAL6, STORELOCAL7, STORELOCAL8, STORELOCAL9, | 63 | STORELOCAL5, STORELOCAL6, STORELOCAL7, STORELOCAL8, STORELOCAL9, |
61 | STORELOCAL, | 64 | STORELOCAL, |
@@ -65,6 +68,7 @@ typedef enum | |||
65 | STORELIST0, | 68 | STORELIST0, |
66 | STORELIST, | 69 | STORELIST, |
67 | STORERECORD, | 70 | STORERECORD, |
71 | ADJUST0, | ||
68 | ADJUST, | 72 | ADJUST, |
69 | CREATEARRAY, | 73 | CREATEARRAY, |
70 | EQOP, | 74 | EQOP, |
@@ -86,34 +90,25 @@ typedef enum | |||
86 | IFFUPJMP, | 90 | IFFUPJMP, |
87 | POP, | 91 | POP, |
88 | CALLFUNC, | 92 | CALLFUNC, |
93 | RETCODE0, | ||
89 | RETCODE, | 94 | RETCODE, |
90 | HALT, | ||
91 | SETFUNCTION, | 95 | SETFUNCTION, |
92 | SETLINE, | 96 | SETLINE, |
93 | RESET | 97 | RESET |
94 | } OpCode; | 98 | } OpCode; |
95 | 99 | ||
96 | typedef enum | 100 | #define MULT_RET 255 |
97 | { | 101 | |
98 | T_MARK, | ||
99 | T_NIL, | ||
100 | T_NUMBER, | ||
101 | T_STRING, | ||
102 | T_ARRAY, | ||
103 | T_FUNCTION, | ||
104 | T_CFUNCTION, | ||
105 | T_USERDATA | ||
106 | } Type; | ||
107 | 102 | ||
108 | typedef void (*Cfunction) (void); | 103 | typedef void (*Cfunction) (void); |
109 | typedef int (*Input) (void); | 104 | typedef int (*Input) (void); |
110 | 105 | ||
111 | typedef union | 106 | typedef union |
112 | { | 107 | { |
113 | Cfunction f; | 108 | Cfunction f; |
114 | real n; | 109 | real n; |
115 | char *s; | 110 | char *s; |
116 | Byte *b; | 111 | Byte *b; |
117 | struct Hash *a; | 112 | struct Hash *a; |
118 | void *u; | 113 | void *u; |
119 | } Value; | 114 | } Value; |
@@ -157,18 +152,12 @@ typedef struct | |||
157 | 152 | ||
158 | 153 | ||
159 | /* Exported functions */ | 154 | /* Exported functions */ |
160 | int lua_execute (Byte *pc); | ||
161 | void lua_markstack (void); | ||
162 | char *lua_strdup (char *l); | 155 | char *lua_strdup (char *l); |
163 | 156 | ||
164 | void lua_setinput (Input fn); /* from "lex.c" module */ | 157 | void lua_setinput (Input fn); /* from "lex.c" module */ |
165 | char *lua_lasttext (void); /* from "lex.c" module */ | 158 | char *lua_lasttext (void); /* from "lex.c" module */ |
166 | int lua_parse (void); /* from "lua.stx" module */ | 159 | Byte *lua_parse (void); /* from "lua.stx" module */ |
167 | void lua_type (void); | ||
168 | void lua_obj2number (void); | 160 | void lua_obj2number (void); |
169 | void lua_print (void); | ||
170 | void lua_internaldofile (void); | ||
171 | void lua_internaldostring (void); | ||
172 | void lua_travstack (void (*fn)(Object *)); | 161 | void lua_travstack (void (*fn)(Object *)); |
173 | 162 | ||
174 | #endif | 163 | #endif |