|
@@ -1,6 +1,6 @@
|
|
|
%{
|
|
|
|
|
|
-char *rcs_luastx = "$Id: lua.stx,v 3.20 1995/10/04 14:20:26 roberto Exp roberto $";
|
|
|
+char *rcs_luastx = "$Id: lua.stx,v 3.21 1995/10/17 11:58:41 roberto Exp roberto $";
|
|
|
|
|
|
#include <stdio.h>
|
|
|
#include <stdlib.h>
|
|
@@ -37,6 +37,7 @@ static Byte *basepc;
|
|
|
static int maincode;
|
|
|
static int pc;
|
|
|
|
|
|
+
|
|
|
#define MAXVAR 32
|
|
|
static Long varbuffer[MAXVAR]; /* variables in an assignment list;
|
|
|
it's long to store negative Word values */
|
|
@@ -235,15 +236,17 @@ static void lua_codeadjust (int n)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static void init_function (TreeNode *func)
|
|
|
+static void change2main (void)
|
|
|
{
|
|
|
- if (funcCode == NULL) /* first function */
|
|
|
- {
|
|
|
- funcCode = newvector(CODE_BLOCK, Byte);
|
|
|
- maxcode = CODE_BLOCK;
|
|
|
- }
|
|
|
- pc=0; basepc=funcCode; maxcurr=maxcode;
|
|
|
- nlocalvar=0;
|
|
|
+ /* (re)store main values */
|
|
|
+ pc=maincode; basepc=*initcode; maxcurr=maxmain;
|
|
|
+ nlocalvar=0;
|
|
|
+}
|
|
|
+
|
|
|
+static void savemain (void)
|
|
|
+{
|
|
|
+ /* save main values */
|
|
|
+ maincode=pc; *initcode=basepc; maxmain=maxcurr;
|
|
|
}
|
|
|
|
|
|
static void codereturn (void)
|
|
@@ -257,29 +260,43 @@ static void codereturn (void)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static void codedebugline (void)
|
|
|
+void luaI_codedebugline (int line)
|
|
|
{
|
|
|
- if (lua_debug)
|
|
|
+ static int lastline = 0;
|
|
|
+ if (lua_debug && line != lastline)
|
|
|
{
|
|
|
code_byte(SETLINE);
|
|
|
- code_word(lua_linenumber);
|
|
|
+ code_word(line);
|
|
|
+ lastline = line;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static void adjust_mult_assign (int vars, int exps, int temps)
|
|
|
+static int adjust_functioncall (Long exp, int i)
|
|
|
{
|
|
|
- if (exps < 0)
|
|
|
+ if (exp <= 0)
|
|
|
+ return -exp; /* exp is -list length */
|
|
|
+ else
|
|
|
{
|
|
|
- int r = vars - (-exps-1);
|
|
|
- if (r >= 0)
|
|
|
- code_byte(r);
|
|
|
+ int temp = basepc[exp];
|
|
|
+ basepc[exp] = i;
|
|
|
+ return temp+i;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void adjust_mult_assign (int vars, Long exps, int temps)
|
|
|
+{
|
|
|
+ if (exps > 0)
|
|
|
+ { /* must correct function call */
|
|
|
+ int diff = vars - basepc[exps];
|
|
|
+ if (diff >= 0)
|
|
|
+ adjust_functioncall(exps, diff);
|
|
|
else
|
|
|
{
|
|
|
- code_byte(0);
|
|
|
+ adjust_functioncall(exps, 0);
|
|
|
lua_codeadjust(temps);
|
|
|
}
|
|
|
}
|
|
|
- else if (vars != exps)
|
|
|
+ else if (vars != -exps)
|
|
|
lua_codeadjust(temps);
|
|
|
}
|
|
|
|
|
@@ -349,11 +366,14 @@ static void yyerror (char *s)
|
|
|
*/
|
|
|
void lua_parse (TFunc *tf)
|
|
|
{
|
|
|
+ lua_debug = 0;
|
|
|
initcode = &(tf->code);
|
|
|
*initcode = newvector(CODE_BLOCK, Byte);
|
|
|
maincode = 0;
|
|
|
maxmain = CODE_BLOCK;
|
|
|
+ change2main();
|
|
|
if (yyparse ()) lua_error("parse error");
|
|
|
+ savemain();
|
|
|
(*initcode)[maincode++] = RETCODE0;
|
|
|
tf->size = maincode;
|
|
|
#if LISTING
|
|
@@ -391,10 +411,15 @@ void lua_parse (TFunc *tf)
|
|
|
%token <vInt> DEBUG
|
|
|
|
|
|
%type <vLong> PrepJump
|
|
|
-%type <vInt> expr, exprlist, exprlist1, varlist1, funcParams, funcvalue
|
|
|
+%type <vLong> exprlist, exprlist1 /* if > 0, points to function return
|
|
|
+ counter (which has list length); if <= 0, -list lenght */
|
|
|
+%type <vLong> functioncall, expr /* if != 0, points to function return
|
|
|
+ counter */
|
|
|
+%type <vInt> varlist1, funcParams, funcvalue
|
|
|
%type <vInt> fieldlist, localdeclist, decinit
|
|
|
%type <vInt> ffieldlist, ffieldlist1, semicolonpart
|
|
|
%type <vInt> lfieldlist, lfieldlist1
|
|
|
+%type <vInt> functiontoken
|
|
|
%type <vLong> var, singlevar
|
|
|
%type <pFunc> body
|
|
|
|
|
@@ -411,63 +436,63 @@ void lua_parse (TFunc *tf)
|
|
|
|
|
|
|
|
|
functionlist : /* empty */
|
|
|
- | functionlist
|
|
|
- {
|
|
|
- pc=maincode; basepc=*initcode; maxcurr=maxmain;
|
|
|
- nlocalvar=0;
|
|
|
- }
|
|
|
- stat sc
|
|
|
- {
|
|
|
- maincode=pc; *initcode=basepc; maxmain=maxcurr;
|
|
|
- }
|
|
|
+ | functionlist globalstat
|
|
|
| functionlist function
|
|
|
| functionlist method
|
|
|
- | functionlist setdebug
|
|
|
;
|
|
|
|
|
|
-function : FUNCTION NAME
|
|
|
- {
|
|
|
- init_function($2);
|
|
|
- $<vInt>$ = lua_linenumber;
|
|
|
- }
|
|
|
- body
|
|
|
+globalstat : stat sc
|
|
|
+ | setdebug
|
|
|
+ ;
|
|
|
+
|
|
|
+function : functiontoken NAME body
|
|
|
{
|
|
|
Word func = luaI_findsymbol($2);
|
|
|
- luaI_insertfunction($4); /* may take part in GC */
|
|
|
+ luaI_insertfunction($3); /* may take part in GC */
|
|
|
s_tag(func) = LUA_T_FUNCTION;
|
|
|
- lua_table[func].object.value.tf = $4;
|
|
|
- $4->lineDefined = $<vInt>3;
|
|
|
- $4->name1 = $2->ts.str;
|
|
|
- $4->name2 = NULL;
|
|
|
- $4->fileName = lua_parsedfile;
|
|
|
+ lua_table[func].object.value.tf = $3;
|
|
|
+ $3->lineDefined = $1;
|
|
|
+ $3->name1 = $2->ts.str;
|
|
|
+ $3->name2 = NULL;
|
|
|
+ $3->fileName = lua_parsedfile;
|
|
|
}
|
|
|
;
|
|
|
|
|
|
-method : FUNCTION NAME ':' NAME
|
|
|
+method : functiontoken NAME ':' NAME
|
|
|
{
|
|
|
- init_function($4);
|
|
|
add_localvar(luaI_findsymbolbyname("self"));
|
|
|
- $<vInt>$ = lua_linenumber;
|
|
|
}
|
|
|
body
|
|
|
{
|
|
|
/* assign function to table field */
|
|
|
- pc=maincode; basepc=*initcode; maxcurr=maxmain;
|
|
|
- nlocalvar=0;
|
|
|
lua_pushvar(luaI_findsymbol($2)+1);
|
|
|
code_byte(PUSHSTRING);
|
|
|
code_word(luaI_findconstant($4));
|
|
|
code_byte(PUSHFUNCTION);
|
|
|
code_code($6);
|
|
|
code_byte(STOREINDEXED0);
|
|
|
- maincode=pc; *initcode=basepc; maxmain=maxcurr;
|
|
|
- $6->lineDefined = $<vInt>5;
|
|
|
+ $6->lineDefined = $1;
|
|
|
$6->name1 = $4->ts.str;
|
|
|
$6->name2 = $2->ts.str;
|
|
|
$6->fileName = lua_parsedfile;
|
|
|
}
|
|
|
;
|
|
|
|
|
|
+functiontoken : FUNCTION
|
|
|
+ {
|
|
|
+ if (funcCode == NULL) /* first function */
|
|
|
+ {
|
|
|
+ funcCode = newvector(CODE_BLOCK, Byte);
|
|
|
+ maxcode = CODE_BLOCK;
|
|
|
+ }
|
|
|
+ savemain(); /* save main values */
|
|
|
+ /* set func values */
|
|
|
+ pc=0; basepc=funcCode; maxcurr=maxcode;
|
|
|
+ nlocalvar=0;
|
|
|
+ $$ = lua_linenumber;
|
|
|
+ }
|
|
|
+ ;
|
|
|
+
|
|
|
body : '(' parlist ')' block END
|
|
|
{
|
|
|
codereturn();
|
|
@@ -475,10 +500,12 @@ body : '(' parlist ')' block END
|
|
|
$$->size = pc;
|
|
|
$$->code = newvector(pc, Byte);
|
|
|
memcpy($$->code, basepc, pc*sizeof(Byte));
|
|
|
+ /* save func values */
|
|
|
funcCode = basepc; maxcode=maxcurr;
|
|
|
#if LISTING
|
|
|
PrintCode(funcCode,funcCode+pc);
|
|
|
#endif
|
|
|
+ change2main(); /* change back to main code */
|
|
|
}
|
|
|
;
|
|
|
|
|
@@ -488,11 +515,7 @@ statlist : /* empty */
|
|
|
|
|
|
sc : /* empty */ | ';' ;
|
|
|
|
|
|
-stat : { codedebugline(); } stat1 ;
|
|
|
-
|
|
|
-cond : { codedebugline(); } expr1 ;
|
|
|
-
|
|
|
-stat1 : IF expr1 THEN PrepJump block PrepJump elsepart END
|
|
|
+stat : IF expr1 THEN PrepJump block PrepJump elsepart END
|
|
|
{ codeIf($4, $6); }
|
|
|
|
|
|
| WHILE {$<vLong>$=pc;} expr1 DO PrepJump block PrepJump END
|
|
@@ -503,7 +526,7 @@ stat1 : IF expr1 THEN PrepJump block PrepJump elsepart END
|
|
|
code_word_at(basepc+$7+1, pc - ($<vLong>2));
|
|
|
}
|
|
|
|
|
|
- | REPEAT {$<vLong>$=pc;} block UNTIL cond PrepJump
|
|
|
+ | REPEAT {$<vLong>$=pc;} block UNTIL expr1 PrepJump
|
|
|
{
|
|
|
basepc[$6] = IFFUPJMP;
|
|
|
code_word_at(basepc+$6+1, pc - ($<vLong>2));
|
|
@@ -520,7 +543,7 @@ stat1 : IF expr1 THEN PrepJump block PrepJump elsepart END
|
|
|
lua_codeadjust (0);
|
|
|
}
|
|
|
}
|
|
|
- | functioncall { code_byte(0); }
|
|
|
+ | functioncall
|
|
|
| LOCAL localdeclist decinit
|
|
|
{ nlocalvar += $2;
|
|
|
adjust_mult_assign($2, $3, 0);
|
|
@@ -529,7 +552,7 @@ stat1 : IF expr1 THEN PrepJump block PrepJump elsepart END
|
|
|
|
|
|
elsepart : /* empty */
|
|
|
| ELSE block
|
|
|
- | ELSEIF cond THEN PrepJump block PrepJump elsepart
|
|
|
+ | ELSEIF expr1 THEN PrepJump block PrepJump elsepart
|
|
|
{ codeIf($4, $6); }
|
|
|
;
|
|
|
|
|
@@ -544,9 +567,9 @@ block : {$<vInt>$ = nlocalvar;} statlist ret
|
|
|
;
|
|
|
|
|
|
ret : /* empty */
|
|
|
- | RETURN { codedebugline(); } exprlist sc
|
|
|
+ | RETURN exprlist sc
|
|
|
{
|
|
|
- if ($3 < 0) code_byte(MULT_RET);
|
|
|
+ adjust_functioncall($2, MULT_RET);
|
|
|
codereturn();
|
|
|
}
|
|
|
;
|
|
@@ -558,46 +581,49 @@ PrepJump : /* empty */
|
|
|
code_word (0);
|
|
|
}
|
|
|
|
|
|
-expr1 : expr { if ($1 == 0) code_byte(1); }
|
|
|
+expr1 : expr
|
|
|
+ {
|
|
|
+ adjust_functioncall($1, 1);
|
|
|
+ }
|
|
|
;
|
|
|
|
|
|
expr : '(' expr ')' { $$ = $2; }
|
|
|
- | expr1 EQ expr1 { code_byte(EQOP); $$ = 1; }
|
|
|
- | expr1 '<' expr1 { code_byte(LTOP); $$ = 1; }
|
|
|
- | expr1 '>' expr1 { code_byte(GTOP); $$ = 1; }
|
|
|
- | expr1 NE expr1 { code_byte(EQOP); code_byte(NOTOP); $$ = 1; }
|
|
|
- | expr1 LE expr1 { code_byte(LEOP); $$ = 1; }
|
|
|
- | expr1 GE expr1 { code_byte(GEOP); $$ = 1; }
|
|
|
- | expr1 '+' expr1 { code_byte(ADDOP); $$ = 1; }
|
|
|
- | expr1 '-' expr1 { code_byte(SUBOP); $$ = 1; }
|
|
|
- | expr1 '*' expr1 { code_byte(MULTOP); $$ = 1; }
|
|
|
- | expr1 '/' expr1 { code_byte(DIVOP); $$ = 1; }
|
|
|
- | expr1 '^' expr1 { code_byte(POWOP); $$ = 1; }
|
|
|
- | expr1 CONC expr1 { code_byte(CONCOP); $$ = 1; }
|
|
|
- | '-' expr1 %prec UNARY { code_byte(MINUSOP); $$ = 1;}
|
|
|
- | table { $$ = 1; }
|
|
|
- | varexp { $$ = 1;}
|
|
|
- | NUMBER { code_number($1); $$ = 1; }
|
|
|
+ | expr1 EQ expr1 { code_byte(EQOP); $$ = 0; }
|
|
|
+ | expr1 '<' expr1 { code_byte(LTOP); $$ = 0; }
|
|
|
+ | expr1 '>' expr1 { code_byte(GTOP); $$ = 0; }
|
|
|
+ | expr1 NE expr1 { code_byte(EQOP); code_byte(NOTOP); $$ = 0; }
|
|
|
+ | expr1 LE expr1 { code_byte(LEOP); $$ = 0; }
|
|
|
+ | expr1 GE expr1 { code_byte(GEOP); $$ = 0; }
|
|
|
+ | expr1 '+' expr1 { code_byte(ADDOP); $$ = 0; }
|
|
|
+ | expr1 '-' expr1 { code_byte(SUBOP); $$ = 0; }
|
|
|
+ | expr1 '*' expr1 { code_byte(MULTOP); $$ = 0; }
|
|
|
+ | expr1 '/' expr1 { code_byte(DIVOP); $$ = 0; }
|
|
|
+ | expr1 '^' expr1 { code_byte(POWOP); $$ = 0; }
|
|
|
+ | expr1 CONC expr1 { code_byte(CONCOP); $$ = 0; }
|
|
|
+ | '-' expr1 %prec UNARY { code_byte(MINUSOP); $$ = 0;}
|
|
|
+ | table { $$ = 0; }
|
|
|
+ | varexp { $$ = 0;}
|
|
|
+ | NUMBER { code_number($1); $$ = 0; }
|
|
|
| STRING
|
|
|
{
|
|
|
code_byte(PUSHSTRING);
|
|
|
code_word($1);
|
|
|
- $$ = 1;
|
|
|
+ $$ = 0;
|
|
|
}
|
|
|
- | NIL {code_byte(PUSHNIL); $$ = 1; }
|
|
|
- | functioncall { $$ = 0; }
|
|
|
- | NOT expr1 { code_byte(NOTOP); $$ = 1;}
|
|
|
+ | NIL {code_byte(PUSHNIL); $$ = 0; }
|
|
|
+ | functioncall { $$ = $1; }
|
|
|
+ | NOT expr1 { code_byte(NOTOP); $$ = 0;}
|
|
|
| expr1 AND PrepJump {code_byte(POP); } expr1
|
|
|
{
|
|
|
basepc[$3] = ONFJMP;
|
|
|
code_word_at(basepc+$3+1, pc - ($3 + sizeof(Word)+1));
|
|
|
- $$ = 1;
|
|
|
+ $$ = 0;
|
|
|
}
|
|
|
| expr1 OR PrepJump {code_byte(POP); } expr1
|
|
|
{
|
|
|
basepc[$3] = ONTJMP;
|
|
|
code_word_at(basepc+$3+1, pc - ($3 + sizeof(Word)+1));
|
|
|
- $$ = 1;
|
|
|
+ $$ = 0;
|
|
|
}
|
|
|
;
|
|
|
|
|
@@ -613,7 +639,12 @@ table :
|
|
|
;
|
|
|
|
|
|
functioncall : funcvalue funcParams
|
|
|
- { code_byte(CALLFUNC); code_byte($1+$2); }
|
|
|
+ {
|
|
|
+ code_byte(CALLFUNC);
|
|
|
+ code_byte($1+$2);
|
|
|
+ $$ = pc;
|
|
|
+ code_byte(0); /* may be modified by other rules */
|
|
|
+ }
|
|
|
;
|
|
|
|
|
|
funcvalue : varexp { $$ = 0; }
|
|
@@ -626,7 +657,7 @@ funcvalue : varexp { $$ = 0; }
|
|
|
;
|
|
|
|
|
|
funcParams : '(' exprlist ')'
|
|
|
- { if ($2<0) { code_byte(1); $$ = -$2; } else $$ = $2; }
|
|
|
+ { $$ = adjust_functioncall($2, 1); }
|
|
|
| table { $$ = 1; }
|
|
|
;
|
|
|
|
|
@@ -634,11 +665,15 @@ exprlist : /* empty */ { $$ = 0; }
|
|
|
| exprlist1 { $$ = $1; }
|
|
|
;
|
|
|
|
|
|
-exprlist1 : expr { if ($1 == 0) $$ = -1; else $$ = 1; }
|
|
|
- | exprlist1 ',' { if ($1 < 0) code_byte(1); } expr
|
|
|
+exprlist1 : expr { if ($1 != 0) $$ = $1; else $$ = -1; }
|
|
|
+ | exprlist1 ',' { $<vLong>$ = adjust_functioncall($1, 1); } expr
|
|
|
{
|
|
|
- int r = $1 < 0 ? -$1 : $1;
|
|
|
- $$ = ($4 == 0) ? -(r+1) : r+1;
|
|
|
+ if ($4 == 0) $$ = -($<vLong>3 + 1); /* -length */
|
|
|
+ else
|
|
|
+ {
|
|
|
+ adjust_functioncall($4, $<vLong>3);
|
|
|
+ $$ = $4;
|
|
|
+ }
|
|
|
}
|
|
|
;
|
|
|
|
|
@@ -757,7 +792,8 @@ decinit : /* empty */ { $$ = 0; }
|
|
|
| '=' exprlist1 { $$ = $2; }
|
|
|
;
|
|
|
|
|
|
-setdebug : DEBUG {lua_debug = $1;}
|
|
|
+setdebug : DEBUG { lua_debug = $1; }
|
|
|
+ ;
|
|
|
|
|
|
%%
|
|
|
|