diff --git a/inout.c b/inout.c index 0506d11e..ab827c05 100644 --- a/inout.c +++ b/inout.c @@ -5,7 +5,7 @@ ** Also provides some predefined lua functions. */ -char *rcs_inout="$Id: inout.c,v 2.23 1995/10/17 11:58:41 roberto Exp roberto $"; +char *rcs_inout="$Id: inout.c,v 2.24 1995/10/23 13:54:11 roberto Exp roberto $"; #include #include @@ -29,8 +29,7 @@ char *rcs_inout="$Id: inout.c,v 2.23 1995/10/17 11:58:41 roberto Exp roberto $"; /* Exported variables */ Word lua_linenumber; -Bool lua_debug; -Word lua_debugline = 0; +Bool lua_debug = 0; char *lua_parsedfile; diff --git a/lex.c b/lex.c index 3b24857d..6c1f2ac5 100644 --- a/lex.c +++ b/lex.c @@ -1,4 +1,4 @@ -char *rcs_lex = "$Id: lex.c,v 2.18 1995/10/06 13:10:53 roberto Exp roberto $"; +char *rcs_lex = "$Id: lex.c,v 2.19 1995/10/13 15:16:25 roberto Exp roberto $"; #include @@ -148,6 +148,10 @@ static int read_long_string (void) int yylex (void) { float a; + static int linelasttoken = 0; + if (lua_debug) + luaI_codedebugline(linelasttoken); + linelasttoken = lua_linenumber; while (1) { yytextLast = yytext; @@ -159,7 +163,7 @@ int yylex (void) case EOF: case 0: return 0; - case '\n': lua_linenumber++; + case '\n': linelasttoken = ++lua_linenumber; case ' ': case '\r': /* CR: to avoid problems with DOS/Windows */ case '\t': diff --git a/lua.h b/lua.h index 80c50e4c..7ab5204f 100644 --- a/lua.h +++ b/lua.h @@ -2,7 +2,7 @@ ** LUA - Linguagem para Usuarios de Aplicacao ** Grupo de Tecnologia em Computacao Grafica ** TeCGraf - PUC-Rio -** $Id: lua.h,v 3.17 1995/10/06 14:11:10 roberto Exp roberto $ +** $Id: lua.h,v 3.18 1995/10/17 14:12:45 roberto Exp roberto $ */ @@ -26,6 +26,7 @@ typedef enum LUA_T_CFUNCTION= -6, LUA_T_MARK = -7, LUA_T_CMARK = -8, + LUA_T_LINE = -9, LUA_T_USERDATA = 0 } lua_Type; diff --git a/lua.stx b/lua.stx index ed839466..d0f832d7 100644 --- a/lua.stx +++ b/lua.stx @@ -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 #include @@ -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 DEBUG %type PrepJump -%type expr, exprlist, exprlist1, varlist1, funcParams, funcvalue +%type exprlist, exprlist1 /* if > 0, points to function return + counter (which has list length); if <= 0, -list lenght */ +%type functioncall, expr /* if != 0, points to function return + counter */ +%type varlist1, funcParams, funcvalue %type fieldlist, localdeclist, decinit %type ffieldlist, ffieldlist1, semicolonpart %type lfieldlist, lfieldlist1 +%type functiontoken %type var, singlevar %type 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); - $$ = 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 = $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")); - $$ = 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 = $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 {$$=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 - ($2)); } - | REPEAT {$$=pc;} block UNTIL cond PrepJump + | REPEAT {$$=pc;} block UNTIL expr1 PrepJump { basepc[$6] = IFFUPJMP; code_word_at(basepc+$6+1, pc - ($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 : {$$ = 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 ',' { $$ = adjust_functioncall($1, 1); } expr { - int r = $1 < 0 ? -$1 : $1; - $$ = ($4 == 0) ? -(r+1) : r+1; + if ($4 == 0) $$ = -($3 + 1); /* -length */ + else + { + adjust_functioncall($4, $3); + $$ = $4; + } } ; @@ -757,7 +792,8 @@ decinit : /* empty */ { $$ = 0; } | '=' exprlist1 { $$ = $2; } ; -setdebug : DEBUG {lua_debug = $1;} +setdebug : DEBUG { lua_debug = $1; } + ; %% diff --git a/opcode.c b/opcode.c index 9804f82b..768b2595 100644 --- a/opcode.c +++ b/opcode.c @@ -3,7 +3,7 @@ ** TecCGraf - PUC-Rio */ -char *rcs_opcode="$Id: opcode.c,v 3.45 1995/10/17 14:12:45 roberto Exp $"; +char *rcs_opcode="$Id: opcode.c,v 3.46 1995/10/17 14:30:05 roberto Exp roberto $"; #include #include @@ -75,7 +75,7 @@ static void lua_initstack (void) stack = newvector(maxstack, Object); stackLimit = stack+maxstack; top = stack; - *top = initial_stack; + *(top++) = initial_stack; } @@ -86,19 +86,19 @@ static void lua_initstack (void) static void growstack (void) { - StkId t = top-stack; if (stack == &initial_stack) lua_initstack(); else { + StkId t = top-stack; Long maxstack = stackLimit - stack; maxstack *= 2; stack = growvector(stack, maxstack, Object); stackLimit = stack+maxstack; + top = stack + t; if (maxstack >= MAX_WORD/2) lua_error("stack size overflow"); } - top = stack + t; } @@ -227,16 +227,6 @@ static void callFB (int fb) do_call((top-stack)-nParams, luaI_fallBacks[fb].nResults); } -/* -** Call the fallback for invalid functions (see do_call) -*/ -static void call_funcFB (StkId base, int nResults) -{ - open_stack((top-stack)-(base-1)); - stack[base-1] = luaI_fallBacks[FB_FUNCTION].function; - do_call(base, nResults); -} - /* ** Call a function (C or Lua). The parameters must be on the stack, @@ -248,6 +238,7 @@ static void do_call (StkId base, int nResults) { StkId firstResult; Object *func = stack+base-1; + int i; if (tag(func) == LUA_T_CFUNCTION) { tag(func) = LUA_T_CMARK; @@ -260,7 +251,10 @@ static void do_call (StkId base, int nResults) } else { /* func is not a function */ - call_funcFB(base, nResults); + /* Call the fallback for invalid functions */ + open_stack((top-stack)-(base-1)); + stack[base-1] = luaI_fallBacks[FB_FUNCTION].function; + do_call(base, nResults); return; } /* adjust the number of results */ @@ -268,14 +262,10 @@ static void do_call (StkId base, int nResults) adjust_top(firstResult+nResults); /* move results to base-1 (to erase parameters and function) */ base--; - if (firstResult != base) - { - int i; - nResults = top - (stack+firstResult); /* actual number of results */ - for (i=0; itag == LUA_T_LINE) ? + (f+1)->value.i : -1; } @@ -587,9 +580,9 @@ lua_Object lua_getparam (int number) */ real lua_getnumber (lua_Object object) { - if (object == LUA_NOOBJECT || tag(Address(object)) == LUA_T_NIL) return 0.0; + if (object == LUA_NOOBJECT) return 0.0; if (tonumber (Address(object))) return 0.0; - else return (nvalue(Address(object))); + else return (nvalue(Address(object))); } /* @@ -597,7 +590,7 @@ real lua_getnumber (lua_Object object) */ char *lua_getstring (lua_Object object) { - if (object == LUA_NOOBJECT || tag(Address(object)) == LUA_T_NIL) return NULL; + if (object == LUA_NOOBJECT) return NULL; if (tostring (Address(object))) return NULL; else return (svalue(Address(object))); } @@ -1168,9 +1161,16 @@ static StkId lua_execute (Byte *pc, StkId base) { CodeWord code; get_word(code,pc); - lua_debugline = code.w; + if ((stack+base-1)->tag != LUA_T_LINE) + { + /* open space for LINE value */ + open_stack((top-stack)-base); + base++; + (stack+base-1)->tag = LUA_T_LINE; + } + (stack+base-1)->value.i = code.w; + break; } - break; default: lua_error ("internal error - opcode doesn't match"); diff --git a/opcode.h b/opcode.h index 913000a2..e2741108 100644 --- a/opcode.h +++ b/opcode.h @@ -1,6 +1,6 @@ /* ** TeCGraf - PUC-Rio -** $Id: opcode.h,v 3.12 1995/10/04 17:13:02 roberto Exp roberto $ +** $Id: opcode.h,v 3.13 1995/10/17 11:58:41 roberto Exp roberto $ */ #ifndef opcode_h @@ -68,7 +68,7 @@ typedef enum CALLFUNC, RETCODE0, RETCODE, - SETLINE, + SETLINE } OpCode; #define MULT_RET 255 @@ -85,6 +85,7 @@ typedef union TFunc *tf; struct Hash *a; void *u; + int i; } Value; typedef struct Object @@ -147,6 +148,7 @@ void lua_setinput (Input fn); /* from "lex.c" module */ char *lua_lasttext (void); /* from "lex.c" module */ int yylex (void); /* from "lex.c" module */ void lua_parse (TFunc *tf); /* from "lua.stx" module */ +void luaI_codedebugline (int line); /* from "lua.stx" module */ void lua_travstack (int (*fn)(Object *)); Object *luaI_Address (lua_Object o); void luaI_pushobject (Object *o);