diff options
author | Lua Team <team@lua.org> | 1995-11-28 12:00:00 +0000 |
---|---|---|
committer | repogen <> | 1995-11-28 12:00:00 +0000 |
commit | 71754d2f6423fb9b6e87658e58bafc5470d53f65 (patch) | |
tree | c704e97b80e52a52d3152738941bb4c8ca676b97 /src | |
parent | a8b6ba0954edb9e0e669e1f451b9a8f145ce5166 (diff) | |
download | lua-github-71754d2f6423fb9b6e87658e58bafc5470d53f65.tar.gz |
Lua 2.22.2
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 11 | ||||
-rw-r--r-- | src/fallback.c | 50 | ||||
-rw-r--r-- | src/fallback.h | 7 | ||||
-rw-r--r-- | src/func.c | 79 | ||||
-rw-r--r-- | src/func.h | 24 | ||||
-rw-r--r-- | src/hash.c | 9 | ||||
-rw-r--r-- | src/inout.c | 140 | ||||
-rw-r--r-- | src/inout.h | 9 | ||||
-rw-r--r-- | src/lex.c | 98 | ||||
-rw-r--r-- | src/lua.stx (renamed from src/yacc/lua.stx) | 392 | ||||
-rw-r--r-- | src/opcode.c | 396 | ||||
-rw-r--r-- | src/opcode.h | 25 | ||||
-rw-r--r-- | src/parser.c | 1058 | ||||
-rw-r--r-- | src/parser.h | 3 | ||||
-rw-r--r-- | src/table.c | 129 | ||||
-rw-r--r-- | src/table.h | 10 | ||||
-rw-r--r-- | src/tree.c | 42 | ||||
-rw-r--r-- | src/tree.h | 4 | ||||
-rw-r--r-- | src/yacc/Makefile | 3 |
19 files changed, 1348 insertions, 1141 deletions
diff --git a/src/Makefile b/src/Makefile index 6d1f1bb1..f6296781 100644 --- a/src/Makefile +++ b/src/Makefile @@ -10,12 +10,13 @@ WARN= -Wall -Wmissing-prototypes -Wshadow -ansi CC= gcc CFLAGS= $(INCS) $(DEFS) $(WARN) -O2 -OBJS= fallback.o hash.o inout.o lex.o mem.o opcode.o parser.o table.o tree.o +OBJS= fallback.o func.o hash.o inout.o lex.o mem.o opcode.o parser.o table.o tree.o +SRCS= fallback.c func.c hash.c inout.c lex.c mem.c opcode.c table.c tree.c fallback.h func.h hash.h inout.h mem.h opcode.h table.h tree.h types.h ugly.h lua.stx SLIB= $(LIB)/liblua.a # dynamic libraries only work for SunOs -DLIB= $(LIB)/liblua.so.2.1 +DLIB= $(LIB)/liblua.so.$(VERSION) all: $(SLIB) @@ -32,4 +33,8 @@ clean: rm -f $(OBJS) $(SLIB) $(DLIB) co: - co -M fallback.c hash.c inout.c lex.c mem.c opcode.c table.c tree.c fallback.h hash.h inout.h mem.h opcode.h table.h tree.h types.h ugly.h + co -f -M $(SRCS) + yacc -d lua.stx ; mv -f y.tab.c parser.c ; mv -f y.tab.h parser.h + +klean: clean + rm -f $(SRCS) parser.c parser.h diff --git a/src/fallback.c b/src/fallback.c index d5bbbba1..aa9fc99d 100644 --- a/src/fallback.c +++ b/src/fallback.c @@ -3,7 +3,7 @@ ** TecCGraf - PUC-Rio */ -char *rcs_fallback="$Id: fallback.c,v 1.11 1995/02/06 19:34:03 roberto Exp $"; +char *rcs_fallback="$Id: fallback.c,v 1.17 1995/10/17 14:30:05 roberto Exp $"; #include <stdio.h> #include <string.h> @@ -11,7 +11,6 @@ char *rcs_fallback="$Id: fallback.c,v 1.11 1995/02/06 19:34:03 roberto Exp $"; #include "mem.h" #include "fallback.h" #include "opcode.h" -#include "inout.h" #include "lua.h" @@ -29,15 +28,16 @@ static void funcFB (void); ** Warning: This list must be in the same order as the #define's */ struct FB luaI_fallBacks[] = { -{"error", {LUA_T_CFUNCTION, errorFB}}, -{"index", {LUA_T_CFUNCTION, indexFB}}, -{"gettable", {LUA_T_CFUNCTION, gettableFB}}, -{"arith", {LUA_T_CFUNCTION, arithFB}}, -{"order", {LUA_T_CFUNCTION, orderFB}}, -{"concat", {LUA_T_CFUNCTION, concatFB}}, -{"settable", {LUA_T_CFUNCTION, gettableFB}}, -{"gc", {LUA_T_CFUNCTION, GDFB}}, -{"function", {LUA_T_CFUNCTION, funcFB}} +{"error", {LUA_T_CFUNCTION, {errorFB}}, 1, 0}, +{"index", {LUA_T_CFUNCTION, {indexFB}}, 2, 1}, +{"gettable", {LUA_T_CFUNCTION, {gettableFB}}, 2, 1}, +{"arith", {LUA_T_CFUNCTION, {arithFB}}, 3, 1}, +{"order", {LUA_T_CFUNCTION, {orderFB}}, 3, 1}, +{"concat", {LUA_T_CFUNCTION, {concatFB}}, 2, 1}, +{"settable", {LUA_T_CFUNCTION, {gettableFB}}, 3, 0}, +{"gc", {LUA_T_CFUNCTION, {GDFB}}, 1, 0}, +{"function", {LUA_T_CFUNCTION, {funcFB}}, -1, -1} + /* no fixed number of params or results */ }; #define N_FB (sizeof(luaI_fallBacks)/sizeof(struct FB)) @@ -48,10 +48,7 @@ void luaI_setfallback (void) char *name = lua_getstring(lua_getparam(1)); lua_Object func = lua_getparam(2); if (name == NULL || !(lua_isfunction(func) || lua_iscfunction(func))) - { - lua_pushnil(); - return; - } + lua_error("incorrect argument to function `setfallback'"); for (i=0; i<N_FB; i++) { if (strcmp(luaI_fallBacks[i].kind, name) == 0) @@ -62,7 +59,7 @@ void luaI_setfallback (void) } } /* name not found */ - lua_pushnil(); + lua_error("incorrect argument to function `setfallback'"); } @@ -84,31 +81,31 @@ static void indexFB (void) static void gettableFB (void) { - lua_reportbug("indexed expression not a table"); + lua_error("indexed expression not a table"); } static void arithFB (void) { - lua_reportbug("unexpected type at conversion to number"); + lua_error("unexpected type at conversion to number"); } static void concatFB (void) { - lua_reportbug("unexpected type at conversion to string"); + lua_error("unexpected type at conversion to string"); } static void orderFB (void) { - lua_reportbug("unexpected type at comparison"); + lua_error("unexpected type at comparison"); } static void GDFB (void) { } static void funcFB (void) { - lua_reportbug("call expression not a function"); + lua_error("call expression not a function"); } @@ -162,10 +159,19 @@ Object *luaI_getlocked (int ref) } -void luaI_travlock (void (*fn)(Object *)) +void luaI_travlock (int (*fn)(Object *)) { Word i; for (i=0; i<lockSize; i++) fn(&lockArray[i]); } + +char *luaI_travfallbacks (int (*fn)(Object *)) +{ + Word i; + for (i=0; i<N_FB; i++) + if (fn(&luaI_fallBacks[i].function)) + return luaI_fallBacks[i].kind; + return NULL; +} diff --git a/src/fallback.h b/src/fallback.h index 225a9063..f4be0b6f 100644 --- a/src/fallback.h +++ b/src/fallback.h @@ -1,5 +1,5 @@ /* -** $Id: fallback.h,v 1.7 1994/11/21 18:22:58 roberto Stab $ +** $Id: fallback.h,v 1.10 1995/10/17 11:52:38 roberto Exp $ */ #ifndef fallback_h @@ -10,6 +10,8 @@ extern struct FB { char *kind; Object function; + int nParams; + int nResults; } luaI_fallBacks[]; #define FB_ERROR 0 @@ -25,7 +27,8 @@ extern struct FB { void luaI_setfallback (void); int luaI_lock (Object *object); Object *luaI_getlocked (int ref); -void luaI_travlock (void (*fn)(Object *)); +void luaI_travlock (int (*fn)(Object *)); +char *luaI_travfallbacks (int (*fn)(Object *)); #endif diff --git a/src/func.c b/src/func.c new file mode 100644 index 00000000..2982f661 --- /dev/null +++ b/src/func.c @@ -0,0 +1,79 @@ +#include <stdio.h> + +#include "luadebug.h" +#include "table.h" +#include "mem.h" +#include "func.h" +#include "opcode.h" + +static TFunc *function_root = NULL; + + +/* +** Insert function in list for GC +*/ +void luaI_insertfunction (TFunc *f) +{ + lua_pack(); + f->next = function_root; + function_root = f; + f->marked = 0; +} + + +/* +** Free function +*/ +static void freefunc (TFunc *f) +{ + luaI_free (f->code); + luaI_free (f); +} + +/* +** Garbage collection function. +** This function traverse the function list freeing unindexed functions +*/ +Long luaI_funccollector (void) +{ + TFunc *curr = function_root; + TFunc *prev = NULL; + Long counter = 0; + while (curr) + { + TFunc *next = curr->next; + if (!curr->marked) + { + if (prev == NULL) + function_root = next; + else + prev->next = next; + freefunc (curr); + ++counter; + } + else + { + curr->marked = 0; + prev = curr; + } + curr = next; + } + return counter; +} + + +void lua_funcinfo (lua_Object func, char **filename, int *linedefined) +{ + Object *f = luaI_Address(func); + if (f->tag == LUA_T_MARK || f->tag == LUA_T_FUNCTION) + { + *filename = f->value.tf->fileName; + *linedefined = f->value.tf->lineDefined; + } + else if (f->tag == LUA_T_CMARK || f->tag == LUA_T_CFUNCTION) + { + *filename = "(C)"; + *linedefined = -1; + } +} + diff --git a/src/func.h b/src/func.h new file mode 100644 index 00000000..2723180f --- /dev/null +++ b/src/func.h @@ -0,0 +1,24 @@ +#ifndef func_h +#define func_h + +#include "types.h" +#include "lua.h" + +/* +** Header para funcoes. +*/ +typedef struct TFunc +{ + struct TFunc *next; + char marked; + int size; + Byte *code; + int lineDefined; + char *fileName; +} TFunc; + +Long luaI_funccollector (void); +void luaI_insertfunction (TFunc *f); + + +#endif @@ -3,14 +3,13 @@ ** hash manager for lua */ -char *rcs_hash="$Id: hash.c,v 2.24 1995/02/06 19:34:03 roberto Exp $"; +char *rcs_hash="$Id: hash.c,v 2.26 1995/10/04 14:20:26 roberto Exp $"; #include <string.h> #include "mem.h" #include "opcode.h" #include "hash.h" -#include "inout.h" #include "table.h" #include "lua.h" @@ -54,7 +53,7 @@ static Word hashindex (Hash *t, Object *ref) /* hash function */ switch (tag(ref)) { case LUA_T_NIL: - lua_reportbug ("unexpected type to index table"); + lua_error ("unexpected type to index table"); return -1; /* UNREACHEABLE */ case LUA_T_NUMBER: return (((Word)nvalue(ref))%nhash(t)); @@ -71,7 +70,7 @@ static Word hashindex (Hash *t, Object *ref) /* hash function */ return (Word)h%nhash(t); /* make it a valid index */ } case LUA_T_FUNCTION: - return (((IntPoint)bvalue(ref))%nhash(t)); + return (((IntPoint)ref->value.tf)%nhash(t)); case LUA_T_CFUNCTION: return (((IntPoint)fvalue(ref))%nhash(t)); case LUA_T_ARRAY: @@ -90,7 +89,7 @@ Bool lua_equalObj (Object *t1, Object *t2) case LUA_T_NUMBER: return nvalue(t1) == nvalue(t2); case LUA_T_STRING: return streq(svalue(t1), svalue(t2)); case LUA_T_ARRAY: return avalue(t1) == avalue(t2); - case LUA_T_FUNCTION: return bvalue(t1) == bvalue(t2); + case LUA_T_FUNCTION: return t1->value.tf == t2->value.tf; case LUA_T_CFUNCTION: return fvalue(t1) == fvalue(t2); default: return uvalue(t1) == uvalue(t2); } diff --git a/src/inout.c b/src/inout.c index 7bd7c235..c73030e3 100644 --- a/src/inout.c +++ b/src/inout.c @@ -5,7 +5,7 @@ ** Also provides some predefined lua functions. */ -char *rcs_inout="$Id: inout.c,v 2.16 1994/12/20 21:20:36 roberto Exp $"; +char *rcs_inout="$Id: inout.c,v 2.25 1995/10/25 13:05:51 roberto Exp $"; #include <stdio.h> #include <stdlib.h> @@ -19,27 +19,19 @@ char *rcs_inout="$Id: inout.c,v 2.16 1994/12/20 21:20:36 roberto Exp $"; #include "tree.h" #include "lua.h" -/* Exported variables */ -Word lua_linenumber; -Bool lua_debug; -Word lua_debugline = 0; - -/* Internal variables */ - #ifndef MAXFUNCSTACK #define MAXFUNCSTACK 100 #endif - -typedef struct FuncStackNode { - struct FuncStackNode *next; - char *file; - Word function; - Word line; -} FuncStackNode; - -static FuncStackNode *funcStack = NULL; -static Word nfuncstack=0; + +#define MAXMESSAGE MAXFUNCSTACK*80 + + +/* Exported variables */ +Word lua_linenumber; +Bool lua_debug = 0; +char *lua_parsedfile; + static FILE *fp; static char *st; @@ -66,16 +58,23 @@ static int stringinput (void) */ char *lua_openfile (char *fn) { - lua_linenumber = 1; lua_setinput (fileinput); - fp = fopen (fn, "r"); + if (fn == NULL) + { + fp = stdin; + fn = "(stdin)"; + } + else + fp = fopen (fn, "r"); if (fp == NULL) { - static char buff[32]; - sprintf(buff, "unable to open file %.10s", fn); + static char buff[255]; + sprintf(buff, "unable to open file `%.200s'", fn); return buff; } - return lua_addfile (fn); + lua_linenumber = 1; + lua_parsedfile = lua_constcreate(fn)->ts.str; + return NULL; } /* @@ -83,9 +82,8 @@ char *lua_openfile (char *fn) */ void lua_closefile (void) { - if (fp != NULL) + if (fp != NULL && fp != stdin) { - lua_delfile(); fclose (fp); fp = NULL; } @@ -94,16 +92,12 @@ void lua_closefile (void) /* ** Function to open a string to be input unit */ -char *lua_openstring (char *s) +void lua_openstring (char *s) { - lua_linenumber = 1; lua_setinput (stringinput); st = s; - { - char sn[64]; - sprintf (sn, "String: %10.10s...", s); - return lua_addfile (sn); - } + lua_linenumber = 1; + lua_parsedfile = lua_constcreate("(string)")->ts.str; } /* @@ -111,75 +105,6 @@ char *lua_openstring (char *s) */ void lua_closestring (void) { - lua_delfile(); -} - - -/* -** Called to execute SETFUNCTION opcode, this function pushs a function into -** function stack. -*/ -void lua_pushfunction (char *file, Word function) -{ - FuncStackNode *newNode; - if (nfuncstack++ >= MAXFUNCSTACK) - { - lua_reportbug("function stack overflow"); - } - newNode = new(FuncStackNode); - newNode->function = function; - newNode->file = file; - newNode->line= lua_debugline; - newNode->next = funcStack; - funcStack = newNode; -} - -/* -** Called to execute RESET opcode, this function pops a function from -** function stack. -*/ -void lua_popfunction (void) -{ - FuncStackNode *temp = funcStack; - if (temp == NULL) return; - --nfuncstack; - lua_debugline = temp->line; - funcStack = temp->next; - luaI_free(temp); -} - -/* -** Report bug building a message and sending it to lua_error function. -*/ -void lua_reportbug (char *s) -{ - char msg[MAXFUNCSTACK*80]; - strcpy (msg, s); - if (lua_debugline != 0) - { - if (funcStack) - { - FuncStackNode *func = funcStack; - int line = lua_debugline; - sprintf (strchr(msg,0), "\n\tactive stack:\n"); - do - { - sprintf (strchr(msg,0), - "\t-> function \"%s\" at file \"%s\":%u\n", - lua_constant[func->function]->str, func->file, line); - line = func->line; - func = func->next; - lua_popfunction(); - } while (func); - } - else - { - sprintf (strchr(msg,0), - "\n\tin statement begining at line %u of file \"%s\"", - lua_debugline, lua_filename()); - } - } - lua_error (msg); } @@ -218,7 +143,7 @@ void lua_print (void) { if (lua_isnumber(obj)) printf("%g\n",lua_getnumber(obj)); else if (lua_isstring(obj)) printf("%s\n",lua_getstring(obj)); - else if (lua_isfunction(obj)) printf("function: %p\n",bvalue(luaI_Address(obj))); + else if (lua_isfunction(obj)) printf("function: %p\n",(luaI_Address(obj))->value.tf); else if (lua_iscfunction(obj)) printf("cfunction: %p\n",lua_getcfunction(obj) ); else if (lua_isuserdata(obj)) printf("userdata: %p\n",lua_getuserdata(obj)); @@ -235,9 +160,11 @@ void lua_print (void) void luaI_type (void) { lua_Object o = lua_getparam(1); + int t; if (o == LUA_NOOBJECT) lua_error("no parameter to function 'type'"); - switch (lua_type(o)) + t = lua_type(o); + switch (t) { case LUA_T_NIL : lua_pushliteral("nil"); @@ -252,15 +179,14 @@ void luaI_type (void) lua_pushliteral("table"); break; case LUA_T_FUNCTION : - lua_pushliteral("function"); - break; case LUA_T_CFUNCTION : - lua_pushliteral("cfunction"); + lua_pushliteral("function"); break; default : lua_pushliteral("userdata"); break; } + lua_pushnumber(t); } /* @@ -289,6 +215,6 @@ void luaI_error (void) { char *s = lua_getstring(lua_getparam(1)); if (s == NULL) s = "(no message)"; - lua_reportbug(s); + lua_error(s); } diff --git a/src/inout.h b/src/inout.h index 22093020..da9c1cc2 100644 --- a/src/inout.h +++ b/src/inout.h @@ -1,5 +1,5 @@ /* -** $Id: inout.h,v 1.7 1994/12/20 21:20:36 roberto Exp $ +** $Id: inout.h,v 1.10 1995/10/17 11:58:41 roberto Exp $ */ @@ -8,17 +8,16 @@ #include "types.h" + extern Word lua_linenumber; extern Bool lua_debug; extern Word lua_debugline; +extern char *lua_parsedfile; char *lua_openfile (char *fn); void lua_closefile (void); -char *lua_openstring (char *s); +void lua_openstring (char *s); void lua_closestring (void); -void lua_pushfunction (char *file, Word function); -void lua_popfunction (void); -void lua_reportbug (char *s); void lua_internaldofile (void); void lua_internaldostring (void); @@ -1,12 +1,12 @@ -char *rcs_lex = "$Id: lex.c,v 2.14 1994/12/27 20:50:38 celes Exp $"; +char *rcs_lex = "$Id: lex.c,v 2.21 1995/11/16 20:46:24 roberto Exp $"; #include <ctype.h> -#include <math.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include "mem.h" #include "tree.h" #include "table.h" #include "opcode.h" @@ -14,6 +14,8 @@ char *rcs_lex = "$Id: lex.c,v 2.14 1994/12/27 20:50:38 celes Exp $"; #include "parser.h" #include "ugly.h" +#define MINBUFF 260 + #define lua_strcmp(a,b) (a[0]<b[0]?(-1):(a[0]>b[0]?(1):strcmp(a,b))) #define next() { current = input(); } @@ -21,7 +23,8 @@ char *rcs_lex = "$Id: lex.c,v 2.14 1994/12/27 20:50:38 celes Exp $"; #define save_and_next() { save(current); next(); } static int current; -static char yytext[256]; +static char *yytext = NULL; +static int textsize = 0; static char *yytextLast; static Input input; @@ -30,6 +33,11 @@ void lua_setinput (Input fn) { current = ' '; input = fn; + if (yytext == NULL) + { + textsize = MINBUFF; + yytext = newvector(textsize, char); + } } char *lua_lasttext (void) @@ -85,9 +93,64 @@ static int findReserved (char *name) } +static void growtext (void) +{ + int size = yytextLast - yytext; + textsize *= 2; + yytext = growvector(yytext, textsize, char); + yytextLast = yytext + size; +} + + +static int read_long_string (void) +{ + int cont = 0; + int spaceleft = textsize - (yytextLast - yytext); + while (1) + { + if (spaceleft <= 2) /* may read more than 1 char in one cicle */ + { + growtext(); + spaceleft = textsize - (yytextLast - yytext); + } + switch (current) + { + case EOF: + case 0: + return WRONGTOKEN; + case '[': + save_and_next(); spaceleft--; + if (current == '[') + { + cont++; + save_and_next(); spaceleft--; + } + continue; + case ']': + save_and_next(); spaceleft--; + if (current == ']') + { + if (cont == 0) return STRING; + cont--; + save_and_next(); spaceleft--; + } + continue; + case '\n': + lua_linenumber++; /* goes through */ + default: + save_and_next(); spaceleft--; + } + } +} + + int yylex (void) { float a; + static int linelasttoken = 0; + if (lua_debug) + luaI_codedebugline(linelasttoken); + linelasttoken = lua_linenumber; while (1) { yytextLast = yytext; @@ -99,8 +162,9 @@ 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': next(); continue; @@ -124,10 +188,25 @@ int yylex (void) case '-': save_and_next(); - if (current != '-') return '-'; + if (current != '-') return '-'; /* else goes through */ + case '#': do { next(); } while (current != '\n' && current != 0); continue; + case '[': + save_and_next(); + if (current != '[') return '['; + else + { + save_and_next(); /* pass the second '[' */ + if (read_long_string() == WRONGTOKEN) + return WRONGTOKEN; + save_and_next(); /* pass the second ']' */ + *(yytextLast-2) = 0; /* erases ']]' */ + yylval.vWord = luaI_findconstantbyname(yytext+2); + return STRING; + } + case '=': save_and_next(); if (current != '=') return '='; @@ -152,9 +231,16 @@ int yylex (void) case '\'': { int del = current; + int spaceleft = textsize - (yytextLast - yytext); next(); /* skip the delimiter */ while (current != del) { + if (spaceleft <= 2) /* may read more than 1 char in one cicle */ + { + growtext(); + spaceleft = textsize - (yytextLast - yytext); + } + spaceleft--; switch (current) { case EOF: @@ -177,7 +263,7 @@ int yylex (void) } next(); /* skip the delimiter */ *yytextLast = 0; - yylval.vWord = luaI_findconstant(lua_constcreate(yytext)); + yylval.vWord = luaI_findconstantbyname(yytext); return STRING; } diff --git a/src/yacc/lua.stx b/src/lua.stx index 9c818708..99e96179 100644 --- a/src/yacc/lua.stx +++ b/src/lua.stx @@ -1,6 +1,6 @@ %{ -char *rcs_luastx = "$Id: lua.stx,v 3.17 1995/01/13 22:11:12 roberto Exp $"; +char *rcs_luastx = "$Id: lua.stx,v 3.25 1995/10/26 17:02:50 roberto Exp $"; #include <stdio.h> #include <stdlib.h> @@ -13,6 +13,7 @@ char *rcs_luastx = "$Id: lua.stx,v 3.17 1995/01/13 22:11:12 roberto Exp $"; #include "tree.h" #include "table.h" #include "lua.h" +#include "func.h" /* to avoid warnings generated by yacc */ int yyparse (void); @@ -36,12 +37,14 @@ 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 */ static int nvarbuffer=0; /* number of variables at a list */ -static Word localvar[STACKGAP]; /* store local variable names */ +#define MAXLOCALS 32 +static Word localvar[MAXLOCALS]; /* store local variable names */ static int nlocalvar=0; /* number of local variables */ #define MAXFIELDS FIELDS_PER_FLUSH*2 @@ -51,6 +54,14 @@ static int nfields=0; /* Internal functions */ +static void yyerror (char *s) +{ + static char msg[256]; + sprintf (msg,"%s near \"%s\" at line %d in file `%s'", + s, lua_lasttext (), lua_linenumber, lua_parsedfile); + lua_error (msg); +} + static void code_byte (Byte c) { if (pc>maxcurr-2) /* 1 byte free to code HALT of main code */ @@ -83,10 +94,10 @@ static void code_float (float n) code_byte(code.m.c4); } -static void code_code (Byte *b) +static void code_code (TFunc *tf) { CodeCode code; - code.b = b; + code.tf = tf; code_byte(code.m.c1); code_byte(code.m.c2); code_byte(code.m.c3); @@ -103,10 +114,10 @@ static void code_word_at (Byte *p, Word n) static void push_field (Word name) { - if (nfields < STACKGAP-1) + if (nfields < MAXFIELDS) fields[nfields++] = name; else - lua_error ("too many fields in a constructor"); + lua_error ("too many fields in nested constructors"); } static void flush_record (int n) @@ -135,18 +146,26 @@ static void flush_list (int m, int n) code_byte(n); } -static void add_nlocalvar (int n) +static void add_localvar (Word name) +{ + if (nlocalvar < MAXLOCALS) + localvar[nlocalvar++] = name; + else + lua_error ("too many local variables"); +} + +static void store_localvar (Word name, int n) { - if (MAX_TEMPS+nlocalvar+MAXVAR+n < STACKGAP) - nlocalvar += n; + if (nlocalvar+n < MAXLOCALS) + localvar[nlocalvar+n] = name; else lua_error ("too many local variables"); } -static void incr_nvarbuffer (void) +static void add_varbuffer (Long var) { - if (nvarbuffer < MAXVAR-1) - nvarbuffer++; + if (nvarbuffer < MAXVAR) + varbuffer[nvarbuffer++] = var; else lua_error ("variable buffer overflow"); } @@ -225,26 +244,35 @@ 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; - if (lua_debug) + /* (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 init_func (void) +{ + if (funcCode == NULL) /* first function */ { - code_byte(SETFUNCTION); - code_code((Byte *)luaI_strdup(lua_file[lua_nfile-1])); - code_word(luaI_findconstant(func)); + funcCode = newvector(CODE_BLOCK, Byte); + maxcode = CODE_BLOCK; } + savemain(); /* save main values */ + /* set func values */ + pc=0; basepc=funcCode; maxcurr=maxcode; + nlocalvar = 0; + luaI_codedebugline(lua_linenumber); } static void codereturn (void) { - if (lua_debug) code_byte(RESET); if (nlocalvar == 0) code_byte(RETCODE0); else @@ -254,49 +282,71 @@ 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); } -static void lua_codestore (int i) +static void storesinglevar (Long v) { - if (varbuffer[i] > 0) /* global var */ + if (v > 0) /* global var */ { - code_byte(STOREGLOBAL); - code_word(varbuffer[i]-1); + code_byte(STOREGLOBAL); + code_word(v-1); } - else if (varbuffer[i] < 0) /* local var */ + else if (v < 0) /* local var */ { - int number = (-varbuffer[i]) - 1; - if (number < 10) code_byte(STORELOCAL0 + number); - else - { - code_byte(STORELOCAL); - code_byte(number); - } + int number = (-v) - 1; + if (number < 10) code_byte(STORELOCAL0 + number); + else + { + code_byte(STORELOCAL); + code_byte(number); + } } + else + code_byte(STOREINDEXED0); +} + +static void lua_codestore (int i) +{ + if (varbuffer[i] != 0) /* global or local var */ + storesinglevar(varbuffer[i]); else /* indexed var */ { int j; @@ -332,26 +382,22 @@ static void codeIf (Long thenAdd, Long elseAdd) code_word_at(basepc+thenAdd+1,elseinit-(thenAdd+sizeof(Word)+1)); } -static void yyerror (char *s) -{ - static char msg[256]; - sprintf (msg,"%s near \"%s\" at line %d in file \"%s\"", - s, lua_lasttext (), lua_linenumber, lua_filename()); - lua_error (msg); -} - /* ** Parse LUA code. */ -void lua_parse (Byte **code) +void lua_parse (TFunc *tf) { - initcode = code; + 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 { static void PrintCode (Byte *c, Byte *end); PrintCode(*initcode,*initcode+maincode); } @@ -369,7 +415,7 @@ void lua_parse (Byte **code) char *pChar; Word vWord; Long vLong; - Byte *pByte; + TFunc *pFunc; TreeNode *pNode; } @@ -387,12 +433,17 @@ void lua_parse (Byte **code) %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> ffieldlist1 -%type <vInt> lfieldlist1 -%type <vLong> var, singlevar -%type <pByte> body +%type <vInt> ffieldlist, ffieldlist1, semicolonpart +%type <vInt> lfieldlist, lfieldlist1 +%type <vInt> parlist +%type <vLong> var, singlevar, funcname +%type <pFunc> body %left AND OR %left EQ NE '>' '<' LE GE @@ -407,62 +458,48 @@ void lua_parse (Byte **code) 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); - } - body +globalstat : stat sc + | setdebug + ; + +function : FUNCTION funcname body { - Word func = luaI_findsymbol($2); - s_tag(func) = LUA_T_FUNCTION; - s_bvalue(func) = $4; + code_byte(PUSHFUNCTION); + code_code($3); + storesinglevar($2); } ; -method : FUNCTION NAME ':' NAME - { - init_function($4); - localvar[nlocalvar]=luaI_findsymbolbyname("self"); - add_nlocalvar(1); - } - 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; - } - ; +funcname : var { $$ =$1; init_func(); } + | varexp ':' NAME + { + code_byte(PUSHSTRING); + code_word(luaI_findconstant($3)); + $$ = 0; /* indexed variable */ + init_func(); + add_localvar(luaI_findsymbolbyname("self")); + } + ; body : '(' parlist ')' block END { codereturn(); - $$ = newvector(pc, Byte); - memcpy($$, basepc, pc*sizeof(Byte)); + $$ = new(TFunc); + $$->size = pc; + $$->code = newvector(pc, Byte); + $$->fileName = lua_parsedfile; + $$->lineDefined = $2; + 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 */ } ; @@ -472,11 +509,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 @@ -487,7 +520,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)); @@ -504,16 +537,16 @@ stat1 : IF expr1 THEN PrepJump block PrepJump elsepart END lua_codeadjust (0); } } - | functioncall { code_byte(0); } + | functioncall | LOCAL localdeclist decinit - { add_nlocalvar($2); + { nlocalvar += $2; adjust_mult_assign($2, $3, 0); - } + } ; elsepart : /* empty */ | ELSE block - | ELSEIF cond THEN PrepJump block PrepJump elsepart + | ELSEIF expr1 THEN PrepJump block PrepJump elsepart { codeIf($4, $6); } ; @@ -528,9 +561,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(); } ; @@ -542,46 +575,46 @@ 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; } ; @@ -597,7 +630,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; } @@ -610,7 +648,7 @@ funcvalue : varexp { $$ = 0; } ; funcParams : '(' exprlist ')' - { if ($2<0) { code_byte(1); $$ = -$2; } else $$ = $2; } + { $$ = adjust_functioncall($2, 1); } | table { $$ = 1; } ; @@ -618,45 +656,54 @@ 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; + } } ; -parlist : /* empty */ { lua_codeadjust(0); } - | parlist1 { lua_codeadjust(0); } +parlist : /* empty */ { lua_codeadjust(0); $$ = lua_linenumber; } + | parlist1 { lua_codeadjust(0); $$ = lua_linenumber; } ; parlist1 : NAME { - localvar[nlocalvar]=luaI_findsymbol($1); - add_nlocalvar(1); + add_localvar(luaI_findsymbol($1)); } | parlist1 ',' NAME { - localvar[nlocalvar]=luaI_findsymbol($3); - add_nlocalvar(1); + add_localvar(luaI_findsymbol($3)); } ; -fieldlist : /* empty */ { $$ = 0; } - | lfieldlist1 lastcomma - { $$ = $1; flush_list($1/FIELDS_PER_FLUSH, $1%FIELDS_PER_FLUSH); } +fieldlist : lfieldlist + { flush_list($1/FIELDS_PER_FLUSH, $1%FIELDS_PER_FLUSH); } + semicolonpart + { $$ = $1+$3; } | ffieldlist1 lastcomma { $$ = $1; flush_record($1%FIELDS_PER_FLUSH); } - | lfieldlist1 ';' - { flush_list($1/FIELDS_PER_FLUSH, $1%FIELDS_PER_FLUSH); } - ffieldlist1 lastcomma - { $$ = $1+$4; flush_record($4%FIELDS_PER_FLUSH); } ; +semicolonpart : /* empty */ + { $$ = 0; } + | ';' ffieldlist + { $$ = $2; flush_record($2%FIELDS_PER_FLUSH); } + ; + lastcomma : /* empty */ | ',' ; +ffieldlist : /* empty */ { $$ = 0; } + | ffieldlist1 lastcomma { $$ = $1; } + ; + ffieldlist1 : ffield {$$=1;} | ffieldlist1 ',' ffield { @@ -671,6 +718,10 @@ ffield : NAME '=' expr1 } ; +lfieldlist : /* empty */ { $$ = 0; } + | lfieldlist1 lastcomma { $$ = $1; } + ; + lfieldlist1 : expr1 {$$=1;} | lfieldlist1 ',' expr1 { @@ -683,12 +734,12 @@ lfieldlist1 : expr1 {$$=1;} varlist1 : var { nvarbuffer = 0; - varbuffer[nvarbuffer] = $1; incr_nvarbuffer(); + add_varbuffer($1); $$ = ($1 == 0) ? 1 : 0; } | varlist1 ',' var { - varbuffer[nvarbuffer] = $3; incr_nvarbuffer(); + add_varbuffer($3); $$ = ($3 == 0) ? $1 + 1 : $1; } ; @@ -720,10 +771,10 @@ singlevar : NAME varexp : var { lua_pushvar($1); } ; -localdeclist : NAME {localvar[nlocalvar]=luaI_findsymbol($1); $$ = 1;} +localdeclist : NAME {store_localvar(luaI_findsymbol($1), 0); $$ = 1;} | localdeclist ',' NAME { - localvar[nlocalvar+$1]=luaI_findsymbol($3); + store_localvar(luaI_findsymbol($3), $1); $$ = $1+1; } ; @@ -732,7 +783,8 @@ decinit : /* empty */ { $$ = 0; } | '=' exprlist1 { $$ = $2; } ; -setdebug : DEBUG {lua_debug = $1;} +setdebug : DEBUG { lua_debug = $1; } + ; %% @@ -788,7 +840,7 @@ static void PrintCode (Byte *code, Byte *end) int n = p-code; p++; get_code(c,p); - printf ("%d PUSHFUNCTION %p\n", n, c.b); + printf ("%d PUSHFUNCTION %p\n", n, c.tf); } break; @@ -944,17 +996,6 @@ static void PrintCode (Byte *code, Byte *end) printf ("%d RETCODE %d\n", p-code, *(++p)); p++; break; - case SETFUNCTION: - { - CodeCode c1; - CodeWord c2; - int n = p-code; - p++; - get_code(c1,p); - get_word(c2,p); - printf ("%d SETFUNCTION %s %d\n", n, (char *)c1.b, c2.w); - } - break; case SETLINE: { CodeWord c; @@ -965,7 +1006,6 @@ static void PrintCode (Byte *code, Byte *end) } break; - case RESET: printf ("%d RESET\n", (p++)-code); break; default: printf ("%d Cannot happen: code %d\n", (p++)-code, *(p-1)); break; } } diff --git a/src/opcode.c b/src/opcode.c index 7ce5b2a6..e4089f01 100644 --- a/src/opcode.c +++ b/src/opcode.c @@ -3,14 +3,14 @@ ** TecCGraf - PUC-Rio */ -char *rcs_opcode="$Id: opcode.c,v 3.34 1995/02/06 19:35:09 roberto Exp $"; +char *rcs_opcode="$Id: opcode.c,v 3.50 1995/11/16 20:46:24 roberto Exp $"; #include <setjmp.h> #include <stdlib.h> #include <stdio.h> #include <string.h> -#include <math.h> +#include "luadebug.h" #include "mem.h" #include "opcode.h" #include "hash.h" @@ -23,13 +23,15 @@ char *rcs_opcode="$Id: opcode.c,v 3.34 1995/02/06 19:35:09 roberto Exp $"; #define tostring(o) ((tag(o) != LUA_T_STRING) && (lua_tostring(o) != 0)) -#define STACK_BUFFER (STACKGAP+128) +#define STACK_SIZE 128 typedef int StkId; /* index to stack elements */ -static Long maxstack = 0L; -static Object *stack = NULL; -static Object *top = NULL; +static Object initial_stack; + +static Object *stackLimit = &initial_stack+1; +static Object *stack = &initial_stack; +static Object *top = &initial_stack; /* macros to convert from lua_Object to (Object *) and back */ @@ -38,6 +40,11 @@ static Object *top = NULL; #define Ref(st) ((st)-stack+1) +/* macro to increment stack top. There must be always an empty slot in +* the stack +*/ +#define incr_top if (++top >= stackLimit) growstack() + static StkId CBase = 0; /* when Lua calls C or C calls Lua, points to */ /* the first slot after the last parameter. */ static int CnResults = 0; /* when Lua calls C, has the number of parameters; */ @@ -47,7 +54,7 @@ static jmp_buf *errorJmp = NULL; /* current error recover point */ static StkId lua_execute (Byte *pc, StkId base); -static void do_call (Object *func, StkId base, int nResults, StkId whereRes); +static void do_call (StkId base, int nResults); @@ -57,61 +64,40 @@ Object *luaI_Address (lua_Object o) } -/* -** Error messages -*/ - -static void lua_message (char *s) -{ - lua_pushstring(s); - do_call(&luaI_fallBacks[FB_ERROR].function, (top-stack)-1, 0, (top-stack)-1); -} - -/* -** Reports an error, and jumps up to the available recover label -*/ -void lua_error (char *s) -{ - if (s) lua_message(s); - if (errorJmp) - longjmp(*errorJmp, 1); - else - { - fprintf (stderr, "lua: exit(1). Unable to recover\n"); - exit(1); - } -} - /* ** Init stack */ static void lua_initstack (void) { - maxstack = STACK_BUFFER; + Long maxstack = STACK_SIZE; stack = newvector(maxstack, Object); + stackLimit = stack+maxstack; top = stack; + *(top++) = initial_stack; } /* ** Check stack overflow and, if necessary, realloc vector */ -#define lua_checkstack(n) if ((Long)(n) > maxstack) checkstack(n) +#define lua_checkstack(nt) if ((nt) >= stackLimit) growstack() -static void checkstack (StkId n) +static void growstack (void) { - StkId t; - if (stack == NULL) + if (stack == &initial_stack) lua_initstack(); - if (maxstack >= MAX_INT) - lua_error("stack size overflow"); - t = top-stack; - maxstack *= 2; - if (maxstack >= MAX_INT) - maxstack = MAX_INT; - stack = growvector(stack, maxstack, Object); - top = stack + t; + 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"); + } } @@ -184,15 +170,25 @@ static int lua_tostring (Object *obj) */ static void adjust_top (StkId newtop) { - Object *nt = stack+newtop; + Object *nt; + lua_checkstack(stack+newtop); + nt = stack+newtop; /* warning: previous call may change stack */ while (top < nt) tag(top++) = LUA_T_NIL; top = nt; /* top could be bigger than newtop */ } +#define adjustC(nParams) adjust_top(CBase+nParams) + -static void adjustC (int nParams) +/* +** Open a hole below "nelems" from the top. +*/ +static void open_stack (int nelems) { - adjust_top(CBase+nParams); + int i; + for (i=0; i<nelems; i++) + *(top-i) = *(top-i-1); + incr_top; } @@ -217,50 +213,55 @@ static StkId callC (lua_CFunction func, StkId base) } /* -** Call the fallback for invalid functions (see do_call) +** Call the specified fallback, putting it on the stack below its arguments */ -static void call_funcFB (Object *func, StkId base, int nResults, StkId whereRes) +static void callFB (int fb) { - StkId i; - /* open space for first parameter (func) */ - for (i=top-stack; i>base; i--) - stack[i] = stack[i-1]; - top++; - stack[base] = *func; - do_call(&luaI_fallBacks[FB_FUNCTION].function, base, nResults, whereRes); + int nParams = luaI_fallBacks[fb].nParams; + open_stack(nParams); + *(top-nParams-1) = luaI_fallBacks[fb].function; + do_call((top-stack)-nParams, luaI_fallBacks[fb].nResults); } /* ** Call a function (C or Lua). The parameters must be on the stack, -** between [stack+base,top). When returns, the results are on the stack, -** between [stack+whereRes,top). The number of results is nResults, unless -** nResults=MULT_RET. +** between [stack+base,top). The function to be called is at stack+base-1. +** When returns, the results are on the stack, between [stack+base-1,top). +** The number of results is nResults, unless nResults=MULT_RET. */ -static void do_call (Object *func, StkId base, int nResults, StkId whereRes) +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; firstResult = callC(fvalue(func), base); + } else if (tag(func) == LUA_T_FUNCTION) - firstResult = lua_execute(bvalue(func), base); + { + tag(func) = LUA_T_MARK; + firstResult = lua_execute(func->value.tf->code, base); + } else { /* func is not a function */ - call_funcFB(func, base, nResults, whereRes); + /* 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 */ if (nResults != MULT_RET && top - (stack+firstResult) != nResults) adjust_top(firstResult+nResults); - /* move results to the given position */ - if (firstResult != whereRes) - { - int i; - nResults = top - (stack+firstResult); /* actual number of results */ - for (i=0; i<nResults; i++) - *(stack+whereRes+i) = *(stack+firstResult+i); - top -= firstResult-whereRes; - } + /* move results to base-1 (to erase parameters and function) */ + base--; + nResults = top - (stack+firstResult); /* actual number of results */ + for (i=0; i<nResults; i++) + *(stack+base+i) = *(stack+firstResult+i); + top -= firstResult-base; } @@ -271,12 +272,12 @@ static void do_call (Object *func, StkId base, int nResults, StkId whereRes) static void pushsubscript (void) { if (tag(top-2) != LUA_T_ARRAY) - do_call(&luaI_fallBacks[FB_GETTABLE].function, (top-stack)-2, 1, (top-stack)-2); + callFB(FB_GETTABLE); else { Object *h = lua_hashget(avalue(top-2), top-1); if (h == NULL || tag(h) == LUA_T_NIL) - do_call(&luaI_fallBacks[FB_INDEX].function, (top-stack)-2, 1, (top-stack)-2); + callFB(FB_INDEX); else { --top; @@ -292,7 +293,7 @@ static void pushsubscript (void) static void storesubscript (void) { if (tag(top-3) != LUA_T_ARRAY) - do_call(&luaI_fallBacks[FB_SETTABLE].function, (top-stack)-3, 0, (top-stack)-3); + callFB(FB_SETTABLE); else { Object *h = lua_hashdefine (avalue(top-3), top-2); @@ -305,19 +306,63 @@ static void storesubscript (void) /* ** Traverse all objects on stack */ -void lua_travstack (void (*fn)(Object *)) +void lua_travstack (int (*fn)(Object *)) { Object *o; for (o = top-1; o >= stack; o--) - fn (o); + fn (o); } /* -** Execute a protected call. If function is null compiles the pre-set input. -** Leave nResults on the stack. +** Error messages and debug functions +*/ + +static void lua_message (char *s) +{ + lua_pushstring(s); + callFB(FB_ERROR); +} + +/* +** Reports an error, and jumps up to the available recover label */ -static int do_protectedrun (Object *function, int nResults) +void lua_error (char *s) +{ + if (s) lua_message(s); + if (errorJmp) + longjmp(*errorJmp, 1); + else + { + fprintf (stderr, "lua: exit(1). Unable to recover\n"); + exit(1); + } +} + + +lua_Object lua_stackedfunction (int level) +{ + Object *p = top; + while (--p >= stack) + if (p->tag == LUA_T_MARK || p->tag == LUA_T_CMARK) + if (level-- == 0) + return Ref(p); + return LUA_NOOBJECT; +} + + +int lua_currentline (lua_Object func) +{ + Object *f = Address(func); + return (f+1 < top && (f+1)->tag == LUA_T_LINE) ? (f+1)->value.i : -1; +} + + +/* +** Execute a protected call. Assumes that function is at CBase and +** parameters are on top of it. Leave nResults on the stack. +*/ +static int do_protectedrun (int nResults) { jmp_buf myErrorJmp; int status; @@ -326,13 +371,13 @@ static int do_protectedrun (Object *function, int nResults) errorJmp = &myErrorJmp; if (setjmp(myErrorJmp) == 0) { - do_call(function, CBase, nResults, CBase); + do_call(CBase+1, nResults); CnResults = (top-stack) - CBase; /* number of results */ CBase += CnResults; /* incorporate results on the stack */ status = 0; } else - { + { /* an error occurred: restore CBase and top */ CBase = oldCBase; top = stack+CBase; status = 1; @@ -344,27 +389,30 @@ static int do_protectedrun (Object *function, int nResults) static int do_protectedmain (void) { - Byte *code = NULL; + TFunc tf; int status; - StkId oldCBase = CBase; jmp_buf myErrorJmp; jmp_buf *oldErr = errorJmp; errorJmp = &myErrorJmp; + adjustC(1); /* one slot for the pseudo-function */ + stack[CBase].tag = LUA_T_FUNCTION; + stack[CBase].value.tf = &tf; + tf.lineDefined = 0; + tf.fileName = lua_parsedfile; + tf.code = NULL; if (setjmp(myErrorJmp) == 0) { - Object f; - lua_parse(&code); - tag(&f) = LUA_T_FUNCTION; bvalue(&f) = code; - do_call(&f, CBase, 0, CBase); - status = 0; + lua_parse(&tf); + status = do_protectedrun(0); } else + { status = 1; - if (code) - luaI_free(code); + adjustC(0); /* erase extra slot */ + } errorJmp = oldErr; - CBase = oldCBase; - top = stack+CBase; + if (tf.code) + luaI_free(tf.code); return status; } @@ -377,14 +425,20 @@ int lua_callfunction (lua_Object function) if (function == LUA_NOOBJECT) return 1; else - return do_protectedrun (Address(function), MULT_RET); + { + open_stack((top-stack)-CBase); + stack[CBase] = *Address(function); + return do_protectedrun (MULT_RET); + } } int lua_call (char *funcname) { Word n = luaI_findsymbolbyname(funcname); - return do_protectedrun(&s_object(n), MULT_RET); + open_stack((top-stack)-CBase); + stack[CBase] = s_object(n); + return do_protectedrun(MULT_RET); } @@ -413,12 +467,7 @@ int lua_dofile (char *filename) int lua_dostring (char *string) { int status; - char *message = lua_openstring(string); - if (message) - { - lua_message(message); - return 1; - } + lua_openstring(string); status = do_protectedmain(); lua_closestring(); return status; @@ -430,12 +479,15 @@ int lua_dostring (char *string) */ lua_Object lua_setfallback (char *name, lua_CFunction fallback) { - static Object func = {LUA_T_CFUNCTION, luaI_setfallback}; - adjustC(0); + adjustC(1); /* one slot for the pseudo-function */ + stack[CBase].tag = LUA_T_CFUNCTION; + stack[CBase].value.f = luaI_setfallback; lua_pushstring(name); lua_pushcfunction(fallback); - do_protectedrun(&func, 1); - return (Ref(top-1)); + if (do_protectedrun(1) == 0) + return (Ref(top-1)); + else + return LUA_NOOBJECT; } @@ -497,7 +549,7 @@ lua_Object lua_createtable (void) adjustC(0); avalue(top) = lua_createarray(0); tag(top) = LUA_T_ARRAY; - top++; + incr_top; CBase++; /* incorporate object in the stack */ return Ref(top-1); } @@ -519,9 +571,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))); } /* @@ -529,7 +581,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))); } @@ -559,7 +611,7 @@ lua_Object lua_getlocked (int ref) { adjustC(0); *top = *luaI_getlocked(ref); - top++; + incr_top; CBase++; /* incorporate object in the stack */ return Ref(top-1); } @@ -567,9 +619,8 @@ lua_Object lua_getlocked (int ref) void lua_pushlocked (int ref) { - lua_checkstack(top-stack+1); *top = *luaI_getlocked(ref); - top++; + incr_top; } @@ -580,15 +631,16 @@ int lua_lock (void) } + /* -** Get a global object. Return the object handle or NULL on error. +** Get a global object. */ lua_Object lua_getglobal (char *name) { Word n = luaI_findsymbolbyname(name); adjustC(0); *top = s_object(n); - top++; + incr_top; CBase++; /* incorporate object in the stack */ return Ref(top-1); } @@ -608,8 +660,8 @@ void lua_storeglobal (char *name) */ void lua_pushnil (void) { - lua_checkstack(top-stack+1); - tag(top++) = LUA_T_NIL; + tag(top) = LUA_T_NIL; + incr_top; } /* @@ -617,8 +669,8 @@ void lua_pushnil (void) */ void lua_pushnumber (real n) { - lua_checkstack(top-stack+1); - tag(top) = LUA_T_NUMBER; nvalue(top++) = n; + tag(top) = LUA_T_NUMBER; nvalue(top) = n; + incr_top; } /* @@ -626,10 +678,9 @@ void lua_pushnumber (real n) */ void lua_pushstring (char *s) { - lua_checkstack(top-stack+1); tsvalue(top) = lua_createstring(s); tag(top) = LUA_T_STRING; - top++; + incr_top; } /* @@ -637,10 +688,9 @@ void lua_pushstring (char *s) */ void lua_pushliteral (char *s) { - lua_checkstack(top-stack+1); - tsvalue(top) = lua_constant[luaI_findconstant(lua_constcreate(s))]; + tsvalue(top) = lua_constant[luaI_findconstantbyname(s)]; tag(top) = LUA_T_STRING; - top++; + incr_top; } /* @@ -648,8 +698,8 @@ void lua_pushliteral (char *s) */ void lua_pushcfunction (lua_CFunction fn) { - lua_checkstack(top-stack+1); - tag(top) = LUA_T_CFUNCTION; fvalue(top++) = fn; + tag(top) = LUA_T_CFUNCTION; fvalue(top) = fn; + incr_top; } /* @@ -658,8 +708,8 @@ void lua_pushcfunction (lua_CFunction fn) void lua_pushusertag (void *u, int tag) { if (tag < LUA_T_USERDATA) return; - lua_checkstack(top-stack+1); - tag(top) = tag; uvalue(top++) = u; + tag(top) = tag; uvalue(top) = u; + incr_top; } /* @@ -667,8 +717,8 @@ void lua_pushusertag (void *u, int tag) */ void lua_pushobject (lua_Object o) { - lua_checkstack(top-stack+1); - *top++ = *Address(o); + *top = *Address(o); + incr_top; } /* @@ -676,8 +726,8 @@ void lua_pushobject (lua_Object o) */ void luaI_pushobject (Object *o) { - lua_checkstack(top-stack+1); - *top++ = *o; + *top = *o; + incr_top; } int lua_type (lua_Object o) @@ -691,15 +741,16 @@ int lua_type (lua_Object o) void luaI_gcFB (Object *o) { - *(top++) = *o; - do_call(&luaI_fallBacks[FB_GC].function, (top-stack)-1, 0, (top-stack)-1); + *top = *o; + incr_top; + callFB(FB_GC); } static void call_arith (char *op) { lua_pushstring(op); - do_call(&luaI_fallBacks[FB_ARITH].function, (top-stack)-3, 1, (top-stack)-3); + callFB(FB_ARITH); } static void comparison (lua_Type tag_less, lua_Type tag_equal, @@ -713,7 +764,7 @@ static void comparison (lua_Type tag_less, lua_Type tag_equal, else if (tostring(l) || tostring(r)) { lua_pushstring(op); - do_call(&luaI_fallBacks[FB_ORDER].function, (top-stack)-3, 1, (top-stack)-3); + callFB(FB_ORDER); return; } else @@ -732,26 +783,28 @@ static void comparison (lua_Type tag_less, lua_Type tag_equal, */ static StkId lua_execute (Byte *pc, StkId base) { - lua_checkstack(STACKGAP+MAX_TEMPS+base); while (1) { OpCode opcode; switch (opcode = (OpCode)*pc++) { - case PUSHNIL: tag(top++) = LUA_T_NIL; break; + case PUSHNIL: tag(top) = LUA_T_NIL; incr_top; break; case PUSH0: case PUSH1: case PUSH2: tag(top) = LUA_T_NUMBER; - nvalue(top++) = opcode-PUSH0; + nvalue(top) = opcode-PUSH0; + incr_top; break; - case PUSHBYTE: tag(top) = LUA_T_NUMBER; nvalue(top++) = *pc++; break; + case PUSHBYTE: + tag(top) = LUA_T_NUMBER; nvalue(top) = *pc++; incr_top; break; case PUSHWORD: { CodeWord code; get_word(code,pc); - tag(top) = LUA_T_NUMBER; nvalue(top++) = code.w; + tag(top) = LUA_T_NUMBER; nvalue(top) = code.w; + incr_top; } break; @@ -759,7 +812,8 @@ static StkId lua_execute (Byte *pc, StkId base) { CodeFloat code; get_float(code,pc); - tag(top) = LUA_T_NUMBER; nvalue(top++) = code.f; + tag(top) = LUA_T_NUMBER; nvalue(top) = code.f; + incr_top; } break; @@ -767,7 +821,8 @@ static StkId lua_execute (Byte *pc, StkId base) { CodeWord code; get_word(code,pc); - tag(top) = LUA_T_STRING; tsvalue(top++) = lua_constant[code.w]; + tag(top) = LUA_T_STRING; tsvalue(top) = lua_constant[code.w]; + incr_top; } break; @@ -775,22 +830,27 @@ static StkId lua_execute (Byte *pc, StkId base) { CodeCode code; get_code(code,pc); - tag(top) = LUA_T_FUNCTION; bvalue(top++) = code.b; + luaI_insertfunction(code.tf); /* may take part in GC */ + top->tag = LUA_T_FUNCTION; + top->value.tf = code.tf; + incr_top; } break; case PUSHLOCAL0: case PUSHLOCAL1: case PUSHLOCAL2: case PUSHLOCAL3: case PUSHLOCAL4: case PUSHLOCAL5: case PUSHLOCAL6: case PUSHLOCAL7: case PUSHLOCAL8: - case PUSHLOCAL9: *top++ = *((stack+base) + (int)(opcode-PUSHLOCAL0)); break; + case PUSHLOCAL9: + *top = *((stack+base) + (int)(opcode-PUSHLOCAL0)); incr_top; break; - case PUSHLOCAL: *top++ = *((stack+base) + (*pc++)); break; + case PUSHLOCAL: *top = *((stack+base) + (*pc++)); incr_top; break; case PUSHGLOBAL: { CodeWord code; get_word(code,pc); - *top++ = s_object(code.w); + *top = s_object(code.w); + incr_top; } break; @@ -803,9 +863,11 @@ static StkId lua_execute (Byte *pc, StkId base) Object receiver = *(top-1); CodeWord code; get_word(code,pc); - tag(top) = LUA_T_STRING; tsvalue(top++) = lua_constant[code.w]; + tag(top) = LUA_T_STRING; tsvalue(top) = lua_constant[code.w]; + incr_top; pushsubscript(); - *(top++) = receiver; + *top = receiver; + incr_top; break; } @@ -835,11 +897,12 @@ static StkId lua_execute (Byte *pc, StkId base) int n = *pc++; if (tag(top-3-n) != LUA_T_ARRAY) { + lua_checkstack(top+2); *(top+1) = *(top-1); *(top) = *(top-2-n); *(top-1) = *(top-3-n); top += 2; - do_call(&luaI_fallBacks[FB_SETTABLE].function, (top-stack)-3, 0, (top-stack)-3); + callFB(FB_SETTABLE); } else { @@ -899,7 +962,7 @@ static StkId lua_execute (Byte *pc, StkId base) get_word(size,pc); avalue(top) = lua_createarray(size.w); tag(top) = LUA_T_ARRAY; - top++; + incr_top; } break; @@ -993,7 +1056,7 @@ static StkId lua_execute (Byte *pc, StkId base) Object *l = top-2; Object *r = top-1; if (tostring(r) || tostring(l)) - do_call(&luaI_fallBacks[FB_CONCAT].function, (top-stack)-2, 1, (top-stack)-2); + callFB(FB_CONCAT); else { tsvalue(l) = lua_createstring (lua_strconc(svalue(l),svalue(r))); @@ -1005,7 +1068,8 @@ static StkId lua_execute (Byte *pc, StkId base) case MINUSOP: if (tonumber(top-1)) { - tag(top++) = LUA_T_NIL; + tag(top) = LUA_T_NIL; + incr_top; call_arith("unm"); } else @@ -1073,9 +1137,8 @@ static StkId lua_execute (Byte *pc, StkId base) { int nParams = *(pc++); int nResults = *(pc++); - Object *func = top-1-nParams; /* function is below parameters */ StkId newBase = (top-stack)-nParams; - do_call(func, newBase, nResults, newBase-1); + do_call(newBase, nResults); } break; @@ -1085,27 +1148,20 @@ static StkId lua_execute (Byte *pc, StkId base) case RETCODE: return base+*pc; - case SETFUNCTION: - { - CodeCode file; - CodeWord func; - get_code(file,pc); - get_word(func,pc); - lua_pushfunction ((char *)file.b, func.w); - } - break; - case SETLINE: { 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; - - case RESET: - lua_popfunction (); - break; default: lua_error ("internal error - opcode doesn't match"); diff --git a/src/opcode.h b/src/opcode.h index e3a6d37c..5e33c2cf 100644 --- a/src/opcode.h +++ b/src/opcode.h @@ -1,6 +1,6 @@ /* ** TeCGraf - PUC-Rio -** $Id: opcode.h,v 3.10 1994/12/20 21:20:36 roberto Exp $ +** $Id: opcode.h,v 3.14 1995/10/25 13:05:51 roberto Exp $ */ #ifndef opcode_h @@ -9,10 +9,7 @@ #include "lua.h" #include "types.h" #include "tree.h" - -#ifndef STACKGAP -#define STACKGAP 128 -#endif +#include "func.h" #ifndef real #define real float @@ -20,8 +17,6 @@ #define FIELDS_PER_FLUSH 40 -#define MAX_TEMPS 20 - typedef enum { @@ -73,9 +68,7 @@ typedef enum CALLFUNC, RETCODE0, RETCODE, - SETFUNCTION, - SETLINE, - RESET + SETLINE } OpCode; #define MULT_RET 255 @@ -89,9 +82,10 @@ typedef union Cfunction f; real n; TaggedString *ts; - Byte *b; + TFunc *tf; struct Hash *a; void *u; + int i; } Value; typedef struct Object @@ -110,7 +104,6 @@ typedef struct #define nvalue(o) ((o)->value.n) #define svalue(o) ((o)->value.ts->str) #define tsvalue(o) ((o)->value.ts) -#define bvalue(o) ((o)->value.b) #define avalue(o) ((o)->value.a) #define fvalue(o) ((o)->value.f) #define uvalue(o) ((o)->value.u) @@ -120,7 +113,6 @@ typedef struct #define s_tag(i) (tag(&s_object(i))) #define s_nvalue(i) (nvalue(&s_object(i))) #define s_svalue(i) (svalue(&s_object(i))) -#define s_bvalue(i) (bvalue(&s_object(i))) #define s_avalue(i) (avalue(&s_object(i))) #define s_fvalue(i) (fvalue(&s_object(i))) #define s_uvalue(i) (uvalue(&s_object(i))) @@ -143,7 +135,7 @@ typedef union typedef union { struct {char c1; char c2; char c3; char c4;} m; - Byte *b; + TFunc *tf; } CodeCode; #define get_code(code,pc) {code.m.c1 = *pc++; code.m.c2 = *pc++;\ code.m.c3 = *pc++; code.m.c4 = *pc++;} @@ -155,8 +147,9 @@ char *lua_strdup (char *l); 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 (Byte **code); /* from "lua.stx" module */ -void lua_travstack (void (*fn)(Object *)); +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); void luaI_gcFB (Object *o); diff --git a/src/parser.c b/src/parser.c index 47b77fb0..6b0dba94 100644 --- a/src/parser.c +++ b/src/parser.c @@ -13,7 +13,7 @@ # line 2 "lua.stx" -char *rcs_luastx = "$Id: lua.stx,v 3.17 1995/01/13 22:11:12 roberto Exp $"; +char *rcs_luastx = "$Id: lua.stx,v 3.25 1995/10/26 17:02:50 roberto Exp $"; #include <stdio.h> #include <stdlib.h> @@ -26,6 +26,7 @@ char *rcs_luastx = "$Id: lua.stx,v 3.17 1995/01/13 22:11:12 roberto Exp $"; #include "tree.h" #include "table.h" #include "lua.h" +#include "func.h" /* to avoid warnings generated by yacc */ int yyparse (void); @@ -49,12 +50,14 @@ 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 */ static int nvarbuffer=0; /* number of variables at a list */ -static Word localvar[STACKGAP]; /* store local variable names */ +#define MAXLOCALS 32 +static Word localvar[MAXLOCALS]; /* store local variable names */ static int nlocalvar=0; /* number of local variables */ #define MAXFIELDS FIELDS_PER_FLUSH*2 @@ -64,6 +67,14 @@ static int nfields=0; /* Internal functions */ +static void yyerror (char *s) +{ + static char msg[256]; + sprintf (msg,"%s near \"%s\" at line %d in file `%s'", + s, lua_lasttext (), lua_linenumber, lua_parsedfile); + lua_error (msg); +} + static void code_byte (Byte c) { if (pc>maxcurr-2) /* 1 byte free to code HALT of main code */ @@ -96,10 +107,10 @@ static void code_float (float n) code_byte(code.m.c4); } -static void code_code (Byte *b) +static void code_code (TFunc *tf) { CodeCode code; - code.b = b; + code.tf = tf; code_byte(code.m.c1); code_byte(code.m.c2); code_byte(code.m.c3); @@ -116,10 +127,10 @@ static void code_word_at (Byte *p, Word n) static void push_field (Word name) { - if (nfields < STACKGAP-1) + if (nfields < MAXFIELDS) fields[nfields++] = name; else - lua_error ("too many fields in a constructor"); + lua_error ("too many fields in nested constructors"); } static void flush_record (int n) @@ -148,18 +159,26 @@ static void flush_list (int m, int n) code_byte(n); } -static void add_nlocalvar (int n) +static void add_localvar (Word name) { - if (MAX_TEMPS+nlocalvar+MAXVAR+n < STACKGAP) - nlocalvar += n; + if (nlocalvar < MAXLOCALS) + localvar[nlocalvar++] = name; else lua_error ("too many local variables"); } -static void incr_nvarbuffer (void) +static void store_localvar (Word name, int n) { - if (nvarbuffer < MAXVAR-1) - nvarbuffer++; + if (nlocalvar+n < MAXLOCALS) + localvar[nlocalvar+n] = name; + else + lua_error ("too many local variables"); +} + +static void add_varbuffer (Long var) +{ + if (nvarbuffer < MAXVAR) + varbuffer[nvarbuffer++] = var; else lua_error ("variable buffer overflow"); } @@ -238,26 +257,35 @@ 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; - if (lua_debug) + /* (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 init_func (void) +{ + if (funcCode == NULL) /* first function */ { - code_byte(SETFUNCTION); - code_code((Byte *)luaI_strdup(lua_file[lua_nfile-1])); - code_word(luaI_findconstant(func)); + funcCode = newvector(CODE_BLOCK, Byte); + maxcode = CODE_BLOCK; } + savemain(); /* save main values */ + /* set func values */ + pc=0; basepc=funcCode; maxcurr=maxcode; + nlocalvar = 0; + luaI_codedebugline(lua_linenumber); } static void codereturn (void) { - if (lua_debug) code_byte(RESET); if (nlocalvar == 0) code_byte(RETCODE0); else @@ -267,49 +295,71 @@ 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); } -static void lua_codestore (int i) +static void storesinglevar (Long v) { - if (varbuffer[i] > 0) /* global var */ + if (v > 0) /* global var */ { - code_byte(STOREGLOBAL); - code_word(varbuffer[i]-1); + code_byte(STOREGLOBAL); + code_word(v-1); } - else if (varbuffer[i] < 0) /* local var */ + else if (v < 0) /* local var */ { - int number = (-varbuffer[i]) - 1; - if (number < 10) code_byte(STORELOCAL0 + number); - else - { - code_byte(STORELOCAL); - code_byte(number); - } + int number = (-v) - 1; + if (number < 10) code_byte(STORELOCAL0 + number); + else + { + code_byte(STORELOCAL); + code_byte(number); + } } + else + code_byte(STOREINDEXED0); +} + +static void lua_codestore (int i) +{ + if (varbuffer[i] != 0) /* global or local var */ + storesinglevar(varbuffer[i]); else /* indexed var */ { int j; @@ -345,26 +395,22 @@ static void codeIf (Long thenAdd, Long elseAdd) code_word_at(basepc+thenAdd+1,elseinit-(thenAdd+sizeof(Word)+1)); } -static void yyerror (char *s) -{ - static char msg[256]; - sprintf (msg,"%s near \"%s\" at line %d in file \"%s\"", - s, lua_lasttext (), lua_linenumber, lua_filename()); - lua_error (msg); -} - /* ** Parse LUA code. */ -void lua_parse (Byte **code) +void lua_parse (TFunc *tf) { - initcode = code; + 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 { static void PrintCode (Byte *c, Byte *end); PrintCode(*initcode,*initcode+maincode); } @@ -373,7 +419,7 @@ void lua_parse (Byte **code) -# line 365 "lua.stx" +# line 411 "lua.stx" typedef union { int vInt; @@ -381,7 +427,7 @@ typedef union char *pChar; Word vWord; Long vLong; - Byte *pByte; + TFunc *pFunc; TreeNode *pNode; } YYSTYPE; # define WRONGTOKEN 257 @@ -421,7 +467,7 @@ extern int yyerrflag; YYSTYPE yylval, yyval; # define YYERRCODE 256 -# line 737 "lua.stx" +# line 789 "lua.stx" #if LISTING @@ -476,7 +522,7 @@ static void PrintCode (Byte *code, Byte *end) int n = p-code; p++; get_code(c,p); - printf ("%d PUSHFUNCTION %p\n", n, c.b); + printf ("%d PUSHFUNCTION %p\n", n, c.tf); } break; @@ -632,17 +678,6 @@ static void PrintCode (Byte *code, Byte *end) printf ("%d RETCODE %d\n", p-code, *(++p)); p++; break; - case SETFUNCTION: - { - CodeCode c1; - CodeWord c2; - int n = p-code; - p++; - get_code(c1,p); - get_word(c2,p); - printf ("%d SETFUNCTION %s %d\n", n, (char *)c1.b, c2.w); - } - break; case SETLINE: { CodeWord c; @@ -653,7 +688,6 @@ static void PrintCode (Byte *code, Byte *end) } break; - case RESET: printf ("%d RESET\n", (p++)-code); break; default: printf ("%d Cannot happen: code %d\n", (p++)-code, *(p-1)); break; } } @@ -663,203 +697,194 @@ static void PrintCode (Byte *code, Byte *end) int yyexca[] ={ -1, 1, 0, -1, - -2, 2, --1, 20, - 61, 91, - 44, 91, - -2, 97, --1, 32, - 40, 66, - 123, 66, - -2, 53, --1, 47, - 123, 63, - -2, 70, --1, 74, - 125, 79, + -2, 0, +-1, 14, + 61, 88, + 44, 88, + -2, 94, +-1, 22, + 40, 7, + -2, 94, +-1, 29, + 40, 59, + 123, 59, + -2, 46, +-1, 44, + 123, 56, -2, 63, --1, 79, - 275, 37, - 276, 37, - 277, 37, - 278, 37, - 62, 37, - 60, 37, - 279, 37, - 280, 37, - 281, 37, - 43, 37, - 45, 37, - 42, 37, - 47, 37, - 94, 37, - -2, 72, --1, 80, - 91, 97, - 46, 97, - -2, 92, --1, 118, - 261, 33, - 262, 33, - 266, 33, - 267, 33, - -2, 16, --1, 133, - 125, 85, +-1, 71, + 123, 56, + -2, 84, +-1, 76, + 275, 30, + 276, 30, + 277, 30, + 278, 30, + 62, 30, + 60, 30, + 279, 30, + 280, 30, + 281, 30, + 43, 30, + 45, 30, + 42, 30, + 47, 30, + 94, 30, + -2, 65, +-1, 77, + 91, 94, + 46, 94, + -2, 89, +-1, 132, + 123, 56, + -2, 78, +-1, 138, + 123, 56, -2, 63, --1, 158, - 123, 63, - -2, 70, --1, 159, - 275, 37, - 276, 37, - 277, 37, - 278, 37, - 62, 37, - 60, 37, - 279, 37, - 280, 37, - 281, 37, - 43, 37, - 45, 37, - 42, 37, - 47, 37, - 94, 37, - -2, 74, +-1, 155, + 275, 30, + 276, 30, + 277, 30, + 278, 30, + 62, 30, + 60, 30, + 279, 30, + 280, 30, + 281, 30, + 43, 30, + 45, 30, + 42, 30, + 47, 30, + 94, 30, + -2, 67, }; -# define YYNPROD 103 -# define YYLAST 351 +# define YYNPROD 100 +# define YYLAST 311 int yyact[]={ - 64, 62, 6, 63, 152, 65, 7, 64, 62, 145, - 63, 120, 65, 92, 64, 62, 89, 63, 57, 65, - 58, 64, 62, 87, 63, 57, 65, 58, 64, 62, - 24, 63, 57, 65, 58, 64, 62, 54, 63, 57, - 65, 58, 45, 10, 29, 142, 57, 171, 58, 30, - 29, 123, 66, 167, 14, 30, 160, 117, 15, 66, - 16, 162, 163, 173, 19, 131, 66, 138, 24, 28, - 112, 114, 130, 66, 74, 71, 8, 64, 66, 52, - 66, 86, 65, 51, 161, 83, 51, 66, 43, 136, - 27, 12, 64, 62, 26, 63, 133, 65, 49, 70, - 135, 119, 84, 125, 124, 42, 72, 122, 109, 32, - 53, 132, 79, 73, 85, 39, 75, 79, 47, 23, - 149, 91, 143, 31, 78, 20, 88, 38, 50, 66, - 11, 50, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 66, 48, 36, 129, 128, 158, - 113, 141, 94, 81, 79, 77, 18, 41, 40, 80, - 139, 13, 9, 118, 90, 93, 121, 25, 5, 4, - 3, 2, 22, 126, 111, 76, 82, 44, 134, 110, - 21, 46, 17, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 140, 0, 0, 0, 0, - 0, 0, 0, 0, 147, 148, 0, 151, 0, 150, - 0, 0, 153, 159, 0, 156, 0, 0, 0, 0, - 164, 107, 108, 0, 0, 0, 0, 0, 79, 116, - 170, 169, 55, 68, 69, 56, 59, 60, 61, 67, - 68, 69, 56, 59, 60, 61, 67, 68, 69, 56, - 59, 60, 61, 67, 68, 69, 56, 59, 60, 61, - 67, 177, 35, 56, 59, 60, 61, 67, 35, 137, - 127, 157, 0, 166, 67, 33, 34, 24, 0, 0, - 146, 33, 34, 115, 0, 0, 0, 37, 0, 0, - 0, 155, 0, 37, 0, 0, 0, 172, 0, 0, - 144, 0, 0, 0, 0, 0, 0, 165, 0, 0, - 0, 0, 0, 154, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 174, 0, 176, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 168, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 175 }; + 61, 59, 148, 60, 141, 62, 118, 61, 59, 90, + 60, 89, 62, 86, 84, 18, 42, 168, 54, 164, + 55, 61, 59, 156, 60, 54, 62, 55, 61, 59, + 115, 60, 73, 62, 157, 61, 59, 19, 60, 54, + 62, 55, 61, 59, 82, 60, 54, 62, 55, 158, + 159, 129, 63, 54, 91, 55, 111, 25, 121, 63, + 54, 109, 55, 127, 26, 61, 59, 26, 60, 27, + 62, 7, 27, 63, 71, 8, 33, 9, 11, 63, + 63, 12, 6, 80, 67, 18, 13, 63, 68, 7, + 48, 40, 4, 8, 63, 9, 24, 76, 138, 12, + 81, 133, 76, 18, 61, 59, 61, 60, 39, 62, + 20, 62, 146, 130, 117, 132, 69, 63, 123, 48, + 104, 105, 122, 70, 124, 120, 72, 106, 48, 50, + 29, 46, 17, 44, 128, 47, 85, 23, 83, 76, + 51, 28, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 88, 140, 63, 45, 63, 36, + 112, 14, 131, 139, 47, 35, 22, 151, 126, 134, + 125, 78, 137, 47, 153, 74, 38, 37, 75, 142, + 116, 5, 3, 154, 2, 49, 21, 147, 16, 87, + 152, 165, 163, 11, 110, 108, 76, 155, 145, 160, + 77, 79, 41, 171, 135, 107, 162, 173, 161, 136, + 15, 43, 10, 167, 143, 144, 1, 0, 169, 0, + 119, 149, 150, 0, 170, 0, 172, 0, 0, 0, + 0, 0, 0, 65, 66, 53, 56, 57, 58, 64, + 65, 66, 53, 56, 57, 58, 64, 17, 166, 0, + 114, 0, 0, 52, 65, 66, 53, 56, 57, 58, + 64, 65, 66, 53, 56, 57, 58, 64, 65, 66, + 53, 56, 57, 58, 64, 0, 14, 53, 56, 57, + 58, 64, 32, 0, 0, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 30, 31, 18, 30, 31, + 113, 0, 0, 0, 64, 0, 0, 34, 0, 0, + 34 }; int yypact[]={ - -1000, -268, -1000, -1000, -1000, -1000, -230, -1000, 32, -205, - 36, -1000, -1000, -1000, 4, -1000, -1000, 44, -1000, -231, - -1000, 78, -1000, 40, -1000, 70, -236, -28, -1000, 4, - 4, -1000, 40, -1000, -1000, -1000, -1000, 4, -49, -1000, - 4, -1000, 4, -243, 41, -1000, -1000, 4, -1000, -250, - 4, -257, -1000, -260, -1000, -1000, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, -1000, -1000, - 67, -21, -16, -16, 10, -35, -209, -1000, 57, -1000, - -1000, 37, -1000, -262, 4, 66, 57, -1000, -42, -1000, - 63, 59, -1000, 70, -1000, -7, -7, -7, -7, -7, - -7, 35, 35, -16, -16, -16, 50, -1000, -1000, -1000, - -53, 52, 56, -21, -1000, 28, -1000, -1000, -223, -1000, - -1000, 57, -1000, -1000, -1000, -264, -1000, -1000, 4, 4, - -1000, -1000, -1000, 4, -1000, -269, 4, -1000, -1000, 4, - 32, -1000, -1000, 4, -211, -1000, -200, -14, -14, -269, - -21, -1000, 28, -21, -1000, -1000, -21, -1000, 4, -1000, - -1000, -214, -1000, -1000, 56, -220, 32, -1000, -1000, -197, - -1000, -1000, -1000, -1000, -1000, -1000, -200, -1000 }; + -1000, -188, -1000, -1000, 51, -1000, -258, 24, -1000, -1000, + 47, -1000, -257, -1000, -1000, 93, -1000, 73, -1000, -1000, + -1000, 89, -1000, 82, -7, -1000, 24, 24, -1000, 73, + -1000, -1000, -1000, -1000, 24, -49, -1000, 24, -1000, 24, + -258, 39, -1000, -1000, 24, -1000, -259, 24, -260, -1000, + -262, -264, -1000, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, -1000, -1000, 86, -21, -15, + -15, 27, -14, -236, -1000, 70, -1000, -1000, 44, -1000, + -267, 24, 84, 70, -1000, -35, -1000, 81, 74, -1000, + -1000, -1000, 23, 23, 23, 23, 23, 23, 64, 64, + -15, -15, -15, 62, -1000, -1000, -1000, -62, -1000, 69, + 71, -1000, -21, 40, -1000, 24, -170, -1000, -1000, 70, + -1000, -1000, -1000, -269, -1000, 24, 24, -1000, 53, -1000, + -271, -1000, 24, 24, -1000, -21, 51, -1000, 24, 24, + -244, -1000, -212, 0, 0, -1000, -271, -1000, 40, -21, + -21, -1000, -1000, -1000, 51, -1000, -1000, -248, -1000, 24, + -1000, 69, -250, -1000, -1000, -1000, -42, -1000, -1000, -1000, + -1000, -1000, -212, -1000 }; int yypgo[]={ - 0, 183, 152, 69, 114, 81, 182, 181, 180, 179, - 177, 176, 70, 174, 115, 172, 79, 171, 76, 130, - 170, 169, 168, 167, 165, 164, 175, 163, 162, 161, - 67, 160, 75, 84, 158, 157, 146, 155, 151, 149, - 123, 109, 148, 147, 127, 122, 121, 65, 120, 71 }; + 0, 216, 54, 44, 138, 76, 57, 212, 211, 210, + 205, 202, 201, 199, 61, 198, 195, 194, 189, 159, + 188, 186, 185, 184, 182, 92, 37, 181, 130, 32, + 180, 88, 34, 177, 176, 175, 172, 141, 170, 168, + 165, 163, 154, 134, 51, 56 }; int yyr1[]={ - 0, 1, 17, 1, 1, 1, 1, 23, 20, 24, - 21, 16, 27, 27, 19, 19, 28, 18, 31, 30, - 29, 34, 29, 35, 29, 29, 29, 29, 33, 33, - 33, 37, 26, 38, 39, 38, 2, 32, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 42, - 3, 43, 3, 44, 40, 36, 8, 8, 7, 7, - 4, 4, 5, 45, 5, 25, 25, 46, 46, 9, - 9, 9, 48, 9, 47, 47, 12, 12, 49, 13, - 13, 6, 6, 14, 14, 14, 15, 41, 10, 10, - 11, 11, 22 }; + 0, 1, 1, 1, 23, 23, 24, 21, 21, 22, + 30, 30, 26, 26, 25, 33, 25, 34, 25, 25, + 25, 25, 32, 32, 32, 35, 29, 36, 36, 2, + 31, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 38, 6, 39, 6, 40, 37, 5, 9, + 9, 8, 8, 3, 3, 4, 41, 4, 18, 18, + 42, 42, 43, 10, 10, 15, 15, 44, 44, 13, + 13, 14, 14, 45, 16, 16, 17, 17, 7, 7, + 19, 19, 19, 20, 28, 11, 11, 12, 12, 27 }; int yyr2[]={ - 0, 0, 1, 9, 4, 4, 4, 1, 9, 1, - 13, 11, 0, 6, 0, 2, 1, 4, 1, 4, - 17, 1, 17, 1, 13, 7, 3, 7, 0, 4, - 15, 1, 7, 0, 1, 9, 1, 3, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 5, 3, 3, 3, 3, 3, 3, 5, 1, - 11, 1, 11, 1, 9, 5, 3, 7, 7, 3, - 1, 3, 3, 1, 9, 1, 3, 3, 7, 1, - 5, 5, 1, 11, 0, 2, 3, 7, 7, 3, - 7, 3, 7, 3, 9, 7, 3, 3, 3, 7, - 1, 5, 3 }; + 0, 0, 4, 4, 4, 2, 7, 3, 7, 11, + 0, 6, 0, 2, 17, 1, 17, 1, 13, 7, + 2, 7, 0, 4, 15, 1, 7, 0, 7, 1, + 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 5, 3, 3, 3, 3, 3, + 3, 5, 1, 11, 1, 11, 1, 9, 5, 3, + 7, 7, 3, 1, 3, 3, 1, 9, 1, 3, + 3, 7, 1, 7, 5, 1, 5, 0, 2, 1, + 5, 3, 7, 7, 1, 5, 3, 7, 3, 7, + 3, 9, 7, 3, 3, 3, 7, 1, 5, 3 }; int yychk[]={ - -1000, -1, -17, -20, -21, -22, 270, 274, -18, -28, - 273, -19, 59, -29, 259, 263, 265, -6, -36, 269, - -14, -8, -15, -41, 273, -23, 58, -32, -3, 40, - 45, -40, -41, 271, 272, 258, -36, 283, -44, -14, - -34, -35, 61, 44, -10, 273, -7, 40, -40, 58, - 91, 46, -16, 40, 273, 260, 277, 60, 62, 278, - 279, 280, 43, 45, 42, 47, 94, 281, 275, 276, - -3, -32, -32, -32, 123, -32, -26, -37, -5, -3, - -14, -41, -11, 44, 61, -4, -5, 273, -32, 273, - -25, -46, 273, -24, -2, -32, -32, -32, -32, -32, - -32, -32, -32, -32, -32, -32, -32, -2, -2, 41, - -9, -13, -12, -32, -49, 273, 264, 266, -27, 44, - 273, -5, 41, 93, 41, 44, -16, -26, -42, -43, - 125, -47, 59, 44, -47, 44, 61, -2, -30, -31, - -18, -38, 268, -45, -26, 273, -2, -32, -32, -48, - -32, -49, 273, -32, -26, -2, -32, -19, -39, -3, - 267, -33, 261, 262, -12, -2, -4, 267, -26, -30, - -47, 267, -19, 260, -2, -26, -2, -33 }; + -1000, -1, -23, -24, -25, -27, 270, 259, 263, 265, + -7, -5, 269, 274, -19, -9, -20, -28, 273, -26, + 59, -21, -19, -28, -31, -6, 40, 45, -37, -28, + 271, 272, 258, -5, 283, -40, -19, -33, -34, 61, + 44, -11, 273, -8, 40, -37, 58, 91, 46, -22, + 40, 58, 260, 277, 60, 62, 278, 279, 280, 43, + 45, 42, 47, 94, 281, 275, 276, -6, -31, -31, + -31, 123, -31, -29, -35, -4, -6, -19, -28, -12, + 44, 61, -3, -4, 273, -31, 273, -18, -42, 273, + 273, -2, -31, -31, -31, -31, -31, -31, -31, -31, + -31, -31, -31, -31, -2, -2, 41, -10, -16, -14, + -17, -45, -31, 273, 264, 266, -30, 44, 273, -4, + 41, 93, 41, 44, -29, -38, -39, 125, -43, -44, + 44, -44, 44, 61, -2, -31, -25, -36, 268, -41, + -29, 273, -2, -31, -31, -15, 59, -45, 273, -31, + -31, -29, -2, -26, -3, -6, 267, -32, 261, 262, + -13, -14, -2, -26, 267, -29, -31, -44, 267, 260, + -2, -29, -2, -32 }; int yydef[]={ - 1, -2, 16, 4, 5, 6, 0, 102, 14, 0, - 7, 3, 15, 17, 63, 21, 23, 0, 26, 0, - -2, 63, 93, 66, 96, 0, 0, 0, 37, 63, - 63, 52, -2, 54, 55, 56, 57, 63, 0, 97, - 63, 31, 63, 0, 100, 98, 65, -2, 69, 0, - 63, 0, 8, 75, 9, 36, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, 36, 36, - 37, 0, 51, 58, -2, 0, 0, 12, 25, -2, - -2, 0, 27, 0, 63, 0, 71, 67, 0, 95, - 0, 76, 77, 0, 31, 39, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 59, 61, 38, - 0, 84, 84, 89, 86, 96, 36, 18, -2, 73, - 99, 101, 68, 94, 31, 0, 10, 36, 63, 63, - 64, 80, 82, -2, 81, 85, 63, 31, 36, 63, - 14, 32, 34, 63, 0, 78, 28, 60, 62, 0, - 90, 87, 0, 88, 36, 24, 19, 13, -2, -2, - 11, 0, 31, 18, 84, 0, 14, 20, 29, 0, - 83, 22, 35, 36, 31, 36, 28, 30 }; + 1, -2, 2, 3, 12, 5, 0, 56, 15, 17, + 0, 20, 0, 99, -2, 56, 90, 59, 93, 4, + 13, 0, -2, 0, 0, 30, 56, 56, 45, -2, + 47, 48, 49, 50, 56, 0, 94, 56, 25, 56, + 0, 97, 95, 58, -2, 62, 0, 56, 0, 6, + 68, 0, 29, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 29, 29, 30, 0, 44, + 51, -2, 0, 0, 10, 19, -2, -2, 0, 21, + 0, 56, 0, 64, 60, 0, 92, 0, 69, 70, + 8, 25, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 52, 54, 31, 0, 72, 77, + 77, 81, 86, 93, 29, 56, 27, 66, 96, 98, + 61, 91, 25, 0, 29, 56, 56, 57, 75, 74, + 78, 85, -2, 56, 25, 29, 12, 26, -2, 56, + 0, 71, 22, 53, 55, 73, 79, 82, 0, 87, + 83, 29, 18, 11, 12, -2, 9, 0, 25, 56, + 76, 77, 0, 28, 14, 23, 0, 80, 16, 29, + 25, 29, 22, 24 }; typedef struct { char *t_name; int t_val; } yytoktype; #ifndef YYDEBUG # define YYDEBUG 0 /* don't allow debugging */ @@ -910,39 +935,32 @@ char * yyreds[] = { "-no such reduction-", "functionlist : /* empty */", - "functionlist : functionlist", - "functionlist : functionlist stat sc", + "functionlist : functionlist globalstat", "functionlist : functionlist function", - "functionlist : functionlist method", - "functionlist : functionlist setdebug", - "function : FUNCTION NAME", - "function : FUNCTION NAME body", - "method : FUNCTION NAME ':' NAME", - "method : FUNCTION NAME ':' NAME body", + "globalstat : stat sc", + "globalstat : setdebug", + "function : FUNCTION funcname body", + "funcname : var", + "funcname : varexp ':' NAME", "body : '(' parlist ')' block END", "statlist : /* empty */", "statlist : statlist stat sc", "sc : /* empty */", "sc : ';'", - "stat : /* empty */", - "stat : stat1", - "cond : /* empty */", - "cond : expr1", - "stat1 : IF expr1 THEN PrepJump block PrepJump elsepart END", - "stat1 : WHILE", - "stat1 : WHILE expr1 DO PrepJump block PrepJump END", - "stat1 : REPEAT", - "stat1 : REPEAT block UNTIL cond PrepJump", - "stat1 : varlist1 '=' exprlist1", - "stat1 : functioncall", - "stat1 : LOCAL localdeclist decinit", + "stat : IF expr1 THEN PrepJump block PrepJump elsepart END", + "stat : WHILE", + "stat : WHILE expr1 DO PrepJump block PrepJump END", + "stat : REPEAT", + "stat : REPEAT block UNTIL expr1 PrepJump", + "stat : varlist1 '=' exprlist1", + "stat : functioncall", + "stat : LOCAL localdeclist decinit", "elsepart : /* empty */", "elsepart : ELSE block", - "elsepart : ELSEIF cond THEN PrepJump block PrepJump elsepart", + "elsepart : ELSEIF expr1 THEN PrepJump block PrepJump elsepart", "block : /* empty */", "block : statlist ret", "ret : /* empty */", - "ret : RETURN", "ret : RETURN exprlist sc", "PrepJump : /* empty */", "expr1 : expr", @@ -987,16 +1005,20 @@ char * yyreds[] = "parlist : parlist1", "parlist1 : NAME", "parlist1 : parlist1 ',' NAME", - "fieldlist : /* empty */", - "fieldlist : lfieldlist1 lastcomma", + "fieldlist : lfieldlist", + "fieldlist : lfieldlist semicolonpart", "fieldlist : ffieldlist1 lastcomma", - "fieldlist : lfieldlist1 ';'", - "fieldlist : lfieldlist1 ';' ffieldlist1 lastcomma", + "semicolonpart : /* empty */", + "semicolonpart : ';' ffieldlist", "lastcomma : /* empty */", "lastcomma : ','", + "ffieldlist : /* empty */", + "ffieldlist : ffieldlist1 lastcomma", "ffieldlist1 : ffield", "ffieldlist1 : ffieldlist1 ',' ffield", "ffield : NAME '=' expr1", + "lfieldlist : /* empty */", + "lfieldlist : lfieldlist1 lastcomma", "lfieldlist1 : expr1", "lfieldlist1 : lfieldlist1 ',' expr1", "varlist1 : var", @@ -1507,118 +1529,90 @@ $vars */ switch( yytmp ) { -case 2: -# line 411 "lua.stx" -{ - pc=maincode; basepc=*initcode; maxcurr=maxmain; - nlocalvar=0; - } break; -case 3: -# line 416 "lua.stx" -{ - maincode=pc; *initcode=basepc; maxmain=maxcurr; - } break; -case 7: -# line 425 "lua.stx" -{ - init_function(yypvt[-0].pNode); - } break; -case 8: -# line 429 "lua.stx" +case 6: +# line 470 "lua.stx" { - Word func = luaI_findsymbol(yypvt[-2].pNode); - s_tag(func) = LUA_T_FUNCTION; - s_bvalue(func) = yypvt[-0].pByte; + code_byte(PUSHFUNCTION); + code_code(yypvt[-0].pFunc); + storesinglevar(yypvt[-1].vLong); } break; -case 9: -# line 437 "lua.stx" -{ - init_function(yypvt[-0].pNode); - localvar[nlocalvar]=luaI_findsymbolbyname("self"); - add_nlocalvar(1); - } break; -case 10: -# line 443 "lua.stx" +case 7: +# line 477 "lua.stx" +{ yyval.vLong =yypvt[-0].vLong; init_func(); } break; +case 8: +# line 479 "lua.stx" { - /* assign function to table field */ - pc=maincode; basepc=*initcode; maxcurr=maxmain; - nlocalvar=0; - lua_pushvar(luaI_findsymbol(yypvt[-4].pNode)+1); - code_byte(PUSHSTRING); - code_word(luaI_findconstant(yypvt[-2].pNode)); - code_byte(PUSHFUNCTION); - code_code(yypvt[-0].pByte); - code_byte(STOREINDEXED0); - maincode=pc; *initcode=basepc; maxmain=maxcurr; - } break; -case 11: -# line 458 "lua.stx" + code_byte(PUSHSTRING); + code_word(luaI_findconstant(yypvt[-0].pNode)); + yyval.vLong = 0; /* indexed variable */ + init_func(); + add_localvar(luaI_findsymbolbyname("self")); + } break; +case 9: +# line 489 "lua.stx" { codereturn(); - yyval.pByte = newvector(pc, Byte); - memcpy(yyval.pByte, basepc, pc*sizeof(Byte)); + yyval.pFunc = new(TFunc); + yyval.pFunc->size = pc; + yyval.pFunc->code = newvector(pc, Byte); + yyval.pFunc->fileName = lua_parsedfile; + yyval.pFunc->lineDefined = yypvt[-3].vInt; + memcpy(yyval.pFunc->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 */ } break; -case 16: -# line 475 "lua.stx" -{ codedebugline(); } break; -case 18: -# line 477 "lua.stx" -{ codedebugline(); } break; -case 20: -# line 480 "lua.stx" +case 14: +# line 513 "lua.stx" { codeIf(yypvt[-4].vLong, yypvt[-2].vLong); } break; -case 21: -# line 482 "lua.stx" +case 15: +# line 515 "lua.stx" {yyval.vLong=pc;} break; -case 22: -# line 483 "lua.stx" +case 16: +# line 516 "lua.stx" { basepc[yypvt[-3].vLong] = IFFJMP; code_word_at(basepc+yypvt[-3].vLong+1, pc - (yypvt[-3].vLong + sizeof(Word)+1)); basepc[yypvt[-1].vLong] = UPJMP; code_word_at(basepc+yypvt[-1].vLong+1, pc - (yypvt[-6].vLong)); } break; -case 23: -# line 490 "lua.stx" +case 17: +# line 523 "lua.stx" {yyval.vLong=pc;} break; -case 24: -# line 491 "lua.stx" +case 18: +# line 524 "lua.stx" { basepc[yypvt[-0].vLong] = IFFUPJMP; code_word_at(basepc+yypvt[-0].vLong+1, pc - (yypvt[-4].vLong)); } break; -case 25: -# line 497 "lua.stx" +case 19: +# line 530 "lua.stx" { { int i; - adjust_mult_assign(nvarbuffer, yypvt[-0].vInt, yypvt[-2].vInt * 2 + nvarbuffer); + adjust_mult_assign(nvarbuffer, yypvt[-0].vLong, yypvt[-2].vInt * 2 + nvarbuffer); for (i=nvarbuffer-1; i>=0; i--) lua_codestore (i); if (yypvt[-2].vInt > 1 || (yypvt[-2].vInt == 1 && varbuffer[0] != 0)) lua_codeadjust (0); } } break; -case 26: -# line 507 "lua.stx" -{ code_byte(0); } break; -case 27: -# line 509 "lua.stx" -{ add_nlocalvar(yypvt[-1].vInt); +case 21: +# line 542 "lua.stx" +{ nlocalvar += yypvt[-1].vInt; adjust_mult_assign(yypvt[-1].vInt, yypvt[-0].vInt, 0); - } break; -case 30: -# line 517 "lua.stx" + } break; +case 24: +# line 550 "lua.stx" { codeIf(yypvt[-3].vLong, yypvt[-1].vLong); } break; -case 31: -# line 520 "lua.stx" +case 25: +# line 553 "lua.stx" {yyval.vInt = nlocalvar;} break; -case 32: -# line 521 "lua.stx" +case 26: +# line 554 "lua.stx" { if (nlocalvar != yypvt[-2].vInt) { @@ -1626,247 +1620,263 @@ case 32: lua_codeadjust (0); } } break; -case 34: -# line 531 "lua.stx" -{ codedebugline(); } break; -case 35: -# line 532 "lua.stx" +case 28: +# line 565 "lua.stx" { - if (yypvt[-1].vInt < 0) code_byte(MULT_RET); + adjust_functioncall(yypvt[-1].vLong, MULT_RET); codereturn(); } break; -case 36: -# line 539 "lua.stx" +case 29: +# line 572 "lua.stx" { yyval.vLong = pc; code_byte(0); /* open space */ code_word (0); } break; +case 30: +# line 578 "lua.stx" +{ adjust_functioncall(yypvt[-0].vLong, 1); } break; +case 31: +# line 581 "lua.stx" +{ yyval.vLong = yypvt[-1].vLong; } break; +case 32: +# line 582 "lua.stx" +{ code_byte(EQOP); yyval.vLong = 0; } break; +case 33: +# line 583 "lua.stx" +{ code_byte(LTOP); yyval.vLong = 0; } break; +case 34: +# line 584 "lua.stx" +{ code_byte(GTOP); yyval.vLong = 0; } break; +case 35: +# line 585 "lua.stx" +{ code_byte(EQOP); code_byte(NOTOP); yyval.vLong = 0; } break; +case 36: +# line 586 "lua.stx" +{ code_byte(LEOP); yyval.vLong = 0; } break; case 37: -# line 545 "lua.stx" -{ if (yypvt[-0].vInt == 0) code_byte(1); } break; +# line 587 "lua.stx" +{ code_byte(GEOP); yyval.vLong = 0; } break; case 38: -# line 548 "lua.stx" -{ yyval.vInt = yypvt[-1].vInt; } break; +# line 588 "lua.stx" +{ code_byte(ADDOP); yyval.vLong = 0; } break; case 39: -# line 549 "lua.stx" -{ code_byte(EQOP); yyval.vInt = 1; } break; +# line 589 "lua.stx" +{ code_byte(SUBOP); yyval.vLong = 0; } break; case 40: -# line 550 "lua.stx" -{ code_byte(LTOP); yyval.vInt = 1; } break; +# line 590 "lua.stx" +{ code_byte(MULTOP); yyval.vLong = 0; } break; case 41: -# line 551 "lua.stx" -{ code_byte(GTOP); yyval.vInt = 1; } break; +# line 591 "lua.stx" +{ code_byte(DIVOP); yyval.vLong = 0; } break; case 42: -# line 552 "lua.stx" -{ code_byte(EQOP); code_byte(NOTOP); yyval.vInt = 1; } break; +# line 592 "lua.stx" +{ code_byte(POWOP); yyval.vLong = 0; } break; case 43: -# line 553 "lua.stx" -{ code_byte(LEOP); yyval.vInt = 1; } break; +# line 593 "lua.stx" +{ code_byte(CONCOP); yyval.vLong = 0; } break; case 44: -# line 554 "lua.stx" -{ code_byte(GEOP); yyval.vInt = 1; } break; +# line 594 "lua.stx" +{ code_byte(MINUSOP); yyval.vLong = 0;} break; case 45: -# line 555 "lua.stx" -{ code_byte(ADDOP); yyval.vInt = 1; } break; +# line 595 "lua.stx" +{ yyval.vLong = 0; } break; case 46: -# line 556 "lua.stx" -{ code_byte(SUBOP); yyval.vInt = 1; } break; +# line 596 "lua.stx" +{ yyval.vLong = 0;} break; case 47: -# line 557 "lua.stx" -{ code_byte(MULTOP); yyval.vInt = 1; } break; +# line 597 "lua.stx" +{ code_number(yypvt[-0].vFloat); yyval.vLong = 0; } break; case 48: -# line 558 "lua.stx" -{ code_byte(DIVOP); yyval.vInt = 1; } break; -case 49: -# line 559 "lua.stx" -{ code_byte(POWOP); yyval.vInt = 1; } break; -case 50: -# line 560 "lua.stx" -{ code_byte(CONCOP); yyval.vInt = 1; } break; -case 51: -# line 561 "lua.stx" -{ code_byte(MINUSOP); yyval.vInt = 1;} break; -case 52: -# line 562 "lua.stx" -{ yyval.vInt = 1; } break; -case 53: -# line 563 "lua.stx" -{ yyval.vInt = 1;} break; -case 54: -# line 564 "lua.stx" -{ code_number(yypvt[-0].vFloat); yyval.vInt = 1; } break; -case 55: -# line 566 "lua.stx" +# line 599 "lua.stx" { code_byte(PUSHSTRING); code_word(yypvt[-0].vWord); - yyval.vInt = 1; + yyval.vLong = 0; } break; -case 56: -# line 571 "lua.stx" -{code_byte(PUSHNIL); yyval.vInt = 1; } break; -case 57: -# line 572 "lua.stx" -{ yyval.vInt = 0; } break; -case 58: -# line 573 "lua.stx" -{ code_byte(NOTOP); yyval.vInt = 1;} break; -case 59: -# line 574 "lua.stx" +case 49: +# line 604 "lua.stx" +{code_byte(PUSHNIL); yyval.vLong = 0; } break; +case 50: +# line 605 "lua.stx" +{ yyval.vLong = yypvt[-0].vLong; } break; +case 51: +# line 606 "lua.stx" +{ code_byte(NOTOP); yyval.vLong = 0;} break; +case 52: +# line 607 "lua.stx" {code_byte(POP); } break; -case 60: -# line 575 "lua.stx" +case 53: +# line 608 "lua.stx" { basepc[yypvt[-2].vLong] = ONFJMP; code_word_at(basepc+yypvt[-2].vLong+1, pc - (yypvt[-2].vLong + sizeof(Word)+1)); - yyval.vInt = 1; + yyval.vLong = 0; } break; -case 61: -# line 580 "lua.stx" +case 54: +# line 613 "lua.stx" {code_byte(POP); } break; -case 62: -# line 581 "lua.stx" +case 55: +# line 614 "lua.stx" { basepc[yypvt[-2].vLong] = ONTJMP; code_word_at(basepc+yypvt[-2].vLong+1, pc - (yypvt[-2].vLong + sizeof(Word)+1)); - yyval.vInt = 1; + yyval.vLong = 0; } break; -case 63: -# line 589 "lua.stx" +case 56: +# line 622 "lua.stx" { code_byte(CREATEARRAY); yyval.vLong = pc; code_word(0); } break; -case 64: -# line 594 "lua.stx" +case 57: +# line 627 "lua.stx" { code_word_at(basepc+yypvt[-3].vLong, yypvt[-1].vInt); } break; -case 65: -# line 600 "lua.stx" -{ code_byte(CALLFUNC); code_byte(yypvt[-1].vInt+yypvt[-0].vInt); } break; -case 66: -# line 603 "lua.stx" +case 58: +# line 633 "lua.stx" +{ + code_byte(CALLFUNC); + code_byte(yypvt[-1].vInt+yypvt[-0].vInt); + yyval.vLong = pc; + code_byte(0); /* may be modified by other rules */ + } break; +case 59: +# line 641 "lua.stx" { yyval.vInt = 0; } break; -case 67: -# line 605 "lua.stx" +case 60: +# line 643 "lua.stx" { code_byte(PUSHSELF); code_word(luaI_findconstant(yypvt[-0].pNode)); yyval.vInt = 1; } break; +case 61: +# line 651 "lua.stx" +{ yyval.vInt = adjust_functioncall(yypvt[-1].vLong, 1); } break; +case 62: +# line 652 "lua.stx" +{ yyval.vInt = 1; } break; +case 63: +# line 655 "lua.stx" +{ yyval.vLong = 0; } break; +case 64: +# line 656 "lua.stx" +{ yyval.vLong = yypvt[-0].vLong; } break; +case 65: +# line 659 "lua.stx" +{ if (yypvt[-0].vLong != 0) yyval.vLong = yypvt[-0].vLong; else yyval.vLong = -1; } break; +case 66: +# line 660 "lua.stx" +{ yyval.vLong = adjust_functioncall(yypvt[-1].vLong, 1); } break; +case 67: +# line 661 "lua.stx" +{ + if (yypvt[-0].vLong == 0) yyval.vLong = -(yypvt[-1].vLong + 1); /* -length */ + else + { + adjust_functioncall(yypvt[-0].vLong, yypvt[-1].vLong); + yyval.vLong = yypvt[-0].vLong; + } + } break; case 68: -# line 613 "lua.stx" -{ if (yypvt[-1].vInt<0) { code_byte(1); yyval.vInt = -yypvt[-1].vInt; } else yyval.vInt = yypvt[-1].vInt; } break; +# line 671 "lua.stx" +{ lua_codeadjust(0); yyval.vInt = lua_linenumber; } break; case 69: -# line 614 "lua.stx" -{ yyval.vInt = 1; } break; +# line 672 "lua.stx" +{ lua_codeadjust(0); yyval.vInt = lua_linenumber; } break; case 70: -# line 617 "lua.stx" -{ yyval.vInt = 0; } break; +# line 676 "lua.stx" +{ + add_localvar(luaI_findsymbol(yypvt[-0].pNode)); + } break; case 71: -# line 618 "lua.stx" -{ yyval.vInt = yypvt[-0].vInt; } break; +# line 680 "lua.stx" +{ + add_localvar(luaI_findsymbol(yypvt[-0].pNode)); + } break; case 72: -# line 621 "lua.stx" -{ if (yypvt[-0].vInt == 0) yyval.vInt = -1; else yyval.vInt = 1; } break; +# line 686 "lua.stx" +{ flush_list(yypvt[-0].vInt/FIELDS_PER_FLUSH, yypvt[-0].vInt%FIELDS_PER_FLUSH); } break; case 73: -# line 622 "lua.stx" -{ if (yypvt[-1].vInt < 0) code_byte(1); } break; +# line 688 "lua.stx" +{ yyval.vInt = yypvt[-2].vInt+yypvt[-0].vInt; } break; case 74: -# line 623 "lua.stx" -{ - int r = yypvt[-3].vInt < 0 ? -yypvt[-3].vInt : yypvt[-3].vInt; - yyval.vInt = (yypvt[-0].vInt == 0) ? -(r+1) : r+1; - } break; +# line 690 "lua.stx" +{ yyval.vInt = yypvt[-1].vInt; flush_record(yypvt[-1].vInt%FIELDS_PER_FLUSH); } break; case 75: -# line 629 "lua.stx" -{ lua_codeadjust(0); } break; +# line 694 "lua.stx" +{ yyval.vInt = 0; } break; case 76: -# line 630 "lua.stx" -{ lua_codeadjust(0); } break; -case 77: -# line 634 "lua.stx" -{ - localvar[nlocalvar]=luaI_findsymbol(yypvt[-0].pNode); - add_nlocalvar(1); - } break; -case 78: -# line 639 "lua.stx" -{ - localvar[nlocalvar]=luaI_findsymbol(yypvt[-0].pNode); - add_nlocalvar(1); - } break; +# line 696 "lua.stx" +{ yyval.vInt = yypvt[-0].vInt; flush_record(yypvt[-0].vInt%FIELDS_PER_FLUSH); } break; case 79: -# line 645 "lua.stx" -{ yyval.vInt = 0; } break; +# line 703 "lua.stx" +{ yyval.vInt = 0; } break; case 80: -# line 647 "lua.stx" -{ yyval.vInt = yypvt[-1].vInt; flush_list(yypvt[-1].vInt/FIELDS_PER_FLUSH, yypvt[-1].vInt%FIELDS_PER_FLUSH); } break; +# line 704 "lua.stx" +{ yyval.vInt = yypvt[-1].vInt; } break; case 81: -# line 649 "lua.stx" -{ yyval.vInt = yypvt[-1].vInt; flush_record(yypvt[-1].vInt%FIELDS_PER_FLUSH); } break; -case 82: -# line 651 "lua.stx" -{ flush_list(yypvt[-1].vInt/FIELDS_PER_FLUSH, yypvt[-1].vInt%FIELDS_PER_FLUSH); } break; -case 83: -# line 653 "lua.stx" -{ yyval.vInt = yypvt[-4].vInt+yypvt[-1].vInt; flush_record(yypvt[-1].vInt%FIELDS_PER_FLUSH); } break; -case 86: -# line 660 "lua.stx" +# line 707 "lua.stx" {yyval.vInt=1;} break; -case 87: -# line 662 "lua.stx" +case 82: +# line 709 "lua.stx" { yyval.vInt=yypvt[-2].vInt+1; if (yyval.vInt%FIELDS_PER_FLUSH == 0) flush_record(FIELDS_PER_FLUSH); } break; -case 88: -# line 669 "lua.stx" +case 83: +# line 716 "lua.stx" { push_field(luaI_findconstant(yypvt[-2].pNode)); } break; -case 89: -# line 674 "lua.stx" +case 84: +# line 721 "lua.stx" +{ yyval.vInt = 0; } break; +case 85: +# line 722 "lua.stx" +{ yyval.vInt = yypvt[-1].vInt; } break; +case 86: +# line 725 "lua.stx" {yyval.vInt=1;} break; -case 90: -# line 676 "lua.stx" +case 87: +# line 727 "lua.stx" { yyval.vInt=yypvt[-2].vInt+1; if (yyval.vInt%FIELDS_PER_FLUSH == 0) flush_list(yyval.vInt/FIELDS_PER_FLUSH - 1, FIELDS_PER_FLUSH); } break; -case 91: -# line 684 "lua.stx" +case 88: +# line 735 "lua.stx" { nvarbuffer = 0; - varbuffer[nvarbuffer] = yypvt[-0].vLong; incr_nvarbuffer(); + add_varbuffer(yypvt[-0].vLong); yyval.vInt = (yypvt[-0].vLong == 0) ? 1 : 0; } break; -case 92: -# line 690 "lua.stx" +case 89: +# line 741 "lua.stx" { - varbuffer[nvarbuffer] = yypvt[-0].vLong; incr_nvarbuffer(); + add_varbuffer(yypvt[-0].vLong); yyval.vInt = (yypvt[-0].vLong == 0) ? yypvt[-2].vInt + 1 : yypvt[-2].vInt; } break; -case 93: -# line 696 "lua.stx" +case 90: +# line 747 "lua.stx" { yyval.vLong = yypvt[-0].vLong; } break; -case 94: -# line 698 "lua.stx" +case 91: +# line 749 "lua.stx" { yyval.vLong = 0; /* indexed variable */ } break; -case 95: -# line 702 "lua.stx" +case 92: +# line 753 "lua.stx" { code_byte(PUSHSTRING); code_word(luaI_findconstant(yypvt[-0].pNode)); yyval.vLong = 0; /* indexed variable */ } break; -case 96: -# line 710 "lua.stx" +case 93: +# line 761 "lua.stx" { Word s = luaI_findsymbol(yypvt[-0].pNode); int local = lua_localname (s); @@ -1875,27 +1885,27 @@ case 96: else yyval.vLong = -(local+1); /* return negative value */ } break; -case 97: -# line 720 "lua.stx" +case 94: +# line 771 "lua.stx" { lua_pushvar(yypvt[-0].vLong); } break; -case 98: -# line 723 "lua.stx" -{localvar[nlocalvar]=luaI_findsymbol(yypvt[-0].pNode); yyval.vInt = 1;} break; -case 99: -# line 725 "lua.stx" +case 95: +# line 774 "lua.stx" +{store_localvar(luaI_findsymbol(yypvt[-0].pNode), 0); yyval.vInt = 1;} break; +case 96: +# line 776 "lua.stx" { - localvar[nlocalvar+yypvt[-2].vInt]=luaI_findsymbol(yypvt[-0].pNode); + store_localvar(luaI_findsymbol(yypvt[-0].pNode), yypvt[-2].vInt); yyval.vInt = yypvt[-2].vInt+1; } break; -case 100: -# line 731 "lua.stx" +case 97: +# line 782 "lua.stx" { yyval.vInt = 0; } break; -case 101: -# line 732 "lua.stx" -{ yyval.vInt = yypvt[-0].vInt; } break; -case 102: -# line 735 "lua.stx" -{lua_debug = yypvt[-0].vInt;} break; +case 98: +# line 783 "lua.stx" +{ yyval.vInt = yypvt[-0].vLong; } break; +case 99: +# line 786 "lua.stx" +{ lua_debug = yypvt[-0].vInt; } break; } goto yystack; /* reset registers in driver code */ } diff --git a/src/parser.h b/src/parser.h index 4c125dad..ea815f11 100644 --- a/src/parser.h +++ b/src/parser.h @@ -1,4 +1,3 @@ - typedef union { int vInt; @@ -6,7 +5,7 @@ typedef union char *pChar; Word vWord; Long vLong; - Byte *pByte; + TFunc *pFunc; TreeNode *pNode; } YYSTYPE; extern YYSTYPE yylval; diff --git a/src/table.c b/src/table.c index cedbf31c..1a2ac96b 100644 --- a/src/table.c +++ b/src/table.c @@ -3,38 +3,34 @@ ** Module to control static tables */ -char *rcs_table="$Id: table.c,v 2.28 1995/01/18 20:15:54 celes Exp $"; +char *rcs_table="$Id: table.c,v 2.38 1995/11/03 15:30:50 roberto Exp $"; -#include <string.h> +/*#include <string.h>*/ #include "mem.h" #include "opcode.h" #include "tree.h" #include "hash.h" -#include "inout.h" #include "table.h" +#include "inout.h" #include "lua.h" #include "fallback.h" +#include "luadebug.h" #define BUFFER_BLOCK 256 -Symbol *lua_table; +Symbol *lua_table = NULL; static Word lua_ntable = 0; static Long lua_maxsymbol = 0; -TaggedString **lua_constant; +TaggedString **lua_constant = NULL; static Word lua_nconstant = 0; static Long lua_maxconstant = 0; - -#define MAXFILE 20 -char *lua_file[MAXFILE]; -int lua_nfile; - -#define GARBAGE_BLOCK 256 -#define MIN_GARBAGE_BLOCK 10 +#define GARBAGE_BLOCK 1024 +#define MIN_GARBAGE_BLOCK (GARBAGE_BLOCK/2) static void lua_nextvar (void); static void setglobal (void); @@ -117,9 +113,8 @@ Word luaI_findsymbolbyname (char *name) /* -** Given a name, search it at constant table and return its index. If not -** found, allocate it. -** On error, return -1. +** Given a tree node, check it is has a correspondent constant index. If not, +** allocate it. */ Word luaI_findconstant (TreeNode *t) { @@ -144,26 +139,38 @@ Word luaI_findconstant (TreeNode *t) } +Word luaI_findconstantbyname (char *name) +{ + return luaI_findconstant(lua_constcreate(name)); +} + + /* ** Traverse symbol table objects */ -void lua_travsymbol (void (*fn)(Object *)) +static char *lua_travsymbol (int (*fn)(Object *)) { Word i; for (i=0; i<lua_ntable; i++) - fn(&s_object(i)); + if (fn(&s_object(i))) + return luaI_nodebysymbol(i)->ts.str; + return NULL; } /* ** Mark an object if it is a string or a unmarked array. */ -void lua_markobject (Object *o) +int lua_markobject (Object *o) { if (tag(o) == LUA_T_STRING && !tsvalue(o)->marked) tsvalue(o)->marked = 1; else if (tag(o) == LUA_T_ARRAY) lua_hashmark (avalue(o)); + else if ((o->tag == LUA_T_FUNCTION || o->tag == LUA_T_MARK) + && !o->value.tf->marked) + o->value.tf->marked = 1; + return 0; } @@ -180,8 +187,10 @@ void lua_pack (void) lua_travstack(lua_markobject); /* mark stack objects */ lua_travsymbol(lua_markobject); /* mark symbol table objects */ luaI_travlock(lua_markobject); /* mark locked objects */ + luaI_travfallbacks(lua_markobject); /* mark fallbacks */ recovered += lua_strcollector(); recovered += lua_hashcollector(); + recovered += luaI_funccollector(); nentity = 0; /* reset counter */ block=(16*block-7*recovered)/12; /* adapt block size */ if (block < MIN_GARBAGE_BLOCK) block = MIN_GARBAGE_BLOCK; @@ -189,70 +198,39 @@ void lua_pack (void) /* -** Add a file name at file table, checking overflow. This function also set -** the external variable "lua_filename" with the function filename set. -** Return 0 on success or error message on error. -*/ -char *lua_addfile (char *fn) -{ - if (lua_nfile >= MAXFILE) - return "too many files"; - if ((lua_file[lua_nfile++] = luaI_strdup (fn)) == NULL) - return "not enough memory"; - return NULL; -} - -/* -** Delete a file from file stack -*/ -int lua_delfile (void) -{ - luaI_free(lua_file[--lua_nfile]); - return 1; -} - -/* -** Return the last file name set. -*/ -char *lua_filename (void) -{ - return lua_file[lua_nfile-1]; -} - -/* ** Internal function: return next global variable */ static void lua_nextvar (void) { - char *varname; - TreeNode *next; + Word next; lua_Object o = lua_getparam(1); if (o == LUA_NOOBJECT) - lua_reportbug("too few arguments to function `nextvar'"); + lua_error("too few arguments to function `nextvar'"); if (lua_getparam(2) != LUA_NOOBJECT) - lua_reportbug("too many arguments to function `nextvar'"); + lua_error("too many arguments to function `nextvar'"); if (lua_isnil(o)) - varname = NULL; + next = 0; else if (!lua_isstring(o)) { - lua_reportbug("incorrect argument to function `nextvar'"); + lua_error("incorrect argument to function `nextvar'"); return; /* to avoid warnings */ } else - varname = lua_getstring(o); - next = lua_varnext(varname); - if (next == NULL) + next = luaI_findsymbolbyname(lua_getstring(o)) + 1; + while (next < lua_ntable && s_tag(next) == LUA_T_NIL) next++; + if (next >= lua_ntable) { lua_pushnil(); lua_pushnil(); } else { + TreeNode *t = luaI_nodebysymbol(next); Object name; tag(&name) = LUA_T_STRING; - tsvalue(&name) = &(next->ts); + tsvalue(&name) = &(t->ts); luaI_pushobject(&name); - luaI_pushobject(&s_object(next->varindex)); + luaI_pushobject(&s_object(next)); } } @@ -262,7 +240,7 @@ static void setglobal (void) lua_Object name = lua_getparam(1); lua_Object value = lua_getparam(2); if (!lua_isstring(name)) - lua_reportbug("incorrect argument to function `setglobal'"); + lua_error("incorrect argument to function `setglobal'"); lua_pushobject(value); lua_storeglobal(lua_getstring(name)); } @@ -272,6 +250,33 @@ static void getglobal (void) { lua_Object name = lua_getparam(1); if (!lua_isstring(name)) - lua_reportbug("incorrect argument to function `getglobal'"); + lua_error("incorrect argument to function `getglobal'"); lua_pushobject(lua_getglobal(lua_getstring(name))); } + + +static Object *functofind; +static int checkfunc (Object *o) +{ + if (o->tag == LUA_T_FUNCTION) + return + ((functofind->tag == LUA_T_FUNCTION || functofind->tag == LUA_T_MARK) + && (functofind->value.tf == o->value.tf)); + if (o->tag == LUA_T_CFUNCTION) + return + ((functofind->tag == LUA_T_CFUNCTION || functofind->tag == LUA_T_CMARK) + && (functofind->value.f == o->value.f)); + return 0; +} + + +char *getobjname (lua_Object o, char **name) +{ /* try to find a name for given function */ + functofind = luaI_Address(o); + if ((*name = luaI_travfallbacks(checkfunc)) != NULL) + return "fallback"; + else if ((*name = lua_travsymbol(checkfunc)) != NULL) + return "global"; + else return ""; +} + diff --git a/src/table.h b/src/table.h index c25075c0..4e581401 100644 --- a/src/table.h +++ b/src/table.h @@ -1,7 +1,7 @@ /* ** Module to control static tables ** TeCGraf - PUC-Rio -** $Id: table.h,v 2.10 1994/12/20 21:20:36 roberto Exp $ +** $Id: table.h,v 2.13 1995/10/26 14:21:56 roberto Exp $ */ #ifndef table_h @@ -21,11 +21,9 @@ void lua_initconstant (void); Word luaI_findsymbolbyname (char *name); Word luaI_findsymbol (TreeNode *t); Word luaI_findconstant (TreeNode *t); -void lua_travsymbol (void (*fn)(Object *)); -void lua_markobject (Object *o); +Word luaI_findconstantbyname (char *name); +int lua_markobject (Object *o); void lua_pack (void); -char *lua_addfile (char *fn); -int lua_delfile (void); -char *lua_filename (void); + #endif @@ -3,7 +3,7 @@ ** TecCGraf - PUC-Rio */ -char *rcs_tree="$Id: tree.c,v 1.13 1995/01/12 14:19:04 roberto Exp $"; +char *rcs_tree="$Id: tree.c,v 1.14 1995/10/17 11:53:53 roberto Exp $"; #include <string.h> @@ -102,40 +102,22 @@ Long lua_strcollector (void) return counter; } + /* -** Return next variable. +** Traverse the constant tree looking for a specific symbol number */ -static TreeNode *tree_next (TreeNode *node, char *str) +static TreeNode *nodebysymbol (TreeNode *root, Word symbol) { - if (node == NULL) return NULL; - else if (str == NULL) return node; - else - { - int c = lua_strcmp(str, node->ts.str); - if (c == 0) - return node->left != NULL ? node->left : node->right; - else if (c < 0) - { - TreeNode *result = tree_next(node->left, str); - return result != NULL ? result : node->right; - } - else - return tree_next(node->right, str); - } + TreeNode *t; + if (root == NULL) return NULL; + if (root->varindex == symbol) return root; + t = nodebysymbol(root->left, symbol); + if (t) return t; + return nodebysymbol(root->right, symbol); } -TreeNode *lua_varnext (char *n) +TreeNode *luaI_nodebysymbol (Word symbol) { - TreeNode *result; - char *name = n; - while (1) - { /* repeat until a valid (non nil) variable */ - result = tree_next(constant_root, name); - if (result == NULL) return NULL; - if (result->varindex != NOT_USED && - s_tag(result->varindex) != LUA_T_NIL) - return result; - name = result->ts.str; - } + return nodebysymbol(constant_root, symbol); } @@ -1,7 +1,7 @@ /* ** tree.h ** TecCGraf - PUC-Rio -** $Id: tree.h,v 1.9 1995/01/12 14:19:04 roberto Exp $ +** $Id: tree.h,v 1.10 1995/10/17 11:53:53 roberto Exp $ */ #ifndef tree_h @@ -32,6 +32,6 @@ typedef struct TreeNode TaggedString *lua_createstring (char *str); TreeNode *lua_constcreate (char *str); Long lua_strcollector (void); -TreeNode *lua_varnext (char *n); +TreeNode *luaI_nodebysymbol (Word symbol); #endif diff --git a/src/yacc/Makefile b/src/yacc/Makefile deleted file mode 100644 index 284d4ab5..00000000 --- a/src/yacc/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -parser.c: - co -M lua.stx - yacc -d lua.stx ; mv -f y.tab.c ../parser.c ; mv -f y.tab.h ../parser.h |