diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 68 | ||||
-rw-r--r-- | src/fallback.c | 92 | ||||
-rw-r--r-- | src/fallback.h | 9 | ||||
-rw-r--r-- | src/func.c | 83 | ||||
-rw-r--r-- | src/func.h | 24 | ||||
-rw-r--r-- | src/hash.c | 70 | ||||
-rw-r--r-- | src/hash.h | 15 | ||||
-rw-r--r-- | src/inout.c | 130 | ||||
-rw-r--r-- | src/inout.h | 12 | ||||
-rw-r--r-- | src/lex.c | 91 | ||||
-rw-r--r-- | src/lex.h | 19 | ||||
-rw-r--r-- | src/lua.stx | 320 | ||||
-rw-r--r-- | src/luac/Makefile | 24 | ||||
-rw-r--r-- | src/luac/dump.c | 247 | ||||
-rw-r--r-- | src/luac/luac.c | 104 | ||||
-rw-r--r-- | src/luac/luac.h | 24 | ||||
-rw-r--r-- | src/luac/print.c | 189 | ||||
-rw-r--r-- | src/luac/print.h | 76 | ||||
-rw-r--r-- | src/mem.c | 45 | ||||
-rw-r--r-- | src/mem.h | 22 | ||||
-rw-r--r-- | src/opcode.c | 291 | ||||
-rw-r--r-- | src/opcode.h | 26 | ||||
-rw-r--r-- | src/parser.c | 1102 | ||||
-rw-r--r-- | src/parser.h | 5 | ||||
-rw-r--r-- | src/table.c | 191 | ||||
-rw-r--r-- | src/table.h | 25 | ||||
-rw-r--r-- | src/tree.c | 178 | ||||
-rw-r--r-- | src/tree.h | 17 | ||||
-rw-r--r-- | src/types.h | 4 | ||||
-rw-r--r-- | src/ugly.h | 36 | ||||
-rw-r--r-- | src/undump.c | 326 | ||||
-rw-r--r-- | src/undump.h | 23 |
32 files changed, 2358 insertions, 1530 deletions
diff --git a/src/Makefile b/src/Makefile index f6296781..843220dc 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,40 +1,66 @@ -# makefile for lua distribution +# makefile for lua distribution (main library) -INC= $(LUA)/include -LIB= $(LUA)/lib +LUA= .. -# in SunOs /usr/5include contains prototypes for standard lib -INCS= -I/usr/5include -I$(INC) -WARN= -Wall -Wmissing-prototypes -Wshadow -ansi +include $(LUA)/config -CC= gcc -CFLAGS= $(INCS) $(DEFS) $(WARN) -O2 +OBJS= fallback.o\ + func.o\ + hash.o\ + inout.o\ + lex.o\ + mem.o\ + opcode.o\ + parser.o\ + table.o\ + tree.o\ + undump.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 +SRCS= fallback.c\ + fallback.h\ + func.c\ + func.h\ + hash.c\ + hash.h\ + inout.c\ + inout.h\ + lex.c\ + lex.h\ + mem.c\ + mem.h\ + opcode.c\ + opcode.h\ + parser.c\ + parser.h\ + table.c\ + table.h\ + tree.c\ + tree.h\ + types.h\ + undump.c\ + undump.h\ + lua.stx SLIB= $(LIB)/liblua.a -# dynamic libraries only work for SunOs -DLIB= $(LIB)/liblua.so.$(VERSION) - all: $(SLIB) -dynamic: $(DLIB) - $(SLIB): $(OBJS) ar rcuv $@ $(OBJS) ranlib $@ -$(DLIB): $(OBJS) - ld -o $@ $(OBJS) - clean: - rm -f $(OBJS) $(SLIB) $(DLIB) + rm -f $(OBJS) $(SLIB) co: co -f -M $(SRCS) - yacc -d lua.stx ; mv -f y.tab.c parser.c ; mv -f y.tab.h parser.h + +parser: + yacc -d lua.stx + rm -f parser.c parser.h + sed -e 's/yy/luaY_/g' y.tab.c > parser.c + sed -e 's/yy/luaY_/g' y.tab.h > parser.h + rm y.tab.c y.tab.h klean: clean - rm -f $(SRCS) parser.c parser.h + rm -f $(SRCS) diff --git a/src/fallback.c b/src/fallback.c index aa9fc99d..5718f5c1 100644 --- a/src/fallback.c +++ b/src/fallback.c @@ -3,7 +3,7 @@ ** TecCGraf - PUC-Rio */ -char *rcs_fallback="$Id: fallback.c,v 1.17 1995/10/17 14:30:05 roberto Exp $"; +char *rcs_fallback="$Id: fallback.c,v 1.25 1996/04/25 14:10:00 roberto Exp $"; #include <stdio.h> #include <string.h> @@ -12,6 +12,7 @@ char *rcs_fallback="$Id: fallback.c,v 1.17 1995/10/17 14:30:05 roberto Exp $"; #include "fallback.h" #include "opcode.h" #include "lua.h" +#include "table.h" static void errorFB (void); @@ -36,8 +37,10 @@ struct FB luaI_fallBacks[] = { {"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} +{"function", {LUA_T_CFUNCTION, {funcFB}}, -1, -1}, /* no fixed number of params or results */ +{"getglobal", {LUA_T_CFUNCTION, {indexFB}}, 1, 1} + /* same default behavior of index FB */ }; #define N_FB (sizeof(luaI_fallBacks)/sizeof(struct FB)) @@ -47,7 +50,7 @@ void luaI_setfallback (void) int i; char *name = lua_getstring(lua_getparam(1)); lua_Object func = lua_getparam(2); - if (name == NULL || !(lua_isfunction(func) || lua_iscfunction(func))) + if (name == NULL || !lua_isfunction(func)) lua_error("incorrect argument to function `setfallback'"); for (i=0; i<N_FB; i++) { @@ -110,66 +113,77 @@ static void funcFB (void) /* -** Lock routines +** Reference routines */ -static Object *lockArray = NULL; -static Word lockSize = 0; +static struct ref { + Object o; + enum {LOCK, HOLD, FREE, COLLECTED} status; +} *refArray = NULL; +static int refSize = 0; -int luaI_lock (Object *object) +int luaI_ref (Object *object, int lock) { - Word i; - Word oldSize; + int i; + int oldSize; if (tag(object) == LUA_T_NIL) - return -1; - for (i=0; i<lockSize; i++) - if (tag(&lockArray[i]) == LUA_T_NIL) - { - lockArray[i] = *object; - return i; - } + return -1; /* special ref for nil */ + for (i=0; i<refSize; i++) + if (refArray[i].status == FREE) + goto found; /* no more empty spaces */ - oldSize = lockSize; - if (lockArray == NULL) - { - lockSize = 10; - lockArray = newvector(lockSize, Object); - } - else - { - lockSize = 3*oldSize/2 + 5; - lockArray = growvector(lockArray, lockSize, Object); - } - for (i=oldSize; i<lockSize; i++) - tag(&lockArray[i]) = LUA_T_NIL; - lockArray[oldSize] = *object; - return oldSize; + oldSize = refSize; + refSize = growvector(&refArray, refSize, struct ref, refEM, MAX_WORD); + for (i=oldSize; i<refSize; i++) + refArray[i].status = FREE; + i = oldSize; + found: + refArray[i].o = *object; + refArray[i].status = lock ? LOCK : HOLD; + return i; } -void lua_unlock (int ref) +void lua_unref (int ref) { - tag(&lockArray[ref]) = LUA_T_NIL; + if (ref >= 0 && ref < refSize) + refArray[ref].status = FREE; } -Object *luaI_getlocked (int ref) +Object *luaI_getref (int ref) { - return &lockArray[ref]; + static Object nul = {LUA_T_NIL, {0}}; + if (ref == -1) + return &nul; + if (ref >= 0 && ref < refSize && + (refArray[ref].status == LOCK || refArray[ref].status == HOLD)) + return &refArray[ref].o; + else + return NULL; } void luaI_travlock (int (*fn)(Object *)) { - Word i; - for (i=0; i<lockSize; i++) - fn(&lockArray[i]); + int i; + for (i=0; i<refSize; i++) + if (refArray[i].status == LOCK) + fn(&refArray[i].o); } +void luaI_invalidaterefs (void) +{ + int i; + for (i=0; i<refSize; i++) + if (refArray[i].status == HOLD && !luaI_ismarked(&refArray[i].o)) + refArray[i].status = COLLECTED; +} + char *luaI_travfallbacks (int (*fn)(Object *)) { - Word i; + int i; for (i=0; i<N_FB; i++) if (fn(&luaI_fallBacks[i].function)) return luaI_fallBacks[i].kind; diff --git a/src/fallback.h b/src/fallback.h index f4be0b6f..71f150f7 100644 --- a/src/fallback.h +++ b/src/fallback.h @@ -1,10 +1,11 @@ /* -** $Id: fallback.h,v 1.10 1995/10/17 11:52:38 roberto Exp $ +** $Id: fallback.h,v 1.13 1996/04/25 14:10:00 roberto Exp $ */ #ifndef fallback_h #define fallback_h +#include "lua.h" #include "opcode.h" extern struct FB { @@ -23,11 +24,13 @@ extern struct FB { #define FB_SETTABLE 6 #define FB_GC 7 #define FB_FUNCTION 8 +#define FB_GETGLOBAL 9 void luaI_setfallback (void); -int luaI_lock (Object *object); -Object *luaI_getlocked (int ref); +int luaI_ref (Object *object, int lock); +Object *luaI_getref (int ref); void luaI_travlock (int (*fn)(Object *)); +void luaI_invalidaterefs (void); char *luaI_travfallbacks (int (*fn)(Object *)); #endif @@ -1,4 +1,4 @@ -#include <stdio.h> +#include <stdlib.h> #include "luadebug.h" #include "table.h" @@ -6,8 +6,26 @@ #include "func.h" #include "opcode.h" + static TFunc *function_root = NULL; +static LocVar *currvars = NULL; +static int numcurrvars = 0; +static int maxcurrvars = 0; + +/* +** Initialize TFunc struct +*/ +void luaI_initTFunc (TFunc *f) +{ + f->next = NULL; + f->marked = 0; + f->size = 0; + f->code = NULL; + f->lineDefined = 0; + f->fileName = NULL; + f->locvars = NULL; +} /* ** Insert function in list for GC @@ -24,9 +42,10 @@ void luaI_insertfunction (TFunc *f) /* ** Free function */ -static void freefunc (TFunc *f) +void luaI_freefunc (TFunc *f) { luaI_free (f->code); + luaI_free (f->locvars); luaI_free (f); } @@ -48,7 +67,7 @@ Long luaI_funccollector (void) function_root = next; else prev->next = next; - freefunc (curr); + luaI_freefunc (curr); ++counter; } else @@ -77,3 +96,61 @@ void lua_funcinfo (lua_Object func, char **filename, int *linedefined) } } +/* +** Stores information to know that variable has been declared in given line +*/ +void luaI_registerlocalvar (TaggedString *varname, int line) +{ + if (numcurrvars >= maxcurrvars) + maxcurrvars = growvector(&currvars, maxcurrvars, LocVar, "", MAX_WORD); + currvars[numcurrvars].varname = varname; + currvars[numcurrvars].line = line; + numcurrvars++; +} + +/* +** Stores information to know that variable has been out of scope in given line +*/ +void luaI_unregisterlocalvar (int line) +{ + luaI_registerlocalvar(NULL, line); +} + +/* +** Copies "currvars" into a new area and store it in function header. +** The values (varname = NULL, line = -1) signal the end of vector. +*/ +void luaI_closelocalvars (TFunc *func) +{ + func->locvars = newvector (numcurrvars+1, LocVar); + memcpy (func->locvars, currvars, numcurrvars*sizeof(LocVar)); + func->locvars[numcurrvars].varname = NULL; + func->locvars[numcurrvars].line = -1; + numcurrvars = 0; /* prepares for next function */ +} + +/* +** Look for n-esim local variable at line "line" in function "func". +** Returns NULL if not found. +*/ +char *luaI_getlocalname (TFunc *func, int local_number, int line) +{ + int count = 0; + char *varname = NULL; + LocVar *lv = func->locvars; + if (lv == NULL) + return NULL; + for (; lv->line != -1 && lv->line < line; lv++) + { + if (lv->varname) /* register */ + { + if (++count == local_number) + varname = lv->varname->str; + } + else /* unregister */ + if (--count < local_number) + varname = NULL; + } + return varname; +} + @@ -1,24 +1,44 @@ +/* +** $Id: func.h,v 1.8 1996/03/14 15:54:20 roberto Exp $ +*/ + #ifndef func_h #define func_h #include "types.h" #include "lua.h" +#include "tree.h" + +typedef struct LocVar +{ + TaggedString *varname; /* NULL signals end of scope */ + int line; +} LocVar; + /* -** Header para funcoes. +** Function Headers */ typedef struct TFunc { struct TFunc *next; - char marked; + int marked; int size; Byte *code; int lineDefined; char *fileName; + LocVar *locvars; } TFunc; Long luaI_funccollector (void); void luaI_insertfunction (TFunc *f); +void luaI_initTFunc (TFunc *f); +void luaI_freefunc (TFunc *f); + +void luaI_registerlocalvar (TaggedString *varname, int line); +void luaI_unregisterlocalvar (int line); +void luaI_closelocalvars (TFunc *func); +char *luaI_getlocalname (TFunc *func, int local_number, int line); #endif @@ -3,9 +3,8 @@ ** hash manager for lua */ -char *rcs_hash="$Id: hash.c,v 2.26 1995/10/04 14:20:26 roberto Exp $"; +char *rcs_hash="$Id: hash.c,v 2.30 1996/05/06 14:30:27 roberto Exp $"; -#include <string.h> #include "mem.h" #include "opcode.h" @@ -13,7 +12,6 @@ char *rcs_hash="$Id: hash.c,v 2.26 1995/10/04 14:20:26 roberto Exp $"; #include "table.h" #include "lua.h" -#define streq(s1,s2) (s1 == s2 || (*(s1) == *(s2) && strcmp(s1,s2)==0)) #define nhash(t) ((t)->nhash) #define nuse(t) ((t)->nuse) @@ -24,22 +22,22 @@ char *rcs_hash="$Id: hash.c,v 2.26 1995/10/04 14:20:26 roberto Exp $"; #define val(n) (&(n)->val) -#define REHASH_LIMIT 0.70 /* avoid more than this % full */ +#define REHASH_LIMIT 0.70 /* avoid more than this % full */ static Hash *listhead = NULL; - /* hash dimensions values */ -static Word dimensions[] = - {3, 5, 7, 11, 23, 47, 97, 197, 397, 797, 1597, 3203, 6421, - 12853, 25717, 51437, 65521, 0}; /* 65521 == last prime < MAX_WORD */ +static Long dimensions[] = + {3L, 5L, 7L, 11L, 23L, 47L, 97L, 197L, 397L, 797L, 1597L, 3203L, 6421L, + 12853L, 25717L, 51437L, 102811L, 205619L, 411233L, 822433L, + 1644817L, 3289613L, 6579211L, 13158023L, MAX_INT}; -static Word redimension (Word nhash) +int luaI_redimension (int nhash) { - Word i; - for (i=0; dimensions[i]!=0; i++) + int i; + for (i=0; dimensions[i]<MAX_INT; i++) { if (dimensions[i] > nhash) return dimensions[i]; @@ -48,7 +46,7 @@ static Word redimension (Word nhash) return 0; /* to avoid warnings */ } -static Word hashindex (Hash *t, Object *ref) /* hash function */ +static int hashindex (Hash *t, Object *ref) /* hash function */ { switch (tag(ref)) { @@ -56,19 +54,9 @@ static Word hashindex (Hash *t, Object *ref) /* hash function */ lua_error ("unexpected type to index table"); return -1; /* UNREACHEABLE */ case LUA_T_NUMBER: - return (((Word)nvalue(ref))%nhash(t)); + return (((int)nvalue(ref))%nhash(t)); case LUA_T_STRING: - { - unsigned long h = tsvalue(ref)->hash; - if (h == 0) - { - char *name = svalue(ref); - while (*name) - h = ((h<<5)-h)^(unsigned char)*(name++); - tsvalue(ref)->hash = h; - } - return (Word)h%nhash(t); /* make it a valid index */ - } + return (int)((tsvalue(ref)->hash)%nhash(t)); /* make it a valid index */ case LUA_T_FUNCTION: return (((IntPoint)ref->value.tf)%nhash(t)); case LUA_T_CFUNCTION: @@ -80,14 +68,14 @@ static Word hashindex (Hash *t, Object *ref) /* hash function */ } } -Bool lua_equalObj (Object *t1, Object *t2) +int lua_equalObj (Object *t1, Object *t2) { if (tag(t1) != tag(t2)) return 0; switch (tag(t1)) { case LUA_T_NIL: return 1; case LUA_T_NUMBER: return nvalue(t1) == nvalue(t2); - case LUA_T_STRING: return streq(svalue(t1), svalue(t2)); + case LUA_T_STRING: return svalue(t1) == svalue(t2); case LUA_T_ARRAY: return avalue(t1) == avalue(t2); case LUA_T_FUNCTION: return t1->value.tf == t2->value.tf; case LUA_T_CFUNCTION: return fvalue(t1) == fvalue(t2); @@ -95,9 +83,9 @@ Bool lua_equalObj (Object *t1, Object *t2) } } -static Word present (Hash *t, Object *ref) +static int present (Hash *t, Object *ref) { - Word h = hashindex(t, ref); + int h = hashindex(t, ref); while (tag(ref(node(t, h))) != LUA_T_NIL) { if (lua_equalObj(ref, ref(node(t, h)))) @@ -111,9 +99,9 @@ static Word present (Hash *t, Object *ref) /* ** Alloc a vector node */ -static Node *hashnodecreate (Word nhash) +static Node *hashnodecreate (int nhash) { - Word i; + int i; Node *v = newvector (nhash, Node); for (i=0; i<nhash; i++) tag(ref(&v[i])) = LUA_T_NIL; @@ -123,10 +111,10 @@ static Node *hashnodecreate (Word nhash) /* ** Create a new hash. Return the hash pointer or NULL on error. */ -static Hash *hashcreate (Word nhash) +static Hash *hashcreate (int nhash) { Hash *t = new(Hash); - nhash = redimension((Word)((float)nhash/REHASH_LIMIT)); + nhash = luaI_redimension((int)((float)nhash/REHASH_LIMIT)); nodevector(t) = hashnodecreate(nhash); nhash(t) = nhash; nuse(t) = 0; @@ -151,7 +139,7 @@ void lua_hashmark (Hash *h) { if (markarray(h) == 0) { - Word i; + int i; markarray(h) = 1; for (i=0; i<nhash(h); i++) { @@ -218,7 +206,7 @@ Long lua_hashcollector (void) ** executes garbage collection if the number of arrays created ** exceed a pre-defined range. */ -Hash *lua_createarray (Word nhash) +Hash *lua_createarray (int nhash) { Hash *array; lua_pack(); @@ -234,10 +222,10 @@ Hash *lua_createarray (Word nhash) */ static void rehash (Hash *t) { - Word i; - Word nold = nhash(t); + int i; + int nold = nhash(t); Node *vold = nodevector(t); - nhash(t) = redimension(nhash(t)); + nhash(t) = luaI_redimension(nhash(t)); nodevector(t) = hashnodecreate(nhash(t)); for (i=0; i<nold; i++) { @@ -254,7 +242,7 @@ static void rehash (Hash *t) */ Object *lua_hashget (Hash *t, Object *ref) { - Word h = present(t, ref); + int h = present(t, ref); if (tag(ref(node(t, h))) != LUA_T_NIL) return val(node(t, h)); else return NULL; } @@ -266,7 +254,7 @@ Object *lua_hashget (Hash *t, Object *ref) */ Object *lua_hashdefine (Hash *t, Object *ref) { - Word h; + int h; Node *n; h = present(t, ref); n = node(t, h); @@ -292,7 +280,7 @@ Object *lua_hashdefine (Hash *t, Object *ref) ** in the hash. ** This function pushs the element value and its reference to the stack. */ -static void hashnext (Hash *t, Word i) +static void hashnext (Hash *t, int i) { if (i >= nhash(t)) { @@ -329,7 +317,7 @@ void lua_next (void) } else { - Word h = present (t, luaI_Address(r)); + int h = present (t, luaI_Address(r)); hashnext(t, h+1); } } @@ -1,14 +1,14 @@ /* ** hash.h ** hash manager for lua -** Luiz Henrique de Figueiredo - 17 Aug 90 -** $Id: hash.h,v 2.8 1995/01/12 14:19:04 roberto Exp $ +** $Id: hash.h,v 2.12 1996/05/06 14:30:27 roberto Exp $ */ #ifndef hash_h #define hash_h #include "types.h" +#include "opcode.h" typedef struct node { @@ -19,15 +19,16 @@ typedef struct node typedef struct Hash { struct Hash *next; - char mark; - Word nhash; - Word nuse; Node *node; + int nhash; + int nuse; + char mark; } Hash; -Bool lua_equalObj (Object *t1, Object *t2); -Hash *lua_createarray (Word nhash); +int lua_equalObj (Object *t1, Object *t2); +int luaI_redimension (int nhash); +Hash *lua_createarray (int nhash); void lua_hashmark (Hash *h); Long lua_hashcollector (void); Object *lua_hashget (Hash *t, Object *ref); diff --git a/src/inout.c b/src/inout.c index c73030e3..85722c3c 100644 --- a/src/inout.c +++ b/src/inout.c @@ -5,31 +5,21 @@ ** Also provides some predefined lua functions. */ -char *rcs_inout="$Id: inout.c,v 2.25 1995/10/25 13:05:51 roberto Exp $"; +char *rcs_inout="$Id: inout.c,v 2.36 1996/03/19 22:28:37 roberto Exp $"; #include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "mem.h" +#include "lex.h" #include "opcode.h" -#include "hash.h" #include "inout.h" #include "table.h" #include "tree.h" #include "lua.h" - - -#ifndef MAXFUNCSTACK -#define MAXFUNCSTACK 100 -#endif - -#define MAXMESSAGE MAXFUNCSTACK*80 +#include "mem.h" /* Exported variables */ Word lua_linenumber; -Bool lua_debug = 0; char *lua_parsedfile; @@ -54,9 +44,9 @@ static int stringinput (void) /* ** Function to open a file to be input unit. -** Return 0 on success or error message on error. +** Return the file. */ -char *lua_openfile (char *fn) +FILE *lua_openfile (char *fn) { lua_setinput (fileinput); if (fn == NULL) @@ -67,14 +57,10 @@ char *lua_openfile (char *fn) else fp = fopen (fn, "r"); if (fp == NULL) - { - static char buff[255]; - sprintf(buff, "unable to open file `%.200s'", fn); - return buff; - } + return NULL; lua_linenumber = 1; - lua_parsedfile = lua_constcreate(fn)->ts.str; - return NULL; + lua_parsedfile = luaI_createfixedstring(fn)->str; + return fp; } /* @@ -97,7 +83,7 @@ void lua_openstring (char *s) lua_setinput (stringinput); st = s; lua_linenumber = 1; - lua_parsedfile = lua_constcreate("(string)")->ts.str; + lua_parsedfile = luaI_createfixedstring("(string)")->str; } /* @@ -126,33 +112,57 @@ void lua_internaldostring (void) void lua_internaldofile (void) { lua_Object obj = lua_getparam (1); - if (lua_isstring(obj) && !lua_dofile(lua_getstring(obj))) + char *fname = NULL; + if (lua_isstring(obj)) + fname = lua_getstring(obj); + else if (obj != LUA_NOOBJECT) + lua_error("invalid argument to function `dofile'"); + /* else fname = NULL */ + if (!lua_dofile(fname)) lua_pushnumber(1); else lua_pushnil(); } -/* -** Internal function: print object values -*/ -void lua_print (void) + +static char *tostring (lua_Object obj) { - int i=1; - lua_Object obj; - while ((obj=lua_getparam (i++)) != LUA_NOOBJECT) - { - 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",(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)); - else if (lua_istable(obj)) printf("table: %p\n",avalue(luaI_Address(obj))); - else if (lua_isnil(obj)) printf("nil\n"); - else printf("invalid value to print\n"); - } + char *buff = luaI_buffer(20); + if (lua_isstring(obj)) /* get strings and numbers */ + return lua_getstring(obj); + else switch(lua_type(obj)) + { + case LUA_T_FUNCTION: + sprintf(buff, "function: %p", (luaI_Address(obj))->value.tf); + break; + case LUA_T_CFUNCTION: + sprintf(buff, "cfunction: %p", lua_getcfunction(obj)); + break; + case LUA_T_ARRAY: + sprintf(buff, "table: %p", avalue(luaI_Address(obj))); + break; + case LUA_T_NIL: + sprintf(buff, "nil"); + break; + default: + sprintf(buff, "userdata: %p", lua_getuserdata(obj)); + break; + } + return buff; } +void luaI_tostring (void) +{ + lua_pushstring(tostring(lua_getparam(1))); +} + +void luaI_print (void) +{ + int i = 1; + lua_Object obj; + while ((obj = lua_getparam(i++)) != LUA_NOOBJECT) + printf("%s\n", tostring(obj)); +} /* ** Internal function: return an object type. @@ -196,16 +206,7 @@ void lua_obj2number (void) { lua_Object o = lua_getparam(1); if (lua_isnumber(o)) - lua_pushobject(o); - else if (lua_isstring(o)) - { - char c; - float f; - if (sscanf(lua_getstring(o),"%f %c",&f,&c) == 1) - lua_pushnumber(f); - else - lua_pushnil(); - } + lua_pushnumber(lua_getnumber(o)); else lua_pushnil(); } @@ -218,3 +219,28 @@ void luaI_error (void) lua_error(s); } +void luaI_assert (void) +{ + lua_Object p = lua_getparam(1); + if (p == LUA_NOOBJECT || lua_isnil(p)) + lua_error("assertion failed!"); +} + +void luaI_setglobal (void) +{ + lua_Object name = lua_getparam(1); + lua_Object value = lua_getparam(2); + if (!lua_isstring(name)) + lua_error("incorrect argument to function `setglobal'"); + lua_pushobject(value); + lua_storeglobal(lua_getstring(name)); + lua_pushobject(value); /* return given value */ +} + +void luaI_getglobal (void) +{ + lua_Object name = lua_getparam(1); + if (!lua_isstring(name)) + lua_error("incorrect argument to function `getglobal'"); + lua_pushobject(lua_getglobal(lua_getstring(name))); +} diff --git a/src/inout.h b/src/inout.h index da9c1cc2..e5957753 100644 --- a/src/inout.h +++ b/src/inout.h @@ -1,5 +1,5 @@ /* -** $Id: inout.h,v 1.10 1995/10/17 11:58:41 roberto Exp $ +** $Id: inout.h,v 1.15 1996/03/15 18:21:58 roberto Exp $ */ @@ -7,23 +7,27 @@ #define inout_h #include "types.h" +#include <stdio.h> extern Word lua_linenumber; -extern Bool lua_debug; extern Word lua_debugline; extern char *lua_parsedfile; -char *lua_openfile (char *fn); +FILE *lua_openfile (char *fn); void lua_closefile (void); void lua_openstring (char *s); void lua_closestring (void); void lua_internaldofile (void); void lua_internaldostring (void); -void lua_print (void); +void luaI_tostring (void); +void luaI_print (void); void luaI_type (void); void lua_obj2number (void); void luaI_error (void); +void luaI_assert (void); +void luaI_setglobal (void); +void luaI_getglobal (void); #endif @@ -1,23 +1,19 @@ -char *rcs_lex = "$Id: lex.c,v 2.21 1995/11/16 20:46:24 roberto Exp $"; +char *rcs_lex = "$Id: lex.c,v 2.32 1996/03/21 16:33:47 roberto Exp $"; #include <ctype.h> -#include <stdio.h> -#include <stdlib.h> #include <string.h> #include "mem.h" #include "tree.h" #include "table.h" -#include "opcode.h" +#include "lex.h" #include "inout.h" +#include "luadebug.h" #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(); } #define save(x) { *yytextLast++ = (x); } #define save_and_next() { save(current); next(); } @@ -47,7 +43,6 @@ char *lua_lasttext (void) } -/* The reserved words must be listed in lexicographic order */ static struct { char *name; @@ -74,30 +69,21 @@ static struct #define RESERVEDSIZE (sizeof(reserved)/sizeof(reserved[0])) -static int findReserved (char *name) +void luaI_addReserved (void) { - int l = 0; - int h = RESERVEDSIZE - 1; - while (l <= h) + int i; + for (i=0; i<RESERVEDSIZE; i++) { - int m = (l+h)/2; - int comp = lua_strcmp(name, reserved[m].name); - if (comp < 0) - h = m-1; - else if (comp == 0) - return reserved[m].token; - else - l = m+1; + TaggedString *ts = lua_createstring(reserved[i].name); + ts->marked = reserved[i].token; /* reserved word (always > 255) */ } - return 0; } static void growtext (void) { int size = yytextLast - yytext; - textsize *= 2; - yytext = growvector(yytext, textsize, char); + textsize = growvector(&yytext, textsize, char, lexEM, MAX_WORD); yytextLast = yytext + size; } @@ -144,9 +130,9 @@ static int read_long_string (void) } -int yylex (void) +int luaY_lex (void) { - float a; + double a; static int linelasttoken = 0; if (lua_debug) luaI_codedebugline(linelasttoken); @@ -154,9 +140,6 @@ int yylex (void) while (1) { yytextLast = yytext; -#if 0 - fprintf(stderr,"'%c' %d\n",current,current); -#endif switch (current) { case EOF: @@ -174,22 +157,21 @@ int yylex (void) while (isalnum(current) || current == '_') save_and_next(); *yytextLast = 0; - if (lua_strcmp(yytext, "debug") == 0) + if (strcmp(yytext, "debug") == 0) { - yylval.vInt = 1; + luaY_lval.vInt = 1; return DEBUG; } - else if (lua_strcmp(yytext, "nodebug") == 0) + else if (strcmp(yytext, "nodebug") == 0) { - yylval.vInt = 0; + luaY_lval.vInt = 0; return DEBUG; } return WRONGTOKEN; case '-': save_and_next(); - if (current != '-') return '-'; /* else goes through */ - case '#': + if (current != '-') return '-'; do { next(); } while (current != '\n' && current != 0); continue; @@ -203,7 +185,7 @@ int yylex (void) return WRONGTOKEN; save_and_next(); /* pass the second ']' */ *(yytextLast-2) = 0; /* erases ']]' */ - yylval.vWord = luaI_findconstantbyname(yytext+2); + luaY_lval.vWord = luaI_findconstantbyname(yytext+2); return STRING; } @@ -254,6 +236,7 @@ int yylex (void) case 'n': save('\n'); next(); break; case 't': save('\t'); next(); break; case 'r': save('\r'); next(); break; + case '\n': lua_linenumber++; /* goes through */ default : save(current); next(); break; } break; @@ -263,7 +246,7 @@ int yylex (void) } next(); /* skip the delimiter */ *yytextLast = 0; - yylval.vWord = luaI_findconstantbyname(yytext); + luaY_lval.vWord = luaI_findconstantbyname(yytext); return STRING; } @@ -281,12 +264,14 @@ int yylex (void) case 'Z': case '_': { - Word res; + TaggedString *ts; do { save_and_next(); } while (isalnum(current) || current == '_'); *yytextLast = 0; - res = findReserved(yytext); - if (res) return res; - yylval.pNode = lua_constcreate(yytext); + ts = lua_createstring(yytext); + if (ts->marked > 2) + return ts->marked; /* reserved word */ + luaY_lval.pTStr = ts; + ts->marked = 2; /* avoid GC */ return NAME; } @@ -305,48 +290,32 @@ int yylex (void) case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': a=0.0; - do { a=10*a+current-'0'; save_and_next(); } while (isdigit(current)); + do { a=10.0*a+(current-'0'); save_and_next(); } while (isdigit(current)); if (current == '.') save_and_next(); fraction: - { float da=0.1; + { double da=0.1; while (isdigit(current)) {a+=(current-'0')*da; da/=10.0; save_and_next()}; if (current == 'e' || current == 'E') { int e=0; int neg; - float ea; + double ea; save_and_next(); neg=(current=='-'); if (current == '+' || current == '-') save_and_next(); if (!isdigit(current)) return WRONGTOKEN; - do { e=10*e+current-'0'; save_and_next(); } while (isdigit(current)); + do { e=10.0*e+(current-'0'); save_and_next(); } while (isdigit(current)); for (ea=neg?0.1:10.0; e>0; e>>=1) { if (e & 1) a*=ea; ea*=ea; } } - yylval.vFloat = a; + luaY_lval.vFloat = a; return NUMBER; } - case U_and: case U_do: case U_else: case U_elseif: case U_end: - case U_function: case U_if: case U_local: case U_nil: case U_not: - case U_or: case U_repeat: case U_return: case U_then: - case U_until: case U_while: - { - int old = current; - next(); - return reserved[old-U_and].token; - } - - case U_eq: next(); return EQ; - case U_le: next(); return LE; - case U_ge: next(); return GE; - case U_ne: next(); return NE; - case U_sc: next(); return CONC; - default: /* also end of file */ { save_and_next(); diff --git a/src/lex.h b/src/lex.h new file mode 100644 index 00000000..7ed6fd2d --- /dev/null +++ b/src/lex.h @@ -0,0 +1,19 @@ +/* +** lex.h +** TecCGraf - PUC-Rio +** $Id: lex.h,v 1.2 1996/02/14 13:35:51 roberto Exp $ +*/ + +#ifndef lex_h +#define lex_h + + +typedef int (*Input) (void); + +void lua_setinput (Input fn); +char *lua_lasttext (void); +int luaY_lex (void); +void luaI_addReserved (void); + + +#endif diff --git a/src/lua.stx b/src/lua.stx index 99e96179..54c5a38c 100644 --- a/src/lua.stx +++ b/src/lua.stx @@ -1,12 +1,13 @@ %{ -char *rcs_luastx = "$Id: lua.stx,v 3.25 1995/10/26 17:02:50 roberto Exp $"; +char *rcs_luastx = "$Id: lua.stx,v 3.36 1996/03/21 16:31:32 roberto Exp $"; #include <stdio.h> #include <stdlib.h> -#include <string.h> +#include "luadebug.h" #include "mem.h" +#include "lex.h" #include "opcode.h" #include "hash.h" #include "inout.h" @@ -30,7 +31,7 @@ int yyparse (void); #endif static int maxcode; static int maxmain; -static Long maxcurr; /* to allow maxcurr *= 2 without overflow */ +static int maxcurr; static Byte *funcCode = NULL; static Byte **initcode; static Byte *basepc; @@ -44,35 +45,32 @@ static Long varbuffer[MAXVAR]; /* variables in an assignment list; static int nvarbuffer=0; /* number of variables at a list */ #define MAXLOCALS 32 -static Word localvar[MAXLOCALS]; /* store local variable names */ +static TaggedString *localvar[MAXLOCALS]; /* store local variable names */ static int nlocalvar=0; /* number of local variables */ #define MAXFIELDS FIELDS_PER_FLUSH*2 static Word fields[MAXFIELDS]; /* fieldnames to be flushed */ static int nfields=0; +int lua_debug = 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); + char msg[256]; + char *token = lua_lasttext(); + if (token[0] == 0) + token = "<eof>"; + sprintf (msg,"%s; last token read: \"%s\" at line %d in file `%s'", + s, token, 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 */ - { - if (maxcurr >= MAX_INT) - lua_error("code size overflow"); - maxcurr *= 2; - if (maxcurr >= MAX_INT) - maxcurr = MAX_INT; - basepc = growvector(basepc, maxcurr, Byte); - } + maxcurr = growvector(&basepc, maxcurr, Byte, codeEM, MAX_INT); basepc[pc++] = c; } @@ -104,10 +102,12 @@ static void code_code (TFunc *tf) code_byte(code.m.c4); } -static void code_word_at (Byte *p, Word n) +static void code_word_at (Byte *p, int n) { CodeWord code; - code.w = n; + if ((Word)n != n) + yyerror("block too big"); + code.w = (Word)n; *p++ = code.m.c1; *p++ = code.m.c2; } @@ -117,7 +117,7 @@ static void push_field (Word name) if (nfields < MAXFIELDS) fields[nfields++] = name; else - lua_error ("too many fields in nested constructors"); + yyerror ("too many fields in nested constructors"); } static void flush_record (int n) @@ -142,24 +142,24 @@ static void flush_list (int m, int n) code_byte(m); } else - lua_error ("list constructor too long"); + yyerror ("list constructor too long"); code_byte(n); } -static void add_localvar (Word name) +static void store_localvar (TaggedString *name, int n) { - if (nlocalvar < MAXLOCALS) - localvar[nlocalvar++] = name; + if (nlocalvar+n < MAXLOCALS) + localvar[nlocalvar+n] = name; else - lua_error ("too many local variables"); + yyerror ("too many local variables"); + if (lua_debug) + luaI_registerlocalvar(name, lua_linenumber); } -static void store_localvar (Word name, int n) +static void add_localvar (TaggedString *name) { - if (nlocalvar+n < MAXLOCALS) - localvar[nlocalvar+n] = name; - else - lua_error ("too many local variables"); + store_localvar(name, 0); + nlocalvar++; } static void add_varbuffer (Long var) @@ -167,7 +167,7 @@ static void add_varbuffer (Long var) if (nvarbuffer < MAXVAR) varbuffer[nvarbuffer++] = var; else - lua_error ("variable buffer overflow"); + yyerror ("variable buffer overflow"); } static void code_number (float f) @@ -197,7 +197,7 @@ static void code_number (float f) /* ** Search a local name and if find return its index. If do not find return -1 */ -static int lua_localname (Word n) +static int lua_localname (TaggedString *n) { int i; for (i=nlocalvar-1; i >= 0; i--) @@ -388,7 +388,6 @@ static void codeIf (Long thenAdd, Long elseAdd) */ void lua_parse (TFunc *tf) { - lua_debug = 0; initcode = &(tf->code); *initcode = newvector(CODE_BLOCK, Byte); maincode = 0; @@ -416,7 +415,7 @@ void lua_parse (TFunc *tf) Word vWord; Long vLong; TFunc *pFunc; - TreeNode *pNode; + TaggedString *pTStr; } %start functionlist @@ -429,7 +428,7 @@ void lua_parse (TFunc *tf) %token FUNCTION %token <vFloat> NUMBER %token <vWord> STRING -%token <pNode> NAME +%token <pTStr> NAME %token <vInt> DEBUG %type <vLong> PrepJump @@ -481,7 +480,7 @@ funcname : var { $$ =$1; init_func(); } code_word(luaI_findconstant($3)); $$ = 0; /* indexed variable */ init_func(); - add_localvar(luaI_findsymbolbyname("self")); + add_localvar(luaI_createfixedstring("self")); } ; @@ -489,11 +488,14 @@ body : '(' parlist ')' block END { codereturn(); $$ = new(TFunc); + luaI_initTFunc($$); $$->size = pc; $$->code = newvector(pc, Byte); $$->fileName = lua_parsedfile; $$->lineDefined = $2; memcpy($$->code, basepc, pc*sizeof(Byte)); + if (lua_debug) + luaI_closelocalvars($$); /* save func values */ funcCode = basepc; maxcode=maxcurr; #if LISTING @@ -554,7 +556,11 @@ block : {$<vInt>$ = nlocalvar;} statlist ret { if (nlocalvar != $<vInt>1) { - nlocalvar = $<vInt>1; + if (lua_debug) + for (; nlocalvar > $<vInt>1; nlocalvar--) + luaI_unregisterlocalvar(lua_linenumber); + else + nlocalvar = $<vInt>1; lua_codeadjust (0); } } @@ -672,14 +678,8 @@ parlist : /* empty */ { lua_codeadjust(0); $$ = lua_linenumber; } | parlist1 { lua_codeadjust(0); $$ = lua_linenumber; } ; -parlist1 : NAME - { - add_localvar(luaI_findsymbol($1)); - } - | parlist1 ',' NAME - { - add_localvar(luaI_findsymbol($3)); - } +parlist1 : NAME { add_localvar($1); } + | parlist1 ',' NAME { add_localvar($3); } ; fieldlist : lfieldlist @@ -759,10 +759,9 @@ var : singlevar { $$ = $1; } singlevar : NAME { - Word s = luaI_findsymbol($1); - int local = lua_localname (s); + int local = lua_localname($1); if (local == -1) /* global var */ - $$ = s + 1; /* return positive value */ + $$ = luaI_findsymbol($1)+1; /* return positive value */ else $$ = -(local+1); /* return negative value */ } @@ -771,10 +770,10 @@ singlevar : NAME varexp : var { lua_pushvar($1); } ; -localdeclist : NAME {store_localvar(luaI_findsymbol($1), 0); $$ = 1;} +localdeclist : NAME {store_localvar($1, 0); $$ = 1;} | localdeclist ',' NAME { - store_localvar(luaI_findsymbol($3), $1); + store_localvar($3, $1); $$ = $1+1; } ; @@ -787,228 +786,3 @@ setdebug : DEBUG { lua_debug = $1; } ; %% - -#if LISTING - -static void PrintCode (Byte *code, Byte *end) -{ - Byte *p = code; - printf ("\n\nCODE\n"); - while (p != end) - { - switch ((OpCode)*p) - { - case PUSHNIL: printf ("%d PUSHNIL\n", (p++)-code); break; - case PUSH0: case PUSH1: case PUSH2: - printf ("%d PUSH%c\n", p-code, *p-PUSH0+'0'); - p++; - break; - case PUSHBYTE: - printf ("%d PUSHBYTE %d\n", p-code, *(++p)); - p++; - break; - case PUSHWORD: - { - CodeWord c; - int n = p-code; - p++; - get_word(c,p); - printf ("%d PUSHWORD %d\n", n, c.w); - } - break; - case PUSHFLOAT: - { - CodeFloat c; - int n = p-code; - p++; - get_float(c,p); - printf ("%d PUSHFLOAT %f\n", n, c.f); - } - break; - case PUSHSTRING: - { - CodeWord c; - int n = p-code; - p++; - get_word(c,p); - printf ("%d PUSHSTRING %d\n", n, c.w); - } - break; - case PUSHFUNCTION: - { - CodeCode c; - int n = p-code; - p++; - get_code(c,p); - printf ("%d PUSHFUNCTION %p\n", n, c.tf); - } - break; - - case PUSHLOCAL0: case PUSHLOCAL1: case PUSHLOCAL2: case PUSHLOCAL3: - case PUSHLOCAL4: case PUSHLOCAL5: case PUSHLOCAL6: case PUSHLOCAL7: - case PUSHLOCAL8: case PUSHLOCAL9: - printf ("%d PUSHLOCAL%c\n", p-code, *p-PUSHLOCAL0+'0'); - p++; - break; - case PUSHLOCAL: printf ("%d PUSHLOCAL %d\n", p-code, *(++p)); - p++; - break; - case PUSHGLOBAL: - { - CodeWord c; - int n = p-code; - p++; - get_word(c,p); - printf ("%d PUSHGLOBAL %d\n", n, c.w); - } - break; - case PUSHINDEXED: printf ("%d PUSHINDEXED\n", (p++)-code); break; - case STORELOCAL0: case STORELOCAL1: case STORELOCAL2: case STORELOCAL3: - case STORELOCAL4: case STORELOCAL5: case STORELOCAL6: case STORELOCAL7: - case STORELOCAL8: case STORELOCAL9: - printf ("%d STORELOCAL%c\n", p-code, *p-STORELOCAL0+'0'); - p++; - break; - case STORELOCAL: - printf ("%d STORELOCAL %d\n", p-code, *(++p)); - p++; - break; - case STOREGLOBAL: - { - CodeWord c; - int n = p-code; - p++; - get_word(c,p); - printf ("%d STOREGLOBAL %d\n", n, c.w); - } - break; - case PUSHSELF: - { - CodeWord c; - int n = p-code; - p++; - get_word(c,p); - printf ("%d PUSHSELF %d\n", n, c.w); - } - break; - case STOREINDEXED0: printf ("%d STOREINDEXED0\n", (p++)-code); break; - case STOREINDEXED: printf ("%d STOREINDEXED %d\n", p-code, *(++p)); - p++; - break; - case STORELIST0: - printf("%d STORELIST0 %d\n", p-code, *(++p)); - p++; - break; - case STORELIST: - printf("%d STORELIST %d %d\n", p-code, *(p+1), *(p+2)); - p+=3; - break; - case STORERECORD: - printf("%d STORERECORD %d\n", p-code, *(++p)); - p += *p*sizeof(Word) + 1; - break; - case ADJUST0: printf ("%d ADJUST0\n", (p++)-code); break; - case ADJUST: - printf ("%d ADJUST %d\n", p-code, *(++p)); - p++; - break; - case CREATEARRAY: - { - CodeWord c; - int n = p-code; - p++; - get_word(c,p); - printf ("%d CREATEARRAY %d\n", n, c.w); - break; - } - case EQOP: printf ("%d EQOP\n", (p++)-code); break; - case LTOP: printf ("%d LTOP\n", (p++)-code); break; - case LEOP: printf ("%d LEOP\n", (p++)-code); break; - case ADDOP: printf ("%d ADDOP\n", (p++)-code); break; - case SUBOP: printf ("%d SUBOP\n", (p++)-code); break; - case MULTOP: printf ("%d MULTOP\n", (p++)-code); break; - case DIVOP: printf ("%d DIVOP\n", (p++)-code); break; - case POWOP: printf ("%d POWOP\n", (p++)-code); break; - case CONCOP: printf ("%d CONCOP\n", (p++)-code); break; - case MINUSOP: printf ("%d MINUSOP\n", (p++)-code); break; - case NOTOP: printf ("%d NOTOP\n", (p++)-code); break; - case ONTJMP: - { - CodeWord c; - int n = p-code; - p++; - get_word(c,p); - printf ("%d ONTJMP %d\n", n, c.w); - } - break; - case ONFJMP: - { - CodeWord c; - int n = p-code; - p++; - get_word(c,p); - printf ("%d ONFJMP %d\n", n, c.w); - } - break; - case JMP: - { - CodeWord c; - int n = p-code; - p++; - get_word(c,p); - printf ("%d JMP %d\n", n, c.w); - } - break; - case UPJMP: - { - CodeWord c; - int n = p-code; - p++; - get_word(c,p); - printf ("%d UPJMP %d\n", n, c.w); - } - break; - case IFFJMP: - { - CodeWord c; - int n = p-code; - p++; - get_word(c,p); - printf ("%d IFFJMP %d\n", n, c.w); - } - break; - case IFFUPJMP: - { - CodeWord c; - int n = p-code; - p++; - get_word(c,p); - printf ("%d IFFUPJMP %d\n", n, c.w); - } - break; - case POP: printf ("%d POP\n", (p++)-code); break; - case CALLFUNC: - printf ("%d CALLFUNC %d %d\n", p-code, *(p+1), *(p+2)); - p+=3; - break; - case RETCODE0: printf ("%d RETCODE0\n", (p++)-code); break; - case RETCODE: - printf ("%d RETCODE %d\n", p-code, *(++p)); - p++; - break; - case SETLINE: - { - CodeWord c; - int n = p-code; - p++; - get_word(c,p); - printf ("%d SETLINE %d\n", n, c.w); - } - break; - - default: printf ("%d Cannot happen: code %d\n", (p++)-code, *(p-1)); break; - } - } -} -#endif - diff --git a/src/luac/Makefile b/src/luac/Makefile new file mode 100644 index 00000000..813393e4 --- /dev/null +++ b/src/luac/Makefile @@ -0,0 +1,24 @@ +# makefile for lua distribution (compiler) + +LUA= ../.. + +include $(LUA)/config + +INCS= -I$(INC) $(EXTRA_INCS) -I.. +OBJS= dump.o luac.o print.o +SRCS= dump.c luac.c print.c luac.h print.h +T=$(BIN)/luac + +all: $T + +$T: $(OBJS) + $(CC) -o $@ $(OBJS) -L$(LIB) -llua + +clean: + rm -f $(OBJS) $T + +co: + co -f -M $(SRCS) + +klean: clean + rm -f $(SRCS) diff --git a/src/luac/dump.c b/src/luac/dump.c new file mode 100644 index 00000000..22db5e36 --- /dev/null +++ b/src/luac/dump.c @@ -0,0 +1,247 @@ +/* +** dump.c +** thread and save bytecodes to file +*/ + +char* rcs_dump="$Id: dump.c,v 1.12 1996/03/12 20:00:03 lhf Exp $"; + +#include <stdio.h> +#include <string.h> +#include "luac.h" + +static TFunc* lastF=NULL; /* list of functions seen in code */ + +static int SawVar(int i, int at) +{ + int old=VarLoc(i); + VarLoc(i)=at; + return old; +} + +static int SawStr(int i, int at) +{ + int old=StrLoc(i); + StrLoc(i)=at; + return old; +} + +static void ThreadCode(Byte* code, Byte* end) +{ + Byte* p; + int i; + for (i=0; i<lua_ntable; i++) VarLoc(i)=0; + for (i=0; i<lua_nconstant; i++) StrLoc(i)=0; + for (p=code; p!=end;) + { + OpCode op=(OpCode)*p; + int at=p-code+1; + switch (op) + { + case PUSHNIL: + case PUSH0: + case PUSH1: + case PUSH2: + case PUSHLOCAL0: + case PUSHLOCAL1: + case PUSHLOCAL2: + case PUSHLOCAL3: + case PUSHLOCAL4: + case PUSHLOCAL5: + case PUSHLOCAL6: + case PUSHLOCAL7: + case PUSHLOCAL8: + case PUSHLOCAL9: + case PUSHINDEXED: + case STORELOCAL0: + case STORELOCAL1: + case STORELOCAL2: + case STORELOCAL3: + case STORELOCAL4: + case STORELOCAL5: + case STORELOCAL6: + case STORELOCAL7: + case STORELOCAL8: + case STORELOCAL9: + case STOREINDEXED0: + case ADJUST0: + case EQOP: + case LTOP: + case LEOP: + case GTOP: + case GEOP: + case ADDOP: + case SUBOP: + case MULTOP: + case DIVOP: + case POWOP: + case CONCOP: + case MINUSOP: + case NOTOP: + case POP: + case RETCODE0: + p++; + break; + case PUSHBYTE: + case PUSHLOCAL: + case STORELOCAL: + case STOREINDEXED: + case STORELIST0: + case ADJUST: + case RETCODE: + p+=2; + break; + case PUSHWORD: + case CREATEARRAY: + case ONTJMP: + case ONFJMP: + case JMP: + case UPJMP: + case IFFJMP: + case IFFUPJMP: + case SETLINE: + case STORELIST: + case CALLFUNC: + p+=3; + break; + case PUSHFLOAT: + p+=5; + break; + case PUSHSELF: + case PUSHSTRING: + { + CodeWord c; + p++; + get_word(c,p); + c.w=SawStr(c.w,at); + p[-2]=c.m.c1; + p[-1]=c.m.c2; + break; + } + case PUSHFUNCTION: + { + CodeCode c; + p++; + get_code(c,p); + c.tf->marked=at; + c.tf->next=NULL; /* TODO: remove? */ + lastF=lastF->next=c.tf; + break; + } + case PUSHGLOBAL: + case STOREGLOBAL: + { + CodeWord c; + p++; + get_word(c,p); + c.w=SawVar(c.w,at); + p[-2]=c.m.c1; + p[-1]=c.m.c2; + break; + } + case STORERECORD: + { + int n=*++p; + p++; + while (n--) + { + CodeWord c; + at=p-code; + get_word(c,p); + c.w=SawStr(c.w,at); + p[-2]=c.m.c1; + p[-1]=c.m.c2; + } + break; + } + default: + fprintf(stderr,"luac: cannot happen: opcode=%d",*p); + exit(1); + break; + } + } +} + +static void DumpWord(int i, FILE* D) +{ + Word w=i; + fwrite(&w,sizeof(w),1,D); +} + +static void DumpBlock(char* b, int size, FILE* D) +{ + fwrite(b,size,1,D); +} + +static void DumpSize(int i, FILE* D) +{ + Word lo=i&0x0FFFF; + Word hi=(i>>16)&0x0FFFF; + fwrite(&hi,sizeof(hi),1,D); + fwrite(&lo,sizeof(lo),1,D); + if (hi!=0) + fprintf(stderr, + "luac: warning: code too long for 16-bit machines (%d bytes)\n",i); +} + +static void DumpString(char* s, FILE* D) +{ + int n=strlen(s)+1; + if ((Word)n != n) + { + fprintf(stderr,"luac: string too long: \"%.32s...\"\n",s); + exit(1); + } + DumpWord(n,D); + DumpBlock(s,n,D); +} + +static void DumpStrings(FILE* D) +{ + int i; + for (i=0; i<lua_ntable; i++) + { + if (VarLoc(i)!=0) + { + fputc(ID_VAR,D); + DumpWord(VarLoc(i),D); + DumpString(VarStr(i),D); + } + VarLoc(i)=i; + } + for (i=0; i<lua_nconstant; i++) + { + if (StrLoc(i)!=0) + { + fputc(ID_STR,D); + DumpWord(StrLoc(i),D); + DumpString(StrStr(i),D); + } + StrLoc(i)=i; + } +} + +void DumpFunction(TFunc* tf, FILE* D) +{ + lastF=tf; + ThreadCode(tf->code,tf->code+tf->size); + fputc(ID_FUN,D); + DumpSize(tf->size,D); + DumpWord(tf->lineDefined,D); + if (IsMain(tf)) + DumpString(tf->fileName,D); + else + DumpWord(tf->marked,D); + DumpBlock(tf->code,tf->size,D); + DumpStrings(D); +} + +void DumpHeader(FILE* D) +{ + Word w=TEST_WORD; + float f=TEST_FLOAT; + fputc(ID_CHUNK,D); + fputs(SIGNATURE,D); + fputc(VERSION,D); + fwrite(&w,sizeof(w),1,D); + fwrite(&f,sizeof(f),1,D); +} diff --git a/src/luac/luac.c b/src/luac/luac.c new file mode 100644 index 00000000..aa71afcf --- /dev/null +++ b/src/luac/luac.c @@ -0,0 +1,104 @@ +/* +** luac.c +** lua compiler (saves bytecodes to files) +*/ + +char* rcs_luac="$Id: luac.c,v 1.16 1996/03/13 17:33:03 lhf Exp $"; + +#include <stdio.h> +#include <string.h> +#include "luac.h" + +static void compile(char* filename); + +static int listing=0; /* list bytecodes? */ +static int dumping=1; /* dump bytecodes? */ +static FILE* D; /* output file */ + +static void usage(void) +{ + fprintf(stderr,"usage: luac [-dlpv] [-o output] file ...\n"); + exit(0); +} + +#define IS(s) (strcmp(argv[i],s)==0) + +int main(int argc, char* argv[]) +{ + char* d="luac.out"; /* default output file */ + int i; + for (i=1; i<argc; i++) + { + if (argv[i][0]!='-') /* end of options */ + break; + else if (IS("-")) /* use stdin */ + break; + else if (IS("-d")) /* debug */ + lua_debug=1; + else if (IS("-l")) /* list */ + listing=1; + else if (IS("-o")) /* output file */ + d=argv[++i]; + else if (IS("-p")) /* parse only (for timing purposes) */ + dumping=0; + else if (IS("-v")) /* show version */ + printf("%s %s\n(written by %s)\n\n",LUA_VERSION,LUA_COPYRIGHT,LUA_AUTHORS); + else /* unknown option */ + usage(); + } + --i; /* fake new argv[0] */ + argc-=i; + argv+=i; + if (argc<2) usage(); + for (i=1; i<argc; i++) + if (IS(d)) + { + fprintf(stderr,"luac: will not overwrite input file \"%s\"\n",d); + exit(1); + } + D=(dumping) ? fopen(d,"wb") : stdout; /* must open in binary mode */ + if (D==NULL) + { + fprintf(stderr,"luac: cannot open "); + perror(d); + exit(1); + } + for (i=1; i<argc; i++) compile(IS("-")? NULL : argv[i]); + fclose(D); + return 0; +} + +static void do_dump(TFunc* tf) /* only for tf==main */ +{ + if (dumping) DumpHeader(D); + while (tf!=NULL) + { + TFunc* nf; + if (listing) PrintFunction(tf); + if (dumping) DumpFunction(tf,D); + nf=tf->next; /* list only built after first main */ + luaI_freefunc(tf); + tf=nf; + } +} + +static void do_compile(void) +{ + TFunc* tf=new(TFunc); + luaI_initTFunc(tf); + tf->fileName = lua_parsedfile; + lua_parse(tf); + do_dump(tf); +} + +static void compile(char* filename) +{ + if (lua_openfile(filename)==NULL) + { + fprintf(stderr,"luac: cannot open "); + perror(filename); + exit(1); + } + do_compile(); + lua_closefile(); +} diff --git a/src/luac/luac.h b/src/luac/luac.h new file mode 100644 index 00000000..ceb311b8 --- /dev/null +++ b/src/luac/luac.h @@ -0,0 +1,24 @@ +/* +** luac.h +** definitions for luac compiler +** $Id: luac.h,v 1.5 1996/03/08 21:41:47 lhf Exp $ +*/ + +#include "inout.h" +#include "mem.h" +#include "opcode.h" +#include "table.h" +#include "undump.h" + +#define VarStr(i) (lua_table[i].varname->str) +#define VarLoc(i) (lua_table[i].varname->varindex) +#define StrStr(i) (lua_constant[i]->str) +#define StrLoc(i) (lua_constant[i]->constindex) + +extern Word lua_ntable; +extern Word lua_nconstant; +extern int lua_debug; + +void DumpHeader(FILE* D); +void DumpFunction(TFunc* tf, FILE* D); +void PrintFunction(TFunc* tf); diff --git a/src/luac/print.c b/src/luac/print.c new file mode 100644 index 00000000..1b338931 --- /dev/null +++ b/src/luac/print.c @@ -0,0 +1,189 @@ +/* +** print.c +** print bytecodes +*/ + +char* rcs_print="$Id: print.c,v 1.6 1996/03/12 20:00:24 lhf Exp $"; + +#include <stdio.h> +#include <string.h> +#include "luac.h" +#include "print.h" + +static LocVar* V=NULL; + +static char* LocStr(int i) +{ + if (V==NULL) return ""; else return V[i].varname->str; +} + +static void PrintCode(Byte* code, Byte* end) +{ + Byte* p; + for (p=code; p!=end;) + { + OpCode op=(OpCode)*p; + if (op>SETLINE) op=SETLINE+1; + printf("%6d\t%s",p-code,OpCodeName[op]); + switch (op) + { + case PUSHNIL: + case PUSH0: + case PUSH1: + case PUSH2: + case PUSHINDEXED: + case STOREINDEXED0: + case ADJUST0: + case EQOP: + case LTOP: + case LEOP: + case GTOP: + case GEOP: + case ADDOP: + case SUBOP: + case MULTOP: + case DIVOP: + case POWOP: + case CONCOP: + case MINUSOP: + case NOTOP: + case POP: + case RETCODE0: + p++; + break; + case PUSHLOCAL0: + case PUSHLOCAL1: + case PUSHLOCAL2: + case PUSHLOCAL3: + case PUSHLOCAL4: + case PUSHLOCAL5: + case PUSHLOCAL6: + case PUSHLOCAL7: + case PUSHLOCAL8: + case PUSHLOCAL9: + { + int i=op-PUSHLOCAL0; + printf("\t%d\t; %s",i,LocStr(i)); + p++; + break; + } + case STORELOCAL0: + case STORELOCAL1: + case STORELOCAL2: + case STORELOCAL3: + case STORELOCAL4: + case STORELOCAL5: + case STORELOCAL6: + case STORELOCAL7: + case STORELOCAL8: + case STORELOCAL9: + { + int i=op-STORELOCAL0; + printf("\t%d\t; %s",i,LocStr(i)); + p++; + break; + } + case PUSHLOCAL: + case STORELOCAL: + { + int i=*(p+1); + printf("\t%d\t; %s",i,LocStr(i)); + p+=2; + break; + } + case PUSHBYTE: + case STOREINDEXED: + case STORELIST0: + case ADJUST: + case RETCODE: + printf("\t%d",*(p+1)); + p+=2; + break; + case PUSHWORD: + case CREATEARRAY: + case ONTJMP: + case ONFJMP: + case JMP: + case UPJMP: + case IFFJMP: + case IFFUPJMP: + case SETLINE: + { + CodeWord c; + p++; + get_word(c,p); + printf("\t%d",c.w); + break; + } + case PUSHFLOAT: + { + CodeFloat c; + p++; + get_float(c,p); + printf("\t%g",c.f); + break; + } + case PUSHSELF: + case PUSHSTRING: + { + CodeWord c; + p++; + get_word(c,p); + printf("\t%d\t; \"%s\"",c.w,StrStr(c.w)); + break; + } + case PUSHFUNCTION: + { + CodeCode c; + p++; + get_code(c,p); + printf("\t%p\t; \"%s\":%d",c.tf,c.tf->fileName,c.tf->lineDefined); + break; + } + case PUSHGLOBAL: + case STOREGLOBAL: + { + CodeWord c; + p++; + get_word(c,p); + printf("\t%d\t; %s",c.w,VarStr(c.w)); + break; + } + case STORELIST: + case CALLFUNC: + printf("\t%d %d",*(p+1),*(p+2)); + p+=3; + break; + case STORERECORD: + { + int n=*++p; + printf("\t%d",n); + p++; + while (n--) + { + CodeWord c; + printf("\n%6d\t FIELD",p-code); + get_word(c,p); + printf("\t%d\t; \"%s\"",c.w,StrStr(c.w)); + } + break; + } + default: + printf("\tcannot happen: opcode=%d",*p); + exit(1); + break; + } + printf("\n"); + } +} + +void PrintFunction(TFunc* tf) +{ + if (IsMain(tf)) + printf("\nmain of \"%s\" (%d bytes at %p)\n",tf->fileName,tf->size,tf); + else + printf("\nfunction \"%s\":%d (%d bytes at %p); used at main+%d\n", + tf->fileName,tf->lineDefined,tf->size,tf,tf->marked); + V=tf->locvars; + PrintCode(tf->code,tf->code+tf->size); +} diff --git a/src/luac/print.h b/src/luac/print.h new file mode 100644 index 00000000..31e2bb89 --- /dev/null +++ b/src/luac/print.h @@ -0,0 +1,76 @@ +/* +** print.h +** opcode names +** $Id: print.h,v 1.1 1996/02/23 19:04:13 lhf Exp $ +*/ + +static char* OpCodeName[]={ /* attention: same order as enum in opcode.h */ + "PUSHNIL", + "PUSH0", + "PUSH1", + "PUSH2", + "PUSHBYTE", + "PUSHWORD", + "PUSHFLOAT", + "PUSHSTRING", + "PUSHFUNCTION", + "PUSHLOCAL0", + "PUSHLOCAL1", + "PUSHLOCAL2", + "PUSHLOCAL3", + "PUSHLOCAL4", + "PUSHLOCAL5", + "PUSHLOCAL6", + "PUSHLOCAL7", + "PUSHLOCAL8", + "PUSHLOCAL9", + "PUSHLOCAL", + "PUSHGLOBAL", + "PUSHINDEXED", + "PUSHSELF", + "STORELOCAL0", + "STORELOCAL1", + "STORELOCAL2", + "STORELOCAL3", + "STORELOCAL4", + "STORELOCAL5", + "STORELOCAL6", + "STORELOCAL7", + "STORELOCAL8", + "STORELOCAL9", + "STORELOCAL", + "STOREGLOBAL", + "STOREINDEXED0", + "STOREINDEXED", + "STORELIST0", + "STORELIST", + "STORERECORD", + "ADJUST0", + "ADJUST", + "CREATEARRAY", + "EQOP", + "LTOP", + "LEOP", + "GTOP", + "GEOP", + "ADDOP", + "SUBOP", + "MULTOP", + "DIVOP", + "POWOP", + "CONCOP", + "MINUSOP", + "NOTOP", + "ONTJMP", + "ONFJMP", + "JMP", + "UPJMP", + "IFFJMP", + "IFFUPJMP", + "POP", + "CALLFUNC", + "RETCODE0", + "RETCODE", + "SETLINE", + "" +}; @@ -3,18 +3,24 @@ ** TecCGraf - PUC-Rio */ -char *rcs_mem = "$Id: mem.c,v 1.5 1995/02/06 19:34:03 roberto Exp $"; +char *rcs_mem = "$Id: mem.c,v 1.12 1996/05/06 16:59:00 roberto Exp $"; #include <stdlib.h> -#include <string.h> #include "mem.h" #include "lua.h" + +#define mem_error() lua_error(memEM) + + void luaI_free (void *block) { - *((int *)block) = -1; /* to catch errors */ - free(block); + if (block) + { + *((int *)block) = -1; /* to catch errors */ + free(block); + } } @@ -22,23 +28,40 @@ void *luaI_malloc (unsigned long size) { void *block = malloc((size_t)size); if (block == NULL) - lua_error("not enough memory"); + mem_error(); return block; } void *luaI_realloc (void *oldblock, unsigned long size) { - void *block = realloc(oldblock, (size_t)size); + void *block = oldblock ? realloc(oldblock, (size_t)size) : + malloc((size_t)size); if (block == NULL) - lua_error("not enough memory"); + mem_error(); return block; } -char *luaI_strdup (char *str) +int luaI_growvector (void **block, unsigned long nelems, int size, + char *errormsg, unsigned long limit) { - char *newstr = luaI_malloc(strlen(str)+1); - strcpy(newstr, str); - return newstr; + if (nelems >= limit) + lua_error(errormsg); + nelems = (nelems == 0) ? 20 : nelems*2; + if (nelems > limit) + nelems = limit; + *block = luaI_realloc(*block, nelems*size); + return (int) nelems; } + + +void* luaI_buffer (unsigned long size) +{ + static unsigned long buffsize = 0; + static char* buffer = NULL; + if (size > buffsize) + buffer = luaI_realloc(buffer, buffsize=size); + return buffer; +} + @@ -1,7 +1,7 @@ /* ** mem.c ** memory manager for lua -** $Id: mem.h,v 1.2 1995/01/13 22:11:12 roberto Exp $ +** $Id: mem.h,v 1.7 1996/04/22 18:00:37 roberto Exp $ */ #ifndef mem_h @@ -11,15 +11,29 @@ #define NULL 0 #endif + +/* memory error messages */ +#define codeEM "code size overflow" +#define symbolEM "symbol table overflow" +#define constantEM "constant table overflow" +#define stackEM "stack size overflow" +#define lexEM "lex buffer overflow" +#define refEM "reference table overflow" +#define tableEM "table overflow" +#define memEM "not enough memory" + + void luaI_free (void *block); void *luaI_malloc (unsigned long size); void *luaI_realloc (void *oldblock, unsigned long size); - -char *luaI_strdup (char *str); +void *luaI_buffer (unsigned long size); +int luaI_growvector (void **block, unsigned long nelems, int size, + char *errormsg, unsigned long limit); #define new(s) ((s *)luaI_malloc(sizeof(s))) #define newvector(n,s) ((s *)luaI_malloc((n)*sizeof(s))) -#define growvector(old,n,s) ((s *)luaI_realloc(old,(n)*sizeof(s))) +#define growvector(old,n,s,e,l) \ + (luaI_growvector((void**)old,n,sizeof(s),e,l)) #endif diff --git a/src/opcode.c b/src/opcode.c index e4089f01..d3f655be 100644 --- a/src/opcode.c +++ b/src/opcode.c @@ -3,10 +3,9 @@ ** TecCGraf - PUC-Rio */ -char *rcs_opcode="$Id: opcode.c,v 3.50 1995/11/16 20:46:24 roberto Exp $"; +char *rcs_opcode="$Id: opcode.c,v 3.68 1996/04/25 14:10:00 roberto Exp $"; #include <setjmp.h> -#include <stdlib.h> #include <stdio.h> #include <string.h> @@ -18,6 +17,7 @@ char *rcs_opcode="$Id: opcode.c,v 3.50 1995/11/16 20:46:24 roberto Exp $"; #include "table.h" #include "lua.h" #include "fallback.h" +#include "undump.h" #define tonumber(o) ((tag(o) != LUA_T_NUMBER) && (lua_tonumber(o) != 0)) #define tostring(o) ((tag(o) != LUA_T_STRING) && (lua_tostring(o) != 0)) @@ -25,6 +25,10 @@ char *rcs_opcode="$Id: opcode.c,v 3.50 1995/11/16 20:46:24 roberto Exp $"; #define STACK_SIZE 128 +#ifndef STACK_LIMIT +#define STACK_LIMIT 6000 +#endif + typedef int StkId; /* index to stack elements */ static Object initial_stack; @@ -53,6 +57,11 @@ static int CnResults = 0; /* when Lua calls C, has the number of parameters; */ static jmp_buf *errorJmp = NULL; /* current error recover point */ +/* Hooks */ +lua_LHFunction lua_linehook = NULL; +lua_CHFunction lua_callhook = NULL; + + static StkId lua_execute (Byte *pc, StkId base); static void do_call (StkId base, int nResults); @@ -64,7 +73,6 @@ Object *luaI_Address (lua_Object o) } - /* ** Init stack */ @@ -89,14 +97,17 @@ static void growstack (void) lua_initstack(); else { + static int limit = STACK_LIMIT; StkId t = top-stack; - Long maxstack = stackLimit - stack; - maxstack *= 2; - stack = growvector(stack, maxstack, Object); - stackLimit = stack+maxstack; + Long stacksize = stackLimit - stack; + stacksize = growvector(&stack, stacksize, Object, stackEM, limit+100); + stackLimit = stack+stacksize; top = stack + t; - if (maxstack >= MAX_WORD/2) - lua_error("stack size overflow"); + if (stacksize >= limit) + { + limit = stacksize; + lua_error(stackEM); + } } } @@ -106,18 +117,9 @@ static void growstack (void) */ static char *lua_strconc (char *l, char *r) { - static char *buffer = NULL; - static int buffer_size = 0; - int nl = strlen(l); - int n = nl+strlen(r)+1; - if (n > buffer_size) - { - buffer_size = n; - if (buffer != NULL) - luaI_free(buffer); - buffer = newvector(buffer_size, char); - } - strcpy(buffer,l); + int nl = strlen(l); + char *buffer = luaI_buffer(nl+strlen(r)+1); + strcpy(buffer, l); strcpy(buffer+nl, r); return buffer; } @@ -150,7 +152,7 @@ static int lua_tonumber (Object *obj) */ static int lua_tostring (Object *obj) { - static char s[256]; + char s[256]; if (tag(obj) != LUA_T_NUMBER) return 1; if ((int) nvalue(obj) == nvalue(obj)) @@ -158,8 +160,6 @@ static int lua_tostring (Object *obj) else sprintf (s, "%g", nvalue(obj)); tsvalue(obj) = lua_createstring(s); - if (tsvalue(obj) == NULL) - return 1; tag(obj) = LUA_T_STRING; return 0; } @@ -193,6 +193,48 @@ static void open_stack (int nelems) /* +** call Line hook +*/ +static void lineHook (int line) +{ + StkId oldBase = CBase; + int oldCnResults = CnResults; + StkId old_top = CBase = top-stack; + CnResults = 0; + (*lua_linehook)(line); + top = stack+old_top; + CnResults = oldCnResults; + CBase = oldBase; +} + + +/* +** Call hook +** The function being called is in [stack+base-1] +*/ +static void callHook (StkId base, lua_Type type, int isreturn) +{ + StkId oldBase = CBase; + int oldCnResults = CnResults; + StkId old_top = CBase = top-stack; + CnResults = 0; + if (isreturn) + (*lua_callhook)(LUA_NOOBJECT, "(return)", 0); + else + { + Object *f = stack+base-1; + if (type == LUA_T_MARK) + (*lua_callhook)(Ref(f), f->value.tf->fileName, f->value.tf->lineDefined); + else + (*lua_callhook)(Ref(f), "(C)", -1); + } + top = stack+old_top; + CnResults = oldCnResults; + CBase = oldBase; +} + + +/* ** Call a C function. CBase will point to the top of the stack, ** and CnResults is the number of parameters. Returns an index ** to the first result from C. @@ -204,8 +246,12 @@ static StkId callC (lua_CFunction func, StkId base) StkId firstResult; CnResults = (top-stack) - base; /* incorporate parameters on the stack */ - CBase = base+CnResults; + CBase = base+CnResults; /* == top-stack */ + if (lua_callhook) + callHook(base, LUA_T_CMARK, 0); (*func)(); + if (lua_callhook) /* func may have changed lua_callhook */ + callHook(base, LUA_T_CMARK, 1); firstResult = CBase; CBase = oldBase; CnResults = oldCnResults; @@ -303,6 +349,18 @@ static void storesubscript (void) } +static void getglobal (Word n) +{ + *top = lua_table[n].object; + incr_top; + if (tag(top-1) == LUA_T_NIL) + { /* must call getglobal fallback */ + tag(top-1) = LUA_T_STRING; + tsvalue(top-1) = lua_table[n].varname; + callFB(FB_GETGLOBAL); + } +} + /* ** Traverse all objects on stack */ @@ -340,7 +398,7 @@ void lua_error (char *s) } -lua_Object lua_stackedfunction (int level) +lua_Function lua_stackedfunction (int level) { Object *p = top; while (--p >= stack) @@ -351,13 +409,45 @@ lua_Object lua_stackedfunction (int level) } -int lua_currentline (lua_Object func) +int lua_currentline (lua_Function func) { Object *f = Address(func); return (f+1 < top && (f+1)->tag == LUA_T_LINE) ? (f+1)->value.i : -1; } +lua_Object lua_getlocal (lua_Function func, int local_number, char **name) +{ + Object *f = luaI_Address(func); + *name = luaI_getlocalname(f->value.tf, local_number, lua_currentline(func)); + if (*name) + { + /* if "*name", there must be a LUA_T_LINE */ + /* therefore, f+2 points to function base */ + return Ref((f+2)+(local_number-1)); + } + else + return LUA_NOOBJECT; +} + +int lua_setlocal (lua_Function func, int local_number) +{ + Object *f = Address(func); + char *name = luaI_getlocalname(f->value.tf, local_number, lua_currentline(func)); + adjustC(1); + --top; + if (name) + { + /* if "name", there must be a LUA_T_LINE */ + /* therefore, f+2 points to function base */ + *((f+2)+(local_number-1)) = *top; + return 1; + } + else + return 0; +} + + /* ** Execute a protected call. Assumes that function is at CBase and ** parameters are on top of it. Leave nResults on the stack. @@ -386,6 +476,16 @@ static int do_protectedrun (int nResults) return status; } +int luaI_dorun (TFunc *tf) +{ + int status; + adjustC(1); /* one slot for the pseudo-function */ + stack[CBase].tag = LUA_T_FUNCTION; + stack[CBase].value.tf = tf; + status = do_protectedrun(0); + adjustC(0); + return status; +} static int do_protectedmain (void) { @@ -394,16 +494,12 @@ static int do_protectedmain (void) 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; + luaI_initTFunc(&tf); tf.fileName = lua_parsedfile; - tf.code = NULL; if (setjmp(myErrorJmp) == 0) { lua_parse(&tf); - status = do_protectedrun(0); + status = luaI_dorun(&tf); } else { @@ -411,8 +507,7 @@ static int do_protectedmain (void) adjustC(0); /* erase extra slot */ } errorJmp = oldErr; - if (tf.code) - luaI_free(tf.code); + luaI_free(tf.code); return status; } @@ -449,13 +544,13 @@ int lua_call (char *funcname) int lua_dofile (char *filename) { int status; - char *message = lua_openfile (filename); - if (message) - { - lua_message(message); + int c; + FILE *f = lua_openfile(filename); + if (f == NULL) return 1; - } - status = do_protectedmain(); + c = fgetc(f); + ungetc(c, f); + status = (c == ID_CHUNK) ? luaI_undump(f) : do_protectedmain(); lua_closefile(); return status; } @@ -514,8 +609,9 @@ static StkId Cblocks[MAX_C_BLOCKS]; */ void lua_beginblock (void) { - if (numCblocks < MAX_C_BLOCKS) - Cblocks[numCblocks] = CBase; + if (numCblocks >= MAX_C_BLOCKS) + lua_error("`lua_beginblock': too many nested blocks"); + Cblocks[numCblocks] = CBase; numCblocks++; } @@ -525,11 +621,8 @@ void lua_beginblock (void) void lua_endblock (void) { --numCblocks; - if (numCblocks < MAX_C_BLOCKS) - { - CBase = Cblocks[numCblocks]; - adjustC(0); - } + CBase = Cblocks[numCblocks]; + adjustC(0); } /* @@ -566,6 +659,23 @@ lua_Object lua_getparam (int number) return CBase-CnResults+number; } +int lua_isnumber (lua_Object object) +{ + return (object != LUA_NOOBJECT) && (tonumber(Address(object)) == 0); +} + +int lua_isstring (lua_Object object) +{ + int t = lua_type(object); + return (t == LUA_T_STRING) || (t == LUA_T_NUMBER); +} + +int lua_isfunction (lua_Object object) +{ + int t = lua_type(object); + return (t == LUA_T_FUNCTION) || (t == LUA_T_CFUNCTION); +} + /* ** Given an object handle, return its number value. On error, return 0.0. */ @@ -607,27 +717,31 @@ void *lua_getuserdata (lua_Object object) } -lua_Object lua_getlocked (int ref) +lua_Object lua_getref (int ref) { - adjustC(0); - *top = *luaI_getlocked(ref); - incr_top; - CBase++; /* incorporate object in the stack */ - return Ref(top-1); + Object *o = luaI_getref(ref); + if (o == NULL) + return LUA_NOOBJECT; + adjustC(0); + luaI_pushobject(o); + CBase++; /* incorporate object in the stack */ + return Ref(top-1); } -void lua_pushlocked (int ref) +void lua_pushref (int ref) { - *top = *luaI_getlocked(ref); - incr_top; + Object *o = luaI_getref(ref); + if (o == NULL) + lua_error("access to invalid (possibly garbage collected) reference"); + luaI_pushobject(o); } -int lua_lock (void) +int lua_ref (int lock) { adjustC(1); - return luaI_lock(--top); + return luaI_ref(--top, lock); } @@ -637,10 +751,8 @@ int lua_lock (void) */ lua_Object lua_getglobal (char *name) { - Word n = luaI_findsymbolbyname(name); adjustC(0); - *top = s_object(n); - incr_top; + getglobal(luaI_findsymbolbyname(name)); CBase++; /* incorporate object in the stack */ return Ref(top-1); } @@ -678,20 +790,17 @@ void lua_pushnumber (real n) */ void lua_pushstring (char *s) { - tsvalue(top) = lua_createstring(s); - tag(top) = LUA_T_STRING; - incr_top; -} - -/* -** Push an object (tag=string) on stack and register it on the constant table. -*/ -void lua_pushliteral (char *s) -{ - tsvalue(top) = lua_constant[luaI_findconstantbyname(s)]; - tag(top) = LUA_T_STRING; - incr_top; + if (s == NULL) + tag(top) = LUA_T_NIL; + else + { + tsvalue(top) = lua_createstring(s); + tag(top) = LUA_T_STRING; + } + incr_top; } +/*>>>>>>>>>#undef lua_pushliteral +void lua_pushliteral(char *s) { lua_pushstring(s); }*/ /* ** Push an object (tag=cfunction) to stack. @@ -707,27 +816,29 @@ void lua_pushcfunction (lua_CFunction fn) */ void lua_pushusertag (void *u, int tag) { - if (tag < LUA_T_USERDATA) return; + if (tag < LUA_T_USERDATA) + lua_error("invalid tag in `lua_pushusertag'"); tag(top) = tag; uvalue(top) = u; incr_top; } /* -** Push a lua_Object to stack. +** Push an object on the stack. */ -void lua_pushobject (lua_Object o) +void luaI_pushobject (Object *o) { - *top = *Address(o); + *top = *o; incr_top; } /* -** Push an object on the stack. +** Push a lua_Object on stack. */ -void luaI_pushobject (Object *o) +void lua_pushobject (lua_Object o) { - *top = *o; - incr_top; + if (o == LUA_NOOBJECT) + lua_error("attempt to push a NOOBJECT"); + luaI_pushobject(Address(o)); } int lua_type (lua_Object o) @@ -783,6 +894,8 @@ static void comparison (lua_Type tag_less, lua_Type tag_equal, */ static StkId lua_execute (Byte *pc, StkId base) { + if (lua_callhook) + callHook (base, LUA_T_MARK, 0); while (1) { OpCode opcode; @@ -849,8 +962,7 @@ static StkId lua_execute (Byte *pc, StkId base) { CodeWord code; get_word(code,pc); - *top = s_object(code.w); - incr_top; + getglobal(code.w); } break; @@ -1143,10 +1255,10 @@ static StkId lua_execute (Byte *pc, StkId base) break; case RETCODE0: - return base; - case RETCODE: - return base+*pc; + if (lua_callhook) + callHook (base, LUA_T_MARK, 1); + return (base + ((opcode==RETCODE0) ? 0 : *pc)); case SETLINE: { @@ -1160,6 +1272,8 @@ static StkId lua_execute (Byte *pc, StkId base) (stack+base-1)->tag = LUA_T_LINE; } (stack+base-1)->value.i = code.w; + if (lua_linehook) + lineHook (code.w); break; } @@ -1169,4 +1283,3 @@ static StkId lua_execute (Byte *pc, StkId base) } } - diff --git a/src/opcode.h b/src/opcode.h index 5e33c2cf..d42ff3ee 100644 --- a/src/opcode.h +++ b/src/opcode.h @@ -1,6 +1,6 @@ /* ** TeCGraf - PUC-Rio -** $Id: opcode.h,v 3.14 1995/10/25 13:05:51 roberto Exp $ +** $Id: opcode.h,v 3.20 1996/03/15 13:13:13 roberto Exp $ */ #ifndef opcode_h @@ -11,9 +11,6 @@ #include "tree.h" #include "func.h" -#ifndef real -#define real float -#endif #define FIELDS_PER_FLUSH 40 @@ -74,12 +71,9 @@ typedef enum #define MULT_RET 255 -typedef void (*Cfunction) (void); -typedef int (*Input) (void); - typedef union { - Cfunction f; + lua_CFunction f; real n; TaggedString *ts; TFunc *tf; @@ -94,10 +88,6 @@ typedef struct Object Value value; } Object; -typedef struct -{ - Object object; -} Symbol; /* Macros to access structure members */ #define tag(o) ((o)->tag) @@ -119,14 +109,14 @@ typedef struct typedef union { - struct {char c1; char c2;} m; + struct {Byte c1; Byte c2;} m; Word w; } CodeWord; #define get_word(code,pc) {code.m.c1 = *pc++; code.m.c2 = *pc++;} typedef union { - struct {char c1; char c2; char c3; char c4;} m; + struct {Byte c1; Byte c2; Byte c3; Byte c4;} m; float f; } CodeFloat; #define get_float(code,pc) {code.m.c1 = *pc++; code.m.c2 = *pc++;\ @@ -134,7 +124,7 @@ typedef union typedef union { - struct {char c1; char c2; char c3; char c4;} m; + struct {Byte c1; Byte c2; Byte c3; Byte c4;} m; TFunc *tf; } CodeCode; #define get_code(code,pc) {code.m.c1 = *pc++; code.m.c2 = *pc++;\ @@ -142,16 +132,12 @@ typedef union /* Exported functions */ -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 (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); +int luaI_dorun (TFunc *tf); #endif diff --git a/src/parser.c b/src/parser.c index 6b0dba94..1cbb3c17 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1,25 +1,26 @@ #if defined (__cplusplus) || defined (c_plusplus) #include <c_varieties.h> #ifdef __EXTERN_C__ - EXTERN_FUNCTION ( extern int yylex, ()); + EXTERN_FUNCTION ( extern int luaY_lex, ()); #else - extern int yylex(); + extern int luaY_lex(); #endif - extern void yyerror(char *); - extern int yyparse(); + extern void luaY_error(char *); + extern int luaY_parse(); #endif -#include <malloc.h> +#include <stdlib.h> # line 2 "lua.stx" -char *rcs_luastx = "$Id: lua.stx,v 3.25 1995/10/26 17:02:50 roberto Exp $"; +char *rcs_luastx = "$Id: parser.c,v 1.1 1996/05/14 19:44:57 lhf Exp $"; #include <stdio.h> #include <stdlib.h> -#include <string.h> +#include "luadebug.h" #include "mem.h" +#include "lex.h" #include "opcode.h" #include "hash.h" #include "inout.h" @@ -29,7 +30,7 @@ char *rcs_luastx = "$Id: lua.stx,v 3.25 1995/10/26 17:02:50 roberto Exp $"; #include "func.h" /* to avoid warnings generated by yacc */ -int yyparse (void); +int luaY_parse (void); #define malloc luaI_malloc #define realloc luaI_realloc #define free luaI_free @@ -43,7 +44,7 @@ int yyparse (void); #endif static int maxcode; static int maxmain; -static Long maxcurr; /* to allow maxcurr *= 2 without overflow */ +static int maxcurr; static Byte *funcCode = NULL; static Byte **initcode; static Byte *basepc; @@ -57,35 +58,32 @@ static Long varbuffer[MAXVAR]; /* variables in an assignment list; static int nvarbuffer=0; /* number of variables at a list */ #define MAXLOCALS 32 -static Word localvar[MAXLOCALS]; /* store local variable names */ +static TaggedString *localvar[MAXLOCALS]; /* store local variable names */ static int nlocalvar=0; /* number of local variables */ #define MAXFIELDS FIELDS_PER_FLUSH*2 static Word fields[MAXFIELDS]; /* fieldnames to be flushed */ static int nfields=0; +int lua_debug = 0; /* Internal functions */ -static void yyerror (char *s) +static void luaY_error (char *s) { - static char msg[256]; - sprintf (msg,"%s near \"%s\" at line %d in file `%s'", - s, lua_lasttext (), lua_linenumber, lua_parsedfile); + char msg[256]; + char *token = lua_lasttext(); + if (token[0] == 0) + token = "<eof>"; + sprintf (msg,"%s; last token read: \"%s\" at line %d in file `%s'", + s, token, 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 */ - { - if (maxcurr >= MAX_INT) - lua_error("code size overflow"); - maxcurr *= 2; - if (maxcurr >= MAX_INT) - maxcurr = MAX_INT; - basepc = growvector(basepc, maxcurr, Byte); - } + maxcurr = growvector(&basepc, maxcurr, Byte, codeEM, MAX_INT); basepc[pc++] = c; } @@ -117,10 +115,12 @@ static void code_code (TFunc *tf) code_byte(code.m.c4); } -static void code_word_at (Byte *p, Word n) +static void code_word_at (Byte *p, int n) { CodeWord code; - code.w = n; + if ((Word)n != n) + luaY_error("block too big"); + code.w = (Word)n; *p++ = code.m.c1; *p++ = code.m.c2; } @@ -130,7 +130,7 @@ static void push_field (Word name) if (nfields < MAXFIELDS) fields[nfields++] = name; else - lua_error ("too many fields in nested constructors"); + luaY_error ("too many fields in nested constructors"); } static void flush_record (int n) @@ -155,24 +155,24 @@ static void flush_list (int m, int n) code_byte(m); } else - lua_error ("list constructor too long"); + luaY_error ("list constructor too long"); code_byte(n); } -static void add_localvar (Word name) +static void store_localvar (TaggedString *name, int n) { - if (nlocalvar < MAXLOCALS) - localvar[nlocalvar++] = name; + if (nlocalvar+n < MAXLOCALS) + localvar[nlocalvar+n] = name; else - lua_error ("too many local variables"); + luaY_error ("too many local variables"); + if (lua_debug) + luaI_registerlocalvar(name, lua_linenumber); } -static void store_localvar (Word name, int n) +static void add_localvar (TaggedString *name) { - if (nlocalvar+n < MAXLOCALS) - localvar[nlocalvar+n] = name; - else - lua_error ("too many local variables"); + store_localvar(name, 0); + nlocalvar++; } static void add_varbuffer (Long var) @@ -180,7 +180,7 @@ static void add_varbuffer (Long var) if (nvarbuffer < MAXVAR) varbuffer[nvarbuffer++] = var; else - lua_error ("variable buffer overflow"); + luaY_error ("variable buffer overflow"); } static void code_number (float f) @@ -210,7 +210,7 @@ static void code_number (float f) /* ** Search a local name and if find return its index. If do not find return -1 */ -static int lua_localname (Word n) +static int lua_localname (TaggedString *n) { int i; for (i=nlocalvar-1; i >= 0; i--) @@ -401,13 +401,12 @@ static void codeIf (Long thenAdd, Long elseAdd) */ void lua_parse (TFunc *tf) { - lua_debug = 0; initcode = &(tf->code); *initcode = newvector(CODE_BLOCK, Byte); maincode = 0; maxmain = CODE_BLOCK; change2main(); - if (yyparse ()) lua_error("parse error"); + if (luaY_parse ()) lua_error("parse error"); savemain(); (*initcode)[maincode++] = RETCODE0; tf->size = maincode; @@ -419,7 +418,7 @@ void lua_parse (TFunc *tf) -# line 411 "lua.stx" +# line 410 "lua.stx" typedef union { int vInt; @@ -428,7 +427,7 @@ typedef union Word vWord; Long vLong; TFunc *pFunc; - TreeNode *pNode; + TaggedString *pTStr; } YYSTYPE; # define WRONGTOKEN 257 # define NIL 258 @@ -457,244 +456,19 @@ typedef union # define CONC 281 # define UNARY 282 # define NOT 283 -#define yyclearin yychar = -1 -#define yyerrok yyerrflag = 0 -extern int yychar; -extern int yyerrflag; +#define luaY_clearin luaY_char = -1 +#define luaY_errok luaY_errflag = 0 +extern int luaY_char; +extern int luaY_errflag; #ifndef YYMAXDEPTH #define YYMAXDEPTH 150 #endif -YYSTYPE yylval, yyval; +YYSTYPE luaY_lval, luaY_val; # define YYERRCODE 256 -# line 789 "lua.stx" - - -#if LISTING - -static void PrintCode (Byte *code, Byte *end) -{ - Byte *p = code; - printf ("\n\nCODE\n"); - while (p != end) - { - switch ((OpCode)*p) - { - case PUSHNIL: printf ("%d PUSHNIL\n", (p++)-code); break; - case PUSH0: case PUSH1: case PUSH2: - printf ("%d PUSH%c\n", p-code, *p-PUSH0+'0'); - p++; - break; - case PUSHBYTE: - printf ("%d PUSHBYTE %d\n", p-code, *(++p)); - p++; - break; - case PUSHWORD: - { - CodeWord c; - int n = p-code; - p++; - get_word(c,p); - printf ("%d PUSHWORD %d\n", n, c.w); - } - break; - case PUSHFLOAT: - { - CodeFloat c; - int n = p-code; - p++; - get_float(c,p); - printf ("%d PUSHFLOAT %f\n", n, c.f); - } - break; - case PUSHSTRING: - { - CodeWord c; - int n = p-code; - p++; - get_word(c,p); - printf ("%d PUSHSTRING %d\n", n, c.w); - } - break; - case PUSHFUNCTION: - { - CodeCode c; - int n = p-code; - p++; - get_code(c,p); - printf ("%d PUSHFUNCTION %p\n", n, c.tf); - } - break; - - case PUSHLOCAL0: case PUSHLOCAL1: case PUSHLOCAL2: case PUSHLOCAL3: - case PUSHLOCAL4: case PUSHLOCAL5: case PUSHLOCAL6: case PUSHLOCAL7: - case PUSHLOCAL8: case PUSHLOCAL9: - printf ("%d PUSHLOCAL%c\n", p-code, *p-PUSHLOCAL0+'0'); - p++; - break; - case PUSHLOCAL: printf ("%d PUSHLOCAL %d\n", p-code, *(++p)); - p++; - break; - case PUSHGLOBAL: - { - CodeWord c; - int n = p-code; - p++; - get_word(c,p); - printf ("%d PUSHGLOBAL %d\n", n, c.w); - } - break; - case PUSHINDEXED: printf ("%d PUSHINDEXED\n", (p++)-code); break; - case STORELOCAL0: case STORELOCAL1: case STORELOCAL2: case STORELOCAL3: - case STORELOCAL4: case STORELOCAL5: case STORELOCAL6: case STORELOCAL7: - case STORELOCAL8: case STORELOCAL9: - printf ("%d STORELOCAL%c\n", p-code, *p-STORELOCAL0+'0'); - p++; - break; - case STORELOCAL: - printf ("%d STORELOCAL %d\n", p-code, *(++p)); - p++; - break; - case STOREGLOBAL: - { - CodeWord c; - int n = p-code; - p++; - get_word(c,p); - printf ("%d STOREGLOBAL %d\n", n, c.w); - } - break; - case PUSHSELF: - { - CodeWord c; - int n = p-code; - p++; - get_word(c,p); - printf ("%d PUSHSELF %d\n", n, c.w); - } - break; - case STOREINDEXED0: printf ("%d STOREINDEXED0\n", (p++)-code); break; - case STOREINDEXED: printf ("%d STOREINDEXED %d\n", p-code, *(++p)); - p++; - break; - case STORELIST0: - printf("%d STORELIST0 %d\n", p-code, *(++p)); - p++; - break; - case STORELIST: - printf("%d STORELIST %d %d\n", p-code, *(p+1), *(p+2)); - p+=3; - break; - case STORERECORD: - printf("%d STORERECORD %d\n", p-code, *(++p)); - p += *p*sizeof(Word) + 1; - break; - case ADJUST0: printf ("%d ADJUST0\n", (p++)-code); break; - case ADJUST: - printf ("%d ADJUST %d\n", p-code, *(++p)); - p++; - break; - case CREATEARRAY: - { - CodeWord c; - int n = p-code; - p++; - get_word(c,p); - printf ("%d CREATEARRAY %d\n", n, c.w); - break; - } - case EQOP: printf ("%d EQOP\n", (p++)-code); break; - case LTOP: printf ("%d LTOP\n", (p++)-code); break; - case LEOP: printf ("%d LEOP\n", (p++)-code); break; - case ADDOP: printf ("%d ADDOP\n", (p++)-code); break; - case SUBOP: printf ("%d SUBOP\n", (p++)-code); break; - case MULTOP: printf ("%d MULTOP\n", (p++)-code); break; - case DIVOP: printf ("%d DIVOP\n", (p++)-code); break; - case POWOP: printf ("%d POWOP\n", (p++)-code); break; - case CONCOP: printf ("%d CONCOP\n", (p++)-code); break; - case MINUSOP: printf ("%d MINUSOP\n", (p++)-code); break; - case NOTOP: printf ("%d NOTOP\n", (p++)-code); break; - case ONTJMP: - { - CodeWord c; - int n = p-code; - p++; - get_word(c,p); - printf ("%d ONTJMP %d\n", n, c.w); - } - break; - case ONFJMP: - { - CodeWord c; - int n = p-code; - p++; - get_word(c,p); - printf ("%d ONFJMP %d\n", n, c.w); - } - break; - case JMP: - { - CodeWord c; - int n = p-code; - p++; - get_word(c,p); - printf ("%d JMP %d\n", n, c.w); - } - break; - case UPJMP: - { - CodeWord c; - int n = p-code; - p++; - get_word(c,p); - printf ("%d UPJMP %d\n", n, c.w); - } - break; - case IFFJMP: - { - CodeWord c; - int n = p-code; - p++; - get_word(c,p); - printf ("%d IFFJMP %d\n", n, c.w); - } - break; - case IFFUPJMP: - { - CodeWord c; - int n = p-code; - p++; - get_word(c,p); - printf ("%d IFFUPJMP %d\n", n, c.w); - } - break; - case POP: printf ("%d POP\n", (p++)-code); break; - case CALLFUNC: - printf ("%d CALLFUNC %d %d\n", p-code, *(p+1), *(p+2)); - p+=3; - break; - case RETCODE0: printf ("%d RETCODE0\n", (p++)-code); break; - case RETCODE: - printf ("%d RETCODE %d\n", p-code, *(++p)); - p++; - break; - case SETLINE: - { - CodeWord c; - int n = p-code; - p++; - get_word(c,p); - printf ("%d SETLINE %d\n", n, c.w); - } - break; - - default: printf ("%d Cannot happen: code %d\n", (p++)-code, *(p-1)); break; - } - } -} -#endif +# line 788 "lua.stx" -int yyexca[] ={ +int luaY_exca[] ={ -1, 1, 0, -1, -2, 0, @@ -760,7 +534,7 @@ int yyexca[] ={ }; # define YYNPROD 100 # define YYLAST 311 -int yyact[]={ +int luaY_act[]={ 61, 59, 148, 60, 141, 62, 118, 61, 59, 90, 60, 89, 62, 86, 84, 18, 42, 168, 54, 164, @@ -794,7 +568,7 @@ int yyact[]={ 0, 0, 0, 0, 0, 30, 31, 18, 30, 31, 113, 0, 0, 0, 64, 0, 0, 34, 0, 0, 34 }; -int yypact[]={ +int luaY_pact[]={ -1000, -188, -1000, -1000, 51, -1000, -258, 24, -1000, -1000, 47, -1000, -257, -1000, -1000, 93, -1000, 73, -1000, -1000, @@ -814,14 +588,14 @@ int yypact[]={ -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[]={ +int luaY_pgo[]={ 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[]={ +int luaY_r1[]={ 0, 1, 1, 1, 23, 23, 24, 21, 21, 22, 30, 30, 26, 26, 25, 33, 25, 34, 25, 25, @@ -833,7 +607,7 @@ int yyr1[]={ 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[]={ +int luaY_r2[]={ 0, 0, 4, 4, 4, 2, 7, 3, 7, 11, 0, 6, 0, 2, 17, 1, 17, 1, 13, 7, @@ -845,7 +619,7 @@ int yyr2[]={ 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[]={ +int luaY_chk[]={ -1000, -1, -23, -24, -25, -27, 270, 259, 263, 265, -7, -5, 269, 274, -19, -9, -20, -28, 273, -26, @@ -865,7 +639,7 @@ int yychk[]={ -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[]={ +int luaY_def[]={ 1, -2, 2, 3, 12, 5, 0, 56, 15, 17, 0, 20, 0, 99, -2, 56, 90, 59, 93, 4, @@ -885,14 +659,14 @@ int yydef[]={ 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; +typedef struct { char *t_name; int t_val; } luaY_toktype; #ifndef YYDEBUG # define YYDEBUG 0 /* don't allow debugging */ #endif #if YYDEBUG -yytoktype yytoks[] = +luaY_toktype luaY_toks[] = { "WRONGTOKEN", 257, "NIL", 258, @@ -931,7 +705,7 @@ yytoktype yytoks[] = "-unknown-", -1 /* ends search */ }; -char * yyreds[] = +char * luaY_reds[] = { "-no such reduction-", "functionlist : /* empty */", @@ -1048,24 +822,24 @@ char * yyreds[] = /* ** yacc user known macros and defines */ -#define YYERROR goto yyerrlab +#define YYERROR goto luaY_errlab #define YYACCEPT return(0) #define YYABORT return(1) #define YYBACKUP( newtoken, newvalue )\ {\ - if ( yychar >= 0 || ( yyr2[ yytmp ] >> 1 ) != 1 )\ + if ( luaY_char >= 0 || ( luaY_r2[ luaY_tmp ] >> 1 ) != 1 )\ {\ - yyerror( "syntax error - cannot backup" );\ - goto yyerrlab;\ + luaY_error( "syntax error - cannot backup" );\ + goto luaY_errlab;\ }\ - yychar = newtoken;\ - yystate = *yyps;\ - yylval = newvalue;\ - goto yynewstate;\ + luaY_char = newtoken;\ + luaY_state = *luaY_ps;\ + luaY_lval = newvalue;\ + goto luaY_newstate;\ } -#define YYRECOVERING() (!!yyerrflag) +#define YYRECOVERING() (!!luaY_errflag) #define YYCOPY(to, from, type) \ - (type *) memcpy(to, (char *) from, yynewmax * sizeof(type)) + (type *) memcpy(to, (char *) from, luaY_newmax * sizeof(type)) #ifndef YYDEBUG # define YYDEBUG 1 /* make debugging available */ #endif @@ -1085,7 +859,7 @@ EXTERN_FUNCTION ( extern void *memcpy, (void *, const void *, int) ); /* ** user known globals */ -int yydebug; /* set to 1 to get debugging */ +int luaY_debug; /* set to 1 to get debugging */ /* ** driver internal defines @@ -1095,50 +869,50 @@ int yydebug; /* set to 1 to get debugging */ /* ** static variables used by the parser */ -static YYSTYPE yy_yyv[YYMAXDEPTH], *yyv = yy_yyv; /* value stack */ -static int yy_yys[YYMAXDEPTH], *yys = yy_yys; /* state stack */ +static YYSTYPE luaY__luaY_v[YYMAXDEPTH], *luaY_v = luaY__luaY_v; /* value stack */ +static int luaY__luaY_s[YYMAXDEPTH], *luaY_s = luaY__luaY_s; /* state stack */ -static YYSTYPE *yypv; /* top of value stack */ -static int *yyps; /* top of state stack */ +static YYSTYPE *luaY_pv; /* top of value stack */ +static int *luaY_ps; /* top of state stack */ -static int yystate; /* current state */ -static int yytmp; /* extra var (lasts between blocks) */ +static int luaY_state; /* current state */ +static int luaY_tmp; /* extra var (lasts between blocks) */ #if defined(__cplusplus) || defined(__STDC__) || defined(lint) static int __yaccpar_lint_hack__ = 0; /* if you change the value from 0 to something else, make sure you know - what to do with yyerrlab reference. + what to do with luaY_errlab reference. This is a hack - to make sure C++ and lint are happy with the 4.1 yacc code. */ #endif -int yynerrs; /* number of errors */ +int luaY_nerrs; /* number of errors */ -int yyerrflag; /* error recovery flag */ -int yychar; /* current input token number */ -static unsigned yymaxdepth = YYMAXDEPTH; +int luaY_errflag; /* error recovery flag */ +int luaY_char; /* current input token number */ +static unsigned luaY_maxdepth = YYMAXDEPTH; /* -** yyparse - return 0 if worked, 1 if syntax error not recovered from +** luaY_parse - return 0 if worked, 1 if syntax error not recovered from */ int -yyparse() +luaY_parse() { - register YYSTYPE *yypvt = (YYSTYPE*)0 ; /* top of value stack for + register YYSTYPE *luaY_pvt = (YYSTYPE*)0 ; /* top of value stack for $vars */ /* - ** Initialize externals - yyparse may be called more than once + ** Initialize externals - luaY_parse may be called more than once */ - yypv = &yyv[-1]; - yyps = &yys[-1]; - yystate = 0; - yytmp = 0; - yynerrs = 0; - yyerrflag = 0; - yychar = -1; + luaY_pv = &luaY_v[-1]; + luaY_ps = &luaY_s[-1]; + luaY_state = 0; + luaY_tmp = 0; + luaY_nerrs = 0; + luaY_errflag = 0; + luaY_char = -1; #if defined(__cplusplus) || defined(__STDC__) || defined(lint) /* @@ -1147,42 +921,42 @@ $vars */ */ switch (__yaccpar_lint_hack__) { - case 1: goto yyerrlab; - case 2: goto yynewstate; + case 1: goto luaY_errlab; + case 2: goto luaY_newstate; } #endif { - register YYSTYPE *yy_pv; /* top of value stack */ - register int *yy_ps; /* top of state stack */ - register int yy_state; /* current state */ - register int yy_n; /* internal state number info */ + register YYSTYPE *luaY__pv; /* top of value stack */ + register int *luaY__ps; /* top of state stack */ + register int luaY__state; /* current state */ + register int luaY__n; /* internal state number info */ - goto yystack; + goto luaY_stack; /* ** get globals into registers. ** branch to here only if YYBACKUP was called. */ - yynewstate: - yy_pv = yypv; - yy_ps = yyps; - yy_state = yystate; - goto yy_newstate; + luaY_newstate: + luaY__pv = luaY_pv; + luaY__ps = luaY_ps; + luaY__state = luaY_state; + goto luaY__newstate; /* ** get globals into registers. ** either we just started, or we just finished a reduction */ - yystack: - yy_pv = yypv; - yy_ps = yyps; - yy_state = yystate; + luaY_stack: + luaY__pv = luaY_pv; + luaY__ps = luaY_ps; + luaY__state = luaY_state; /* ** top of for (;;) loop while no reductions done */ - yy_stack: + luaY__stack: /* ** put a state and value onto the stacks */ @@ -1193,153 +967,153 @@ $vars */ ** Note: linear search is used since time is not a real ** consideration while debugging. */ - if ( yydebug ) + if ( luaY_debug ) { - register int yy_i; + register int luaY__i; - (void)printf( "State %d, token ", yy_state ); - if ( yychar == 0 ) + (void)printf( "State %d, token ", luaY__state ); + if ( luaY_char == 0 ) (void)printf( "end-of-file\n" ); - else if ( yychar < 0 ) + else if ( luaY_char < 0 ) (void)printf( "-none-\n" ); else { - for ( yy_i = 0; yytoks[yy_i].t_val >= 0; - yy_i++ ) + for ( luaY__i = 0; luaY_toks[luaY__i].t_val >= 0; + luaY__i++ ) { - if ( yytoks[yy_i].t_val == yychar ) + if ( luaY_toks[luaY__i].t_val == luaY_char ) break; } - (void)printf( "%s\n", yytoks[yy_i].t_name ); + (void)printf( "%s\n", luaY_toks[luaY__i].t_name ); } } #endif /* YYDEBUG */ - if ( ++yy_ps >= &yys[ yymaxdepth ] ) /* room on stack? */ + if ( ++luaY__ps >= &luaY_s[ luaY_maxdepth ] ) /* room on stack? */ { /* ** reallocate and recover. Note that pointers ** have to be reset, or bad things will happen */ - int yyps_index = (yy_ps - yys); - int yypv_index = (yy_pv - yyv); - int yypvt_index = (yypvt - yyv); - int yynewmax; + int luaY_ps_index = (luaY__ps - luaY_s); + int luaY_pv_index = (luaY__pv - luaY_v); + int luaY_pvt_index = (luaY_pvt - luaY_v); + int luaY_newmax; - yynewmax = yymaxdepth + YYMAXDEPTH; - if (yymaxdepth == YYMAXDEPTH) /* first time growth */ + luaY_newmax = luaY_maxdepth + YYMAXDEPTH; + if (luaY_maxdepth == YYMAXDEPTH) /* first time growth */ { - YYSTYPE *newyyv = (YYSTYPE*)malloc(yynewmax*sizeof(YYSTYPE)); - int *newyys = (int*)malloc(yynewmax*sizeof(int)); - if (newyys != 0 && newyyv != 0) + YYSTYPE *newluaY_v = (YYSTYPE*)malloc(luaY_newmax*sizeof(YYSTYPE)); + int *newluaY_s = (int*)malloc(luaY_newmax*sizeof(int)); + if (newluaY_s != 0 && newluaY_v != 0) { - yys = YYCOPY(newyys, yys, int); - yyv = YYCOPY(newyyv, yyv, YYSTYPE); + luaY_s = YYCOPY(newluaY_s, luaY_s, int); + luaY_v = YYCOPY(newluaY_v, luaY_v, YYSTYPE); } else - yynewmax = 0; /* failed */ + luaY_newmax = 0; /* failed */ } else /* not first time */ { - yyv = (YYSTYPE*)realloc((char*)yyv, - yynewmax * sizeof(YYSTYPE)); - yys = (int*)realloc((char*)yys, - yynewmax * sizeof(int)); - if (yys == 0 || yyv == 0) - yynewmax = 0; /* failed */ + luaY_v = (YYSTYPE*)realloc((char*)luaY_v, + luaY_newmax * sizeof(YYSTYPE)); + luaY_s = (int*)realloc((char*)luaY_s, + luaY_newmax * sizeof(int)); + if (luaY_s == 0 || luaY_v == 0) + luaY_newmax = 0; /* failed */ } - if (yynewmax <= yymaxdepth) /* tables not expanded */ + if (luaY_newmax <= luaY_maxdepth) /* tables not expanded */ { - yyerror( "yacc stack overflow" ); + luaY_error( "yacc stack overflow" ); YYABORT; } - yymaxdepth = yynewmax; + luaY_maxdepth = luaY_newmax; - yy_ps = yys + yyps_index; - yy_pv = yyv + yypv_index; - yypvt = yyv + yypvt_index; + luaY__ps = luaY_s + luaY_ps_index; + luaY__pv = luaY_v + luaY_pv_index; + luaY_pvt = luaY_v + luaY_pvt_index; } - *yy_ps = yy_state; - *++yy_pv = yyval; + *luaY__ps = luaY__state; + *++luaY__pv = luaY_val; /* ** we have a new state - find out what to do */ - yy_newstate: - if ( ( yy_n = yypact[ yy_state ] ) <= YYFLAG ) - goto yydefault; /* simple state */ + luaY__newstate: + if ( ( luaY__n = luaY_pact[ luaY__state ] ) <= YYFLAG ) + goto luaY_default; /* simple state */ #if YYDEBUG /* ** if debugging, need to mark whether new token grabbed */ - yytmp = yychar < 0; + luaY_tmp = luaY_char < 0; #endif - if ( ( yychar < 0 ) && ( ( yychar = yylex() ) < 0 ) ) - yychar = 0; /* reached EOF */ + if ( ( luaY_char < 0 ) && ( ( luaY_char = luaY_lex() ) < 0 ) ) + luaY_char = 0; /* reached EOF */ #if YYDEBUG - if ( yydebug && yytmp ) + if ( luaY_debug && luaY_tmp ) { - register int yy_i; + register int luaY__i; (void)printf( "Received token " ); - if ( yychar == 0 ) + if ( luaY_char == 0 ) (void)printf( "end-of-file\n" ); - else if ( yychar < 0 ) + else if ( luaY_char < 0 ) (void)printf( "-none-\n" ); else { - for ( yy_i = 0; yytoks[yy_i].t_val >= 0; - yy_i++ ) + for ( luaY__i = 0; luaY_toks[luaY__i].t_val >= 0; + luaY__i++ ) { - if ( yytoks[yy_i].t_val == yychar ) + if ( luaY_toks[luaY__i].t_val == luaY_char ) break; } - (void)printf( "%s\n", yytoks[yy_i].t_name ); + (void)printf( "%s\n", luaY_toks[luaY__i].t_name ); } } #endif /* YYDEBUG */ - if ( ( ( yy_n += yychar ) < 0 ) || ( yy_n >= YYLAST ) ) - goto yydefault; - if ( yychk[ yy_n = yyact[ yy_n ] ] == yychar ) /*valid shift*/ + if ( ( ( luaY__n += luaY_char ) < 0 ) || ( luaY__n >= YYLAST ) ) + goto luaY_default; + if ( luaY_chk[ luaY__n = luaY_act[ luaY__n ] ] == luaY_char ) /*valid shift*/ { - yychar = -1; - yyval = yylval; - yy_state = yy_n; - if ( yyerrflag > 0 ) - yyerrflag--; - goto yy_stack; + luaY_char = -1; + luaY_val = luaY_lval; + luaY__state = luaY__n; + if ( luaY_errflag > 0 ) + luaY_errflag--; + goto luaY__stack; } - yydefault: - if ( ( yy_n = yydef[ yy_state ] ) == -2 ) + luaY_default: + if ( ( luaY__n = luaY_def[ luaY__state ] ) == -2 ) { #if YYDEBUG - yytmp = yychar < 0; + luaY_tmp = luaY_char < 0; #endif - if ( ( yychar < 0 ) && ( ( yychar = yylex() ) < 0 ) ) - yychar = 0; /* reached EOF */ + if ( ( luaY_char < 0 ) && ( ( luaY_char = luaY_lex() ) < 0 ) ) + luaY_char = 0; /* reached EOF */ #if YYDEBUG - if ( yydebug && yytmp ) + if ( luaY_debug && luaY_tmp ) { - register int yy_i; + register int luaY__i; (void)printf( "Received token " ); - if ( yychar == 0 ) + if ( luaY_char == 0 ) (void)printf( "end-of-file\n" ); - else if ( yychar < 0 ) + else if ( luaY_char < 0 ) (void)printf( "-none-\n" ); else { - for ( yy_i = 0; - yytoks[yy_i].t_val >= 0; - yy_i++ ) + for ( luaY__i = 0; + luaY_toks[luaY__i].t_val >= 0; + luaY__i++ ) { - if ( yytoks[yy_i].t_val - == yychar ) + if ( luaY_toks[luaY__i].t_val + == luaY_char ) { break; } } - (void)printf( "%s\n", yytoks[yy_i].t_name ); + (void)printf( "%s\n", luaY_toks[luaY__i].t_name ); } } #endif /* YYDEBUG */ @@ -1347,17 +1121,17 @@ $vars */ ** look through exception table */ { - register int *yyxi = yyexca; + register int *luaY_xi = luaY_exca; - while ( ( *yyxi != -1 ) || - ( yyxi[1] != yy_state ) ) + while ( ( *luaY_xi != -1 ) || + ( luaY_xi[1] != luaY__state ) ) { - yyxi += 2; + luaY_xi += 2; } - while ( ( *(yyxi += 2) >= 0 ) && - ( *yyxi != yychar ) ) + while ( ( *(luaY_xi += 2) >= 0 ) && + ( *luaY_xi != luaY_char ) ) ; - if ( ( yy_n = yyxi[1] ) < 0 ) + if ( ( luaY__n = luaY_xi[1] ) < 0 ) YYACCEPT; } } @@ -1365,42 +1139,42 @@ $vars */ /* ** check for syntax error */ - if ( yy_n == 0 ) /* have an error */ + if ( luaY__n == 0 ) /* have an error */ { /* no worry about speed here! */ - switch ( yyerrflag ) + switch ( luaY_errflag ) { case 0: /* new error */ - yyerror( "syntax error" ); + luaY_error( "syntax error" ); goto skip_init; - yyerrlab: + luaY_errlab: /* ** get globals into registers. ** we have a user generated syntax type error */ - yy_pv = yypv; - yy_ps = yyps; - yy_state = yystate; - yynerrs++; + luaY__pv = luaY_pv; + luaY__ps = luaY_ps; + luaY__state = luaY_state; + luaY_nerrs++; skip_init: case 1: case 2: /* incompletely recovered error */ /* try again... */ - yyerrflag = 3; + luaY_errflag = 3; /* ** find state where "error" is a legal ** shift action */ - while ( yy_ps >= yys ) + while ( luaY__ps >= luaY_s ) { - yy_n = yypact[ *yy_ps ] + YYERRCODE; - if ( yy_n >= 0 && yy_n < YYLAST && - yychk[yyact[yy_n]] == YYERRCODE) { + luaY__n = luaY_pact[ *luaY__ps ] + YYERRCODE; + if ( luaY__n >= 0 && luaY__n < YYLAST && + luaY_chk[luaY_act[luaY__n]] == YYERRCODE) { /* ** simulate shift of "error" */ - yy_state = yyact[ yy_n ]; - goto yy_stack; + luaY__state = luaY_act[ luaY__n ]; + goto luaY__stack; } /* ** current state has no shift on @@ -1408,13 +1182,13 @@ $vars */ */ #if YYDEBUG # define _POP_ "Error recovery pops state %d, uncovers state %d\n" - if ( yydebug ) - (void)printf( _POP_, *yy_ps, - yy_ps[-1] ); + if ( luaY_debug ) + (void)printf( _POP_, *luaY__ps, + luaY__ps[-1] ); # undef _POP_ #endif - yy_ps--; - yy_pv--; + luaY__ps--; + luaY__pv--; } /* ** there is no state on stack with "error" as @@ -1430,40 +1204,40 @@ $vars */ ** debugging, it doesn't hurt to leave the ** tests here. */ - if ( yydebug ) + if ( luaY_debug ) { - register int yy_i; + register int luaY__i; (void)printf( "Error recovery discards " ); - if ( yychar == 0 ) + if ( luaY_char == 0 ) (void)printf( "token end-of-file\n" ); - else if ( yychar < 0 ) + else if ( luaY_char < 0 ) (void)printf( "token -none-\n" ); else { - for ( yy_i = 0; - yytoks[yy_i].t_val >= 0; - yy_i++ ) + for ( luaY__i = 0; + luaY_toks[luaY__i].t_val >= 0; + luaY__i++ ) { - if ( yytoks[yy_i].t_val - == yychar ) + if ( luaY_toks[luaY__i].t_val + == luaY_char ) { break; } } (void)printf( "token %s\n", - yytoks[yy_i].t_name ); + luaY_toks[luaY__i].t_name ); } } #endif /* YYDEBUG */ - if ( yychar == 0 ) /* reached EOF. quit */ + if ( luaY_char == 0 ) /* reached EOF. quit */ YYABORT; - yychar = -1; - goto yy_newstate; + luaY_char = -1; + goto luaY__newstate; } - }/* end if ( yy_n == 0 ) */ + }/* end if ( luaY__n == 0 ) */ /* - ** reduction by production yy_n + ** reduction by production luaY__n ** put stack tops, etc. so things right after switch */ #if YYDEBUG @@ -1472,92 +1246,95 @@ $vars */ ** specification of the reduction which is just about ** to be done. */ - if ( yydebug ) + if ( luaY_debug ) (void)printf( "Reduce by (%d) \"%s\"\n", - yy_n, yyreds[ yy_n ] ); + luaY__n, luaY_reds[ luaY__n ] ); #endif - yytmp = yy_n; /* value to switch over */ - yypvt = yy_pv; /* $vars top of value stack */ + luaY_tmp = luaY__n; /* value to switch over */ + luaY_pvt = luaY__pv; /* $vars top of value stack */ /* ** Look in goto table for next state - ** Sorry about using yy_state here as temporary + ** Sorry about using luaY__state here as temporary ** register variable, but why not, if it works... - ** If yyr2[ yy_n ] doesn't have the low order bit + ** If luaY_r2[ luaY__n ] doesn't have the low order bit ** set, then there is no action to be done for ** this reduction. So, no saving & unsaving of ** registers done. The only difference between the ** code just after the if and the body of the if is - ** the goto yy_stack in the body. This way the test + ** the goto luaY__stack in the body. This way the test ** can be made before the choice of what to do is needed. */ { /* length of production doubled with extra bit */ - register int yy_len = yyr2[ yy_n ]; + register int luaY__len = luaY_r2[ luaY__n ]; - if ( !( yy_len & 01 ) ) + if ( !( luaY__len & 01 ) ) { - yy_len >>= 1; - yyval = ( yy_pv -= yy_len )[1]; /* $$ = $1 */ - yy_state = yypgo[ yy_n = yyr1[ yy_n ] ] + - *( yy_ps -= yy_len ) + 1; - if ( yy_state >= YYLAST || - yychk[ yy_state = - yyact[ yy_state ] ] != -yy_n ) + luaY__len >>= 1; + luaY_val = ( luaY__pv -= luaY__len )[1]; /* $$ = $1 */ + luaY__state = luaY_pgo[ luaY__n = luaY_r1[ luaY__n ] ] + + *( luaY__ps -= luaY__len ) + 1; + if ( luaY__state >= YYLAST || + luaY_chk[ luaY__state = + luaY_act[ luaY__state ] ] != -luaY__n ) { - yy_state = yyact[ yypgo[ yy_n ] ]; + luaY__state = luaY_act[ luaY_pgo[ luaY__n ] ]; } - goto yy_stack; + goto luaY__stack; } - yy_len >>= 1; - yyval = ( yy_pv -= yy_len )[1]; /* $$ = $1 */ - yy_state = yypgo[ yy_n = yyr1[ yy_n ] ] + - *( yy_ps -= yy_len ) + 1; - if ( yy_state >= YYLAST || - yychk[ yy_state = yyact[ yy_state ] ] != -yy_n ) + luaY__len >>= 1; + luaY_val = ( luaY__pv -= luaY__len )[1]; /* $$ = $1 */ + luaY__state = luaY_pgo[ luaY__n = luaY_r1[ luaY__n ] ] + + *( luaY__ps -= luaY__len ) + 1; + if ( luaY__state >= YYLAST || + luaY_chk[ luaY__state = luaY_act[ luaY__state ] ] != -luaY__n ) { - yy_state = yyact[ yypgo[ yy_n ] ]; + luaY__state = luaY_act[ luaY_pgo[ luaY__n ] ]; } } /* save until reenter driver code */ - yystate = yy_state; - yyps = yy_ps; - yypv = yy_pv; + luaY_state = luaY__state; + luaY_ps = luaY__ps; + luaY_pv = luaY__pv; } /* ** code supplied by user is placed in this switch */ - switch( yytmp ) + switch( luaY_tmp ) { case 6: -# line 470 "lua.stx" +# line 469 "lua.stx" { code_byte(PUSHFUNCTION); - code_code(yypvt[-0].pFunc); - storesinglevar(yypvt[-1].vLong); + code_code(luaY_pvt[-0].pFunc); + storesinglevar(luaY_pvt[-1].vLong); } break; case 7: -# line 477 "lua.stx" -{ yyval.vLong =yypvt[-0].vLong; init_func(); } break; +# line 476 "lua.stx" +{ luaY_val.vLong =luaY_pvt[-0].vLong; init_func(); } break; case 8: -# line 479 "lua.stx" +# line 478 "lua.stx" { code_byte(PUSHSTRING); - code_word(luaI_findconstant(yypvt[-0].pNode)); - yyval.vLong = 0; /* indexed variable */ + code_word(luaI_findconstant(luaY_pvt[-0].pTStr)); + luaY_val.vLong = 0; /* indexed variable */ init_func(); - add_localvar(luaI_findsymbolbyname("self")); + add_localvar(luaI_createfixedstring("self")); } break; case 9: -# line 489 "lua.stx" +# line 488 "lua.stx" { codereturn(); - 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)); + luaY_val.pFunc = new(TFunc); + luaI_initTFunc(luaY_val.pFunc); + luaY_val.pFunc->size = pc; + luaY_val.pFunc->code = newvector(pc, Byte); + luaY_val.pFunc->fileName = lua_parsedfile; + luaY_val.pFunc->lineDefined = luaY_pvt[-3].vInt; + memcpy(luaY_val.pFunc->code, basepc, pc*sizeof(Byte)); + if (lua_debug) + luaI_closelocalvars(luaY_val.pFunc); /* save func values */ funcCode = basepc; maxcode=maxcurr; #if LISTING @@ -1566,346 +1343,345 @@ case 9: change2main(); /* change back to main code */ } break; case 14: -# line 513 "lua.stx" -{ codeIf(yypvt[-4].vLong, yypvt[-2].vLong); } break; -case 15: # line 515 "lua.stx" -{yyval.vLong=pc;} break; +{ codeIf(luaY_pvt[-4].vLong, luaY_pvt[-2].vLong); } break; +case 15: +# line 517 "lua.stx" +{luaY_val.vLong=pc;} break; case 16: -# line 516 "lua.stx" +# line 518 "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)); + basepc[luaY_pvt[-3].vLong] = IFFJMP; + code_word_at(basepc+luaY_pvt[-3].vLong+1, pc - (luaY_pvt[-3].vLong + sizeof(Word)+1)); + basepc[luaY_pvt[-1].vLong] = UPJMP; + code_word_at(basepc+luaY_pvt[-1].vLong+1, pc - (luaY_pvt[-6].vLong)); } break; case 17: -# line 523 "lua.stx" -{yyval.vLong=pc;} break; +# line 525 "lua.stx" +{luaY_val.vLong=pc;} break; case 18: -# line 524 "lua.stx" +# line 526 "lua.stx" { - basepc[yypvt[-0].vLong] = IFFUPJMP; - code_word_at(basepc+yypvt[-0].vLong+1, pc - (yypvt[-4].vLong)); + basepc[luaY_pvt[-0].vLong] = IFFUPJMP; + code_word_at(basepc+luaY_pvt[-0].vLong+1, pc - (luaY_pvt[-4].vLong)); } break; case 19: -# line 530 "lua.stx" +# line 532 "lua.stx" { { int i; - adjust_mult_assign(nvarbuffer, yypvt[-0].vLong, yypvt[-2].vInt * 2 + nvarbuffer); + adjust_mult_assign(nvarbuffer, luaY_pvt[-0].vLong, luaY_pvt[-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)) + if (luaY_pvt[-2].vInt > 1 || (luaY_pvt[-2].vInt == 1 && varbuffer[0] != 0)) lua_codeadjust (0); } } break; case 21: -# line 542 "lua.stx" -{ nlocalvar += yypvt[-1].vInt; - adjust_mult_assign(yypvt[-1].vInt, yypvt[-0].vInt, 0); +# line 544 "lua.stx" +{ nlocalvar += luaY_pvt[-1].vInt; + adjust_mult_assign(luaY_pvt[-1].vInt, luaY_pvt[-0].vInt, 0); } break; case 24: -# line 550 "lua.stx" -{ codeIf(yypvt[-3].vLong, yypvt[-1].vLong); } break; +# line 552 "lua.stx" +{ codeIf(luaY_pvt[-3].vLong, luaY_pvt[-1].vLong); } break; case 25: -# line 553 "lua.stx" -{yyval.vInt = nlocalvar;} break; +# line 555 "lua.stx" +{luaY_val.vInt = nlocalvar;} break; case 26: -# line 554 "lua.stx" +# line 556 "lua.stx" { - if (nlocalvar != yypvt[-2].vInt) + if (nlocalvar != luaY_pvt[-2].vInt) { - nlocalvar = yypvt[-2].vInt; + if (lua_debug) + for (; nlocalvar > luaY_pvt[-2].vInt; nlocalvar--) + luaI_unregisterlocalvar(lua_linenumber); + else + nlocalvar = luaY_pvt[-2].vInt; lua_codeadjust (0); } } break; case 28: -# line 565 "lua.stx" +# line 571 "lua.stx" { - adjust_functioncall(yypvt[-1].vLong, MULT_RET); + adjust_functioncall(luaY_pvt[-1].vLong, MULT_RET); codereturn(); } break; case 29: -# line 572 "lua.stx" +# line 578 "lua.stx" { - yyval.vLong = pc; + luaY_val.vLong = pc; code_byte(0); /* open space */ code_word (0); } break; case 30: -# line 578 "lua.stx" -{ adjust_functioncall(yypvt[-0].vLong, 1); } break; +# line 584 "lua.stx" +{ adjust_functioncall(luaY_pvt[-0].vLong, 1); } break; case 31: -# line 581 "lua.stx" -{ yyval.vLong = yypvt[-1].vLong; } break; +# line 587 "lua.stx" +{ luaY_val.vLong = luaY_pvt[-1].vLong; } break; case 32: -# line 582 "lua.stx" -{ code_byte(EQOP); yyval.vLong = 0; } break; +# line 588 "lua.stx" +{ code_byte(EQOP); luaY_val.vLong = 0; } break; case 33: -# line 583 "lua.stx" -{ code_byte(LTOP); yyval.vLong = 0; } break; +# line 589 "lua.stx" +{ code_byte(LTOP); luaY_val.vLong = 0; } break; case 34: -# line 584 "lua.stx" -{ code_byte(GTOP); yyval.vLong = 0; } break; +# line 590 "lua.stx" +{ code_byte(GTOP); luaY_val.vLong = 0; } break; case 35: -# line 585 "lua.stx" -{ code_byte(EQOP); code_byte(NOTOP); yyval.vLong = 0; } break; +# line 591 "lua.stx" +{ code_byte(EQOP); code_byte(NOTOP); luaY_val.vLong = 0; } break; case 36: -# line 586 "lua.stx" -{ code_byte(LEOP); yyval.vLong = 0; } break; +# line 592 "lua.stx" +{ code_byte(LEOP); luaY_val.vLong = 0; } break; case 37: -# line 587 "lua.stx" -{ code_byte(GEOP); yyval.vLong = 0; } break; +# line 593 "lua.stx" +{ code_byte(GEOP); luaY_val.vLong = 0; } break; case 38: -# line 588 "lua.stx" -{ code_byte(ADDOP); yyval.vLong = 0; } break; +# line 594 "lua.stx" +{ code_byte(ADDOP); luaY_val.vLong = 0; } break; case 39: -# line 589 "lua.stx" -{ code_byte(SUBOP); yyval.vLong = 0; } break; +# line 595 "lua.stx" +{ code_byte(SUBOP); luaY_val.vLong = 0; } break; case 40: -# line 590 "lua.stx" -{ code_byte(MULTOP); yyval.vLong = 0; } break; +# line 596 "lua.stx" +{ code_byte(MULTOP); luaY_val.vLong = 0; } break; case 41: -# line 591 "lua.stx" -{ code_byte(DIVOP); yyval.vLong = 0; } break; +# line 597 "lua.stx" +{ code_byte(DIVOP); luaY_val.vLong = 0; } break; case 42: -# line 592 "lua.stx" -{ code_byte(POWOP); yyval.vLong = 0; } break; +# line 598 "lua.stx" +{ code_byte(POWOP); luaY_val.vLong = 0; } break; case 43: -# line 593 "lua.stx" -{ code_byte(CONCOP); yyval.vLong = 0; } break; +# line 599 "lua.stx" +{ code_byte(CONCOP); luaY_val.vLong = 0; } break; case 44: -# line 594 "lua.stx" -{ code_byte(MINUSOP); yyval.vLong = 0;} break; +# line 600 "lua.stx" +{ code_byte(MINUSOP); luaY_val.vLong = 0;} break; case 45: -# line 595 "lua.stx" -{ yyval.vLong = 0; } break; +# line 601 "lua.stx" +{ luaY_val.vLong = 0; } break; case 46: -# line 596 "lua.stx" -{ yyval.vLong = 0;} break; +# line 602 "lua.stx" +{ luaY_val.vLong = 0;} break; case 47: -# line 597 "lua.stx" -{ code_number(yypvt[-0].vFloat); yyval.vLong = 0; } break; +# line 603 "lua.stx" +{ code_number(luaY_pvt[-0].vFloat); luaY_val.vLong = 0; } break; case 48: -# line 599 "lua.stx" +# line 605 "lua.stx" { code_byte(PUSHSTRING); - code_word(yypvt[-0].vWord); - yyval.vLong = 0; + code_word(luaY_pvt[-0].vWord); + luaY_val.vLong = 0; } break; case 49: -# line 604 "lua.stx" -{code_byte(PUSHNIL); yyval.vLong = 0; } break; +# line 610 "lua.stx" +{code_byte(PUSHNIL); luaY_val.vLong = 0; } break; case 50: -# line 605 "lua.stx" -{ yyval.vLong = yypvt[-0].vLong; } break; +# line 611 "lua.stx" +{ luaY_val.vLong = luaY_pvt[-0].vLong; } break; case 51: -# line 606 "lua.stx" -{ code_byte(NOTOP); yyval.vLong = 0;} break; +# line 612 "lua.stx" +{ code_byte(NOTOP); luaY_val.vLong = 0;} break; case 52: -# line 607 "lua.stx" +# line 613 "lua.stx" {code_byte(POP); } break; case 53: -# line 608 "lua.stx" +# line 614 "lua.stx" { - basepc[yypvt[-2].vLong] = ONFJMP; - code_word_at(basepc+yypvt[-2].vLong+1, pc - (yypvt[-2].vLong + sizeof(Word)+1)); - yyval.vLong = 0; + basepc[luaY_pvt[-2].vLong] = ONFJMP; + code_word_at(basepc+luaY_pvt[-2].vLong+1, pc - (luaY_pvt[-2].vLong + sizeof(Word)+1)); + luaY_val.vLong = 0; } break; case 54: -# line 613 "lua.stx" +# line 619 "lua.stx" {code_byte(POP); } break; case 55: -# line 614 "lua.stx" +# line 620 "lua.stx" { - basepc[yypvt[-2].vLong] = ONTJMP; - code_word_at(basepc+yypvt[-2].vLong+1, pc - (yypvt[-2].vLong + sizeof(Word)+1)); - yyval.vLong = 0; + basepc[luaY_pvt[-2].vLong] = ONTJMP; + code_word_at(basepc+luaY_pvt[-2].vLong+1, pc - (luaY_pvt[-2].vLong + sizeof(Word)+1)); + luaY_val.vLong = 0; } break; case 56: -# line 622 "lua.stx" +# line 628 "lua.stx" { code_byte(CREATEARRAY); - yyval.vLong = pc; code_word(0); + luaY_val.vLong = pc; code_word(0); } break; case 57: -# line 627 "lua.stx" +# line 633 "lua.stx" { - code_word_at(basepc+yypvt[-3].vLong, yypvt[-1].vInt); + code_word_at(basepc+luaY_pvt[-3].vLong, luaY_pvt[-1].vInt); } break; case 58: -# line 633 "lua.stx" +# line 639 "lua.stx" { code_byte(CALLFUNC); - code_byte(yypvt[-1].vInt+yypvt[-0].vInt); - yyval.vLong = pc; + code_byte(luaY_pvt[-1].vInt+luaY_pvt[-0].vInt); + luaY_val.vLong = pc; code_byte(0); /* may be modified by other rules */ } break; case 59: -# line 641 "lua.stx" -{ yyval.vInt = 0; } break; +# line 647 "lua.stx" +{ luaY_val.vInt = 0; } break; case 60: -# line 643 "lua.stx" +# line 649 "lua.stx" { code_byte(PUSHSELF); - code_word(luaI_findconstant(yypvt[-0].pNode)); - yyval.vInt = 1; + code_word(luaI_findconstant(luaY_pvt[-0].pTStr)); + luaY_val.vInt = 1; } break; case 61: -# line 651 "lua.stx" -{ yyval.vInt = adjust_functioncall(yypvt[-1].vLong, 1); } break; +# line 657 "lua.stx" +{ luaY_val.vInt = adjust_functioncall(luaY_pvt[-1].vLong, 1); } break; case 62: -# line 652 "lua.stx" -{ yyval.vInt = 1; } break; +# line 658 "lua.stx" +{ luaY_val.vInt = 1; } break; case 63: -# line 655 "lua.stx" -{ yyval.vLong = 0; } break; +# line 661 "lua.stx" +{ luaY_val.vLong = 0; } break; case 64: -# line 656 "lua.stx" -{ yyval.vLong = yypvt[-0].vLong; } break; +# line 662 "lua.stx" +{ luaY_val.vLong = luaY_pvt[-0].vLong; } break; case 65: -# line 659 "lua.stx" -{ if (yypvt[-0].vLong != 0) yyval.vLong = yypvt[-0].vLong; else yyval.vLong = -1; } break; +# line 665 "lua.stx" +{ if (luaY_pvt[-0].vLong != 0) luaY_val.vLong = luaY_pvt[-0].vLong; else luaY_val.vLong = -1; } break; case 66: -# line 660 "lua.stx" -{ yyval.vLong = adjust_functioncall(yypvt[-1].vLong, 1); } break; +# line 666 "lua.stx" +{ luaY_val.vLong = adjust_functioncall(luaY_pvt[-1].vLong, 1); } break; case 67: -# line 661 "lua.stx" +# line 667 "lua.stx" { - if (yypvt[-0].vLong == 0) yyval.vLong = -(yypvt[-1].vLong + 1); /* -length */ + if (luaY_pvt[-0].vLong == 0) luaY_val.vLong = -(luaY_pvt[-1].vLong + 1); /* -length */ else { - adjust_functioncall(yypvt[-0].vLong, yypvt[-1].vLong); - yyval.vLong = yypvt[-0].vLong; + adjust_functioncall(luaY_pvt[-0].vLong, luaY_pvt[-1].vLong); + luaY_val.vLong = luaY_pvt[-0].vLong; } } break; case 68: -# line 671 "lua.stx" -{ lua_codeadjust(0); yyval.vInt = lua_linenumber; } break; +# line 677 "lua.stx" +{ lua_codeadjust(0); luaY_val.vInt = lua_linenumber; } break; case 69: -# line 672 "lua.stx" -{ lua_codeadjust(0); yyval.vInt = lua_linenumber; } break; +# line 678 "lua.stx" +{ lua_codeadjust(0); luaY_val.vInt = lua_linenumber; } break; case 70: -# line 676 "lua.stx" -{ - add_localvar(luaI_findsymbol(yypvt[-0].pNode)); - } break; +# line 681 "lua.stx" +{ add_localvar(luaY_pvt[-0].pTStr); } break; case 71: -# line 680 "lua.stx" -{ - add_localvar(luaI_findsymbol(yypvt[-0].pNode)); - } break; +# line 682 "lua.stx" +{ add_localvar(luaY_pvt[-0].pTStr); } break; case 72: # line 686 "lua.stx" -{ flush_list(yypvt[-0].vInt/FIELDS_PER_FLUSH, yypvt[-0].vInt%FIELDS_PER_FLUSH); } break; +{ flush_list(luaY_pvt[-0].vInt/FIELDS_PER_FLUSH, luaY_pvt[-0].vInt%FIELDS_PER_FLUSH); } break; case 73: # line 688 "lua.stx" -{ yyval.vInt = yypvt[-2].vInt+yypvt[-0].vInt; } break; +{ luaY_val.vInt = luaY_pvt[-2].vInt+luaY_pvt[-0].vInt; } break; case 74: # line 690 "lua.stx" -{ yyval.vInt = yypvt[-1].vInt; flush_record(yypvt[-1].vInt%FIELDS_PER_FLUSH); } break; +{ luaY_val.vInt = luaY_pvt[-1].vInt; flush_record(luaY_pvt[-1].vInt%FIELDS_PER_FLUSH); } break; case 75: # line 694 "lua.stx" -{ yyval.vInt = 0; } break; +{ luaY_val.vInt = 0; } break; case 76: # line 696 "lua.stx" -{ yyval.vInt = yypvt[-0].vInt; flush_record(yypvt[-0].vInt%FIELDS_PER_FLUSH); } break; +{ luaY_val.vInt = luaY_pvt[-0].vInt; flush_record(luaY_pvt[-0].vInt%FIELDS_PER_FLUSH); } break; case 79: # line 703 "lua.stx" -{ yyval.vInt = 0; } break; +{ luaY_val.vInt = 0; } break; case 80: # line 704 "lua.stx" -{ yyval.vInt = yypvt[-1].vInt; } break; +{ luaY_val.vInt = luaY_pvt[-1].vInt; } break; case 81: # line 707 "lua.stx" -{yyval.vInt=1;} break; +{luaY_val.vInt=1;} break; case 82: # line 709 "lua.stx" { - yyval.vInt=yypvt[-2].vInt+1; - if (yyval.vInt%FIELDS_PER_FLUSH == 0) flush_record(FIELDS_PER_FLUSH); + luaY_val.vInt=luaY_pvt[-2].vInt+1; + if (luaY_val.vInt%FIELDS_PER_FLUSH == 0) flush_record(FIELDS_PER_FLUSH); } break; case 83: # line 716 "lua.stx" { - push_field(luaI_findconstant(yypvt[-2].pNode)); + push_field(luaI_findconstant(luaY_pvt[-2].pTStr)); } break; case 84: # line 721 "lua.stx" -{ yyval.vInt = 0; } break; +{ luaY_val.vInt = 0; } break; case 85: # line 722 "lua.stx" -{ yyval.vInt = yypvt[-1].vInt; } break; +{ luaY_val.vInt = luaY_pvt[-1].vInt; } break; case 86: # line 725 "lua.stx" -{yyval.vInt=1;} break; +{luaY_val.vInt=1;} break; 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); + luaY_val.vInt=luaY_pvt[-2].vInt+1; + if (luaY_val.vInt%FIELDS_PER_FLUSH == 0) + flush_list(luaY_val.vInt/FIELDS_PER_FLUSH - 1, FIELDS_PER_FLUSH); } break; case 88: # line 735 "lua.stx" { nvarbuffer = 0; - add_varbuffer(yypvt[-0].vLong); - yyval.vInt = (yypvt[-0].vLong == 0) ? 1 : 0; + add_varbuffer(luaY_pvt[-0].vLong); + luaY_val.vInt = (luaY_pvt[-0].vLong == 0) ? 1 : 0; } break; case 89: # line 741 "lua.stx" { - add_varbuffer(yypvt[-0].vLong); - yyval.vInt = (yypvt[-0].vLong == 0) ? yypvt[-2].vInt + 1 : yypvt[-2].vInt; + add_varbuffer(luaY_pvt[-0].vLong); + luaY_val.vInt = (luaY_pvt[-0].vLong == 0) ? luaY_pvt[-2].vInt + 1 : luaY_pvt[-2].vInt; } break; case 90: # line 747 "lua.stx" -{ yyval.vLong = yypvt[-0].vLong; } break; +{ luaY_val.vLong = luaY_pvt[-0].vLong; } break; case 91: # line 749 "lua.stx" { - yyval.vLong = 0; /* indexed variable */ + luaY_val.vLong = 0; /* indexed variable */ } break; case 92: # line 753 "lua.stx" { code_byte(PUSHSTRING); - code_word(luaI_findconstant(yypvt[-0].pNode)); - yyval.vLong = 0; /* indexed variable */ + code_word(luaI_findconstant(luaY_pvt[-0].pTStr)); + luaY_val.vLong = 0; /* indexed variable */ } break; case 93: # line 761 "lua.stx" { - Word s = luaI_findsymbol(yypvt[-0].pNode); - int local = lua_localname (s); + int local = lua_localname(luaY_pvt[-0].pTStr); if (local == -1) /* global var */ - yyval.vLong = s + 1; /* return positive value */ + luaY_val.vLong = luaI_findsymbol(luaY_pvt[-0].pTStr)+1; /* return positive value */ else - yyval.vLong = -(local+1); /* return negative value */ + luaY_val.vLong = -(local+1); /* return negative value */ } break; case 94: -# line 771 "lua.stx" -{ lua_pushvar(yypvt[-0].vLong); } break; +# line 770 "lua.stx" +{ lua_pushvar(luaY_pvt[-0].vLong); } break; case 95: -# line 774 "lua.stx" -{store_localvar(luaI_findsymbol(yypvt[-0].pNode), 0); yyval.vInt = 1;} break; +# line 773 "lua.stx" +{store_localvar(luaY_pvt[-0].pTStr, 0); luaY_val.vInt = 1;} break; case 96: -# line 776 "lua.stx" +# line 775 "lua.stx" { - store_localvar(luaI_findsymbol(yypvt[-0].pNode), yypvt[-2].vInt); - yyval.vInt = yypvt[-2].vInt+1; + store_localvar(luaY_pvt[-0].pTStr, luaY_pvt[-2].vInt); + luaY_val.vInt = luaY_pvt[-2].vInt+1; } break; case 97: -# line 782 "lua.stx" -{ yyval.vInt = 0; } break; +# line 781 "lua.stx" +{ luaY_val.vInt = 0; } break; case 98: -# line 783 "lua.stx" -{ yyval.vInt = yypvt[-0].vLong; } break; +# line 782 "lua.stx" +{ luaY_val.vInt = luaY_pvt[-0].vLong; } break; case 99: -# line 786 "lua.stx" -{ lua_debug = yypvt[-0].vInt; } break; +# line 785 "lua.stx" +{ lua_debug = luaY_pvt[-0].vInt; } break; } - goto yystack; /* reset registers in driver code */ + goto luaY_stack; /* reset registers in driver code */ } diff --git a/src/parser.h b/src/parser.h index ea815f11..d681cd66 100644 --- a/src/parser.h +++ b/src/parser.h @@ -1,3 +1,4 @@ + typedef union { int vInt; @@ -6,9 +7,9 @@ typedef union Word vWord; Long vLong; TFunc *pFunc; - TreeNode *pNode; + TaggedString *pTStr; } YYSTYPE; -extern YYSTYPE yylval; +extern YYSTYPE luaY_lval; # define WRONGTOKEN 257 # define NIL 258 # define IF 259 diff --git a/src/table.c b/src/table.c index 1a2ac96b..1d694c4e 100644 --- a/src/table.c +++ b/src/table.c @@ -3,9 +3,7 @@ ** Module to control static tables */ -char *rcs_table="$Id: table.c,v 2.38 1995/11/03 15:30:50 roberto Exp $"; - -/*#include <string.h>*/ +char *rcs_table="$Id: table.c,v 2.54 1996/05/06 14:29:35 roberto Exp $"; #include "mem.h" #include "opcode.h" @@ -21,61 +19,66 @@ char *rcs_table="$Id: table.c,v 2.38 1995/11/03 15:30:50 roberto Exp $"; #define BUFFER_BLOCK 256 Symbol *lua_table = NULL; -static Word lua_ntable = 0; +Word lua_ntable = 0; static Long lua_maxsymbol = 0; TaggedString **lua_constant = NULL; -static Word lua_nconstant = 0; +Word lua_nconstant = 0; static Long lua_maxconstant = 0; -#define GARBAGE_BLOCK 1024 -#define MIN_GARBAGE_BLOCK (GARBAGE_BLOCK/2) +#define GARBAGE_BLOCK 50 static void lua_nextvar (void); -static void setglobal (void); -static void getglobal (void); /* -** Initialise symbol table with internal functions +** Internal functions */ -static void lua_initsymbol (void) +static struct { + char *name; + lua_CFunction func; +} int_funcs[] = { + {"assert", luaI_assert}, + {"dofile", lua_internaldofile}, + {"dostring", lua_internaldostring}, + {"error", luaI_error}, + {"getglobal", luaI_getglobal}, + {"next", lua_next}, + {"nextvar", lua_nextvar}, + {"print", luaI_print}, + {"setfallback", luaI_setfallback}, + {"setglobal", luaI_setglobal}, + {"tonumber", lua_obj2number}, + {"tostring", luaI_tostring}, + {"type", luaI_type} +}; + +#define INTFUNCSIZE (sizeof(int_funcs)/sizeof(int_funcs[0])) + + +void luaI_initsymbol (void) { - Word n; - lua_maxsymbol = BUFFER_BLOCK; - lua_table = newvector(lua_maxsymbol, Symbol); - n = luaI_findsymbolbyname("next"); - s_tag(n) = LUA_T_CFUNCTION; s_fvalue(n) = lua_next; - n = luaI_findsymbolbyname("dofile"); - s_tag(n) = LUA_T_CFUNCTION; s_fvalue(n) = lua_internaldofile; - n = luaI_findsymbolbyname("setglobal"); - s_tag(n) = LUA_T_CFUNCTION; s_fvalue(n) = setglobal; - n = luaI_findsymbolbyname("getglobal"); - s_tag(n) = LUA_T_CFUNCTION; s_fvalue(n) = getglobal; - n = luaI_findsymbolbyname("nextvar"); - s_tag(n) = LUA_T_CFUNCTION; s_fvalue(n) = lua_nextvar; - n = luaI_findsymbolbyname("type"); - s_tag(n) = LUA_T_CFUNCTION; s_fvalue(n) = luaI_type; - n = luaI_findsymbolbyname("tonumber"); - s_tag(n) = LUA_T_CFUNCTION; s_fvalue(n) = lua_obj2number; - n = luaI_findsymbolbyname("print"); - s_tag(n) = LUA_T_CFUNCTION; s_fvalue(n) = lua_print; - n = luaI_findsymbolbyname("dostring"); - s_tag(n) = LUA_T_CFUNCTION; s_fvalue(n) = lua_internaldostring; - n = luaI_findsymbolbyname("setfallback"); - s_tag(n) = LUA_T_CFUNCTION; s_fvalue(n) = luaI_setfallback; - n = luaI_findsymbolbyname("error"); - s_tag(n) = LUA_T_CFUNCTION; s_fvalue(n) = luaI_error; + int i; + lua_maxsymbol = BUFFER_BLOCK; + lua_table = newvector(lua_maxsymbol, Symbol); + for (i=0; i<INTFUNCSIZE; i++) + { + Word n = luaI_findsymbolbyname(int_funcs[i].name); + s_tag(n) = LUA_T_CFUNCTION; s_fvalue(n) = int_funcs[i].func; + } } /* ** Initialise constant table with pre-defined constants */ -void lua_initconstant (void) +void luaI_initconstant (void) { lua_maxconstant = BUFFER_BLOCK; lua_constant = newvector(lua_maxconstant, TaggedString *); + /* pre-register mem error messages, to avoid loop when error arises */ + luaI_findconstantbyname(tableEM); + luaI_findconstantbyname(memEM); } @@ -83,22 +86,15 @@ void lua_initconstant (void) ** Given a name, search it at symbol table and return its index. If not ** found, allocate it. */ -Word luaI_findsymbol (TreeNode *t) +Word luaI_findsymbol (TaggedString *t) { - if (lua_table == NULL) - lua_initsymbol(); if (t->varindex == NOT_USED) { if (lua_ntable == lua_maxsymbol) - { - if (lua_maxsymbol >= MAX_WORD) - lua_error("symbol table overflow"); - lua_maxsymbol *= 2; - if (lua_maxsymbol >= MAX_WORD) - lua_maxsymbol = MAX_WORD; - lua_table = growvector(lua_table, lua_maxsymbol, Symbol); - } + lua_maxsymbol = growvector(&lua_table, lua_maxsymbol, Symbol, + symbolEM, MAX_WORD); t->varindex = lua_ntable; + lua_table[lua_ntable].varname = t; s_tag(lua_ntable) = LUA_T_NIL; lua_ntable++; } @@ -108,7 +104,7 @@ Word luaI_findsymbol (TreeNode *t) Word luaI_findsymbolbyname (char *name) { - return luaI_findsymbol(lua_constcreate(name)); + return luaI_findsymbol(luaI_createfixedstring(name)); } @@ -116,23 +112,15 @@ Word luaI_findsymbolbyname (char *name) ** Given a tree node, check it is has a correspondent constant index. If not, ** allocate it. */ -Word luaI_findconstant (TreeNode *t) +Word luaI_findconstant (TaggedString *t) { - if (lua_constant == NULL) - lua_initconstant(); if (t->constindex == NOT_USED) { if (lua_nconstant == lua_maxconstant) - { - if (lua_maxconstant >= MAX_WORD) - lua_error("constant table overflow"); - lua_maxconstant *= 2; - if (lua_maxconstant >= MAX_WORD) - lua_maxconstant = MAX_WORD; - lua_constant = growvector(lua_constant, lua_maxconstant, TaggedString *); - } + lua_maxconstant = growvector(&lua_constant, lua_maxconstant, TaggedString *, + constantEM, MAX_WORD); t->constindex = lua_nconstant; - lua_constant[lua_nconstant] = &(t->ts); + lua_constant[lua_nconstant] = t; lua_nconstant++; } return t->constindex; @@ -141,7 +129,15 @@ Word luaI_findconstant (TreeNode *t) Word luaI_findconstantbyname (char *name) { - return luaI_findconstant(lua_constcreate(name)); + return luaI_findconstant(luaI_createfixedstring(name)); +} + +TaggedString *luaI_createfixedstring (char *name) +{ + TaggedString *ts = lua_createstring(name); + if (!ts->marked) + ts->marked = 2; /* avoid GC */ + return ts; } @@ -153,7 +149,7 @@ static char *lua_travsymbol (int (*fn)(Object *)) Word i; for (i=0; i<lua_ntable; i++) if (fn(&s_object(i))) - return luaI_nodebysymbol(i)->ts.str; + return lua_table[i].varname->str; return NULL; } @@ -162,7 +158,7 @@ static char *lua_travsymbol (int (*fn)(Object *)) ** Mark an object if it is a string or a unmarked array. */ int lua_markobject (Object *o) -{ +{/* if already marked, does not change mark value */ if (tag(o) == LUA_T_STRING && !tsvalue(o)->marked) tsvalue(o)->marked = 1; else if (tag(o) == LUA_T_ARRAY) @@ -173,27 +169,52 @@ int lua_markobject (Object *o) return 0; } +/* +* returns 0 if the object is going to be (garbage) collected +*/ +int luaI_ismarked (Object *o) +{ + switch (o->tag) + { + case LUA_T_STRING: + return o->value.ts->marked; + case LUA_T_FUNCTION: + return o->value.tf->marked; + case LUA_T_ARRAY: + return o->value.a->mark; + default: /* nil, number, cfunction, or user data */ + return 1; + } +} + /* ** Garbage collection. ** Delete all unused strings and arrays. */ -void lua_pack (void) +Long luaI_collectgarbage (void) { - static Long block = GARBAGE_BLOCK; /* when garbage collector will be called */ - static Long nentity = 0; /* counter of new entities (strings and arrays) */ Long recovered = 0; - if (nentity++ < block) return; 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 */ + luaI_invalidaterefs(); 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; + return recovered; +} + +void lua_pack (void) +{ + static unsigned long block = GARBAGE_BLOCK; + static unsigned long nentity = 0; /* total of strings, arrays, etc */ + unsigned long recovered = 0; + if (nentity++ < block) return; + recovered = luaI_collectgarbage(); + block = block*2*(1.0 - (float)recovered/nentity); + nentity -= recovered; } @@ -225,36 +246,12 @@ static void lua_nextvar (void) } else { - TreeNode *t = luaI_nodebysymbol(next); - Object name; - tag(&name) = LUA_T_STRING; - tsvalue(&name) = &(t->ts); - luaI_pushobject(&name); + lua_pushstring(lua_table[next].varname->str); luaI_pushobject(&s_object(next)); } } -static void setglobal (void) -{ - lua_Object name = lua_getparam(1); - lua_Object value = lua_getparam(2); - if (!lua_isstring(name)) - lua_error("incorrect argument to function `setglobal'"); - lua_pushobject(value); - lua_storeglobal(lua_getstring(name)); -} - - -static void getglobal (void) -{ - lua_Object name = lua_getparam(1); - if (!lua_isstring(name)) - lua_error("incorrect argument to function `getglobal'"); - lua_pushobject(lua_getglobal(lua_getstring(name))); -} - - static Object *functofind; static int checkfunc (Object *o) { @@ -270,7 +267,7 @@ static int checkfunc (Object *o) } -char *getobjname (lua_Object o, char **name) +char *lua_getobjname (lua_Object o, char **name) { /* try to find a name for given function */ functofind = luaI_Address(o); if ((*name = luaI_travfallbacks(checkfunc)) != NULL) diff --git a/src/table.h b/src/table.h index 4e581401..d7003c96 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.13 1995/10/26 14:21:56 roberto Exp $ +** $Id: table.h,v 2.21 1996/04/22 18:00:37 roberto Exp $ */ #ifndef table_h @@ -10,19 +10,28 @@ #include "tree.h" #include "opcode.h" -extern Symbol *lua_table; -extern TaggedString **lua_constant; +typedef struct +{ + Object object; + TaggedString *varname; +} Symbol; -extern char *lua_file[]; -extern int lua_nfile; +extern Symbol *lua_table; +extern Word lua_ntable; +extern TaggedString **lua_constant; +extern Word lua_nconstant; -void lua_initconstant (void); +void luaI_initsymbol (void); +void luaI_initconstant (void); Word luaI_findsymbolbyname (char *name); -Word luaI_findsymbol (TreeNode *t); -Word luaI_findconstant (TreeNode *t); +Word luaI_findsymbol (TaggedString *t); +Word luaI_findconstant (TaggedString *t); Word luaI_findconstantbyname (char *name); +TaggedString *luaI_createfixedstring (char *str); int lua_markobject (Object *o); +int luaI_ismarked (Object *o); +Long luaI_collectgarbage (void); void lua_pack (void); @@ -3,7 +3,7 @@ ** TecCGraf - PUC-Rio */ -char *rcs_tree="$Id: tree.c,v 1.14 1995/10/17 11:53:53 roberto Exp $"; +char *rcs_tree="$Id: tree.c,v 1.20 1996/03/14 15:56:26 roberto Exp $"; #include <string.h> @@ -11,66 +11,104 @@ char *rcs_tree="$Id: tree.c,v 1.14 1995/10/17 11:53:53 roberto Exp $"; #include "mem.h" #include "lua.h" #include "tree.h" +#include "lex.h" +#include "hash.h" #include "table.h" -#define lua_strcmp(a,b) (a[0]<b[0]?(-1):(a[0]>b[0]?(1):strcmp(a,b))) +#define NUM_HASHS 64 +typedef struct { + int size; + int nuse; /* number of elements (including EMPTYs) */ + TaggedString **hash; +} stringtable; -typedef struct StringNode { - struct StringNode *next; - TaggedString ts; -} StringNode; +static int initialized = 0; -static StringNode *string_root = NULL; +static stringtable string_root[NUM_HASHS]; -static TreeNode *constant_root = NULL; +static TaggedString EMPTY = {NOT_USED, NOT_USED, 0, 2, {0}}; -/* -** Insert a new constant/variable at the tree. -*/ -static TreeNode *tree_create (TreeNode **node, char *str) + +static unsigned long hash (char *str) { - if (*node == NULL) - { - *node = (TreeNode *) luaI_malloc(sizeof(TreeNode)+strlen(str)); - (*node)->left = (*node)->right = NULL; - strcpy((*node)->ts.str, str); - (*node)->ts.marked = 0; - (*node)->ts.hash = 0; - (*node)->varindex = (*node)->constindex = NOT_USED; - return *node; - } - else - { - int c = lua_strcmp(str, (*node)->ts.str); - if (c < 0) - return tree_create(&(*node)->left, str); - else if (c > 0) - return tree_create(&(*node)->right, str); - else - return *node; - } + unsigned long h = 0; + while (*str) + h = ((h<<5)-h)^(unsigned char)*(str++); + return h; } -TaggedString *lua_createstring (char *str) +static void initialize (void) { - StringNode *newString; - if (str == NULL) return NULL; - lua_pack(); - newString = (StringNode *)luaI_malloc(sizeof(StringNode)+strlen(str)); - newString->ts.marked = 0; - newString->ts.hash = 0; - strcpy(newString->ts.str, str); - newString->next = string_root; - string_root = newString; - return &(newString->ts); + initialized = 1; + luaI_addReserved(); + luaI_initsymbol(); + luaI_initconstant(); +} + + +static void grow (stringtable *tb) +{ + int newsize = luaI_redimension(tb->size); + TaggedString **newhash = newvector(newsize, TaggedString *); + int i; + for (i=0; i<newsize; i++) + newhash[i] = NULL; + /* rehash */ + tb->nuse = 0; + for (i=0; i<tb->size; i++) + if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY) + { + int h = tb->hash[i]->hash%newsize; + while (newhash[h]) + h = (h+1)%newsize; + newhash[h] = tb->hash[i]; + tb->nuse++; + } + luaI_free(tb->hash); + tb->size = newsize; + tb->hash = newhash; } +static TaggedString *insert (char *str, stringtable *tb) +{ + TaggedString *ts; + unsigned long h = hash(str); + int i; + int j = -1; + if ((Long)tb->nuse*3 >= (Long)tb->size*2) + { + if (!initialized) + initialize(); + grow(tb); + } + i = h%tb->size; + while (tb->hash[i]) + { + if (tb->hash[i] == &EMPTY) + j = i; + else if (strcmp(str, tb->hash[i]->str) == 0) + return tb->hash[i]; + i = (i+1)%tb->size; + } + /* not found */ + lua_pack(); + if (j != -1) /* is there an EMPTY space? */ + i = j; + else + tb->nuse++; + ts = tb->hash[i] = (TaggedString *)luaI_malloc(sizeof(TaggedString)+strlen(str)); + strcpy(ts->str, str); + ts->marked = 0; + ts->hash = h; + ts->varindex = ts->constindex = NOT_USED; + return ts; +} -TreeNode *lua_constcreate (char *str) +TaggedString *lua_createstring (char *str) { - return tree_create(&constant_root, str); + return insert(str, &string_root[(unsigned)str[0]%NUM_HASHS]); } @@ -80,44 +118,28 @@ TreeNode *lua_constcreate (char *str) */ Long lua_strcollector (void) { - StringNode *curr = string_root, *prev = NULL; Long counter = 0; - while (curr) + int i; + for (i=0; i<NUM_HASHS; i++) { - StringNode *next = curr->next; - if (!curr->ts.marked) - { - if (prev == NULL) string_root = next; - else prev->next = next; - luaI_free(curr); - ++counter; - } - else + stringtable *tb = &string_root[i]; + int j; + for (j=0; j<tb->size; j++) { - curr->ts.marked = 0; - prev = curr; + TaggedString *t = tb->hash[j]; + if (t != NULL && t->marked <= 1) + { + if (t->marked) + t->marked = 0; + else + { + luaI_free(t); + tb->hash[j] = &EMPTY; + counter++; + } + } } - curr = next; } return counter; } - -/* -** Traverse the constant tree looking for a specific symbol number -*/ -static TreeNode *nodebysymbol (TreeNode *root, Word symbol) -{ - 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 *luaI_nodebysymbol (Word symbol) -{ - return nodebysymbol(constant_root, symbol); -} - @@ -1,7 +1,7 @@ /* ** tree.h ** TecCGraf - PUC-Rio -** $Id: tree.h,v 1.10 1995/10/17 11:53:53 roberto Exp $ +** $Id: tree.h,v 1.14 1996/02/26 17:07:49 roberto Exp $ */ #ifndef tree_h @@ -14,24 +14,15 @@ typedef struct TaggedString { + Word varindex; /* != NOT_USED if this is a symbol */ + Word constindex; /* != NOT_USED if this is a constant */ unsigned long hash; /* 0 if not initialized */ - char marked; /* for garbage collection */ + int marked; /* for garbage collection; never collect (nor change) if > 1 */ char str[1]; /* \0 byte already reserved */ } TaggedString; -typedef struct TreeNode -{ - struct TreeNode *right; - struct TreeNode *left; - unsigned short varindex; /* != NOT_USED if this is a symbol */ - unsigned short constindex; /* != NOT_USED if this is a constant */ - TaggedString ts; -} TreeNode; - TaggedString *lua_createstring (char *str); -TreeNode *lua_constcreate (char *str); Long lua_strcollector (void); -TreeNode *luaI_nodebysymbol (Word symbol); #endif diff --git a/src/types.h b/src/types.h index 43684228..748ed83f 100644 --- a/src/types.h +++ b/src/types.h @@ -1,6 +1,6 @@ /* ** TeCGraf - PUC-Rio -** $Id: types.h,v 1.3 1995/02/06 19:32:43 roberto Exp $ +** $Id: types.h,v 1.4 1996/02/07 14:13:17 roberto Exp $ */ #ifndef types_h @@ -12,8 +12,6 @@ #define real float #endif -typedef int Bool; /* boolean values */ - #define Byte lua_Byte /* some systems have Byte as a predefined type */ typedef unsigned char Byte; /* unsigned 8 bits */ diff --git a/src/ugly.h b/src/ugly.h deleted file mode 100644 index c7512255..00000000 --- a/src/ugly.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -** ugly.h -** TecCGraf - PUC-Rio -** $Id: ugly.h,v 1.2 1994/11/13 14:39:04 roberto Stab $ -*/ - -#ifndef ugly_h -#define ugly_h - -/* This enum must have the same order of the array 'reserved' in lex.c */ - -enum { - U_and=128, - U_do, - U_else, - U_elseif, - U_end, - U_function, - U_if, - U_local, - U_nil, - U_not, - U_or, - U_repeat, - U_return, - U_then, - U_until, - U_while, - U_eq = '='+128, - U_le = '<'+128, - U_ge = '>'+128, - U_ne = '~'+128, - U_sc = '.'+128 -}; - -#endif diff --git a/src/undump.c b/src/undump.c new file mode 100644 index 00000000..744622fc --- /dev/null +++ b/src/undump.c @@ -0,0 +1,326 @@ +/* +** undump.c +** load bytecodes from files +*/ + +char* rcs_undump="$Id: undump.c,v 1.14 1996/03/14 17:31:15 lhf Exp $"; + +#include <stdio.h> +#include <string.h> +#include "opcode.h" +#include "mem.h" +#include "table.h" +#include "undump.h" + +static int swapword=0; +static int swapfloat=0; +static TFunc* Main=NULL; /* functions in a chunk */ +static TFunc* lastF=NULL; + +static void warn(char* s) /* TODO: remove */ +{ +#if 0 + fprintf(stderr,"undump: %s\n",s); +#endif +} + +static void FixCode(Byte* code, Byte* end) /* swap words */ +{ + Byte* p; + for (p=code; p!=end;) + { + OpCode op=(OpCode)*p; + switch (op) + { + case PUSHNIL: + case PUSH0: + case PUSH1: + case PUSH2: + case PUSHLOCAL0: + case PUSHLOCAL1: + case PUSHLOCAL2: + case PUSHLOCAL3: + case PUSHLOCAL4: + case PUSHLOCAL5: + case PUSHLOCAL6: + case PUSHLOCAL7: + case PUSHLOCAL8: + case PUSHLOCAL9: + case PUSHINDEXED: + case STORELOCAL0: + case STORELOCAL1: + case STORELOCAL2: + case STORELOCAL3: + case STORELOCAL4: + case STORELOCAL5: + case STORELOCAL6: + case STORELOCAL7: + case STORELOCAL8: + case STORELOCAL9: + case STOREINDEXED0: + case ADJUST0: + case EQOP: + case LTOP: + case LEOP: + case GTOP: + case GEOP: + case ADDOP: + case SUBOP: + case MULTOP: + case DIVOP: + case POWOP: + case CONCOP: + case MINUSOP: + case NOTOP: + case POP: + case RETCODE0: + p++; + break; + case PUSHBYTE: + case PUSHLOCAL: + case STORELOCAL: + case STOREINDEXED: + case STORELIST0: + case ADJUST: + case RETCODE: + p+=2; + break; + case STORELIST: + case CALLFUNC: + p+=3; + break; + case PUSHFUNCTION: + p+=5; + break; + case PUSHWORD: + case PUSHSELF: + case CREATEARRAY: + case ONTJMP: + case ONFJMP: + case JMP: + case UPJMP: + case IFFJMP: + case IFFUPJMP: + case SETLINE: + case PUSHSTRING: + case PUSHGLOBAL: + case STOREGLOBAL: + { + Byte t; + t=p[1]; p[1]=p[2]; p[2]=t; + p+=3; + break; + } + case PUSHFLOAT: + { + Byte t; + t=p[1]; p[1]=p[4]; p[4]=t; + t=p[2]; p[2]=p[3]; p[3]=t; + p+=5; + break; + } + case STORERECORD: + { + int n=*++p; + p++; + while (n--) + { + Byte t; + t=p[0]; p[0]=p[1]; p[1]=t; + p+=2; + } + break; + } + default: + lua_error("corrupt binary file"); + break; + } + } +} + +static void Unthread(Byte* code, int i, int v) +{ + while (i!=0) + { + CodeWord c; + Byte* p=code+i; + get_word(c,p); + i=c.w; + c.w=v; + p[-2]=c.m.c1; + p[-1]=c.m.c2; + } +} + +static int LoadWord(FILE* D) +{ + Word w; + fread(&w,sizeof(w),1,D); + if (swapword) + { + Byte* p=(Byte*)&w; /* TODO: need union? */ + Byte t; + t=p[0]; p[0]=p[1]; p[1]=t; + } + return w; +} + +static int LoadSize(FILE* D) +{ + Word hi=LoadWord(D); + Word lo=LoadWord(D); + int s=(hi<<16)|lo; + if ((Word)s != s) lua_error("code too long"); + return s; +} + +static char* LoadBlock(int size, FILE* D) +{ + char* b=luaI_malloc(size); + fread(b,size,1,D); + return b; +} + +static char* LoadString(FILE* D) +{ + int size=LoadWord(D); + char *b=luaI_buffer(size); + fread(b,size,1,D); + return b; +} + +static char* LoadNewString(FILE* D) +{ + return LoadBlock(LoadWord(D),D); +} + +static void LoadFunction(FILE* D) +{ + TFunc* tf=new(TFunc); + tf->next=NULL; + tf->locvars=NULL; + tf->size=LoadSize(D); + tf->lineDefined=LoadWord(D); + if (IsMain(tf)) /* new main */ + { + tf->fileName=LoadNewString(D); + Main=lastF=tf; + } + else /* fix PUSHFUNCTION */ + { + CodeCode c; + Byte* p; + tf->marked=LoadWord(D); + tf->fileName=Main->fileName; + p=Main->code+tf->marked; + c.tf=tf; + *p++=c.m.c1; *p++=c.m.c2; *p++=c.m.c3; *p++=c.m.c4; + lastF=lastF->next=tf; + } + tf->code=LoadBlock(tf->size,D); + if (swapword || swapfloat) FixCode(tf->code,tf->code+tf->size); + while (1) /* unthread */ + { + int c=getc(D); + if (c==ID_VAR) /* global var */ + { + int i=LoadWord(D); + char* s=LoadString(D); + int v=luaI_findsymbolbyname(s); + Unthread(tf->code,i,v); + } + else if (c==ID_STR) /* constant string */ + { + int i=LoadWord(D); + char* s=LoadString(D); + int v=luaI_findconstantbyname(s); + Unthread(tf->code,i,v); + } + else + { + ungetc(c,D); + break; + } + } +} + +static void LoadSignature(FILE* D) +{ + char* s=SIGNATURE; + while (*s!=0 && getc(D)==*s) + ++s; + if (*s!=0) lua_error("bad signature"); +} + +static void LoadHeader(FILE* D) /* TODO: error handling */ +{ + Word w,tw=TEST_WORD; + float f,tf=TEST_FLOAT; + LoadSignature(D); + getc(D); /* skip version */ + fread(&w,sizeof(w),1,D); /* test word */ + if (w!=tw) + { + swapword=1; + warn("different byte order"); + } + fread(&f,sizeof(f),1,D); /* test float */ + if (f!=tf) + { + Byte* p=(Byte*)&f; /* TODO: need union? */ + Byte t; + swapfloat=1; + t=p[0]; p[0]=p[3]; p[3]=t; + t=p[1]; p[1]=p[2]; p[2]=t; + if (f!=tf) /* TODO: try another perm? */ + lua_error("different float representation"); + else + warn("different byte order in floats"); + } +} + +static void LoadChunk(FILE* D) +{ + LoadHeader(D); + while (1) + { + int c=getc(D); + if (c==ID_FUN) LoadFunction(D); else { ungetc(c,D); break; } + } +} + +/* +** load one chunk from a file. +** return list of functions found, headed by main, or NULL at EOF. +*/ +TFunc* luaI_undump1(FILE* D) +{ + while (1) + { + int c=getc(D); + if (c==ID_CHUNK) + { + LoadChunk(D); + return Main; + } + else if (c==EOF) + return NULL; + else + lua_error("not a lua binary file"); + } +} + +/* +** load and run all chunks in a file +*/ +int luaI_undump(FILE* D) +{ + TFunc* m; + while ((m=luaI_undump1(D))) + { + int status=luaI_dorun(m); + luaI_freefunc(m); + if (status!=0) return status; + } + return 0; +} diff --git a/src/undump.h b/src/undump.h new file mode 100644 index 00000000..109634ae --- /dev/null +++ b/src/undump.h @@ -0,0 +1,23 @@ +/* +** undump.h +** definitions for lua decompiler +** $Id: undump.h,v 1.2 1996/03/11 21:59:41 lhf Exp $ +*/ + +#include "func.h" + +#define IsMain(f) (f->lineDefined==0) + +/* definitions for chunk headers */ + +#define ID_CHUNK 27 /* ESC */ +#define ID_FUN 'F' +#define ID_VAR 'V' +#define ID_STR 'S' +#define SIGNATURE "Lua" +#define VERSION 0x23 /* 2.3 */ +#define TEST_WORD 0x1234 /* a word for testing byte ordering */ +#define TEST_FLOAT 0.123456789e-23 /* a float for testing representation */ + +TFunc* luaI_undump1(FILE* D); /* load one chunk */ +int luaI_undump(FILE* D); /* load all chunks */ |