commit 9efc257d9d774501af4538a289729f3e8e5e3d7e
parent fa71304e54f304ceceddef3a4b97b38228822e94
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Wed, 25 Oct 1995 11:05:32 -0200
new method to keep debug line information: current line is stored on the
Lua stack, just below (new) base, with tag LUA_T_LINE.
SETLINE opcodes are generated by lex.
Diffstat:
M | inout.c | | | 5 | ++--- |
M | lex.c | | | 8 | ++++++-- |
M | lua.h | | | 3 | ++- |
M | lua.stx | | | 214 | ++++++++++++++++++++++++++++++++++++++++++++++--------------------------------- |
M | opcode.c | | | 60 | ++++++++++++++++++++++++++++++------------------------------ |
M | opcode.h | | | 6 | ++++-- |
6 files changed, 169 insertions(+), 127 deletions(-)
diff --git 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 <stdio.h>
#include <stdlib.h>
@@ -29,8 +29,7 @@ char *rcs_inout="$Id: inout.c,v 2.23 1995/10/17 11:58:41 roberto Exp roberto $";
/* 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
@@ -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 <ctype.h>
@@ -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
@@ -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
@@ -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; }
+ ;
%%
diff --git 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 <setjmp.h>
#include <stdlib.h>
@@ -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; i<nResults; i++)
- *(stack+base+i) = *(stack+firstResult+i);
- top -= firstResult-base;
- }
+ nResults = top - (stack+firstResult); /* actual number of results */
+ for (i=0; i<nResults; i++)
+ *(stack+base+i) = *(stack+firstResult+i);
+ top -= firstResult-base;
}
@@ -366,9 +356,12 @@ lua_Object lua_stackedfunction (int level)
void lua_funcinfo (lua_Object func, char **filename, char **funcname,
- char **objname, int *linedefined)
+ char **objname, int *line)
{
- return luaI_funcInfo(Address(func), filename, funcname, objname, linedefined);
+ Object *f = Address(func);
+ luaI_funcInfo(f, filename, funcname, objname, line);
+ *line = (f+1 < top && (f+1)->tag == 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
@@ -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);