diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 29 | ||||
-rw-r--r-- | src/fallback.c | 171 | ||||
-rw-r--r-- | src/fallback.h | 31 | ||||
-rw-r--r-- | src/hash.c | 421 | ||||
-rw-r--r-- | src/hash.h | 17 | ||||
-rw-r--r-- | src/inout.c | 239 | ||||
-rw-r--r-- | src/inout.h | 23 | ||||
-rw-r--r-- | src/lex.c | 143 | ||||
-rw-r--r-- | src/mem.c | 44 | ||||
-rw-r--r-- | src/mem.h | 25 | ||||
-rw-r--r-- | src/opcode.c | 1623 | ||||
-rw-r--r-- | src/opcode.h | 92 | ||||
-rw-r--r-- | src/parser.c (renamed from src/y.tab.c) | 1492 | ||||
-rw-r--r-- | src/parser.h (renamed from src/y.tab.h) | 20 | ||||
-rw-r--r-- | src/table.c | 402 | ||||
-rw-r--r-- | src/table.h | 31 | ||||
-rw-r--r-- | src/tree.c | 141 | ||||
-rw-r--r-- | src/tree.h | 37 | ||||
-rw-r--r-- | src/types.h | 31 | ||||
-rw-r--r-- | src/ugly.h | 36 | ||||
-rw-r--r-- | src/yacc/Makefile | 30 | ||||
-rw-r--r-- | src/yacc/exscript | 3 | ||||
-rw-r--r-- | src/yacc/lua.lex | 85 | ||||
-rw-r--r-- | src/yacc/lua.stx | 847 |
24 files changed, 3359 insertions, 2654 deletions
diff --git a/src/Makefile b/src/Makefile index 7e833d4f..6d1f1bb1 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,24 +1,35 @@ -# makefile for lua +# makefile for lua distribution -LIB= $(LUA)/lib INC= $(LUA)/include +LIB= $(LUA)/lib + +# in SunOs /usr/5include contains prototypes for standard lib +INCS= -I/usr/5include -I$(INC) +WARN= -Wall -Wmissing-prototypes -Wshadow -ansi CC= gcc -CFLAGS= -g -Wall -O2 -I$(INC) $(DEFS) -DEFS= -DMAXCODE=64000 -DMAXCONSTANT=1024 -DMAXSYMBOL=1024 -DMAXARRAY=1024 +CFLAGS= $(INCS) $(DEFS) $(WARN) -O2 + +OBJS= fallback.o hash.o inout.o lex.o mem.o opcode.o parser.o table.o tree.o -OBJS= hash.o inout.o lex.o opcode.o table.o y.tab.o SLIB= $(LIB)/liblua.a -DLIB= $(LIB)/liblua.so.1.1 -libs: $(SLIB) $(DLIB) +# dynamic libraries only work for SunOs +DLIB= $(LIB)/liblua.so.2.1 + +all: $(SLIB) + +dynamic: $(DLIB) $(SLIB): $(OBJS) - ar ruvl $@ $(OBJS) - ranlib $(SLIB) + ar rcuv $@ $(OBJS) + ranlib $@ $(DLIB): $(OBJS) ld -o $@ $(OBJS) clean: rm -f $(OBJS) $(SLIB) $(DLIB) + +co: + co -M fallback.c hash.c inout.c lex.c mem.c opcode.c table.c tree.c fallback.h hash.h inout.h mem.h opcode.h table.h tree.h types.h ugly.h diff --git a/src/fallback.c b/src/fallback.c new file mode 100644 index 00000000..d5bbbba1 --- /dev/null +++ b/src/fallback.c @@ -0,0 +1,171 @@ +/* +** fallback.c +** TecCGraf - PUC-Rio +*/ + +char *rcs_fallback="$Id: fallback.c,v 1.11 1995/02/06 19:34:03 roberto Exp $"; + +#include <stdio.h> +#include <string.h> + +#include "mem.h" +#include "fallback.h" +#include "opcode.h" +#include "inout.h" +#include "lua.h" + + +static void errorFB (void); +static void indexFB (void); +static void gettableFB (void); +static void arithFB (void); +static void concatFB (void); +static void orderFB (void); +static void GDFB (void); +static void funcFB (void); + + +/* +** Warning: This list must be in the same order as the #define's +*/ +struct FB luaI_fallBacks[] = { +{"error", {LUA_T_CFUNCTION, errorFB}}, +{"index", {LUA_T_CFUNCTION, indexFB}}, +{"gettable", {LUA_T_CFUNCTION, gettableFB}}, +{"arith", {LUA_T_CFUNCTION, arithFB}}, +{"order", {LUA_T_CFUNCTION, orderFB}}, +{"concat", {LUA_T_CFUNCTION, concatFB}}, +{"settable", {LUA_T_CFUNCTION, gettableFB}}, +{"gc", {LUA_T_CFUNCTION, GDFB}}, +{"function", {LUA_T_CFUNCTION, funcFB}} +}; + +#define N_FB (sizeof(luaI_fallBacks)/sizeof(struct FB)) + +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))) + { + lua_pushnil(); + return; + } + for (i=0; i<N_FB; i++) + { + if (strcmp(luaI_fallBacks[i].kind, name) == 0) + { + luaI_pushobject(&luaI_fallBacks[i].function); + luaI_fallBacks[i].function = *luaI_Address(func); + return; + } + } + /* name not found */ + lua_pushnil(); +} + + +static void errorFB (void) +{ + lua_Object o = lua_getparam(1); + if (lua_isstring(o)) + fprintf (stderr, "lua: %s\n", lua_getstring(o)); + else + fprintf(stderr, "lua: unknown error\n"); +} + + +static void indexFB (void) +{ + lua_pushnil(); +} + + +static void gettableFB (void) +{ + lua_reportbug("indexed expression not a table"); +} + + +static void arithFB (void) +{ + lua_reportbug("unexpected type at conversion to number"); +} + +static void concatFB (void) +{ + lua_reportbug("unexpected type at conversion to string"); +} + + +static void orderFB (void) +{ + lua_reportbug("unexpected type at comparison"); +} + +static void GDFB (void) { } + +static void funcFB (void) +{ + lua_reportbug("call expression not a function"); +} + + +/* +** Lock routines +*/ + +static Object *lockArray = NULL; +static Word lockSize = 0; + +int luaI_lock (Object *object) +{ + Word i; + Word 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; + } + /* 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; +} + + +void lua_unlock (int ref) +{ + tag(&lockArray[ref]) = LUA_T_NIL; +} + + +Object *luaI_getlocked (int ref) +{ + return &lockArray[ref]; +} + + +void luaI_travlock (void (*fn)(Object *)) +{ + Word i; + for (i=0; i<lockSize; i++) + fn(&lockArray[i]); +} + diff --git a/src/fallback.h b/src/fallback.h new file mode 100644 index 00000000..225a9063 --- /dev/null +++ b/src/fallback.h @@ -0,0 +1,31 @@ +/* +** $Id: fallback.h,v 1.7 1994/11/21 18:22:58 roberto Stab $ +*/ + +#ifndef fallback_h +#define fallback_h + +#include "opcode.h" + +extern struct FB { + char *kind; + Object function; +} luaI_fallBacks[]; + +#define FB_ERROR 0 +#define FB_INDEX 1 +#define FB_GETTABLE 2 +#define FB_ARITH 3 +#define FB_ORDER 4 +#define FB_CONCAT 5 +#define FB_SETTABLE 6 +#define FB_GC 7 +#define FB_FUNCTION 8 + +void luaI_setfallback (void); +int luaI_lock (Object *object); +Object *luaI_getlocked (int ref); +void luaI_travlock (void (*fn)(Object *)); + +#endif + @@ -1,138 +1,147 @@ /* ** hash.c ** hash manager for lua -** Luiz Henrique de Figueiredo - 17 Aug 90 */ -char *rcs_hash="$Id: hash.c,v 2.1 1994/04/20 22:07:57 celes Exp $"; +char *rcs_hash="$Id: hash.c,v 2.24 1995/02/06 19:34:03 roberto Exp $"; #include <string.h> -#include <stdlib.h> - -#include "mm.h" +#include "mem.h" #include "opcode.h" #include "hash.h" #include "inout.h" #include "table.h" #include "lua.h" -#define streq(s1,s2) (strcmp(s1,s2)==0) -#define strneq(s1,s2) (strcmp(s1,s2)!=0) - -#define new(s) ((s *)malloc(sizeof(s))) -#define newvector(n,s) ((s *)calloc(n,sizeof(s))) +#define streq(s1,s2) (s1 == s2 || (*(s1) == *(s2) && strcmp(s1,s2)==0)) #define nhash(t) ((t)->nhash) -#define nodelist(t) ((t)->list) -#define list(t,i) ((t)->list[i]) +#define nuse(t) ((t)->nuse) #define markarray(t) ((t)->mark) -#define ref_tag(n) (tag(&(n)->ref)) -#define ref_nvalue(n) (nvalue(&(n)->ref)) -#define ref_svalue(n) (svalue(&(n)->ref)) +#define nodevector(t) ((t)->node) +#define node(t,i) (&(t)->node[i]) +#define ref(n) (&(n)->ref) +#define val(n) (&(n)->val) -#ifndef ARRAYBLOCK -#define ARRAYBLOCK 50 -#endif -typedef struct ArrayList -{ - Hash *array; - struct ArrayList *next; -} ArrayList; +#define REHASH_LIMIT 0.70 /* avoid more than this % full */ + -static ArrayList *listhead = NULL; +static Hash *listhead = NULL; -static int head (Hash *t, Object *ref) /* hash function */ + + +/* 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 Word redimension (Word nhash) { - if (tag(ref) == T_NUMBER) return (((int)nvalue(ref))%nhash(t)); - else if (tag(ref) == T_STRING) + Word i; + for (i=0; dimensions[i]!=0; i++) { - int h; - char *name = svalue(ref); - for (h=0; *name!=0; name++) /* interpret name as binary number */ - { - h <<= 8; - h += (unsigned char) *name; /* avoid sign extension */ - h %= nhash(t); /* make it a valid index */ - } - return h; - } - else - { - lua_reportbug ("unexpected type to index table"); - return -1; + if (dimensions[i] > nhash) + return dimensions[i]; } + lua_error("table overflow"); + return 0; /* to avoid warnings */ } -static Node *present(Hash *t, Object *ref, int h) +static Word hashindex (Hash *t, Object *ref) /* hash function */ { - Node *n=NULL, *p; - if (tag(ref) == T_NUMBER) - { - for (p=NULL,n=list(t,h); n!=NULL; p=n, n=n->next) - if (ref_tag(n) == T_NUMBER && nvalue(ref) == ref_nvalue(n)) break; - } - else if (tag(ref) == T_STRING) - { - for (p=NULL,n=list(t,h); n!=NULL; p=n, n=n->next) - if (ref_tag(n) == T_STRING && streq(svalue(ref),ref_svalue(n))) break; - } - if (n==NULL) /* name not present */ - return NULL; -#if 0 - if (p!=NULL) /* name present but not first */ + switch (tag(ref)) { - p->next=n->next; /* move-to-front self-organization */ - n->next=list(t,h); - list(t,h)=n; + case LUA_T_NIL: + lua_reportbug ("unexpected type to index table"); + return -1; /* UNREACHEABLE */ + case LUA_T_NUMBER: + return (((Word)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 */ + } + case LUA_T_FUNCTION: + return (((IntPoint)bvalue(ref))%nhash(t)); + case LUA_T_CFUNCTION: + return (((IntPoint)fvalue(ref))%nhash(t)); + case LUA_T_ARRAY: + return (((IntPoint)avalue(ref))%nhash(t)); + default: /* user data */ + return (((IntPoint)uvalue(ref))%nhash(t)); } -#endif - return n; } -static void freelist (Node *n) +Bool lua_equalObj (Object *t1, Object *t2) { - while (n) + 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_ARRAY: return avalue(t1) == avalue(t2); + case LUA_T_FUNCTION: return bvalue(t1) == bvalue(t2); + case LUA_T_CFUNCTION: return fvalue(t1) == fvalue(t2); + default: return uvalue(t1) == uvalue(t2); + } +} + +static Word present (Hash *t, Object *ref) +{ + Word h = hashindex(t, ref); + while (tag(ref(node(t, h))) != LUA_T_NIL) { - Node *next = n->next; - free (n); - n = next; + if (lua_equalObj(ref, ref(node(t, h)))) + return h; + h = (h+1) % nhash(t); } + return h; +} + + +/* +** Alloc a vector node +*/ +static Node *hashnodecreate (Word nhash) +{ + Word i; + Node *v = newvector (nhash, Node); + for (i=0; i<nhash; i++) + tag(ref(&v[i])) = LUA_T_NIL; + return v; } /* ** Create a new hash. Return the hash pointer or NULL on error. */ -static Hash *hashcreate (unsigned int nhash) +static Hash *hashcreate (Word nhash) { - Hash *t = new (Hash); - if (t == NULL) - { - lua_error ("not enough memory"); - return NULL; - } + Hash *t = new(Hash); + nhash = redimension((Word)((float)nhash/REHASH_LIMIT)); + nodevector(t) = hashnodecreate(nhash); nhash(t) = nhash; + nuse(t) = 0; markarray(t) = 0; - nodelist(t) = newvector (nhash, Node*); - if (nodelist(t) == NULL) - { - lua_error ("not enough memory"); - return NULL; - } return t; } /* ** Delete a hash */ -static void hashdelete (Hash *h) +static void hashdelete (Hash *t) { - int i; - for (i=0; i<nhash(h); i++) - freelist (list(h,i)); - free (nodelist(h)); - free(h); + luaI_free (nodevector(t)); + luaI_free(t); } @@ -143,12 +152,12 @@ void lua_hashmark (Hash *h) { if (markarray(h) == 0) { - int i; + Word i; markarray(h) = 1; for (i=0; i<nhash(h); i++) { - Node *n; - for (n = list(h,i); n != NULL; n = n->next) + Node *n = node(h,i); + if (tag(ref(n)) != LUA_T_NIL) { lua_markobject(&n->ref); lua_markobject(&n->val); @@ -156,92 +165,125 @@ void lua_hashmark (Hash *h) } } } + + +static void call_fallbacks (void) +{ + Hash *curr_array; + Object t; + tag(&t) = LUA_T_ARRAY; + for (curr_array = listhead; curr_array; curr_array = curr_array->next) + if (markarray(curr_array) != 1) + { + avalue(&t) = curr_array; + luaI_gcFB(&t); + } + tag(&t) = LUA_T_NIL; + luaI_gcFB(&t); /* end of list */ +} + /* ** Garbage collection to arrays ** Delete all unmarked arrays. */ -void lua_hashcollector (void) +Long lua_hashcollector (void) { - ArrayList *curr = listhead, *prev = NULL; - while (curr != NULL) + Hash *curr_array = listhead, *prev = NULL; + Long counter = 0; + call_fallbacks(); + while (curr_array != NULL) { - ArrayList *next = curr->next; - if (markarray(curr->array) != 1) + Hash *next = curr_array->next; + if (markarray(curr_array) != 1) { if (prev == NULL) listhead = next; else prev->next = next; - hashdelete(curr->array); - free(curr); + hashdelete(curr_array); + ++counter; } else { - markarray(curr->array) = 0; - prev = curr; + markarray(curr_array) = 0; + prev = curr_array; } - curr = next; + curr_array = next; } + return counter; } /* ** Create a new array -** This function insert the new array at array list. It also -** execute garbage collection if the number of array created +** This function inserts the new array in the array list. It also +** executes garbage collection if the number of arrays created ** exceed a pre-defined range. */ -Hash *lua_createarray (int nhash) +Hash *lua_createarray (Word nhash) { - ArrayList *new = new(ArrayList); - if (new == NULL) - { - lua_error ("not enough memory"); - return NULL; - } - new->array = hashcreate(nhash); - if (new->array == NULL) + Hash *array; + lua_pack(); + array = hashcreate(nhash); + array->next = listhead; + listhead = array; + return array; +} + + +/* +** Re-hash +*/ +static void rehash (Hash *t) +{ + Word i; + Word nold = nhash(t); + Node *vold = nodevector(t); + nhash(t) = redimension(nhash(t)); + nodevector(t) = hashnodecreate(nhash(t)); + for (i=0; i<nold; i++) { - lua_error ("not enough memory"); - return NULL; + Node *n = vold+i; + if (tag(ref(n)) != LUA_T_NIL && tag(val(n)) != LUA_T_NIL) + *node(t, present(t, ref(n))) = *n; /* copy old node to new hahs */ } + luaI_free(vold); +} - if (lua_nentity == lua_block) - lua_pack(); - - lua_nentity++; - new->next = listhead; - listhead = new; - return new->array; +/* +** If the hash node is present, return its pointer, otherwise return +** null. +*/ +Object *lua_hashget (Hash *t, Object *ref) +{ + Word h = present(t, ref); + if (tag(ref(node(t, h))) != LUA_T_NIL) return val(node(t, h)); + else return NULL; } /* ** If the hash node is present, return its pointer, otherwise create a new ** node for the given reference and also return its pointer. -** On error, return NULL. */ Object *lua_hashdefine (Hash *t, Object *ref) { - int h; + Word h; Node *n; - h = head (t, ref); - if (h < 0) return NULL; - - n = present(t, ref, h); - if (n == NULL) + h = present(t, ref); + n = node(t, h); + if (tag(ref(n)) == LUA_T_NIL) { - n = new(Node); - if (n == NULL) + nuse(t)++; + if ((float)nuse(t) > (float)nhash(t)*REHASH_LIMIT) { - lua_error ("not enough memory"); - return NULL; + rehash(t); + h = present(t, ref); + n = node(t, h); } - n->ref = *ref; - tag(&n->val) = T_NIL; - n->next = list(t,h); /* link node to head of list */ - list(t,h) = n; + *ref(n) = *ref; + tag(val(n)) = LUA_T_NIL; } - return (&n->val); + return (val(n)); } @@ -251,97 +293,44 @@ Object *lua_hashdefine (Hash *t, Object *ref) ** in the hash. ** This function pushs the element value and its reference to the stack. */ -static void firstnode (Hash *a, int h) +static void hashnext (Hash *t, Word i) { - if (h < nhash(a)) - { - int i; - for (i=h; i<nhash(a); i++) + if (i >= nhash(t)) + { + lua_pushnil(); lua_pushnil(); + return; + } + while (tag(ref(node(t,i))) == LUA_T_NIL || tag(val(node(t,i))) == LUA_T_NIL) + { + if (++i >= nhash(t)) { - if (list(a,i) != NULL) - { - if (tag(&list(a,i)->val) != T_NIL) - { - lua_pushobject (&list(a,i)->ref); - lua_pushobject (&list(a,i)->val); - return; - } - else - { - Node *next = list(a,i)->next; - while (next != NULL && tag(&next->val) == T_NIL) next = next->next; - if (next != NULL) - { - lua_pushobject (&next->ref); - lua_pushobject (&next->val); - return; - } - } - } + lua_pushnil(); lua_pushnil(); + return; } } - lua_pushnil(); - lua_pushnil(); + luaI_pushobject(ref(node(t,i))); + luaI_pushobject(val(node(t,i))); } + void lua_next (void) { - Hash *a; - Object *o = lua_getparam (1); - Object *r = lua_getparam (2); - if (o == NULL || r == NULL) - { lua_error ("too few arguments to function `next'"); return; } - if (lua_getparam (3) != NULL) - { lua_error ("too many arguments to function `next'"); return; } - if (tag(o) != T_ARRAY) - { lua_error ("first argument of function `next' is not a table"); return; } - a = avalue(o); - if (tag(r) == T_NIL) + Hash *t; + lua_Object o = lua_getparam(1); + lua_Object r = lua_getparam(2); + if (o == LUA_NOOBJECT || r == LUA_NOOBJECT) + lua_error ("too few arguments to function `next'"); + if (lua_getparam(3) != LUA_NOOBJECT) + lua_error ("too many arguments to function `next'"); + if (!lua_istable(o)) + lua_error ("first argument of function `next' is not a table"); + t = avalue(luaI_Address(o)); + if (lua_isnil(r)) { - firstnode (a, 0); - return; + hashnext(t, 0); } else { - int h = head (a, r); - if (h >= 0) - { - Node *n = list(a,h); - while (n) - { - if (memcmp(&n->ref,r,sizeof(Object)) == 0) - { - if (n->next == NULL) - { - firstnode (a, h+1); - return; - } - else if (tag(&n->next->val) != T_NIL) - { - lua_pushobject (&n->next->ref); - lua_pushobject (&n->next->val); - return; - } - else - { - Node *next = n->next->next; - while (next != NULL && tag(&next->val) == T_NIL) next = next->next; - if (next == NULL) - { - firstnode (a, h+1); - return; - } - else - { - lua_pushobject (&next->ref); - lua_pushobject (&next->val); - } - return; - } - } - n = n->next; - } - if (n == NULL) - lua_error ("error in function 'next': reference not found"); - } + Word h = present (t, luaI_Address(r)); + hashnext(t, h+1); } } @@ -2,30 +2,35 @@ ** hash.h ** hash manager for lua ** Luiz Henrique de Figueiredo - 17 Aug 90 -** $Id: hash.h,v 2.1 1994/04/20 22:07:57 celes Exp $ +** $Id: hash.h,v 2.8 1995/01/12 14:19:04 roberto Exp $ */ #ifndef hash_h #define hash_h +#include "types.h" + typedef struct node { Object ref; Object val; - struct node *next; } Node; typedef struct Hash { + struct Hash *next; char mark; - unsigned int nhash; - Node **list; + Word nhash; + Word nuse; + Node *node; } Hash; -Hash *lua_createarray (int nhash); +Bool lua_equalObj (Object *t1, Object *t2); +Hash *lua_createarray (Word nhash); void lua_hashmark (Hash *h); -void lua_hashcollector (void); +Long lua_hashcollector (void); +Object *lua_hashget (Hash *t, Object *ref); Object *lua_hashdefine (Hash *t, Object *ref); void lua_next (void); diff --git a/src/inout.c b/src/inout.c index d985c1b7..7bd7c235 100644 --- a/src/inout.c +++ b/src/inout.c @@ -2,49 +2,54 @@ ** inout.c ** Provide function to realise the input/output function and debugger ** facilities. +** Also provides some predefined lua functions. */ -char *rcs_inout="$Id: inout.c,v 1.2 1993/12/22 21:15:16 roberto Exp $"; +char *rcs_inout="$Id: inout.c,v 2.16 1994/12/20 21:20:36 roberto Exp $"; #include <stdio.h> +#include <stdlib.h> #include <string.h> +#include "mem.h" #include "opcode.h" #include "hash.h" #include "inout.h" #include "table.h" +#include "tree.h" +#include "lua.h" /* Exported variables */ -int lua_linenumber; -int lua_debug; -int lua_debugline; +Word lua_linenumber; +Bool lua_debug; +Word lua_debugline = 0; + /* Internal variables */ + #ifndef MAXFUNCSTACK -#define MAXFUNCSTACK 32 +#define MAXFUNCSTACK 100 #endif -static struct { int file; int function; } funcstack[MAXFUNCSTACK]; -static int nfuncstack=0; + +typedef struct FuncStackNode { + struct FuncStackNode *next; + char *file; + Word function; + Word line; +} FuncStackNode; + +static FuncStackNode *funcStack = NULL; +static Word nfuncstack=0; static FILE *fp; static char *st; -static void (*usererror) (char *s); - -/* -** Function to set user function to handle errors. -*/ -void lua_errorfunction (void (*fn) (char *s)) -{ - usererror = fn; -} /* ** Function to get the next character from the input file */ static int fileinput (void) { - int c = fgetc (fp); - return (c == EOF ? 0 : c); + return fgetc (fp); } /* @@ -52,22 +57,25 @@ static int fileinput (void) */ static int stringinput (void) { - st++; - return (*(st-1)); + return *st++; } /* ** Function to open a file to be input unit. -** Return 0 on success or 1 on error. +** Return 0 on success or error message on error. */ -int lua_openfile (char *fn) +char *lua_openfile (char *fn) { lua_linenumber = 1; lua_setinput (fileinput); fp = fopen (fn, "r"); - if (fp == NULL) return 1; - if (lua_addfile (fn)) return 1; - return 0; + if (fp == NULL) + { + static char buff[32]; + sprintf(buff, "unable to open file %.10s", fn); + return buff; + } + return lua_addfile (fn); } /* @@ -86,7 +94,7 @@ void lua_closefile (void) /* ** Function to open a string to be input unit */ -int lua_openstring (char *s) +char *lua_openstring (char *s) { lua_linenumber = 1; lua_setinput (stringinput); @@ -94,9 +102,8 @@ int lua_openstring (char *s) { char sn[64]; sprintf (sn, "String: %10.10s...", s); - if (lua_addfile (sn)) return 1; + return lua_addfile (sn); } - return 0; } /* @@ -107,40 +114,38 @@ void lua_closestring (void) lua_delfile(); } -/* -** Call user function to handle error messages, if registred. Or report error -** using standard function (fprintf). -*/ -void lua_error (char *s) -{ - if (usererror != NULL) usererror (s); - else fprintf (stderr, "lua: %s\n", s); -} /* ** Called to execute SETFUNCTION opcode, this function pushs a function into -** function stack. Return 0 on success or 1 on error. +** function stack. */ -int lua_pushfunction (int file, int function) +void lua_pushfunction (char *file, Word function) { - if (nfuncstack >= MAXFUNCSTACK-1) + FuncStackNode *newNode; + if (nfuncstack++ >= MAXFUNCSTACK) { - lua_error ("function stack overflow"); - return 1; + lua_reportbug("function stack overflow"); } - funcstack[nfuncstack].file = file; - funcstack[nfuncstack].function = function; - nfuncstack++; - return 0; + newNode = new(FuncStackNode); + newNode->function = function; + newNode->file = file; + newNode->line= lua_debugline; + newNode->next = funcStack; + funcStack = newNode; } /* -** Called to execute RESET opcode, this function pops a function from +** Called to execute RESET opcode, this function pops a function from ** function stack. */ void lua_popfunction (void) { - nfuncstack--; + FuncStackNode *temp = funcStack; + if (temp == NULL) return; + --nfuncstack; + lua_debugline = temp->line; + funcStack = temp->next; + luaI_free(temp); } /* @@ -148,30 +153,142 @@ void lua_popfunction (void) */ void lua_reportbug (char *s) { - char msg[1024]; + char msg[MAXFUNCSTACK*80]; strcpy (msg, s); if (lua_debugline != 0) { - int i; - if (nfuncstack > 0) + if (funcStack) { - sprintf (strchr(msg,0), - "\n\tin statement begining at line %d in function \"%s\" of file \"%s\"", - lua_debugline, s_name(funcstack[nfuncstack-1].function), - lua_file[funcstack[nfuncstack-1].file]); - sprintf (strchr(msg,0), "\n\tactive stack\n"); - for (i=nfuncstack-1; i>=0; i--) - sprintf (strchr(msg,0), "\t-> function \"%s\" of file \"%s\"\n", - s_name(funcstack[i].function), - lua_file[funcstack[i].file]); + FuncStackNode *func = funcStack; + int line = lua_debugline; + sprintf (strchr(msg,0), "\n\tactive stack:\n"); + do + { + sprintf (strchr(msg,0), + "\t-> function \"%s\" at file \"%s\":%u\n", + lua_constant[func->function]->str, func->file, line); + line = func->line; + func = func->next; + lua_popfunction(); + } while (func); } else { sprintf (strchr(msg,0), - "\n\tin statement begining at line %d of file \"%s\"", + "\n\tin statement begining at line %u of file \"%s\"", lua_debugline, lua_filename()); } } lua_error (msg); } + +/* +** Internal function: do a string +*/ +void lua_internaldostring (void) +{ + lua_Object obj = lua_getparam (1); + if (lua_isstring(obj) && !lua_dostring(lua_getstring(obj))) + lua_pushnumber(1); + else + lua_pushnil(); +} + +/* +** Internal function: do a file +*/ +void lua_internaldofile (void) +{ + lua_Object obj = lua_getparam (1); + if (lua_isstring(obj) && !lua_dofile(lua_getstring(obj))) + lua_pushnumber(1); + else + lua_pushnil(); +} + +/* +** Internal function: print object values +*/ +void lua_print (void) +{ + 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",bvalue(luaI_Address(obj))); + 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"); + } +} + + +/* +** Internal function: return an object type. +*/ +void luaI_type (void) +{ + lua_Object o = lua_getparam(1); + if (o == LUA_NOOBJECT) + lua_error("no parameter to function 'type'"); + switch (lua_type(o)) + { + case LUA_T_NIL : + lua_pushliteral("nil"); + break; + case LUA_T_NUMBER : + lua_pushliteral("number"); + break; + case LUA_T_STRING : + lua_pushliteral("string"); + break; + case LUA_T_ARRAY : + lua_pushliteral("table"); + break; + case LUA_T_FUNCTION : + lua_pushliteral("function"); + break; + case LUA_T_CFUNCTION : + lua_pushliteral("cfunction"); + break; + default : + lua_pushliteral("userdata"); + break; + } +} + +/* +** Internal function: convert an object to a number +*/ +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(); + } + else + lua_pushnil(); +} + + +void luaI_error (void) +{ + char *s = lua_getstring(lua_getparam(1)); + if (s == NULL) s = "(no message)"; + lua_reportbug(s); +} + diff --git a/src/inout.h b/src/inout.h index ca5920ca..22093020 100644 --- a/src/inout.h +++ b/src/inout.h @@ -1,21 +1,30 @@ /* -** $Id: inout.h,v 1.1 1993/12/17 18:41:19 celes Exp $ +** $Id: inout.h,v 1.7 1994/12/20 21:20:36 roberto Exp $ */ #ifndef inout_h #define inout_h -extern int lua_linenumber; -extern int lua_debug; -extern int lua_debugline; +#include "types.h" -int lua_openfile (char *fn); +extern Word lua_linenumber; +extern Bool lua_debug; +extern Word lua_debugline; + +char *lua_openfile (char *fn); void lua_closefile (void); -int lua_openstring (char *s); +char *lua_openstring (char *s); void lua_closestring (void); -int lua_pushfunction (int file, int function); +void lua_pushfunction (char *file, Word function); void lua_popfunction (void); void lua_reportbug (char *s); +void lua_internaldofile (void); +void lua_internaldostring (void); +void lua_print (void); +void luaI_type (void); +void lua_obj2number (void); +void luaI_error (void); + #endif @@ -1,30 +1,20 @@ -char *rcs_lex = "$Id: lex.c,v 2.1 1994/04/15 19:00:28 celes Exp $"; -/*$Log: lex.c,v $ - * Revision 2.1 1994/04/15 19:00:28 celes - * Retirar chamada da funcao lua_findsymbol associada a cada - * token NAME. A decisao de chamar lua_findsymbol ou lua_findconstant - * fica a cargo do modulo "lua.stx". - * - * Revision 1.3 1993/12/28 16:42:29 roberto - * "include"s de string.h e stdlib.h para evitar warnings - * - * Revision 1.2 1993/12/22 21:39:15 celes - * Tratamento do token $debug e $nodebug - * - * Revision 1.1 1993/12/22 21:15:16 roberto - * Initial revision - **/ +char *rcs_lex = "$Id: lex.c,v 2.14 1994/12/27 20:50:38 celes Exp $"; + #include <ctype.h> #include <math.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> +#include "tree.h" +#include "table.h" #include "opcode.h" -#include "hash.h" #include "inout.h" -#include "table.h" -#include "y.tab.h" +#include "parser.h" +#include "ugly.h" + +#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); } @@ -49,7 +39,8 @@ char *lua_lasttext (void) } -static struct +/* The reserved words must be listed in lexicographic order */ +static struct { char *name; int token; @@ -71,17 +62,18 @@ static struct {"until", UNTIL}, {"while", WHILE} }; + #define RESERVEDSIZE (sizeof(reserved)/sizeof(reserved[0])) -int findReserved (char *name) +static int findReserved (char *name) { int l = 0; int h = RESERVEDSIZE - 1; while (l <= h) { int m = (l+h)/2; - int comp = strcmp(name, reserved[m].name); + int comp = lua_strcmp(name, reserved[m].name); if (comp < 0) h = m-1; else if (comp == 0) @@ -93,13 +85,20 @@ int findReserved (char *name) } -int yylex () +int yylex (void) { + float a; while (1) { yytextLast = yytext; +#if 0 + fprintf(stderr,"'%c' %d\n",current,current); +#endif switch (current) { + case EOF: + case 0: + return 0; case '\n': lua_linenumber++; case ' ': case '\t': @@ -111,34 +110,39 @@ int yylex () while (isalnum(current) || current == '_') save_and_next(); *yytextLast = 0; - if (strcmp(yytext, "debug") == 0) + if (lua_strcmp(yytext, "debug") == 0) { yylval.vInt = 1; return DEBUG; } - else if (strcmp(yytext, "nodebug") == 0) + else if (lua_strcmp(yytext, "nodebug") == 0) { yylval.vInt = 0; return DEBUG; } return WRONGTOKEN; - + case '-': save_and_next(); if (current != '-') return '-'; do { next(); } while (current != '\n' && current != 0); continue; - + + case '=': + save_and_next(); + if (current != '=') return '='; + else { save_and_next(); return EQ; } + case '<': save_and_next(); if (current != '=') return '<'; else { save_and_next(); return LE; } - + case '>': save_and_next(); if (current != '=') return '>'; else { save_and_next(); return GE; } - + case '~': save_and_next(); if (current != '=') return '~'; @@ -149,12 +153,13 @@ int yylex () { int del = current; next(); /* skip the delimiter */ - while (current != del) + while (current != del) { switch (current) { - case 0: - case '\n': + case EOF: + case 0: + case '\n': return WRONGTOKEN; case '\\': next(); /* do not save the '\' */ @@ -163,16 +168,16 @@ int yylex () case 'n': save('\n'); next(); break; case 't': save('\t'); next(); break; case 'r': save('\r'); next(); break; - default : save('\\'); break; + default : save(current); next(); break; } break; - default: + default: save_and_next(); } } next(); /* skip the delimiter */ *yytextLast = 0; - yylval.vWord = lua_findconstant (yytext); + yylval.vWord = luaI_findconstant(lua_constcreate(yytext)); return STRING; } @@ -190,49 +195,77 @@ int yylex () case 'Z': case '_': { - int res; + Word res; do { save_and_next(); } while (isalnum(current) || current == '_'); *yytextLast = 0; res = findReserved(yytext); if (res) return res; - yylval.pChar = yytext; + yylval.pNode = lua_constcreate(yytext); return NAME; } - + case '.': save_and_next(); - if (current == '.') - { - save_and_next(); + if (current == '.') + { + save_and_next(); return CONC; } else if (!isdigit(current)) return '.'; /* current is a digit: goes through to number */ + a=0.0; goto fraction; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': - - do { save_and_next(); } while (isdigit(current)); + a=0.0; + do { a=10*a+current-'0'; save_and_next(); } while (isdigit(current)); if (current == '.') save_and_next(); -fraction: while (isdigit(current)) save_and_next(); - if (current == 'e' || current == 'E') - { - save_and_next(); - if (current == '+' || current == '-') save_and_next(); - if (!isdigit(current)) return WRONGTOKEN; - do { save_and_next(); } while (isdigit(current)); +fraction: + { float 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; + 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)); + for (ea=neg?0.1:10.0; e>0; e>>=1) + { + if (e & 1) a*=ea; + ea*=ea; + } + } + yylval.vFloat = a; + return NUMBER; } - *yytextLast = 0; - yylval.vFloat = atof(yytext); - 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(); - return *yytext; + return yytext[0]; } } } } - diff --git a/src/mem.c b/src/mem.c new file mode 100644 index 00000000..90369720 --- /dev/null +++ b/src/mem.c @@ -0,0 +1,44 @@ +/* +** mem.c +** TecCGraf - PUC-Rio +*/ + +char *rcs_mem = "$Id: mem.c,v 1.5 1995/02/06 19:34:03 roberto Exp $"; + +#include <stdlib.h> +#include <string.h> + +#include "mem.h" +#include "lua.h" + +void luaI_free (void *block) +{ + *((int *)block) = -1; /* to catch errors */ + free(block); +} + + +void *luaI_malloc (unsigned long size) +{ + void *block = malloc((size_t)size); + if (block == NULL) + lua_error("not enough memory"); + return block; +} + + +void *luaI_realloc (void *oldblock, unsigned long size) +{ + void *block = realloc(oldblock, (size_t)size); + if (block == NULL) + lua_error("not enough memory"); + return block; +} + + +char *luaI_strdup (char *str) +{ + char *newstr = luaI_malloc(strlen(str)+1); + strcpy(newstr, str); + return newstr; +} diff --git a/src/mem.h b/src/mem.h new file mode 100644 index 00000000..bae5b4d3 --- /dev/null +++ b/src/mem.h @@ -0,0 +1,25 @@ +/* +** mem.c +** memory manager for lua +** $Id: mem.h,v 1.2 1995/01/13 22:11:12 roberto Exp $ +*/ + +#ifndef mem_h +#define mem_h + +#ifndef NULL +#define NULL 0 +#endif + +void luaI_free (void *block); +void *luaI_malloc (unsigned long size); +void *luaI_realloc (void *oldblock, unsigned long size); + +char *luaI_strdup (char *str); + +#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))) + +#endif + diff --git a/src/opcode.c b/src/opcode.c index 6006f7ac..7ce5b2a6 100644 --- a/src/opcode.c +++ b/src/opcode.c @@ -3,171 +3,763 @@ ** TecCGraf - PUC-Rio */ -char *rcs_opcode="$Id: opcode.c,v 2.1 1994/04/20 22:07:57 celes Exp $"; +char *rcs_opcode="$Id: opcode.c,v 3.34 1995/02/06 19:35:09 roberto Exp $"; -#include <stdio.h> +#include <setjmp.h> #include <stdlib.h> +#include <stdio.h> #include <string.h> +#include <math.h> -/* stdlib.h does not have this in SunOS */ -extern double strtod(const char *, char **); - -#include "mm.h" - +#include "mem.h" #include "opcode.h" #include "hash.h" #include "inout.h" #include "table.h" #include "lua.h" +#include "fallback.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)) + + +#define STACK_BUFFER (STACKGAP+128) + +typedef int StkId; /* index to stack elements */ + +static Long maxstack = 0L; +static Object *stack = NULL; +static Object *top = NULL; + + +/* macros to convert from lua_Object to (Object *) and back */ + +#define Address(lo) ((lo)+stack-1) +#define Ref(st) ((st)-stack+1) + + +static StkId CBase = 0; /* when Lua calls C or C calls Lua, points to */ + /* the first slot after the last parameter. */ +static int CnResults = 0; /* when Lua calls C, has the number of parameters; */ + /* when C calls Lua, has the number of results. */ -#define tonumber(o) ((tag(o) != T_NUMBER) && (lua_tonumber(o) != 0)) -#define tostring(o) ((tag(o) != T_STRING) && (lua_tostring(o) != 0)) +static jmp_buf *errorJmp = NULL; /* current error recover point */ -#ifndef MAXSTACK -#define MAXSTACK 256 -#endif -static Object stack[MAXSTACK] = {{T_MARK, {NULL}}}; -static Object *top=stack+1, *base=stack+1; + +static StkId lua_execute (Byte *pc, StkId base); +static void do_call (Object *func, StkId base, int nResults, StkId whereRes); + + + +Object *luaI_Address (lua_Object o) +{ + return Address(o); +} /* -** Concatenate two given string, creating a mark space at the beginning. -** Return the new string pointer. +** Error messages */ -static char *lua_strconc (char *l, char *r) + +static void lua_message (char *s) { - char *s = calloc (strlen(l)+strlen(r)+2, sizeof(char)); - if (s == NULL) - { - lua_error ("not enough memory"); - return NULL; - } - *s++ = 0; /* create mark space */ - return strcat(strcpy(s,l),r); + lua_pushstring(s); + do_call(&luaI_fallBacks[FB_ERROR].function, (top-stack)-1, 0, (top-stack)-1); } /* -** Duplicate a string, creating a mark space at the beginning. -** Return the new string pointer. +** Reports an error, and jumps up to the available recover label */ -char *lua_strdup (char *l) +void lua_error (char *s) { - char *s = calloc (strlen(l)+2, sizeof(char)); - if (s == NULL) - { - lua_error ("not enough memory"); - return NULL; - } - *s++ = 0; /* create mark space */ - return strcpy(s,l); + if (s) lua_message(s); + if (errorJmp) + longjmp(*errorJmp, 1); + else + { + fprintf (stderr, "lua: exit(1). Unable to recover\n"); + exit(1); + } } + /* -** Convert, if possible, to a number tag. -** Return 0 in success or not 0 on error. -*/ -static int lua_tonumber (Object *obj) +** Init stack +*/ +static void lua_initstack (void) { - char *ptr; - if (tag(obj) != T_STRING) - { - lua_reportbug ("unexpected type at conversion to number"); - return 1; - } - nvalue(obj) = strtod(svalue(obj), &ptr); - if (*ptr) - { - lua_reportbug ("string to number convertion failed"); - return 2; - } - tag(obj) = T_NUMBER; - return 0; + maxstack = STACK_BUFFER; + stack = newvector(maxstack, Object); + top = stack; } + /* -** Test if is possible to convert an object to a number one. -** If possible, return the converted object, otherwise return nil object. -*/ -static Object *lua_convtonumber (Object *obj) +** Check stack overflow and, if necessary, realloc vector +*/ +#define lua_checkstack(n) if ((Long)(n) > maxstack) checkstack(n) + +static void checkstack (StkId n) { - static Object cvt; - - if (tag(obj) == T_NUMBER) - { - cvt = *obj; - return &cvt; - } - - tag(&cvt) = T_NIL; - if (tag(obj) == T_STRING) + StkId t; + if (stack == NULL) + lua_initstack(); + if (maxstack >= MAX_INT) + lua_error("stack size overflow"); + t = top-stack; + maxstack *= 2; + if (maxstack >= MAX_INT) + maxstack = MAX_INT; + stack = growvector(stack, maxstack, Object); + top = stack + t; +} + + +/* +** Concatenate two given strings. Return the new string pointer. +*/ +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); + strcpy(buffer+nl, r); + return buffer; +} + + +/* +** Convert, if possible, to a number object. +** Return 0 if success, not 0 if error. +*/ +static int lua_tonumber (Object *obj) +{ + float t; + char c; + if (tag(obj) != LUA_T_STRING) + return 1; + else if (sscanf(svalue(obj), "%f %c",&t, &c) == 1) { - char *ptr; - nvalue(&cvt) = strtod(svalue(obj), &ptr); - if (*ptr == 0) - tag(&cvt) = T_NUMBER; + nvalue(obj) = t; + tag(obj) = LUA_T_NUMBER; + return 0; } - return &cvt; + else + return 2; } - /* ** Convert, if possible, to a string tag ** Return 0 in success or not 0 on error. -*/ +*/ static int lua_tostring (Object *obj) { static char s[256]; - if (tag(obj) != T_NUMBER) - { - lua_reportbug ("unexpected type at conversion to string"); - return 1; - } + if (tag(obj) != LUA_T_NUMBER) + return 1; if ((int) nvalue(obj) == nvalue(obj)) - sprintf (s, "%d", (int) nvalue(obj)); + sprintf (s, "%d", (int) nvalue(obj)); else - sprintf (s, "%g", nvalue(obj)); - svalue(obj) = lua_createstring(lua_strdup(s)); - if (svalue(obj) == NULL) + sprintf (s, "%g", nvalue(obj)); + tsvalue(obj) = lua_createstring(s); + if (tsvalue(obj) == NULL) return 1; - tag(obj) = T_STRING; + tag(obj) = LUA_T_STRING; return 0; } /* -** Execute the given opcode. Return 0 in success or 1 on error. +** Adjust stack. Set top to the given value, pushing NILs if needed. +*/ +static void adjust_top (StkId newtop) +{ + Object *nt = stack+newtop; + while (top < nt) tag(top++) = LUA_T_NIL; + top = nt; /* top could be bigger than newtop */ +} + + +static void adjustC (int nParams) +{ + adjust_top(CBase+nParams); +} + + +/* +** 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. +*/ +static StkId callC (lua_CFunction func, StkId base) +{ + StkId oldBase = CBase; + int oldCnResults = CnResults; + StkId firstResult; + CnResults = (top-stack) - base; + /* incorporate parameters on the stack */ + CBase = base+CnResults; + (*func)(); + firstResult = CBase; + CBase = oldBase; + CnResults = oldCnResults; + return firstResult; +} + +/* +** Call the fallback for invalid functions (see do_call) +*/ +static void call_funcFB (Object *func, StkId base, int nResults, StkId whereRes) +{ + StkId i; + /* open space for first parameter (func) */ + for (i=top-stack; i>base; i--) + stack[i] = stack[i-1]; + top++; + stack[base] = *func; + do_call(&luaI_fallBacks[FB_FUNCTION].function, base, nResults, whereRes); +} + + +/* +** Call a function (C or Lua). The parameters must be on the stack, +** between [stack+base,top). When returns, the results are on the stack, +** between [stack+whereRes,top). The number of results is nResults, unless +** nResults=MULT_RET. +*/ +static void do_call (Object *func, StkId base, int nResults, StkId whereRes) +{ + StkId firstResult; + if (tag(func) == LUA_T_CFUNCTION) + firstResult = callC(fvalue(func), base); + else if (tag(func) == LUA_T_FUNCTION) + firstResult = lua_execute(bvalue(func), base); + else + { /* func is not a function */ + call_funcFB(func, base, nResults, whereRes); + return; + } + /* adjust the number of results */ + if (nResults != MULT_RET && top - (stack+firstResult) != nResults) + adjust_top(firstResult+nResults); + /* move results to the given position */ + if (firstResult != whereRes) + { + int i; + nResults = top - (stack+firstResult); /* actual number of results */ + for (i=0; i<nResults; i++) + *(stack+whereRes+i) = *(stack+firstResult+i); + top -= firstResult-whereRes; + } +} + + +/* +** Function to index a table. Receives the table at top-2 and the index +** at top-1. +*/ +static void pushsubscript (void) +{ + if (tag(top-2) != LUA_T_ARRAY) + do_call(&luaI_fallBacks[FB_GETTABLE].function, (top-stack)-2, 1, (top-stack)-2); + else + { + Object *h = lua_hashget(avalue(top-2), top-1); + if (h == NULL || tag(h) == LUA_T_NIL) + do_call(&luaI_fallBacks[FB_INDEX].function, (top-stack)-2, 1, (top-stack)-2); + else + { + --top; + *(top-1) = *h; + } + } +} + + +/* +** Function to store indexed based on values at the top +*/ +static void storesubscript (void) +{ + if (tag(top-3) != LUA_T_ARRAY) + do_call(&luaI_fallBacks[FB_SETTABLE].function, (top-stack)-3, 0, (top-stack)-3); + else + { + Object *h = lua_hashdefine (avalue(top-3), top-2); + *h = *(top-1); + top -= 3; + } +} + + +/* +** Traverse all objects on stack +*/ +void lua_travstack (void (*fn)(Object *)) +{ + Object *o; + for (o = top-1; o >= stack; o--) + fn (o); +} + + +/* +** Execute a protected call. If function is null compiles the pre-set input. +** Leave nResults on the stack. +*/ +static int do_protectedrun (Object *function, int nResults) +{ + jmp_buf myErrorJmp; + int status; + StkId oldCBase = CBase; + jmp_buf *oldErr = errorJmp; + errorJmp = &myErrorJmp; + if (setjmp(myErrorJmp) == 0) + { + do_call(function, CBase, nResults, CBase); + CnResults = (top-stack) - CBase; /* number of results */ + CBase += CnResults; /* incorporate results on the stack */ + status = 0; + } + else + { + CBase = oldCBase; + top = stack+CBase; + status = 1; + } + errorJmp = oldErr; + return status; +} + + +static int do_protectedmain (void) +{ + Byte *code = NULL; + int status; + StkId oldCBase = CBase; + jmp_buf myErrorJmp; + jmp_buf *oldErr = errorJmp; + errorJmp = &myErrorJmp; + if (setjmp(myErrorJmp) == 0) + { + Object f; + lua_parse(&code); + tag(&f) = LUA_T_FUNCTION; bvalue(&f) = code; + do_call(&f, CBase, 0, CBase); + status = 0; + } + else + status = 1; + if (code) + luaI_free(code); + errorJmp = oldErr; + CBase = oldCBase; + top = stack+CBase; + return status; +} + + +/* +** Execute the given lua function. Return 0 on success or 1 on error. +*/ +int lua_callfunction (lua_Object function) +{ + if (function == LUA_NOOBJECT) + return 1; + else + return do_protectedrun (Address(function), MULT_RET); +} + + +int lua_call (char *funcname) +{ + Word n = luaI_findsymbolbyname(funcname); + return do_protectedrun(&s_object(n), MULT_RET); +} + + +/* +** Open file, generate opcode and execute global statement. Return 0 on +** success or 1 on error. +*/ +int lua_dofile (char *filename) +{ + int status; + char *message = lua_openfile (filename); + if (message) + { + lua_message(message); + return 1; + } + status = do_protectedmain(); + lua_closefile(); + return status; +} + +/* +** Generate opcode stored on string and execute global statement. Return 0 on +** success or 1 on error. +*/ +int lua_dostring (char *string) +{ + int status; + char *message = lua_openstring(string); + if (message) + { + lua_message(message); + return 1; + } + status = do_protectedmain(); + lua_closestring(); + return status; +} + + +/* +** API: set a function as a fallback +*/ +lua_Object lua_setfallback (char *name, lua_CFunction fallback) +{ + static Object func = {LUA_T_CFUNCTION, luaI_setfallback}; + adjustC(0); + lua_pushstring(name); + lua_pushcfunction(fallback); + do_protectedrun(&func, 1); + return (Ref(top-1)); +} + + +/* +** API: receives on the stack the table and the index. +** returns the value. +*/ +lua_Object lua_getsubscript (void) +{ + adjustC(2); + pushsubscript(); + CBase++; /* incorporate object in the stack */ + return (Ref(top-1)); +} + + +#define MAX_C_BLOCKS 10 + +static int numCblocks = 0; +static StkId Cblocks[MAX_C_BLOCKS]; + +/* +** API: starts a new block +*/ +void lua_beginblock (void) +{ + if (numCblocks < MAX_C_BLOCKS) + Cblocks[numCblocks] = CBase; + numCblocks++; +} + +/* +** API: ends a block +*/ +void lua_endblock (void) +{ + --numCblocks; + if (numCblocks < MAX_C_BLOCKS) + { + CBase = Cblocks[numCblocks]; + adjustC(0); + } +} + +/* +** API: receives on the stack the table, the index, and the new value. +*/ +void lua_storesubscript (void) +{ + adjustC(3); + storesubscript(); +} + +/* +** API: creates a new table +*/ +lua_Object lua_createtable (void) +{ + adjustC(0); + avalue(top) = lua_createarray(0); + tag(top) = LUA_T_ARRAY; + top++; + CBase++; /* incorporate object in the stack */ + return Ref(top-1); +} + +/* +** Get a parameter, returning the object handle or LUA_NOOBJECT on error. +** 'number' must be 1 to get the first parameter. +*/ +lua_Object lua_getparam (int number) +{ + if (number <= 0 || number > CnResults) return LUA_NOOBJECT; + /* Ref(stack+(CBase-CnResults+number-1)) == + stack+(CBase-CnResults+number-1)-stack+1 == */ + return CBase-CnResults+number; +} + +/* +** Given an object handle, return its number value. On error, return 0.0. +*/ +real lua_getnumber (lua_Object object) +{ + if (object == LUA_NOOBJECT || tag(Address(object)) == LUA_T_NIL) return 0.0; + if (tonumber (Address(object))) return 0.0; + else return (nvalue(Address(object))); +} + +/* +** Given an object handle, return its string pointer. On error, return NULL. +*/ +char *lua_getstring (lua_Object object) +{ + if (object == LUA_NOOBJECT || tag(Address(object)) == LUA_T_NIL) return NULL; + if (tostring (Address(object))) return NULL; + else return (svalue(Address(object))); +} + +/* +** Given an object handle, return its cfuntion pointer. On error, return NULL. +*/ +lua_CFunction lua_getcfunction (lua_Object object) +{ + if (object == LUA_NOOBJECT || tag(Address(object)) != LUA_T_CFUNCTION) + return NULL; + else return (fvalue(Address(object))); +} + +/* +** Given an object handle, return its user data. On error, return NULL. +*/ +void *lua_getuserdata (lua_Object object) +{ + if (object == LUA_NOOBJECT || tag(Address(object)) < LUA_T_USERDATA) + return NULL; + else return (uvalue(Address(object))); +} + + +lua_Object lua_getlocked (int ref) +{ + adjustC(0); + *top = *luaI_getlocked(ref); + top++; + CBase++; /* incorporate object in the stack */ + return Ref(top-1); +} + + +void lua_pushlocked (int ref) +{ + lua_checkstack(top-stack+1); + *top = *luaI_getlocked(ref); + top++; +} + + +int lua_lock (void) +{ + adjustC(1); + return luaI_lock(--top); +} + + +/* +** Get a global object. Return the object handle or NULL on error. +*/ +lua_Object lua_getglobal (char *name) +{ + Word n = luaI_findsymbolbyname(name); + adjustC(0); + *top = s_object(n); + top++; + CBase++; /* incorporate object in the stack */ + return Ref(top-1); +} + +/* +** Store top of the stack at a global variable array field. +*/ +void lua_storeglobal (char *name) +{ + Word n = luaI_findsymbolbyname(name); + adjustC(1); + s_object(n) = *(--top); +} + +/* +** Push a nil object +*/ +void lua_pushnil (void) +{ + lua_checkstack(top-stack+1); + tag(top++) = LUA_T_NIL; +} + +/* +** Push an object (tag=number) to stack. +*/ +void lua_pushnumber (real n) +{ + lua_checkstack(top-stack+1); + tag(top) = LUA_T_NUMBER; nvalue(top++) = n; +} + +/* +** Push an object (tag=string) to stack. +*/ +void lua_pushstring (char *s) +{ + lua_checkstack(top-stack+1); + tsvalue(top) = lua_createstring(s); + tag(top) = LUA_T_STRING; + top++; +} + +/* +** Push an object (tag=string) on stack and register it on the constant table. +*/ +void lua_pushliteral (char *s) +{ + lua_checkstack(top-stack+1); + tsvalue(top) = lua_constant[luaI_findconstant(lua_constcreate(s))]; + tag(top) = LUA_T_STRING; + top++; +} + +/* +** Push an object (tag=cfunction) to stack. +*/ +void lua_pushcfunction (lua_CFunction fn) +{ + lua_checkstack(top-stack+1); + tag(top) = LUA_T_CFUNCTION; fvalue(top++) = fn; +} + +/* +** Push an object (tag=userdata) to stack. +*/ +void lua_pushusertag (void *u, int tag) +{ + if (tag < LUA_T_USERDATA) return; + lua_checkstack(top-stack+1); + tag(top) = tag; uvalue(top++) = u; +} + +/* +** Push a lua_Object to stack. +*/ +void lua_pushobject (lua_Object o) +{ + lua_checkstack(top-stack+1); + *top++ = *Address(o); +} + +/* +** Push an object on the stack. +*/ +void luaI_pushobject (Object *o) +{ + lua_checkstack(top-stack+1); + *top++ = *o; +} + +int lua_type (lua_Object o) +{ + if (o == LUA_NOOBJECT) + return LUA_T_NIL; + else + return tag(Address(o)); +} + + +void luaI_gcFB (Object *o) +{ + *(top++) = *o; + do_call(&luaI_fallBacks[FB_GC].function, (top-stack)-1, 0, (top-stack)-1); +} + + +static void call_arith (char *op) +{ + lua_pushstring(op); + do_call(&luaI_fallBacks[FB_ARITH].function, (top-stack)-3, 1, (top-stack)-3); +} + +static void comparison (lua_Type tag_less, lua_Type tag_equal, + lua_Type tag_great, char *op) +{ + Object *l = top-2; + Object *r = top-1; + int result; + if (tag(l) == LUA_T_NUMBER && tag(r) == LUA_T_NUMBER) + result = (nvalue(l) < nvalue(r)) ? -1 : (nvalue(l) == nvalue(r)) ? 0 : 1; + else if (tostring(l) || tostring(r)) + { + lua_pushstring(op); + do_call(&luaI_fallBacks[FB_ORDER].function, (top-stack)-3, 1, (top-stack)-3); + return; + } + else + result = strcmp(svalue(l), svalue(r)); + top--; + nvalue(top-1) = 1; + tag(top-1) = (result < 0) ? tag_less : (result == 0) ? tag_equal : tag_great; +} + + + +/* +** Execute the given opcode, until a RET. Parameters are between +** [stack+base,top). Returns n such that the the results are between +** [stack+n,top). */ -int lua_execute (Byte *pc) +static StkId lua_execute (Byte *pc, StkId base) { - Object *oldbase = base; - base = top; + lua_checkstack(STACKGAP+MAX_TEMPS+base); while (1) { OpCode opcode; switch (opcode = (OpCode)*pc++) { - case PUSHNIL: tag(top++) = T_NIL; break; - - case PUSH0: tag(top) = T_NUMBER; nvalue(top++) = 0; break; - case PUSH1: tag(top) = T_NUMBER; nvalue(top++) = 1; break; - case PUSH2: tag(top) = T_NUMBER; nvalue(top++) = 2; break; - - case PUSHBYTE: tag(top) = T_NUMBER; nvalue(top++) = *pc++; break; - - case PUSHWORD: + case PUSHNIL: tag(top++) = LUA_T_NIL; break; + + case PUSH0: case PUSH1: case PUSH2: + tag(top) = LUA_T_NUMBER; + nvalue(top++) = opcode-PUSH0; + break; + + case PUSHBYTE: tag(top) = LUA_T_NUMBER; nvalue(top++) = *pc++; break; + + case PUSHWORD: { CodeWord code; get_word(code,pc); - tag(top) = T_NUMBER; nvalue(top++) = code.w; + tag(top) = LUA_T_NUMBER; nvalue(top++) = code.w; } break; - + case PUSHFLOAT: { CodeFloat code; get_float(code,pc); - tag(top) = T_NUMBER; nvalue(top++) = code.f; + tag(top) = LUA_T_NUMBER; nvalue(top++) = code.f; } break; @@ -175,50 +767,57 @@ int lua_execute (Byte *pc) { CodeWord code; get_word(code,pc); - tag(top) = T_STRING; svalue(top++) = lua_constant[code.w]; + tag(top) = LUA_T_STRING; tsvalue(top++) = lua_constant[code.w]; } break; - + + case PUSHFUNCTION: + { + CodeCode code; + get_code(code,pc); + tag(top) = LUA_T_FUNCTION; bvalue(top++) = code.b; + } + break; + case PUSHLOCAL0: case PUSHLOCAL1: case PUSHLOCAL2: case PUSHLOCAL3: case PUSHLOCAL4: case PUSHLOCAL5: case PUSHLOCAL6: case PUSHLOCAL7: case PUSHLOCAL8: - case PUSHLOCAL9: *top++ = *(base + (int)(opcode-PUSHLOCAL0)); break; - - case PUSHLOCAL: *top++ = *(base + (*pc++)); break; - - case PUSHGLOBAL: + case PUSHLOCAL9: *top++ = *((stack+base) + (int)(opcode-PUSHLOCAL0)); break; + + case PUSHLOCAL: *top++ = *((stack+base) + (*pc++)); break; + + case PUSHGLOBAL: { CodeWord code; get_word(code,pc); *top++ = s_object(code.w); } break; - + case PUSHINDEXED: - --top; - if (tag(top-1) != T_ARRAY) - { - lua_reportbug ("indexed expression not a table"); - return 1; - } - { - Object *h = lua_hashdefine (avalue(top-1), top); - if (h == NULL) return 1; - *(top-1) = *h; - } - break; - - case PUSHMARK: tag(top++) = T_MARK; break; - - case PUSHOBJECT: *top = *(top-3); top++; break; - + pushsubscript(); + break; + + case PUSHSELF: + { + Object receiver = *(top-1); + CodeWord code; + get_word(code,pc); + tag(top) = LUA_T_STRING; tsvalue(top++) = lua_constant[code.w]; + pushsubscript(); + *(top++) = receiver; + break; + } + case STORELOCAL0: case STORELOCAL1: case STORELOCAL2: case STORELOCAL3: case STORELOCAL4: case STORELOCAL5: case STORELOCAL6: case STORELOCAL7: case STORELOCAL8: - case STORELOCAL9: *(base + (int)(opcode-STORELOCAL0)) = *(--top); break; - - case STORELOCAL: *(base + (*pc++)) = *(--top); break; - + case STORELOCAL9: + *((stack+base) + (int)(opcode-STORELOCAL0)) = *(--top); + break; + + case STORELOCAL: *((stack+base) + (*pc++)) = *(--top); break; + case STOREGLOBAL: { CodeWord code; @@ -228,36 +827,29 @@ int lua_execute (Byte *pc) break; case STOREINDEXED0: - if (tag(top-3) != T_ARRAY) - { - lua_reportbug ("indexed expression not a table"); - return 1; - } - { - Object *h = lua_hashdefine (avalue(top-3), top-2); - if (h == NULL) return 1; - *h = *(top-1); - } - top -= 3; - break; - + storesubscript(); + break; + case STOREINDEXED: { int n = *pc++; - if (tag(top-3-n) != T_ARRAY) + if (tag(top-3-n) != LUA_T_ARRAY) { - lua_reportbug ("indexed expression not a table"); - return 1; + *(top+1) = *(top-1); + *(top) = *(top-2-n); + *(top-1) = *(top-3-n); + top += 2; + do_call(&luaI_fallBacks[FB_SETTABLE].function, (top-stack)-3, 0, (top-stack)-3); } + else { Object *h = lua_hashdefine (avalue(top-3-n), top-2-n); - if (h == NULL) return 1; *h = *(top-1); + top--; } - top--; } break; - + case STORELIST0: case STORELIST: { @@ -267,206 +859,180 @@ int lua_execute (Byte *pc) else m = *(pc++) * FIELDS_PER_FLUSH; n = *(pc++); arr = top-n-1; - if (tag(arr) != T_ARRAY) - { - lua_reportbug ("internal error - table expected"); - return 1; - } while (n) { - tag(top) = T_NUMBER; nvalue(top) = n+m; + tag(top) = LUA_T_NUMBER; nvalue(top) = n+m; *(lua_hashdefine (avalue(arr), top)) = *(top-1); top--; n--; } } break; - + case STORERECORD: { int n = *(pc++); Object *arr = top-n-1; - if (tag(arr) != T_ARRAY) - { - lua_reportbug ("internal error - table expected"); - return 1; - } while (n) { CodeWord code; get_word(code,pc); - tag(top) = T_STRING; svalue(top) = lua_constant[code.w]; + tag(top) = LUA_T_STRING; tsvalue(top) = lua_constant[code.w]; *(lua_hashdefine (avalue(arr), top)) = *(top-1); top--; n--; } } break; - + + case ADJUST0: + adjust_top(base); + break; + case ADJUST: + adjust_top(base + *(pc++)); + break; + + case CREATEARRAY: { - Object *newtop = base + *(pc++); - while (top < newtop) tag(top++) = T_NIL; - top = newtop; /* top could be bigger than newtop */ + CodeWord size; + get_word(size,pc); + avalue(top) = lua_createarray(size.w); + tag(top) = LUA_T_ARRAY; + top++; } break; - - case CREATEARRAY: - if (tag(top-1) == T_NIL) - nvalue(top-1) = 101; - else - { - if (tonumber(top-1)) return 1; - if (nvalue(top-1) <= 0) nvalue(top-1) = 101; - } - avalue(top-1) = lua_createarray(nvalue(top-1)); - if (avalue(top-1) == NULL) - return 1; - tag(top-1) = T_ARRAY; - break; - + case EQOP: { - Object *l = top-2; - Object *r = top-1; + int res = lua_equalObj(top-2, top-1); --top; - if (tag(l) != tag(r)) - tag(top-1) = T_NIL; - else - { - switch (tag(l)) - { - case T_NIL: tag(top-1) = T_NUMBER; break; - case T_NUMBER: tag(top-1) = (nvalue(l) == nvalue(r)) ? T_NUMBER : T_NIL; break; - case T_ARRAY: tag(top-1) = (avalue(l) == avalue(r)) ? T_NUMBER : T_NIL; break; - case T_FUNCTION: tag(top-1) = (bvalue(l) == bvalue(r)) ? T_NUMBER : T_NIL; break; - case T_CFUNCTION: tag(top-1) = (fvalue(l) == fvalue(r)) ? T_NUMBER : T_NIL; break; - case T_USERDATA: tag(top-1) = (uvalue(l) == uvalue(r)) ? T_NUMBER : T_NIL; break; - case T_STRING: tag(top-1) = (strcmp (svalue(l), svalue(r)) == 0) ? T_NUMBER : T_NIL; break; - case T_MARK: return 1; - } - } + tag(top-1) = res ? LUA_T_NUMBER : LUA_T_NIL; nvalue(top-1) = 1; } break; - - case LTOP: + + case LTOP: + comparison(LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, "lt"); + break; + + case LEOP: + comparison(LUA_T_NUMBER, LUA_T_NUMBER, LUA_T_NIL, "le"); + break; + + case GTOP: + comparison(LUA_T_NIL, LUA_T_NIL, LUA_T_NUMBER, "gt"); + break; + + case GEOP: + comparison(LUA_T_NIL, LUA_T_NUMBER, LUA_T_NUMBER, "ge"); + break; + + case ADDOP: { Object *l = top-2; Object *r = top-1; - --top; - if (tag(l) == T_NUMBER && tag(r) == T_NUMBER) - tag(top-1) = (nvalue(l) < nvalue(r)) ? T_NUMBER : T_NIL; + if (tonumber(r) || tonumber(l)) + call_arith("add"); else { - if (tostring(l) || tostring(r)) - return 1; - tag(top-1) = (strcmp (svalue(l), svalue(r)) < 0) ? T_NUMBER : T_NIL; + nvalue(l) += nvalue(r); + --top; } - nvalue(top-1) = 1; } break; - - case LEOP: + + case SUBOP: { Object *l = top-2; Object *r = top-1; - --top; - if (tag(l) == T_NUMBER && tag(r) == T_NUMBER) - tag(top-1) = (nvalue(l) <= nvalue(r)) ? T_NUMBER : T_NIL; + if (tonumber(r) || tonumber(l)) + call_arith("sub"); else { - if (tostring(l) || tostring(r)) - return 1; - tag(top-1) = (strcmp (svalue(l), svalue(r)) <= 0) ? T_NUMBER : T_NIL; + nvalue(l) -= nvalue(r); + --top; } - nvalue(top-1) = 1; } break; - - case ADDOP: - { - Object *l = top-2; - Object *r = top-1; - if (tonumber(r) || tonumber(l)) - return 1; - nvalue(l) += nvalue(r); - --top; - } - break; - - case SUBOP: - { - Object *l = top-2; - Object *r = top-1; - if (tonumber(r) || tonumber(l)) - return 1; - nvalue(l) -= nvalue(r); - --top; - } - break; - + case MULTOP: { Object *l = top-2; Object *r = top-1; if (tonumber(r) || tonumber(l)) - return 1; - nvalue(l) *= nvalue(r); - --top; + call_arith("mul"); + else + { + nvalue(l) *= nvalue(r); + --top; + } } - break; - + break; + case DIVOP: { Object *l = top-2; Object *r = top-1; if (tonumber(r) || tonumber(l)) - return 1; - nvalue(l) /= nvalue(r); - --top; + call_arith("div"); + else + { + nvalue(l) /= nvalue(r); + --top; + } } - break; - + break; + + case POWOP: + call_arith("pow"); + break; + case CONCOP: { Object *l = top-2; Object *r = top-1; if (tostring(r) || tostring(l)) - return 1; - svalue(l) = lua_createstring (lua_strconc(svalue(l),svalue(r))); - if (svalue(l) == NULL) - return 1; - --top; + do_call(&luaI_fallBacks[FB_CONCAT].function, (top-stack)-2, 1, (top-stack)-2); + else + { + tsvalue(l) = lua_createstring (lua_strconc(svalue(l),svalue(r))); + --top; + } } - break; - + break; + case MINUSOP: if (tonumber(top-1)) - return 1; - nvalue(top-1) = - nvalue(top-1); - break; - + { + tag(top++) = LUA_T_NIL; + call_arith("unm"); + } + else + nvalue(top-1) = - nvalue(top-1); + break; + case NOTOP: - tag(top-1) = tag(top-1) == T_NIL ? T_NUMBER : T_NIL; - break; - + tag(top-1) = (tag(top-1) == LUA_T_NIL) ? LUA_T_NUMBER : LUA_T_NIL; + nvalue(top-1) = 1; + break; + case ONTJMP: { CodeWord code; get_word(code,pc); - if (tag(top-1) != T_NIL) pc += code.w; + if (tag(top-1) != LUA_T_NIL) pc += code.w; } break; - - case ONFJMP: + + case ONFJMP: { CodeWord code; get_word(code,pc); - if (tag(top-1) == T_NIL) pc += code.w; + if (tag(top-1) == LUA_T_NIL) pc += code.w; } break; - + case JMP: { CodeWord code; @@ -474,7 +1040,7 @@ int lua_execute (Byte *pc) pc += code.w; } break; - + case UPJMP: { CodeWord code; @@ -482,13 +1048,13 @@ int lua_execute (Byte *pc) pc -= code.w; } break; - + case IFFJMP: { CodeWord code; get_word(code,pc); top--; - if (tag(top) == T_NIL) pc += code.w; + if (tag(top) == LUA_T_NIL) pc += code.w; } break; @@ -497,91 +1063,38 @@ int lua_execute (Byte *pc) CodeWord code; get_word(code,pc); top--; - if (tag(top) == T_NIL) pc -= code.w; + if (tag(top) == LUA_T_NIL) pc -= code.w; } break; case POP: --top; break; - + case CALLFUNC: { - Byte *newpc; - Object *b = top-1; - while (tag(b) != T_MARK) b--; - if (tag(b-1) == T_FUNCTION) - { - lua_debugline = 0; /* always reset debug flag */ - newpc = bvalue(b-1); - bvalue(b-1) = pc; /* store return code */ - nvalue(b) = (base-stack); /* store base value */ - base = b+1; - pc = newpc; - if (MAXSTACK-(base-stack) < STACKGAP) - { - lua_error ("stack overflow"); - return 1; - } - } - else if (tag(b-1) == T_CFUNCTION) - { - int nparam; - lua_debugline = 0; /* always reset debug flag */ - nvalue(b) = (base-stack); /* store base value */ - base = b+1; - nparam = top-base; /* number of parameters */ - (fvalue(b-1))(); /* call C function */ - - /* shift returned values */ - { - int i; - int nretval = top - base - nparam; - top = base - 2; - base = stack + (int) nvalue(base-1); - for (i=0; i<nretval; i++) - { - *top = *(top+nparam+2); - ++top; - } - } - } - else - { - lua_reportbug ("call expression not a function"); - return 1; - } + int nParams = *(pc++); + int nResults = *(pc++); + Object *func = top-1-nParams; /* function is below parameters */ + StkId newBase = (top-stack)-nParams; + do_call(func, newBase, nResults, newBase-1); } break; - + + case RETCODE0: + return base; + case RETCODE: - { - int i; - int shift = *pc++; - int nretval = top - base - shift; - top = base - 2; - pc = bvalue(base-2); - base = stack + (int) nvalue(base-1); - for (i=0; i<nretval; i++) - { - *top = *(top+shift+2); - ++top; - } - } - break; - - case HALT: - base = oldbase; - return 0; /* success */ - + return base+*pc; + case SETFUNCTION: { - CodeWord file, func; - get_word(file,pc); + CodeCode file; + CodeWord func; + get_code(file,pc); get_word(func,pc); - if (lua_pushfunction (file.w, func.w)) - return 1; + lua_pushfunction ((char *)file.b, func.w); } break; - + case SETLINE: { CodeWord code; @@ -589,433 +1102,15 @@ int lua_execute (Byte *pc) lua_debugline = code.w; } break; - + case RESET: lua_popfunction (); break; - + default: - lua_error ("internal error - opcode didn't match"); - return 1; + lua_error ("internal error - opcode doesn't match"); } } } -/* -** Traverse all objects on stack -*/ -void lua_travstack (void (*fn)(Object *)) -{ - Object *o; - for (o = top-1; o >= stack; o--) - fn (o); -} - -/* -** Open file, generate opcode and execute global statement. Return 0 on -** success or 1 on error. -*/ -int lua_dofile (char *filename) -{ - if (lua_openfile (filename)) return 1; - if (lua_parse ()) { lua_closefile (); return 1; } - lua_closefile (); - return 0; -} - -/* -** Generate opcode stored on string and execute global statement. Return 0 on -** success or 1 on error. -*/ -int lua_dostring (char *string) -{ - if (lua_openstring (string)) return 1; - if (lua_parse ()) return 1; - lua_closestring(); - return 0; -} - -/* -** Execute the given function. Return 0 on success or 1 on error. -*/ -int lua_call (char *functionname, int nparam) -{ - static Byte startcode[] = {CALLFUNC, HALT}; - int i; - Object func = s_object(lua_findsymbol(functionname)); - if (tag(&func) != T_FUNCTION) return 1; - for (i=1; i<=nparam; i++) - *(top-i+2) = *(top-i); - top += 2; - tag(top-nparam-1) = T_MARK; - *(top-nparam-2) = func; - return (lua_execute (startcode)); -} - -/* -** Get a parameter, returning the object handle or NULL on error. -** 'number' must be 1 to get the first parameter. -*/ -Object *lua_getparam (int number) -{ - if (number <= 0 || number > top-base) return NULL; - return (base+number-1); -} - -/* -** Given an object handle, return its number value. On error, return 0.0. -*/ -real lua_getnumber (Object *object) -{ - if (object == NULL || tag(object) == T_NIL) return 0.0; - if (tonumber (object)) return 0.0; - else return (nvalue(object)); -} - -/* -** Given an object handle, return its string pointer. On error, return NULL. -*/ -char *lua_getstring (Object *object) -{ - if (object == NULL || tag(object) == T_NIL) return NULL; - if (tostring (object)) return NULL; - else return (svalue(object)); -} - -/* -** Given an object handle, return a copy of its string. On error, return NULL. -*/ -char *lua_copystring (Object *object) -{ - if (object == NULL || tag(object) == T_NIL) return NULL; - if (tostring (object)) return NULL; - else return (strdup(svalue(object))); -} - -/* -** Given an object handle, return its cfuntion pointer. On error, return NULL. -*/ -lua_CFunction lua_getcfunction (Object *object) -{ - if (object == NULL) return NULL; - if (tag(object) != T_CFUNCTION) return NULL; - else return (fvalue(object)); -} - -/* -** Given an object handle, return its user data. On error, return NULL. -*/ -void *lua_getuserdata (Object *object) -{ - if (object == NULL) return NULL; - if (tag(object) != T_USERDATA) return NULL; - else return (uvalue(object)); -} - -/* -** Given an object handle and a field name, return its field object. -** On error, return NULL. -*/ -Object *lua_getfield (Object *object, char *field) -{ - if (object == NULL) return NULL; - if (tag(object) != T_ARRAY) - return NULL; - else - { - Object ref; - tag(&ref) = T_STRING; - svalue(&ref) = lua_createstring(lua_strdup(field)); - return (lua_hashdefine(avalue(object), &ref)); - } -} - -/* -** Given an object handle and an index, return its indexed object. -** On error, return NULL. -*/ -Object *lua_getindexed (Object *object, float index) -{ - if (object == NULL) return NULL; - if (tag(object) != T_ARRAY) - return NULL; - else - { - Object ref; - tag(&ref) = T_NUMBER; - nvalue(&ref) = index; - return (lua_hashdefine(avalue(object), &ref)); - } -} - -/* -** Get a global object. Return the object handle or NULL on error. -*/ -Object *lua_getglobal (char *name) -{ - int n = lua_findsymbol(name); - if (n < 0) return NULL; - return &s_object(n); -} - -/* -** Pop and return an object -*/ -Object *lua_pop (void) -{ - if (top <= base) return NULL; - top--; - return top; -} - -/* -** Push a nil object -*/ -int lua_pushnil (void) -{ - if ((top-stack) >= MAXSTACK-1) - { - lua_error ("stack overflow"); - return 1; - } - tag(top) = T_NIL; - return 0; -} - -/* -** Push an object (tag=number) to stack. Return 0 on success or 1 on error. -*/ -int lua_pushnumber (real n) -{ - if ((top-stack) >= MAXSTACK-1) - { - lua_error ("stack overflow"); - return 1; - } - tag(top) = T_NUMBER; nvalue(top++) = n; - return 0; -} - -/* -** Push an object (tag=string) to stack. Return 0 on success or 1 on error. -*/ -int lua_pushstring (char *s) -{ - if ((top-stack) >= MAXSTACK-1) - { - lua_error ("stack overflow"); - return 1; - } - tag(top) = T_STRING; - svalue(top++) = lua_createstring(lua_strdup(s)); - return 0; -} - -/* -** Push an object (tag=cfunction) to stack. Return 0 on success or 1 on error. -*/ -int lua_pushcfunction (lua_CFunction fn) -{ - if ((top-stack) >= MAXSTACK-1) - { - lua_error ("stack overflow"); - return 1; - } - tag(top) = T_CFUNCTION; fvalue(top++) = fn; - return 0; -} - -/* -** Push an object (tag=userdata) to stack. Return 0 on success or 1 on error. -*/ -int lua_pushuserdata (void *u) -{ - if ((top-stack) >= MAXSTACK-1) - { - lua_error ("stack overflow"); - return 1; - } - tag(top) = T_USERDATA; uvalue(top++) = u; - return 0; -} - -/* -** Push an object to stack. -*/ -int lua_pushobject (Object *o) -{ - if ((top-stack) >= MAXSTACK-1) - { - lua_error ("stack overflow"); - return 1; - } - *top++ = *o; - return 0; -} - -/* -** Store top of the stack at a global variable array field. -** Return 1 on error, 0 on success. -*/ -int lua_storeglobal (char *name) -{ - int n = lua_findsymbol (name); - if (n < 0) return 1; - if (tag(top-1) == T_MARK) return 1; - s_object(n) = *(--top); - return 0; -} - -/* -** Store top of the stack at an array field. Return 1 on error, 0 on success. -*/ -int lua_storefield (lua_Object object, char *field) -{ - if (tag(object) != T_ARRAY) - return 1; - else - { - Object ref, *h; - tag(&ref) = T_STRING; - svalue(&ref) = lua_createstring(lua_strdup(field)); - h = lua_hashdefine(avalue(object), &ref); - if (h == NULL) return 1; - if (tag(top-1) == T_MARK) return 1; - *h = *(--top); - } - return 0; -} - - -/* -** Store top of the stack at an array index. Return 1 on error, 0 on success. -*/ -int lua_storeindexed (lua_Object object, float index) -{ - if (tag(object) != T_ARRAY) - return 1; - else - { - Object ref, *h; - tag(&ref) = T_NUMBER; - nvalue(&ref) = index; - h = lua_hashdefine(avalue(object), &ref); - if (h == NULL) return 1; - if (tag(top-1) == T_MARK) return 1; - *h = *(--top); - } - return 0; -} - - -/* -** Given an object handle, return if it is nil. -*/ -int lua_isnil (Object *object) -{ - return (object != NULL && tag(object) == T_NIL); -} - -/* -** Given an object handle, return if it is a number one. -*/ -int lua_isnumber (Object *object) -{ - return (object != NULL && tag(object) == T_NUMBER); -} - -/* -** Given an object handle, return if it is a string one. -*/ -int lua_isstring (Object *object) -{ - return (object != NULL && tag(object) == T_STRING); -} - -/* -** Given an object handle, return if it is an array one. -*/ -int lua_istable (Object *object) -{ - return (object != NULL && tag(object) == T_ARRAY); -} - -/* -** Given an object handle, return if it is a cfunction one. -*/ -int lua_iscfunction (Object *object) -{ - return (object != NULL && tag(object) == T_CFUNCTION); -} - -/* -** Given an object handle, return if it is an user data one. -*/ -int lua_isuserdata (Object *object) -{ - return (object != NULL && tag(object) == T_USERDATA); -} - -/* -** Internal function: return an object type. -*/ -void lua_type (void) -{ - Object *o = lua_getparam(1); - lua_pushstring (lua_constant[tag(o)]); -} - -/* -** Internal function: convert an object to a number -*/ -void lua_obj2number (void) -{ - Object *o = lua_getparam(1); - lua_pushobject (lua_convtonumber(o)); -} - -/* -** Internal function: print object values -*/ -void lua_print (void) -{ - int i=1; - void *obj; - while ((obj=lua_getparam (i++)) != NULL) - { - if (lua_isnumber(obj)) printf("%g\n",lua_getnumber (obj)); - else if (lua_isstring(obj)) printf("%s\n",lua_getstring (obj)); - 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",obj); - else if (lua_isnil(obj)) printf("nil\n"); - else printf("invalid value to print\n"); - } -} - -/* -** Internal function: do a file -*/ -void lua_internaldofile (void) -{ - lua_Object obj = lua_getparam (1); - if (lua_isstring(obj) && !lua_dofile(lua_getstring(obj))) - lua_pushnumber(1); - else - lua_pushnil(); -} - -/* -** Internal function: do a string -*/ -void lua_internaldostring (void) -{ - lua_Object obj = lua_getparam (1); - if (lua_isstring(obj) && !lua_dostring(lua_getstring(obj))) - lua_pushnumber(1); - else - lua_pushnil(); -} - - diff --git a/src/opcode.h b/src/opcode.h index abf284c4..e3a6d37c 100644 --- a/src/opcode.h +++ b/src/opcode.h @@ -1,11 +1,15 @@ /* ** TeCGraf - PUC-Rio -** $Id: opcode.h,v 2.1 1994/04/20 22:07:57 celes Exp $ +** $Id: opcode.h,v 3.10 1994/12/20 21:20:36 roberto Exp $ */ #ifndef opcode_h #define opcode_h +#include "lua.h" +#include "types.h" +#include "tree.h" + #ifndef STACKGAP #define STACKGAP 128 #endif @@ -16,21 +20,8 @@ #define FIELDS_PER_FLUSH 40 -typedef unsigned char Byte; - -typedef unsigned short Word; - -typedef union -{ - struct {char c1; char c2;} m; - Word w; -} CodeWord; +#define MAX_TEMPS 20 -typedef union -{ - struct {char c1; char c2; char c3; char c4;} m; - float f; -} CodeFloat; typedef enum { @@ -40,13 +31,13 @@ typedef enum PUSHWORD, PUSHFLOAT, PUSHSTRING, + PUSHFUNCTION, PUSHLOCAL0, PUSHLOCAL1, PUSHLOCAL2, PUSHLOCAL3, PUSHLOCAL4, PUSHLOCAL5, PUSHLOCAL6, PUSHLOCAL7, PUSHLOCAL8, PUSHLOCAL9, PUSHLOCAL, PUSHGLOBAL, PUSHINDEXED, - PUSHMARK, - PUSHOBJECT, + PUSHSELF, STORELOCAL0, STORELOCAL1, STORELOCAL2, STORELOCAL3, STORELOCAL4, STORELOCAL5, STORELOCAL6, STORELOCAL7, STORELOCAL8, STORELOCAL9, STORELOCAL, @@ -56,15 +47,19 @@ typedef enum STORELIST0, STORELIST, STORERECORD, + ADJUST0, ADJUST, CREATEARRAY, EQOP, LTOP, LEOP, + GTOP, + GEOP, ADDOP, SUBOP, MULTOP, DIVOP, + POWOP, CONCOP, MINUSOP, NOTOP, @@ -76,61 +71,51 @@ typedef enum IFFUPJMP, POP, CALLFUNC, + RETCODE0, RETCODE, - HALT, SETFUNCTION, SETLINE, RESET } OpCode; -typedef enum -{ - T_MARK, - T_NIL, - T_NUMBER, - T_STRING, - T_ARRAY, - T_FUNCTION, - T_CFUNCTION, - T_USERDATA -} Type; +#define MULT_RET 255 + typedef void (*Cfunction) (void); typedef int (*Input) (void); typedef union { - Cfunction f; - real n; - char *s; - Byte *b; + Cfunction f; + real n; + TaggedString *ts; + Byte *b; struct Hash *a; void *u; } Value; typedef struct Object { - Type tag; + lua_Type tag; Value value; } Object; typedef struct { - char *name; Object object; } Symbol; /* Macros to access structure members */ #define tag(o) ((o)->tag) #define nvalue(o) ((o)->value.n) -#define svalue(o) ((o)->value.s) +#define svalue(o) ((o)->value.ts->str) +#define tsvalue(o) ((o)->value.ts) #define bvalue(o) ((o)->value.b) #define avalue(o) ((o)->value.a) #define fvalue(o) ((o)->value.f) #define uvalue(o) ((o)->value.u) /* Macros to access symbol table */ -#define s_name(i) (lua_table[i].name) #define s_object(i) (lua_table[i].object) #define s_tag(i) (tag(&s_object(i))) #define s_nvalue(i) (nvalue(&s_object(i))) @@ -140,25 +125,40 @@ typedef struct #define s_fvalue(i) (fvalue(&s_object(i))) #define s_uvalue(i) (uvalue(&s_object(i))) +typedef union +{ + struct {char c1; char 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; + float f; +} CodeFloat; #define get_float(code,pc) {code.m.c1 = *pc++; code.m.c2 = *pc++;\ code.m.c3 = *pc++; code.m.c4 = *pc++;} - + +typedef union +{ + struct {char c1; char c2; char c3; char c4;} m; + Byte *b; +} CodeCode; +#define get_code(code,pc) {code.m.c1 = *pc++; code.m.c2 = *pc++;\ + code.m.c3 = *pc++; code.m.c4 = *pc++;} /* Exported functions */ -int lua_execute (Byte *pc); -void lua_markstack (void); char *lua_strdup (char *l); void lua_setinput (Input fn); /* from "lex.c" module */ char *lua_lasttext (void); /* from "lex.c" module */ -int lua_parse (void); /* from "lua.stx" module */ -void lua_type (void); -void lua_obj2number (void); -void lua_print (void); -void lua_internaldofile (void); -void lua_internaldostring (void); +int yylex (void); /* from "lex.c" module */ +void lua_parse (Byte **code); /* from "lua.stx" module */ void lua_travstack (void (*fn)(Object *)); +Object *luaI_Address (lua_Object o); +void luaI_pushobject (Object *o); +void luaI_gcFB (Object *o); #endif diff --git a/src/y.tab.c b/src/parser.c index 70dbd3cd..47b77fb0 100644 --- a/src/y.tab.c +++ b/src/parser.c @@ -1,36 +1,56 @@ +#if defined (__cplusplus) || defined (c_plusplus) +#include <c_varieties.h> +#ifdef __EXTERN_C__ + EXTERN_FUNCTION ( extern int yylex, ()); +#else + extern int yylex(); +#endif + extern void yyerror(char *); + extern int yyparse(); +#endif + +#include <malloc.h> # line 2 "lua.stx" -char *rcs_luastx = "$Id: lua.stx,v 2.4 1994/04/20 16:22:21 celes Exp $"; +char *rcs_luastx = "$Id: lua.stx,v 3.17 1995/01/13 22:11:12 roberto Exp $"; #include <stdio.h> #include <stdlib.h> #include <string.h> -#include "mm.h" - +#include "mem.h" #include "opcode.h" #include "hash.h" #include "inout.h" +#include "tree.h" #include "table.h" #include "lua.h" +/* to avoid warnings generated by yacc */ +int yyparse (void); +#define malloc luaI_malloc +#define realloc luaI_realloc +#define free luaI_free + +#ifndef LISTING #define LISTING 0 +#endif -#ifndef GAPCODE -#define GAPCODE 50 +#ifndef CODE_BLOCK +#define CODE_BLOCK 256 #endif -static Word maxcode; -static Word maxmain; -static Word maxcurr ; -static Byte *code = NULL; -static Byte *initcode; +static int maxcode; +static int maxmain; +static Long maxcurr; /* to allow maxcurr *= 2 without overflow */ +static Byte *funcCode = NULL; +static Byte **initcode; static Byte *basepc; -static Word maincode; -static Word pc; +static int maincode; +static int pc; #define MAXVAR 32 -static long varbuffer[MAXVAR]; /* variables in an assignment list; +static Long varbuffer[MAXVAR]; /* variables in an assignment list; it's long to store negative Word values */ static int nvarbuffer=0; /* number of variables at a list */ @@ -40,8 +60,7 @@ 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; -static int ntemp; /* number of temporary var into stack */ -static int err; /* flag to indicate error */ + /* Internal functions */ @@ -49,13 +68,12 @@ static void code_byte (Byte c) { if (pc>maxcurr-2) /* 1 byte free to code HALT of main code */ { - maxcurr += GAPCODE; - basepc = (Byte *)realloc(basepc, maxcurr*sizeof(Byte)); - if (basepc == NULL) - { - lua_error ("not enough memory"); - err = 1; - } + if (maxcurr >= MAX_INT) + lua_error("code size overflow"); + maxcurr *= 2; + if (maxcurr >= MAX_INT) + maxcurr = MAX_INT; + basepc = growvector(basepc, maxcurr, Byte); } basepc[pc++] = c; } @@ -78,6 +96,16 @@ static void code_float (float n) code_byte(code.m.c4); } +static void code_code (Byte *b) +{ + CodeCode code; + code.b = b; + code_byte(code.m.c1); + code_byte(code.m.c2); + code_byte(code.m.c3); + code_byte(code.m.c4); +} + static void code_word_at (Byte *p, Word n) { CodeWord code; @@ -91,10 +119,7 @@ static void push_field (Word name) if (nfields < STACKGAP-1) fields[nfields++] = name; else - { lua_error ("too many fields in a constructor"); - err = 1; - } } static void flush_record (int n) @@ -105,7 +130,6 @@ static void flush_record (int n) code_byte(n); for (i=0; i<n; i++) code_word(fields[--nfields]); - ntemp -= n; } static void flush_list (int m, int n) @@ -114,34 +138,22 @@ static void flush_list (int m, int n) if (m == 0) code_byte(STORELIST0); else + if (m < 255) { code_byte(STORELIST); code_byte(m); } + else + lua_error ("list constructor too long"); code_byte(n); - ntemp-=n; -} - -static void incr_ntemp (void) -{ - if (ntemp+nlocalvar+MAXVAR+1 < STACKGAP) - ntemp++; - else - { - lua_error ("stack overflow"); - err = 1; - } } static void add_nlocalvar (int n) { - if (ntemp+nlocalvar+MAXVAR+n < STACKGAP) + if (MAX_TEMPS+nlocalvar+MAXVAR+n < STACKGAP) nlocalvar += n; else - { - lua_error ("too many local variables or expression too complicate"); - err = 1; - } + lua_error ("too many local variables"); } static void incr_nvarbuffer (void) @@ -149,14 +161,12 @@ static void incr_nvarbuffer (void) if (nvarbuffer < MAXVAR-1) nvarbuffer++; else - { lua_error ("variable buffer overflow"); - err = 1; - } } static void code_number (float f) -{ Word i = (Word)f; +{ + Word i = (Word)f; if (f == (float)i) /* f has an (short) integer value */ { if (i <= 2) code_byte(PUSH0 + i); @@ -176,59 +186,8 @@ static void code_number (float f) code_byte(PUSHFLOAT); code_float(f); } - incr_ntemp(); } - -# line 184 "lua.stx" -typedef union -{ - int vInt; - long vLong; - float vFloat; - char *pChar; - Word vWord; - Byte *pByte; -} YYSTYPE; -# define WRONGTOKEN 257 -# define NIL 258 -# define IF 259 -# define THEN 260 -# define ELSE 261 -# define ELSEIF 262 -# define WHILE 263 -# define DO 264 -# define REPEAT 265 -# define UNTIL 266 -# define END 267 -# define RETURN 268 -# define LOCAL 269 -# define NUMBER 270 -# define FUNCTION 271 -# define STRING 272 -# define NAME 273 -# define DEBUG 274 -# define AND 275 -# define OR 276 -# define NE 277 -# define LE 278 -# define GE 279 -# define CONC 280 -# define UNARY 281 -# define NOT 282 -#define yyclearin yychar = -1 -#define yyerrok yyerrflag = 0 -extern int yychar; -extern int yyerrflag; -#ifndef YYMAXDEPTH -#define YYMAXDEPTH 150 -#endif -YYSTYPE yylval, yyval; -# define YYERRCODE 256 - -# line 622 "lua.stx" - - /* ** Search a local name and if find return its index. If do not find return -1 */ @@ -245,13 +204,12 @@ static int lua_localname (Word n) ** indexed by (number -1). If negative, push local indexed by ABS(number)-1. ** Otherwise, if zero, push indexed variable (record). */ -static void lua_pushvar (long number) +static void lua_pushvar (Long number) { if (number > 0) /* global var */ { code_byte(PUSHGLOBAL); code_word(number-1); - incr_ntemp(); } else if (number < 0) /* local var */ { @@ -262,19 +220,77 @@ static void lua_pushvar (long number) code_byte(PUSHLOCAL); code_byte(number); } - incr_ntemp(); } else { code_byte(PUSHINDEXED); - ntemp--; } } static void lua_codeadjust (int n) { - code_byte(ADJUST); - code_byte(n + nlocalvar); + if (n+nlocalvar == 0) + code_byte(ADJUST0); + else + { + code_byte(ADJUST); + code_byte(n+nlocalvar); + } +} + +static void init_function (TreeNode *func) +{ + if (funcCode == NULL) /* first function */ + { + funcCode = newvector(CODE_BLOCK, Byte); + maxcode = CODE_BLOCK; + } + pc=0; basepc=funcCode; maxcurr=maxcode; + nlocalvar=0; + if (lua_debug) + { + code_byte(SETFUNCTION); + code_code((Byte *)luaI_strdup(lua_file[lua_nfile-1])); + code_word(luaI_findconstant(func)); + } +} + +static void codereturn (void) +{ + if (lua_debug) code_byte(RESET); + if (nlocalvar == 0) + code_byte(RETCODE0); + else + { + code_byte(RETCODE); + code_byte(nlocalvar); + } +} + +static void codedebugline (void) +{ + if (lua_debug) + { + code_byte(SETLINE); + code_word(lua_linenumber); + } +} + +static void adjust_mult_assign (int vars, int exps, int temps) +{ + if (exps < 0) + { + int r = vars - (-exps-1); + if (r >= 0) + code_byte(r); + else + { + code_byte(0); + lua_codeadjust(temps); + } + } + else if (vars != exps) + lua_codeadjust(temps); } static void lua_codestore (int i) @@ -312,48 +328,102 @@ static void lua_codestore (int i) } } -void yyerror (char *s) +static void codeIf (Long thenAdd, Long elseAdd) +{ + Long elseinit = elseAdd+sizeof(Word)+1; + if (pc == elseinit) /* no else */ + { + pc -= sizeof(Word)+1; + elseinit = pc; + } + else + { + basepc[elseAdd] = JMP; + code_word_at(basepc+elseAdd+1, pc-elseinit); + } + basepc[thenAdd] = IFFJMP; + code_word_at(basepc+thenAdd+1,elseinit-(thenAdd+sizeof(Word)+1)); +} + +static void yyerror (char *s) { static char msg[256]; sprintf (msg,"%s near \"%s\" at line %d in file \"%s\"", s, lua_lasttext (), lua_linenumber, lua_filename()); lua_error (msg); - err = 1; -} - -int yywrap (void) -{ - return 1; } /* -** Parse LUA code and execute global statement. -** Return 0 on success or 1 on error. +** Parse LUA code. */ -int lua_parse (void) +void lua_parse (Byte **code) { - Byte *init = initcode = (Byte *) calloc(GAPCODE, sizeof(Byte)); + initcode = code; + *initcode = newvector(CODE_BLOCK, Byte); maincode = 0; - maxmain = GAPCODE; - if (init == NULL) - { - lua_error("not enough memory"); - return 1; - } - err = 0; - if (yyparse () || (err==1)) return 1; - initcode[maincode++] = HALT; - init = initcode; + maxmain = CODE_BLOCK; + if (yyparse ()) lua_error("parse error"); + (*initcode)[maincode++] = RETCODE0; #if LISTING - PrintCode(init,init+maincode); +{ static void PrintCode (Byte *c, Byte *end); + PrintCode(*initcode,*initcode+maincode); } #endif - if (lua_execute (init)) return 1; - free(init); - return 0; } + +# line 365 "lua.stx" +typedef union +{ + int vInt; + float vFloat; + char *pChar; + Word vWord; + Long vLong; + Byte *pByte; + TreeNode *pNode; +} YYSTYPE; +# define WRONGTOKEN 257 +# define NIL 258 +# define IF 259 +# define THEN 260 +# define ELSE 261 +# define ELSEIF 262 +# define WHILE 263 +# define DO 264 +# define REPEAT 265 +# define UNTIL 266 +# define END 267 +# define RETURN 268 +# define LOCAL 269 +# define FUNCTION 270 +# define NUMBER 271 +# define STRING 272 +# define NAME 273 +# define DEBUG 274 +# define AND 275 +# define OR 276 +# define EQ 277 +# define NE 278 +# define LE 279 +# define GE 280 +# define CONC 281 +# define UNARY 282 +# define NOT 283 +#define yyclearin yychar = -1 +#define yyerrok yyerrflag = 0 +extern int yychar; +extern int yyerrflag; +#ifndef YYMAXDEPTH +#define YYMAXDEPTH 150 +#endif +YYSTYPE yylval, yyval; +# define YYERRCODE 256 + +# line 737 "lua.stx" + + #if LISTING static void PrintCode (Byte *code, Byte *end) @@ -400,6 +470,16 @@ static void PrintCode (Byte *code, Byte *end) 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.b); + } + break; + case PUSHLOCAL0: case PUSHLOCAL1: case PUSHLOCAL2: case PUSHLOCAL3: case PUSHLOCAL4: case PUSHLOCAL5: case PUSHLOCAL6: case PUSHLOCAL7: case PUSHLOCAL8: case PUSHLOCAL9: @@ -419,8 +499,6 @@ static void PrintCode (Byte *code, Byte *end) } break; case PUSHINDEXED: printf ("%d PUSHINDEXED\n", (p++)-code); break; - case PUSHMARK: printf ("%d PUSHMARK\n", (p++)-code); break; - case PUSHOBJECT: printf ("%d PUSHOBJECT\n", (p++)-code); break; case STORELOCAL0: case STORELOCAL1: case STORELOCAL2: case STORELOCAL3: case STORELOCAL4: case STORELOCAL5: case STORELOCAL6: case STORELOCAL7: case STORELOCAL8: case STORELOCAL9: @@ -440,6 +518,15 @@ static void PrintCode (Byte *code, Byte *end) 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++; @@ -456,11 +543,20 @@ static void PrintCode (Byte *code, Byte *end) 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: printf ("%d CREATEARRAY\n", (p++)-code); 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; @@ -468,6 +564,7 @@ static void PrintCode (Byte *code, Byte *end) 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; @@ -526,20 +623,24 @@ static void PrintCode (Byte *code, Byte *end) } break; case POP: printf ("%d POP\n", (p++)-code); break; - case CALLFUNC: printf ("%d CALLFUNC\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 HALT: printf ("%d HALT\n", (p++)-code); break; case SETFUNCTION: { - CodeWord c1, c2; + CodeCode c1; + CodeWord c2; int n = p-code; p++; - get_word(c1,p); + get_code(c1,p); get_word(c2,p); - printf ("%d SETFUNCTION %d %d\n", n, c1.w, c2.w); + printf ("%d SETFUNCTION %s %d\n", n, (char *)c1.b, c2.w); } break; case SETLINE: @@ -564,194 +665,201 @@ int yyexca[] ={ 0, -1, -2, 2, -1, 20, - 40, 67, - 91, 94, - 46, 96, - -2, 91, + 61, 91, + 44, 91, + -2, 97, -1, 32, - 40, 67, - 91, 94, - 46, 96, - -2, 51, --1, 73, - 275, 34, - 276, 34, - 61, 34, - 277, 34, - 62, 34, - 60, 34, - 278, 34, - 279, 34, - 280, 34, - 43, 34, - 45, 34, - 42, 34, - 47, 34, + 40, 66, + 123, 66, + -2, 53, +-1, 47, + 123, 63, -2, 70, -1, 74, - 91, 94, - 46, 96, - -2, 92, --1, 105, - 261, 28, - 262, 28, - 266, 28, - 267, 28, - 268, 28, - -2, 11, --1, 125, - 268, 31, - -2, 30, --1, 146, - 275, 34, - 276, 34, - 61, 34, - 277, 34, - 62, 34, - 60, 34, - 278, 34, - 279, 34, - 280, 34, - 43, 34, - 45, 34, - 42, 34, - 47, 34, + 125, 79, + -2, 63, +-1, 79, + 275, 37, + 276, 37, + 277, 37, + 278, 37, + 62, 37, + 60, 37, + 279, 37, + 280, 37, + 281, 37, + 43, 37, + 45, 37, + 42, 37, + 47, 37, + 94, 37, -2, 72, +-1, 80, + 91, 97, + 46, 97, + -2, 92, +-1, 118, + 261, 33, + 262, 33, + 266, 33, + 267, 33, + -2, 16, +-1, 133, + 125, 85, + -2, 63, +-1, 158, + 123, 63, + -2, 70, +-1, 159, + 275, 37, + 276, 37, + 277, 37, + 278, 37, + 62, 37, + 60, 37, + 279, 37, + 280, 37, + 281, 37, + 43, 37, + 45, 37, + 42, 37, + 47, 37, + 94, 37, + -2, 74, }; # define YYNPROD 103 -# define YYLAST 364 +# define YYLAST 351 int yyact[]={ - 58, 56, 22, 57, 132, 59, 58, 56, 137, 57, - 110, 59, 58, 56, 107, 57, 85, 59, 51, 50, - 52, 82, 23, 43, 51, 50, 52, 58, 56, 9, - 57, 157, 59, 58, 56, 165, 57, 5, 59, 162, - 6, 161, 104, 154, 155, 51, 50, 52, 64, 153, - 70, 51, 50, 52, 26, 58, 56, 127, 57, 10, - 59, 111, 25, 78, 27, 58, 56, 28, 57, 29, - 59, 131, 147, 51, 50, 52, 7, 65, 66, 115, - 150, 112, 63, 51, 50, 52, 68, 69, 31, 159, - 11, 79, 58, 76, 128, 73, 41, 59, 151, 87, - 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 77, 114, 148, 40, 58, 56, 102, 57, 106, 59, - 117, 32, 72, 121, 116, 100, 80, 109, 67, 48, - 20, 36, 73, 30, 45, 73, 44, 118, 149, 84, - 17, 126, 18, 46, 21, 47, 120, 119, 101, 145, - 144, 125, 71, 123, 75, 39, 38, 12, 8, 108, - 105, 136, 83, 74, 135, 24, 4, 3, 139, 140, - 2, 81, 134, 141, 133, 130, 129, 42, 113, 16, - 1, 146, 124, 0, 143, 0, 0, 152, 0, 0, - 0, 86, 0, 0, 0, 0, 0, 13, 0, 0, - 160, 14, 0, 15, 164, 163, 0, 19, 167, 0, - 0, 23, 73, 0, 0, 0, 0, 0, 168, 166, - 158, 171, 173, 0, 0, 0, 169, 0, 0, 0, - 0, 0, 0, 61, 62, 53, 54, 55, 60, 61, - 62, 53, 54, 55, 60, 0, 0, 0, 0, 103, - 60, 49, 0, 98, 99, 0, 0, 0, 0, 0, - 61, 62, 53, 54, 55, 60, 61, 62, 53, 54, - 55, 60, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 35, 0, 0, 0, 0, 0, 61, 62, - 53, 54, 55, 60, 33, 122, 34, 23, 0, 0, - 53, 54, 55, 60, 0, 0, 37, 0, 0, 0, - 138, 0, 0, 0, 0, 142, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 156, 0, 0, 0, 0, 0, 0, + 64, 62, 6, 63, 152, 65, 7, 64, 62, 145, + 63, 120, 65, 92, 64, 62, 89, 63, 57, 65, + 58, 64, 62, 87, 63, 57, 65, 58, 64, 62, + 24, 63, 57, 65, 58, 64, 62, 54, 63, 57, + 65, 58, 45, 10, 29, 142, 57, 171, 58, 30, + 29, 123, 66, 167, 14, 30, 160, 117, 15, 66, + 16, 162, 163, 173, 19, 131, 66, 138, 24, 28, + 112, 114, 130, 66, 74, 71, 8, 64, 66, 52, + 66, 86, 65, 51, 161, 83, 51, 66, 43, 136, + 27, 12, 64, 62, 26, 63, 133, 65, 49, 70, + 135, 119, 84, 125, 124, 42, 72, 122, 109, 32, + 53, 132, 79, 73, 85, 39, 75, 79, 47, 23, + 149, 91, 143, 31, 78, 20, 88, 38, 50, 66, + 11, 50, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 66, 48, 36, 129, 128, 158, + 113, 141, 94, 81, 79, 77, 18, 41, 40, 80, + 139, 13, 9, 118, 90, 93, 121, 25, 5, 4, + 3, 2, 22, 126, 111, 76, 82, 44, 134, 110, + 21, 46, 17, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 140, 0, 0, 0, 0, + 0, 0, 0, 0, 147, 148, 0, 151, 0, 150, + 0, 0, 153, 159, 0, 156, 0, 0, 0, 0, + 164, 107, 108, 0, 0, 0, 0, 0, 79, 116, + 170, 169, 55, 68, 69, 56, 59, 60, 61, 67, + 68, 69, 56, 59, 60, 61, 67, 68, 69, 56, + 59, 60, 61, 67, 68, 69, 56, 59, 60, 61, + 67, 177, 35, 56, 59, 60, 61, 67, 35, 137, + 127, 157, 0, 166, 67, 33, 34, 24, 0, 0, + 146, 33, 34, 115, 0, 0, 0, 37, 0, 0, + 0, 155, 0, 37, 0, 0, 0, 172, 0, 0, + 144, 0, 0, 0, 0, 0, 0, 165, 0, 0, + 0, 0, 0, 154, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 174, 0, 176, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 170, 0, 0, 172 }; + 175 }; int yypact[]={ - -1000, -234, -1000, -1000, -1000, -244, -1000, 31, -62, -1000, - -1000, -1000, -1000, 24, -1000, -1000, 52, -1000, -1000, -250, - -1000, -1000, -1000, -1000, 89, -9, -1000, 24, 24, 24, - -1000, 88, -1000, -1000, -1000, -1000, -1000, 24, 24, -1000, - 24, -251, 49, -1000, -28, 45, 86, -252, -257, -1000, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, -1000, -1000, 84, 13, -1000, -1000, 24, -1000, -15, - -224, -1000, 74, -1000, -1000, -1000, -259, 24, 24, -263, - 24, -12, -1000, 83, 76, -1000, -1000, -30, -30, -30, - -30, -30, -30, 50, 50, -1000, -1000, 72, -1000, -1000, - -1000, 82, 13, -1000, 24, -1000, -1000, -1000, 74, -36, - -1000, 53, 74, -1000, -269, 24, -1000, -265, -1000, 24, - 24, -1000, -1000, 13, 31, -1000, 24, -1000, -1000, -53, - 68, -1000, -1000, -13, 54, 13, -1000, -1000, -218, 23, - 23, -1000, -1000, -1000, -1000, -237, -1000, -1000, -269, 28, - -1000, 24, -226, -228, -1000, 24, -232, 24, -1000, 24, - 13, -1000, -1000, -1000, -42, -1000, 31, 13, -1000, -1000, - -1000, -1000, -218, -1000 }; + -1000, -268, -1000, -1000, -1000, -1000, -230, -1000, 32, -205, + 36, -1000, -1000, -1000, 4, -1000, -1000, 44, -1000, -231, + -1000, 78, -1000, 40, -1000, 70, -236, -28, -1000, 4, + 4, -1000, 40, -1000, -1000, -1000, -1000, 4, -49, -1000, + 4, -1000, 4, -243, 41, -1000, -1000, 4, -1000, -250, + 4, -257, -1000, -260, -1000, -1000, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, -1000, -1000, + 67, -21, -16, -16, 10, -35, -209, -1000, 57, -1000, + -1000, 37, -1000, -262, 4, 66, 57, -1000, -42, -1000, + 63, 59, -1000, 70, -1000, -7, -7, -7, -7, -7, + -7, 35, 35, -16, -16, -16, 50, -1000, -1000, -1000, + -53, 52, 56, -21, -1000, 28, -1000, -1000, -223, -1000, + -1000, 57, -1000, -1000, -1000, -264, -1000, -1000, 4, 4, + -1000, -1000, -1000, 4, -1000, -269, 4, -1000, -1000, 4, + 32, -1000, -1000, 4, -211, -1000, -200, -14, -14, -269, + -21, -1000, 28, -21, -1000, -1000, -21, -1000, 4, -1000, + -1000, -214, -1000, -1000, 56, -220, 32, -1000, -1000, -197, + -1000, -1000, -1000, -1000, -1000, -1000, -200, -1000 }; int yypgo[]={ - 0, 180, 191, 54, 61, 81, 179, 133, 178, 177, - 176, 175, 174, 172, 121, 171, 170, 76, 59, 167, - 166, 165, 162, 161, 50, 160, 158, 157, 48, 49, - 156, 155, 131, 154, 152, 151, 150, 149, 148, 147, - 146, 145, 144, 143, 141, 139, 71, 138, 136, 134 }; + 0, 183, 152, 69, 114, 81, 182, 181, 180, 179, + 177, 176, 70, 174, 115, 172, 79, 171, 76, 130, + 170, 169, 168, 167, 165, 164, 175, 163, 162, 161, + 67, 160, 75, 84, 158, 157, 146, 155, 151, 149, + 123, 109, 148, 147, 127, 122, 121, 65, 120, 71 }; int yyr1[]={ - 0, 1, 16, 1, 1, 1, 21, 23, 19, 25, - 25, 26, 17, 18, 18, 27, 30, 27, 31, 27, - 27, 27, 27, 27, 29, 29, 29, 34, 35, 24, - 36, 37, 36, 2, 28, 3, 3, 3, 3, 3, + 0, 1, 17, 1, 1, 1, 1, 23, 20, 24, + 21, 16, 27, 27, 19, 19, 28, 18, 31, 30, + 29, 34, 29, 35, 29, 29, 29, 29, 33, 33, + 33, 37, 26, 38, 39, 38, 2, 32, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 39, 3, 40, - 3, 41, 7, 38, 38, 43, 32, 42, 4, 4, - 5, 44, 5, 22, 22, 45, 45, 15, 15, 8, - 8, 10, 10, 11, 11, 47, 46, 12, 12, 13, - 13, 6, 6, 14, 48, 14, 49, 14, 9, 9, - 33, 33, 20 }; + 3, 3, 3, 3, 3, 3, 3, 3, 3, 42, + 3, 43, 3, 44, 40, 36, 8, 8, 7, 7, + 4, 4, 5, 45, 5, 25, 25, 46, 46, 9, + 9, 9, 48, 9, 47, 47, 12, 12, 49, 13, + 13, 6, 6, 14, 14, 14, 15, 41, 10, 10, + 11, 11, 22 }; int yyr2[]={ - 0, 0, 1, 9, 4, 4, 1, 1, 19, 0, - 6, 1, 4, 0, 2, 17, 1, 17, 1, 13, - 7, 3, 3, 7, 0, 4, 15, 1, 1, 9, - 0, 1, 9, 1, 3, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 5, 5, 3, - 9, 3, 3, 3, 3, 3, 5, 1, 11, 1, - 11, 1, 9, 1, 2, 1, 11, 3, 1, 3, - 3, 1, 9, 0, 2, 3, 7, 1, 3, 7, - 7, 1, 3, 3, 7, 1, 9, 1, 3, 3, - 7, 3, 7, 3, 1, 11, 1, 9, 3, 7, - 0, 4, 3 }; + 0, 0, 1, 9, 4, 4, 4, 1, 9, 1, + 13, 11, 0, 6, 0, 2, 1, 4, 1, 4, + 17, 1, 17, 1, 13, 7, 3, 7, 0, 4, + 15, 1, 7, 0, 1, 9, 1, 3, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 5, 3, 3, 3, 3, 3, 3, 5, 1, + 11, 1, 11, 1, 9, 5, 3, 7, 7, 3, + 1, 3, 3, 1, 9, 1, 3, 3, 7, 1, + 5, 5, 1, 11, 0, 2, 3, 7, 7, 3, + 7, 3, 7, 3, 9, 7, 3, 3, 3, 7, + 1, 5, 3 }; int yychk[]={ - -1000, -1, -16, -19, -20, 271, 274, -17, -26, 273, - -18, 59, -27, 259, 263, 265, -6, -32, -7, 269, - -14, -42, 64, 273, -21, -28, -3, 40, 43, 45, - -7, 64, -14, 270, 272, 258, -32, 282, -30, -31, - 61, 44, -9, 273, -48, -49, -43, -41, 40, 260, - 61, 60, 62, 277, 278, 279, 43, 45, 42, 47, - 280, 275, 276, -3, -28, -28, -28, 40, -28, -28, - -24, -34, -5, -3, -14, -33, 44, 61, 91, 46, - 40, -15, 273, -22, -45, 273, -2, -28, -28, -28, - -28, -28, -28, -28, -28, -28, -28, -28, -2, -2, - 41, -38, -28, 264, 266, -25, 44, 273, -5, -28, - 273, -4, -5, -8, 123, 91, 41, 44, -24, -39, - -40, 41, -2, -28, -17, -35, -44, 93, 41, -10, - -11, -46, 273, -12, -13, -28, -23, 273, -2, -28, - -28, -24, -2, -18, -36, -37, -3, 125, 44, -47, - 93, 44, -24, -29, 261, 262, -2, 268, -46, 61, - -28, 267, 267, -24, -28, 267, -4, -28, 260, -18, - -2, -24, -2, -29 }; + -1000, -1, -17, -20, -21, -22, 270, 274, -18, -28, + 273, -19, 59, -29, 259, 263, 265, -6, -36, 269, + -14, -8, -15, -41, 273, -23, 58, -32, -3, 40, + 45, -40, -41, 271, 272, 258, -36, 283, -44, -14, + -34, -35, 61, 44, -10, 273, -7, 40, -40, 58, + 91, 46, -16, 40, 273, 260, 277, 60, 62, 278, + 279, 280, 43, 45, 42, 47, 94, 281, 275, 276, + -3, -32, -32, -32, 123, -32, -26, -37, -5, -3, + -14, -41, -11, 44, 61, -4, -5, 273, -32, 273, + -25, -46, 273, -24, -2, -32, -32, -32, -32, -32, + -32, -32, -32, -32, -32, -32, -32, -2, -2, 41, + -9, -13, -12, -32, -49, 273, 264, 266, -27, 44, + 273, -5, 41, 93, 41, 44, -16, -26, -42, -43, + 125, -47, 59, 44, -47, 44, 61, -2, -30, -31, + -18, -38, 268, -45, -26, 273, -2, -32, -32, -48, + -32, -49, 273, -32, -26, -2, -32, -19, -39, -3, + 267, -33, 261, 262, -12, -2, -4, 267, -26, -30, + -47, 267, -19, 260, -2, -26, -2, -33 }; int yydef[]={ - 1, -2, 11, 4, 5, 0, 102, 13, 0, 6, - 3, 14, 12, 0, 16, 18, 0, 21, 22, 0, - -2, 65, 61, 93, 0, 0, 34, 0, 0, 0, - 49, 61, -2, 52, 53, 54, 55, 0, 0, 27, - 0, 0, 100, 98, 0, 0, 0, 77, 73, 33, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 33, 33, 34, 0, 47, 48, 63, 56, 0, - 0, 9, 20, -2, -2, 23, 0, 0, 0, 0, - 68, 0, 78, 0, 74, 75, 27, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 57, 59, - 35, 0, 64, 33, 0, -2, 71, 99, 101, 0, - 97, 0, 69, 62, 81, 87, 7, 0, 33, 0, - 0, 50, 27, 33, 13, -2, 0, 95, 66, 0, - 82, 83, 85, 0, 88, 89, 27, 76, 24, 58, - 60, 33, 19, 10, 29, 0, -2, 79, 0, 0, - 80, 0, 0, 0, 27, 0, 0, 68, 84, 0, - 90, 8, 15, 25, 0, 17, 13, 86, 33, 32, - 27, 33, 24, 26 }; + 1, -2, 16, 4, 5, 6, 0, 102, 14, 0, + 7, 3, 15, 17, 63, 21, 23, 0, 26, 0, + -2, 63, 93, 66, 96, 0, 0, 0, 37, 63, + 63, 52, -2, 54, 55, 56, 57, 63, 0, 97, + 63, 31, 63, 0, 100, 98, 65, -2, 69, 0, + 63, 0, 8, 75, 9, 36, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, 36, 36, + 37, 0, 51, 58, -2, 0, 0, 12, 25, -2, + -2, 0, 27, 0, 63, 0, 71, 67, 0, 95, + 0, 76, 77, 0, 31, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 59, 61, 38, + 0, 84, 84, 89, 86, 96, 36, 18, -2, 73, + 99, 101, 68, 94, 31, 0, 10, 36, 63, 63, + 64, 80, 82, -2, 81, 85, 63, 31, 36, 63, + 14, 32, 34, 63, 0, 78, 28, 60, 62, 0, + 90, 87, 0, 88, 36, 24, 19, 13, -2, -2, + 11, 0, 31, 18, 84, 0, 14, 20, 29, 0, + 83, 22, 35, 36, 31, 36, 28, 30 }; typedef struct { char *t_name; int t_val; } yytoktype; #ifndef YYDEBUG # define YYDEBUG 0 /* don't allow debugging */ @@ -774,26 +882,27 @@ yytoktype yytoks[] = "END", 267, "RETURN", 268, "LOCAL", 269, - "NUMBER", 270, - "FUNCTION", 271, + "FUNCTION", 270, + "NUMBER", 271, "STRING", 272, "NAME", 273, "DEBUG", 274, "AND", 275, "OR", 276, - "=", 61, - "NE", 277, + "EQ", 277, + "NE", 278, ">", 62, "<", 60, - "LE", 278, - "GE", 279, - "CONC", 280, + "LE", 279, + "GE", 280, + "CONC", 281, "+", 43, "-", 45, "*", 42, "/", 47, - "UNARY", 281, - "NOT", 282, + "UNARY", 282, + "NOT", 283, + "^", 94, "-unknown-", -1 /* ends search */ }; @@ -804,38 +913,41 @@ char * yyreds[] = "functionlist : functionlist", "functionlist : functionlist stat sc", "functionlist : functionlist function", + "functionlist : functionlist method", "functionlist : functionlist setdebug", "function : FUNCTION NAME", - "function : FUNCTION NAME '(' parlist ')'", - "function : FUNCTION NAME '(' parlist ')' block END", + "function : FUNCTION NAME body", + "method : FUNCTION NAME ':' NAME", + "method : FUNCTION NAME ':' NAME body", + "body : '(' parlist ')' block END", "statlist : /* empty */", "statlist : statlist stat sc", - "stat : /* empty */", - "stat : stat1", "sc : /* empty */", "sc : ';'", + "stat : /* empty */", + "stat : stat1", + "cond : /* empty */", + "cond : expr1", "stat1 : IF expr1 THEN PrepJump block PrepJump elsepart END", "stat1 : WHILE", "stat1 : WHILE expr1 DO PrepJump block PrepJump END", "stat1 : REPEAT", - "stat1 : REPEAT block UNTIL expr1 PrepJump", + "stat1 : REPEAT block UNTIL cond PrepJump", "stat1 : varlist1 '=' exprlist1", "stat1 : functioncall", - "stat1 : typeconstructor", "stat1 : LOCAL localdeclist decinit", "elsepart : /* empty */", "elsepart : ELSE block", - "elsepart : ELSEIF expr1 THEN PrepJump block PrepJump elsepart", + "elsepart : ELSEIF cond THEN PrepJump block PrepJump elsepart", "block : /* empty */", - "block : statlist", "block : statlist ret", "ret : /* empty */", - "ret : /* empty */", + "ret : RETURN", "ret : RETURN exprlist sc", "PrepJump : /* empty */", "expr1 : expr", "expr : '(' expr ')'", - "expr : expr1 '=' expr1", + "expr : expr1 EQ expr1", "expr : expr1 '<' expr1", "expr : expr1 '>' expr1", "expr : expr1 NE expr1", @@ -845,12 +957,11 @@ char * yyreds[] = "expr : expr1 '-' expr1", "expr : expr1 '*' expr1", "expr : expr1 '/' expr1", + "expr : expr1 '^' expr1", "expr : expr1 CONC expr1", - "expr : '+' expr1", "expr : '-' expr1", - "expr : typeconstructor", - "expr : '@' '(' dimension ')'", - "expr : var", + "expr : table", + "expr : varexp", "expr : NUMBER", "expr : STRING", "expr : NIL", @@ -860,13 +971,13 @@ char * yyreds[] = "expr : expr1 AND PrepJump expr1", "expr : expr1 OR PrepJump", "expr : expr1 OR PrepJump expr1", - "typeconstructor : '@'", - "typeconstructor : '@' objectname fieldlist", - "dimension : /* empty */", - "dimension : expr1", - "functioncall : functionvalue", - "functioncall : functionvalue '(' exprlist ')'", - "functionvalue : var", + "table : /* empty */", + "table : '{' fieldlist '}'", + "functioncall : funcvalue funcParams", + "funcvalue : varexp", + "funcvalue : varexp ':' NAME", + "funcParams : '(' exprlist ')'", + "funcParams : table", "exprlist : /* empty */", "exprlist : exprlist1", "exprlist1 : expr", @@ -876,27 +987,25 @@ char * yyreds[] = "parlist : parlist1", "parlist1 : NAME", "parlist1 : parlist1 ',' NAME", - "objectname : /* empty */", - "objectname : NAME", - "fieldlist : '{' ffieldlist '}'", - "fieldlist : '[' lfieldlist ']'", - "ffieldlist : /* empty */", - "ffieldlist : ffieldlist1", + "fieldlist : /* empty */", + "fieldlist : lfieldlist1 lastcomma", + "fieldlist : ffieldlist1 lastcomma", + "fieldlist : lfieldlist1 ';'", + "fieldlist : lfieldlist1 ';' ffieldlist1 lastcomma", + "lastcomma : /* empty */", + "lastcomma : ','", "ffieldlist1 : ffield", "ffieldlist1 : ffieldlist1 ',' ffield", - "ffield : NAME", "ffield : NAME '=' expr1", - "lfieldlist : /* empty */", - "lfieldlist : lfieldlist1", "lfieldlist1 : expr1", "lfieldlist1 : lfieldlist1 ',' expr1", "varlist1 : var", "varlist1 : varlist1 ',' var", - "var : NAME", - "var : var", - "var : var '[' expr1 ']'", - "var : var", - "var : var '.' NAME", + "var : singlevar", + "var : varexp '[' expr1 ']'", + "var : varexp '.' NAME", + "singlevar : NAME", + "varexp : var", "localdeclist : NAME", "localdeclist : localdeclist ',' NAME", "decinit : /* empty */", @@ -904,19 +1013,22 @@ char * yyreds[] = "setdebug : DEBUG", }; #endif /* YYDEBUG */ -#line 1 "/usr/lib/yaccpar" +#line 1 "/usr/lang/SC1.0/yaccpar" /* @(#)yaccpar 1.10 89/04/04 SMI; from S5R3 1.10 */ /* ** Skeleton parser driver for yacc output */ +/* + @(#)RELEASE SC1.0 C++ 2.1 1Mar1991 +*/ /* ** yacc user known macros and defines */ #define YYERROR goto yyerrlab -#define YYACCEPT { free(yys); free(yyv); return(0); } -#define YYABORT { free(yys); free(yyv); return(1); } +#define YYACCEPT return(0) +#define YYABORT return(1) #define YYBACKUP( newtoken, newvalue )\ {\ if ( yychar >= 0 || ( yyr2[ yytmp ] >> 1 ) != 1 )\ @@ -930,10 +1042,24 @@ char * yyreds[] = goto yynewstate;\ } #define YYRECOVERING() (!!yyerrflag) +#define YYCOPY(to, from, type) \ + (type *) memcpy(to, (char *) from, yynewmax * sizeof(type)) #ifndef YYDEBUG # define YYDEBUG 1 /* make debugging available */ #endif + +/* +** extern declarations for C++ - check your own code for correctness +** if you have function redefined error messages here. +*/ + +#ifdef __cplusplus +EXTERN_FUNCTION ( extern int printf, (const char*, DOTDOTDOT) ); +EXTERN_FUNCTION ( extern void *memcpy, (void *, const void *, int) ); +#endif + + /* ** user known globals */ @@ -947,8 +1073,8 @@ int yydebug; /* set to 1 to get debugging */ /* ** static variables used by the parser */ -static YYSTYPE *yyv; /* value stack */ -static int *yys; /* state stack */ +static YYSTYPE yy_yyv[YYMAXDEPTH], *yyv = yy_yyv; /* value stack */ +static int yy_yys[YYMAXDEPTH], *yys = yy_yys; /* state stack */ static YYSTYPE *yypv; /* top of value stack */ static int *yyps; /* top of state stack */ @@ -956,10 +1082,20 @@ static int *yyps; /* top of state stack */ static int yystate; /* current state */ static int yytmp; /* 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. + 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 yyerrflag; /* error recovery flag */ int yychar; /* current input token number */ +static unsigned yymaxdepth = YYMAXDEPTH; /* @@ -968,19 +1104,12 @@ int yychar; /* current input token number */ int yyparse() { - register YYSTYPE *yypvt; /* top of value stack for $vars */ - unsigned yymaxdepth = YYMAXDEPTH; + register YYSTYPE *yypvt = (YYSTYPE*)0 ; /* top of value stack for +$vars */ /* ** Initialize externals - yyparse may be called more than once */ - yyv = (YYSTYPE*)malloc(yymaxdepth*sizeof(YYSTYPE)); - yys = (int*)malloc(yymaxdepth*sizeof(int)); - if (!yyv || !yys) - { - yyerror( "out of memory" ); - return(1); - } yypv = &yyv[-1]; yyps = &yys[-1]; yystate = 0; @@ -989,13 +1118,26 @@ yyparse() yyerrflag = 0; yychar = -1; - goto yystack; +#if defined(__cplusplus) || defined(__STDC__) || defined(lint) +/* + Note that the following can never be executed but simply to please + lint and C++ + */ + switch (__yaccpar_lint_hack__) + { + case 1: goto yyerrlab; + case 2: goto yynewstate; + } +#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 */ + goto yystack; + /* ** get globals into registers. ** branch to here only if YYBACKUP was called. @@ -1052,26 +1194,47 @@ yyparse() #endif /* YYDEBUG */ if ( ++yy_ps >= &yys[ yymaxdepth ] ) /* 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); - yymaxdepth += YYMAXDEPTH; - yyv = (YYSTYPE*)realloc((char*)yyv, - yymaxdepth * sizeof(YYSTYPE)); - yys = (int*)realloc((char*)yys, - yymaxdepth * sizeof(int)); - if (!yyv || !yys) + /* + ** 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; + + yynewmax = yymaxdepth + YYMAXDEPTH; + if (yymaxdepth == YYMAXDEPTH) /* first time growth */ + { + YYSTYPE *newyyv = (YYSTYPE*)malloc(yynewmax*sizeof(YYSTYPE)); + int *newyys = (int*)malloc(yynewmax*sizeof(int)); + if (newyys != 0 && newyyv != 0) + { + yys = YYCOPY(newyys, yys, int); + yyv = YYCOPY(newyyv, yyv, YYSTYPE); + } + else + yynewmax = 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 */ + } + if (yynewmax <= yymaxdepth) /* tables not expanded */ { yyerror( "yacc stack overflow" ); - return(1); + YYABORT; } - yy_ps = yys + yyps_index; - yy_pv = yyv + yypv_index; - yypvt = yyv + yypvt_index; + yymaxdepth = yynewmax; + + yy_ps = yys + yyps_index; + yy_pv = yyv + yypv_index; + yypvt = yyv + yypvt_index; } *yy_ps = yy_state; *++yy_pv = yyval; @@ -1292,7 +1455,7 @@ yyparse() yy_n, yyreds[ yy_n ] ); #endif yytmp = yy_n; /* value to switch over */ - yypvt = yy_pv; /* $vars top of value stack */ + yypvt = yy_pv; /* $vars top of value stack */ /* ** Look in goto table for next state ** Sorry about using yy_state here as temporary @@ -1345,466 +1508,393 @@ yyparse() { case 2: -# line 227 "lua.stx" +# line 411 "lua.stx" { - pc=maincode; basepc=initcode; maxcurr=maxmain; + pc=maincode; basepc=*initcode; maxcurr=maxmain; nlocalvar=0; } break; case 3: -# line 232 "lua.stx" +# line 416 "lua.stx" { - maincode=pc; initcode=basepc; maxmain=maxcurr; + maincode=pc; *initcode=basepc; maxmain=maxcurr; } break; -case 6: -# line 240 "lua.stx" -{ - if (code == NULL) /* first function */ - { - code = (Byte *) calloc(GAPCODE, sizeof(Byte)); - if (code == NULL) - { - lua_error("not enough memory"); - err = 1; - } - maxcode = GAPCODE; - } - pc=0; basepc=code; maxcurr=maxcode; - nlocalvar=0; - yyval.vWord = lua_findsymbol(yypvt[-0].pChar); - } break; case 7: -# line 256 "lua.stx" +# line 425 "lua.stx" { - if (lua_debug) - { - code_byte(SETFUNCTION); - code_word(lua_nfile-1); - code_word(yypvt[-3].vWord); - } - lua_codeadjust (0); + init_function(yypvt[-0].pNode); } break; case 8: -# line 267 "lua.stx" +# line 429 "lua.stx" { - if (lua_debug) code_byte(RESET); - code_byte(RETCODE); code_byte(nlocalvar); - s_tag(yypvt[-6].vWord) = T_FUNCTION; - s_bvalue(yypvt[-6].vWord) = calloc (pc, sizeof(Byte)); - if (s_bvalue(yypvt[-6].vWord) == NULL) - { - lua_error("not enough memory"); - err = 1; - } - memcpy (s_bvalue(yypvt[-6].vWord), basepc, pc*sizeof(Byte)); - code = basepc; maxcode=maxcurr; -#if LISTING -PrintCode(code,code+pc); -#endif + Word func = luaI_findsymbol(yypvt[-2].pNode); + s_tag(func) = LUA_T_FUNCTION; + s_bvalue(func) = yypvt[-0].pByte; } break; -case 11: -# line 289 "lua.stx" +case 9: +# line 437 "lua.stx" { - ntemp = 0; - if (lua_debug) - { - code_byte(SETLINE); code_word(lua_linenumber); - } - } break; -case 15: -# line 302 "lua.stx" + init_function(yypvt[-0].pNode); + localvar[nlocalvar]=luaI_findsymbolbyname("self"); + add_nlocalvar(1); + } break; +case 10: +# line 443 "lua.stx" { - { - Word elseinit = yypvt[-2].vWord+sizeof(Word)+1; - if (pc - elseinit == 0) /* no else */ - { - pc -= sizeof(Word)+1; - elseinit = pc; - } - else - { - basepc[yypvt[-2].vWord] = JMP; - code_word_at(basepc+yypvt[-2].vWord+1, pc - elseinit); - } - basepc[yypvt[-4].vWord] = IFFJMP; - code_word_at(basepc+yypvt[-4].vWord+1,elseinit-(yypvt[-4].vWord+sizeof(Word)+1)); - } - } break; + /* assign function to table field */ + pc=maincode; basepc=*initcode; maxcurr=maxmain; + nlocalvar=0; + lua_pushvar(luaI_findsymbol(yypvt[-4].pNode)+1); + code_byte(PUSHSTRING); + code_word(luaI_findconstant(yypvt[-2].pNode)); + code_byte(PUSHFUNCTION); + code_code(yypvt[-0].pByte); + code_byte(STOREINDEXED0); + maincode=pc; *initcode=basepc; maxmain=maxcurr; + } break; +case 11: +# line 458 "lua.stx" +{ + codereturn(); + yyval.pByte = newvector(pc, Byte); + memcpy(yyval.pByte, basepc, pc*sizeof(Byte)); + funcCode = basepc; maxcode=maxcurr; +#if LISTING + PrintCode(funcCode,funcCode+pc); +#endif + } break; case 16: -# line 320 "lua.stx" -{yyval.vWord=pc;} break; -case 17: -# line 322 "lua.stx" +# line 475 "lua.stx" +{ codedebugline(); } break; +case 18: +# line 477 "lua.stx" +{ codedebugline(); } break; +case 20: +# line 480 "lua.stx" +{ codeIf(yypvt[-4].vLong, yypvt[-2].vLong); } break; +case 21: +# line 482 "lua.stx" +{yyval.vLong=pc;} break; +case 22: +# line 483 "lua.stx" { - basepc[yypvt[-3].vWord] = IFFJMP; - code_word_at(basepc+yypvt[-3].vWord+1, pc - (yypvt[-3].vWord + sizeof(Word)+1)); - - basepc[yypvt[-1].vWord] = UPJMP; - code_word_at(basepc+yypvt[-1].vWord+1, pc - (yypvt[-6].vWord)); + basepc[yypvt[-3].vLong] = IFFJMP; + code_word_at(basepc+yypvt[-3].vLong+1, pc - (yypvt[-3].vLong + sizeof(Word)+1)); + basepc[yypvt[-1].vLong] = UPJMP; + code_word_at(basepc+yypvt[-1].vLong+1, pc - (yypvt[-6].vLong)); } break; -case 18: -# line 330 "lua.stx" -{yyval.vWord=pc;} break; -case 19: -# line 332 "lua.stx" +case 23: +# line 490 "lua.stx" +{yyval.vLong=pc;} break; +case 24: +# line 491 "lua.stx" { - basepc[yypvt[-0].vWord] = IFFUPJMP; - code_word_at(basepc+yypvt[-0].vWord+1, pc - (yypvt[-4].vWord)); + basepc[yypvt[-0].vLong] = IFFUPJMP; + code_word_at(basepc+yypvt[-0].vLong+1, pc - (yypvt[-4].vLong)); } break; -case 20: -# line 339 "lua.stx" +case 25: +# line 497 "lua.stx" { { int i; - if (yypvt[-0].vInt == 0 || nvarbuffer != ntemp - yypvt[-2].vInt * 2) - lua_codeadjust (yypvt[-2].vInt * 2 + nvarbuffer); + adjust_mult_assign(nvarbuffer, yypvt[-0].vInt, yypvt[-2].vInt * 2 + nvarbuffer); for (i=nvarbuffer-1; i>=0; i--) lua_codestore (i); if (yypvt[-2].vInt > 1 || (yypvt[-2].vInt == 1 && varbuffer[0] != 0)) lua_codeadjust (0); } } break; -case 21: -# line 350 "lua.stx" -{ lua_codeadjust (0); } break; -case 22: -# line 351 "lua.stx" -{ lua_codeadjust (0); } break; -case 23: -# line 352 "lua.stx" -{ add_nlocalvar(yypvt[-1].vInt); lua_codeadjust (0); } break; case 26: -# line 358 "lua.stx" -{ - { - Word elseinit = yypvt[-1].vWord+sizeof(Word)+1; - if (pc - elseinit == 0) /* no else */ - { - pc -= sizeof(Word)+1; - elseinit = pc; - } - else - { - basepc[yypvt[-1].vWord] = JMP; - code_word_at(basepc+yypvt[-1].vWord+1, pc - elseinit); - } - basepc[yypvt[-3].vWord] = IFFJMP; - code_word_at(basepc+yypvt[-3].vWord+1, elseinit - (yypvt[-3].vWord + sizeof(Word)+1)); - } - } break; +# line 507 "lua.stx" +{ code_byte(0); } break; case 27: -# line 377 "lua.stx" +# line 509 "lua.stx" +{ add_nlocalvar(yypvt[-1].vInt); + adjust_mult_assign(yypvt[-1].vInt, yypvt[-0].vInt, 0); + } break; +case 30: +# line 517 "lua.stx" +{ codeIf(yypvt[-3].vLong, yypvt[-1].vLong); } break; +case 31: +# line 520 "lua.stx" {yyval.vInt = nlocalvar;} break; -case 28: -# line 377 "lua.stx" -{ntemp = 0;} break; -case 29: -# line 378 "lua.stx" +case 32: +# line 521 "lua.stx" { - if (nlocalvar != yypvt[-3].vInt) + if (nlocalvar != yypvt[-2].vInt) { - nlocalvar = yypvt[-3].vInt; + nlocalvar = yypvt[-2].vInt; lua_codeadjust (0); } } break; -case 31: -# line 388 "lua.stx" -{ if (lua_debug){code_byte(SETLINE);code_word(lua_linenumber);}} break; -case 32: -# line 390 "lua.stx" -{ - if (lua_debug) code_byte(RESET); - code_byte(RETCODE); code_byte(nlocalvar); +case 34: +# line 531 "lua.stx" +{ codedebugline(); } break; +case 35: +# line 532 "lua.stx" +{ + if (yypvt[-1].vInt < 0) code_byte(MULT_RET); + codereturn(); } break; -case 33: -# line 397 "lua.stx" +case 36: +# line 539 "lua.stx" { - yyval.vWord = pc; + yyval.vLong = pc; code_byte(0); /* open space */ code_word (0); } break; -case 34: -# line 403 "lua.stx" -{ if (yypvt[-0].vInt == 0) {lua_codeadjust (ntemp+1); incr_ntemp();}} break; -case 35: -# line 406 "lua.stx" -{ yyval.vInt = yypvt[-1].vInt; } break; -case 36: -# line 407 "lua.stx" -{ code_byte(EQOP); yyval.vInt = 1; ntemp--;} break; case 37: -# line 408 "lua.stx" -{ code_byte(LTOP); yyval.vInt = 1; ntemp--;} break; +# line 545 "lua.stx" +{ if (yypvt[-0].vInt == 0) code_byte(1); } break; case 38: -# line 409 "lua.stx" -{ code_byte(LEOP); code_byte(NOTOP); yyval.vInt = 1; ntemp--;} break; +# line 548 "lua.stx" +{ yyval.vInt = yypvt[-1].vInt; } break; case 39: -# line 410 "lua.stx" -{ code_byte(EQOP); code_byte(NOTOP); yyval.vInt = 1; ntemp--;} break; +# line 549 "lua.stx" +{ code_byte(EQOP); yyval.vInt = 1; } break; case 40: -# line 411 "lua.stx" -{ code_byte(LEOP); yyval.vInt = 1; ntemp--;} break; +# line 550 "lua.stx" +{ code_byte(LTOP); yyval.vInt = 1; } break; case 41: -# line 412 "lua.stx" -{ code_byte(LTOP); code_byte(NOTOP); yyval.vInt = 1; ntemp--;} break; +# line 551 "lua.stx" +{ code_byte(GTOP); yyval.vInt = 1; } break; case 42: -# line 413 "lua.stx" -{ code_byte(ADDOP); yyval.vInt = 1; ntemp--;} break; +# line 552 "lua.stx" +{ code_byte(EQOP); code_byte(NOTOP); yyval.vInt = 1; } break; case 43: -# line 414 "lua.stx" -{ code_byte(SUBOP); yyval.vInt = 1; ntemp--;} break; +# line 553 "lua.stx" +{ code_byte(LEOP); yyval.vInt = 1; } break; case 44: -# line 415 "lua.stx" -{ code_byte(MULTOP); yyval.vInt = 1; ntemp--;} break; +# line 554 "lua.stx" +{ code_byte(GEOP); yyval.vInt = 1; } break; case 45: -# line 416 "lua.stx" -{ code_byte(DIVOP); yyval.vInt = 1; ntemp--;} break; +# line 555 "lua.stx" +{ code_byte(ADDOP); yyval.vInt = 1; } break; case 46: -# line 417 "lua.stx" -{ code_byte(CONCOP); yyval.vInt = 1; ntemp--;} break; +# line 556 "lua.stx" +{ code_byte(SUBOP); yyval.vInt = 1; } break; case 47: -# line 418 "lua.stx" -{ yyval.vInt = 1; } break; +# line 557 "lua.stx" +{ code_byte(MULTOP); yyval.vInt = 1; } break; case 48: -# line 419 "lua.stx" -{ code_byte(MINUSOP); yyval.vInt = 1;} break; +# line 558 "lua.stx" +{ code_byte(DIVOP); yyval.vInt = 1; } break; case 49: -# line 420 "lua.stx" -{ yyval.vInt = yypvt[-0].vInt; } break; +# line 559 "lua.stx" +{ code_byte(POWOP); yyval.vInt = 1; } break; case 50: -# line 422 "lua.stx" -{ - code_byte(CREATEARRAY); - yyval.vInt = 1; - } break; +# line 560 "lua.stx" +{ code_byte(CONCOP); yyval.vInt = 1; } break; case 51: -# line 426 "lua.stx" -{ lua_pushvar (yypvt[-0].vLong); yyval.vInt = 1;} break; +# line 561 "lua.stx" +{ code_byte(MINUSOP); yyval.vInt = 1;} break; case 52: -# line 427 "lua.stx" -{ code_number(yypvt[-0].vFloat); yyval.vInt = 1; } break; +# line 562 "lua.stx" +{ yyval.vInt = 1; } break; case 53: -# line 429 "lua.stx" +# line 563 "lua.stx" +{ yyval.vInt = 1;} break; +case 54: +# line 564 "lua.stx" +{ code_number(yypvt[-0].vFloat); yyval.vInt = 1; } break; +case 55: +# line 566 "lua.stx" { code_byte(PUSHSTRING); code_word(yypvt[-0].vWord); yyval.vInt = 1; - incr_ntemp(); - } break; -case 54: -# line 435 "lua.stx" -{code_byte(PUSHNIL); yyval.vInt = 1; incr_ntemp();} break; -case 55: -# line 437 "lua.stx" -{ - yyval.vInt = 0; - if (lua_debug) - { - code_byte(SETLINE); code_word(lua_linenumber); - } } break; case 56: -# line 444 "lua.stx" -{ code_byte(NOTOP); yyval.vInt = 1;} break; +# line 571 "lua.stx" +{code_byte(PUSHNIL); yyval.vInt = 1; } break; case 57: -# line 445 "lua.stx" -{code_byte(POP); ntemp--;} break; +# line 572 "lua.stx" +{ yyval.vInt = 0; } break; case 58: -# line 446 "lua.stx" -{ - basepc[yypvt[-2].vWord] = ONFJMP; - code_word_at(basepc+yypvt[-2].vWord+1, pc - (yypvt[-2].vWord + sizeof(Word)+1)); - yyval.vInt = 1; - } break; +# line 573 "lua.stx" +{ code_byte(NOTOP); yyval.vInt = 1;} break; case 59: -# line 451 "lua.stx" -{code_byte(POP); ntemp--;} break; +# line 574 "lua.stx" +{code_byte(POP); } break; case 60: -# line 452 "lua.stx" +# line 575 "lua.stx" { - basepc[yypvt[-2].vWord] = ONTJMP; - code_word_at(basepc+yypvt[-2].vWord+1, pc - (yypvt[-2].vWord + sizeof(Word)+1)); + basepc[yypvt[-2].vLong] = ONFJMP; + code_word_at(basepc+yypvt[-2].vLong+1, pc - (yypvt[-2].vLong + sizeof(Word)+1)); yyval.vInt = 1; } break; case 61: -# line 460 "lua.stx" +# line 580 "lua.stx" +{code_byte(POP); } break; +case 62: +# line 581 "lua.stx" +{ + basepc[yypvt[-2].vLong] = ONTJMP; + code_word_at(basepc+yypvt[-2].vLong+1, pc - (yypvt[-2].vLong + sizeof(Word)+1)); + yyval.vInt = 1; + } break; +case 63: +# line 589 "lua.stx" { - code_byte(PUSHBYTE); - yyval.vWord = pc; code_byte(0); - incr_ntemp(); code_byte(CREATEARRAY); + yyval.vLong = pc; code_word(0); } break; -case 62: -# line 467 "lua.stx" +case 64: +# line 594 "lua.stx" { - basepc[yypvt[-2].vWord] = yypvt[-0].vInt; - if (yypvt[-1].vLong < 0) /* there is no function to be called */ - { - yyval.vInt = 1; - } - else - { - lua_pushvar (yypvt[-1].vLong+1); - code_byte(PUSHMARK); - incr_ntemp(); - code_byte(PUSHOBJECT); - incr_ntemp(); - code_byte(CALLFUNC); - ntemp -= 4; - yyval.vInt = 0; - if (lua_debug) - { - code_byte(SETLINE); code_word(lua_linenumber); - } - } + code_word_at(basepc+yypvt[-3].vLong, yypvt[-1].vInt); } break; -case 63: -# line 491 "lua.stx" -{ code_byte(PUSHNIL); incr_ntemp();} break; case 65: -# line 495 "lua.stx" -{code_byte(PUSHMARK); yyval.vInt = ntemp; incr_ntemp();} break; +# line 600 "lua.stx" +{ code_byte(CALLFUNC); code_byte(yypvt[-1].vInt+yypvt[-0].vInt); } break; case 66: -# line 496 "lua.stx" -{ code_byte(CALLFUNC); ntemp = yypvt[-3].vInt-1;} break; +# line 603 "lua.stx" +{ yyval.vInt = 0; } break; case 67: -# line 498 "lua.stx" -{lua_pushvar (yypvt[-0].vLong); } break; +# line 605 "lua.stx" +{ + code_byte(PUSHSELF); + code_word(luaI_findconstant(yypvt[-0].pNode)); + yyval.vInt = 1; + } break; case 68: -# line 501 "lua.stx" -{ yyval.vInt = 1; } break; +# line 613 "lua.stx" +{ if (yypvt[-1].vInt<0) { code_byte(1); yyval.vInt = -yypvt[-1].vInt; } else yyval.vInt = yypvt[-1].vInt; } break; case 69: -# line 502 "lua.stx" -{ yyval.vInt = yypvt[-0].vInt; } break; +# line 614 "lua.stx" +{ yyval.vInt = 1; } break; case 70: -# line 505 "lua.stx" -{ yyval.vInt = yypvt[-0].vInt; } break; +# line 617 "lua.stx" +{ yyval.vInt = 0; } break; case 71: -# line 506 "lua.stx" -{if (!yypvt[-1].vInt){lua_codeadjust (ntemp+1); incr_ntemp();}} break; +# line 618 "lua.stx" +{ yyval.vInt = yypvt[-0].vInt; } break; case 72: -# line 507 "lua.stx" -{yyval.vInt = yypvt[-0].vInt;} break; +# line 621 "lua.stx" +{ if (yypvt[-0].vInt == 0) yyval.vInt = -1; else yyval.vInt = 1; } break; +case 73: +# line 622 "lua.stx" +{ if (yypvt[-1].vInt < 0) code_byte(1); } break; +case 74: +# line 623 "lua.stx" +{ + int r = yypvt[-3].vInt < 0 ? -yypvt[-3].vInt : yypvt[-3].vInt; + yyval.vInt = (yypvt[-0].vInt == 0) ? -(r+1) : r+1; + } break; case 75: -# line 515 "lua.stx" +# line 629 "lua.stx" +{ lua_codeadjust(0); } break; +case 76: +# line 630 "lua.stx" +{ lua_codeadjust(0); } break; +case 77: +# line 634 "lua.stx" { - localvar[nlocalvar]=lua_findsymbol(yypvt[-0].pChar); + localvar[nlocalvar]=luaI_findsymbol(yypvt[-0].pNode); add_nlocalvar(1); } break; -case 76: -# line 520 "lua.stx" +case 78: +# line 639 "lua.stx" { - localvar[nlocalvar]=lua_findsymbol(yypvt[-0].pChar); + localvar[nlocalvar]=luaI_findsymbol(yypvt[-0].pNode); add_nlocalvar(1); } break; -case 77: -# line 526 "lua.stx" -{yyval.vLong=-1;} break; -case 78: -# line 527 "lua.stx" -{yyval.vLong=lua_findsymbol(yypvt[-0].pChar);} break; case 79: -# line 531 "lua.stx" -{ - flush_record(yypvt[-1].vInt%FIELDS_PER_FLUSH); - yyval.vInt = yypvt[-1].vInt; - } break; +# line 645 "lua.stx" +{ yyval.vInt = 0; } break; case 80: -# line 536 "lua.stx" -{ - flush_list(yypvt[-1].vInt/FIELDS_PER_FLUSH, yypvt[-1].vInt%FIELDS_PER_FLUSH); - yyval.vInt = yypvt[-1].vInt; - } break; +# line 647 "lua.stx" +{ yyval.vInt = yypvt[-1].vInt; flush_list(yypvt[-1].vInt/FIELDS_PER_FLUSH, yypvt[-1].vInt%FIELDS_PER_FLUSH); } break; case 81: -# line 542 "lua.stx" -{ yyval.vInt = 0; } break; +# line 649 "lua.stx" +{ yyval.vInt = yypvt[-1].vInt; flush_record(yypvt[-1].vInt%FIELDS_PER_FLUSH); } break; case 82: -# line 543 "lua.stx" -{ yyval.vInt = yypvt[-0].vInt; } break; +# line 651 "lua.stx" +{ flush_list(yypvt[-1].vInt/FIELDS_PER_FLUSH, yypvt[-1].vInt%FIELDS_PER_FLUSH); } break; case 83: -# line 546 "lua.stx" +# line 653 "lua.stx" +{ yyval.vInt = yypvt[-4].vInt+yypvt[-1].vInt; flush_record(yypvt[-1].vInt%FIELDS_PER_FLUSH); } break; +case 86: +# line 660 "lua.stx" {yyval.vInt=1;} break; -case 84: -# line 548 "lua.stx" +case 87: +# line 662 "lua.stx" { yyval.vInt=yypvt[-2].vInt+1; if (yyval.vInt%FIELDS_PER_FLUSH == 0) flush_record(FIELDS_PER_FLUSH); } break; -case 85: -# line 554 "lua.stx" -{yyval.vWord = lua_findconstant(yypvt[-0].pChar);} break; -case 86: -# line 555 "lua.stx" +case 88: +# line 669 "lua.stx" { - push_field(yypvt[-2].vWord); + push_field(luaI_findconstant(yypvt[-2].pNode)); } break; -case 87: -# line 560 "lua.stx" -{ yyval.vInt = 0; } break; -case 88: -# line 561 "lua.stx" -{ yyval.vInt = yypvt[-0].vInt; } break; case 89: -# line 564 "lua.stx" +# line 674 "lua.stx" {yyval.vInt=1;} break; case 90: -# line 566 "lua.stx" +# line 676 "lua.stx" { yyval.vInt=yypvt[-2].vInt+1; if (yyval.vInt%FIELDS_PER_FLUSH == 0) flush_list(yyval.vInt/FIELDS_PER_FLUSH - 1, FIELDS_PER_FLUSH); } break; case 91: -# line 574 "lua.stx" +# line 684 "lua.stx" { nvarbuffer = 0; varbuffer[nvarbuffer] = yypvt[-0].vLong; incr_nvarbuffer(); yyval.vInt = (yypvt[-0].vLong == 0) ? 1 : 0; } break; case 92: -# line 580 "lua.stx" +# line 690 "lua.stx" { varbuffer[nvarbuffer] = yypvt[-0].vLong; incr_nvarbuffer(); yyval.vInt = (yypvt[-0].vLong == 0) ? yypvt[-2].vInt + 1 : yypvt[-2].vInt; } break; case 93: -# line 587 "lua.stx" +# line 696 "lua.stx" +{ yyval.vLong = yypvt[-0].vLong; } break; +case 94: +# line 698 "lua.stx" { - Word s = lua_findsymbol(yypvt[-0].pChar); - int local = lua_localname (s); - if (local == -1) /* global var */ - yyval.vLong = s + 1; /* return positive value */ - else - yyval.vLong = -(local+1); /* return negative value */ + yyval.vLong = 0; /* indexed variable */ } break; -case 94: -# line 596 "lua.stx" -{lua_pushvar (yypvt[-0].vLong);} break; case 95: -# line 597 "lua.stx" +# line 702 "lua.stx" { + code_byte(PUSHSTRING); + code_word(luaI_findconstant(yypvt[-0].pNode)); yyval.vLong = 0; /* indexed variable */ } break; case 96: -# line 600 "lua.stx" -{lua_pushvar (yypvt[-0].vLong);} break; -case 97: -# line 601 "lua.stx" +# line 710 "lua.stx" { - code_byte(PUSHSTRING); - code_word(lua_findconstant(yypvt[-0].pChar)); incr_ntemp(); - yyval.vLong = 0; /* indexed variable */ + Word s = luaI_findsymbol(yypvt[-0].pNode); + int local = lua_localname (s); + if (local == -1) /* global var */ + yyval.vLong = s + 1; /* return positive value */ + else + yyval.vLong = -(local+1); /* return negative value */ } break; +case 97: +# line 720 "lua.stx" +{ lua_pushvar(yypvt[-0].vLong); } break; case 98: -# line 608 "lua.stx" -{localvar[nlocalvar]=lua_findsymbol(yypvt[-0].pChar); yyval.vInt = 1;} break; +# line 723 "lua.stx" +{localvar[nlocalvar]=luaI_findsymbol(yypvt[-0].pNode); yyval.vInt = 1;} break; case 99: -# line 610 "lua.stx" +# line 725 "lua.stx" { - localvar[nlocalvar+yypvt[-2].vInt]=lua_findsymbol(yypvt[-0].pChar); + localvar[nlocalvar+yypvt[-2].vInt]=luaI_findsymbol(yypvt[-0].pNode); yyval.vInt = yypvt[-2].vInt+1; } break; +case 100: +# line 731 "lua.stx" +{ yyval.vInt = 0; } break; +case 101: +# line 732 "lua.stx" +{ yyval.vInt = yypvt[-0].vInt; } break; case 102: -# line 620 "lua.stx" +# line 735 "lua.stx" {lua_debug = yypvt[-0].vInt;} break; } goto yystack; /* reset registers in driver code */ diff --git a/src/y.tab.h b/src/parser.h index 5bee29f9..4c125dad 100644 --- a/src/y.tab.h +++ b/src/parser.h @@ -2,11 +2,12 @@ typedef union { int vInt; - long vLong; float vFloat; char *pChar; Word vWord; + Long vLong; Byte *pByte; + TreeNode *pNode; } YYSTYPE; extern YYSTYPE yylval; # define WRONGTOKEN 257 @@ -22,16 +23,17 @@ extern YYSTYPE yylval; # define END 267 # define RETURN 268 # define LOCAL 269 -# define NUMBER 270 -# define FUNCTION 271 +# define FUNCTION 270 +# define NUMBER 271 # define STRING 272 # define NAME 273 # define DEBUG 274 # define AND 275 # define OR 276 -# define NE 277 -# define LE 278 -# define GE 279 -# define CONC 280 -# define UNARY 281 -# define NOT 282 +# define EQ 277 +# define NE 278 +# define LE 279 +# define GE 280 +# define CONC 281 +# define UNARY 282 +# define NOT 283 diff --git a/src/table.c b/src/table.c index 7b93df76..cedbf31c 100644 --- a/src/table.c +++ b/src/table.c @@ -3,159 +3,144 @@ ** Module to control static tables */ -char *rcs_table="$Id: table.c,v 2.1 1994/04/20 22:07:57 celes Exp $"; +char *rcs_table="$Id: table.c,v 2.28 1995/01/18 20:15:54 celes Exp $"; -#include <stdlib.h> #include <string.h> -#include "mm.h" - +#include "mem.h" #include "opcode.h" +#include "tree.h" #include "hash.h" #include "inout.h" #include "table.h" #include "lua.h" +#include "fallback.h" + + +#define BUFFER_BLOCK 256 + +Symbol *lua_table; +static Word lua_ntable = 0; +static Long lua_maxsymbol = 0; + +TaggedString **lua_constant; +static Word lua_nconstant = 0; +static Long lua_maxconstant = 0; + -#define streq(s1,s2) (s1[0]==s2[0]&&strcmp(s1+1,s2+1)==0) - -#ifndef MAXSYMBOL -#define MAXSYMBOL 512 -#endif -static Symbol tablebuffer[MAXSYMBOL] = { - {"type",{T_CFUNCTION,{lua_type}}}, - {"tonumber",{T_CFUNCTION,{lua_obj2number}}}, - {"next",{T_CFUNCTION,{lua_next}}}, - {"nextvar",{T_CFUNCTION,{lua_nextvar}}}, - {"print",{T_CFUNCTION,{lua_print}}}, - {"dofile",{T_CFUNCTION,{lua_internaldofile}}}, - {"dostring",{T_CFUNCTION,{lua_internaldostring}}} - }; -Symbol *lua_table=tablebuffer; -Word lua_ntable=7; - -struct List -{ - Symbol *s; - struct List *next; -}; - -static struct List o6={ tablebuffer+6, 0}; -static struct List o5={ tablebuffer+5, &o6 }; -static struct List o4={ tablebuffer+4, &o5 }; -static struct List o3={ tablebuffer+3, &o4 }; -static struct List o2={ tablebuffer+2, &o3 }; -static struct List o1={ tablebuffer+1, &o2 }; -static struct List o0={ tablebuffer+0, &o1 }; -static struct List *searchlist=&o0; - -#ifndef MAXCONSTANT -#define MAXCONSTANT 256 -#endif -/* pre-defined constants need garbage collection extra byte */ -static char tm[] = " mark"; -static char ti[] = " nil"; -static char tn[] = " number"; -static char ts[] = " string"; -static char tt[] = " table"; -static char tf[] = " function"; -static char tc[] = " cfunction"; -static char tu[] = " userdata"; -static char *constantbuffer[MAXCONSTANT] = {tm+1, ti+1, - tn+1, ts+1, - tt+1, tf+1, - tc+1, tu+1 - }; -char **lua_constant = constantbuffer; -Word lua_nconstant=T_USERDATA+1; - -#ifndef MAXSTRING -#define MAXSTRING 512 -#endif -static char *stringbuffer[MAXSTRING]; -char **lua_string = stringbuffer; -Word lua_nstring=0; #define MAXFILE 20 char *lua_file[MAXFILE]; int lua_nfile; +#define GARBAGE_BLOCK 256 +#define MIN_GARBAGE_BLOCK 10 -#define markstring(s) (*((s)-1)) +static void lua_nextvar (void); +static void setglobal (void); +static void getglobal (void); + +/* +** Initialise symbol table with internal functions +*/ +static void lua_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; +} -/* Variables to controll garbage collection */ -Word lua_block=10; /* to check when garbage collector will be called */ -Word lua_nentity; /* counter of new entities (strings and arrays) */ +/* +** Initialise constant table with pre-defined constants +*/ +void lua_initconstant (void) +{ + lua_maxconstant = BUFFER_BLOCK; + lua_constant = newvector(lua_maxconstant, TaggedString *); +} /* ** Given a name, search it at symbol table and return its index. If not -** found, allocate at end of table, checking oveflow and return its index. -** On error, return -1. +** found, allocate it. */ -int lua_findsymbol (char *s) +Word luaI_findsymbol (TreeNode *t) { - struct List *l, *p; - for (p=NULL, l=searchlist; l!=NULL; p=l, l=l->next) - if (streq(s,l->s->name)) + if (lua_table == NULL) + lua_initsymbol(); + if (t->varindex == NOT_USED) + { + if (lua_ntable == lua_maxsymbol) { - if (p!=NULL) - { - p->next = l->next; - l->next = searchlist; - searchlist = l; - } - return (l->s-lua_table); + 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); } - - if (lua_ntable >= MAXSYMBOL-1) - { - lua_error ("symbol table overflow"); - return -1; + t->varindex = lua_ntable; + s_tag(lua_ntable) = LUA_T_NIL; + lua_ntable++; } - s_name(lua_ntable) = strdup(s); - if (s_name(lua_ntable) == NULL) - { - lua_error ("not enough memory"); - return -1; - } - s_tag(lua_ntable) = T_NIL; - p = malloc(sizeof(*p)); - p->s = lua_table+lua_ntable; - p->next = searchlist; - searchlist = p; + return t->varindex; +} - return lua_ntable++; + +Word luaI_findsymbolbyname (char *name) +{ + return luaI_findsymbol(lua_constcreate(name)); } + /* -** Given a constant string, search it at constant table and return its index. -** If not found, allocate at end of the table, checking oveflow and return -** its index. -** -** For each allocation, the function allocate a extra char to be used to -** mark used string (it's necessary to deal with constant and string -** uniformily). The function store at the table the second position allocated, -** that represents the beginning of the real string. On error, return -1. -** +** Given a name, search it at constant table and return its index. If not +** found, allocate it. +** On error, return -1. */ -int lua_findconstant (char *s) +Word luaI_findconstant (TreeNode *t) { - int i; - for (i=0; i<lua_nconstant; i++) - if (streq(s,lua_constant[i])) - return i; - if (lua_nconstant >= MAXCONSTANT-1) + if (lua_constant == NULL) + lua_initconstant(); + if (t->constindex == NOT_USED) { - lua_error ("lua: constant string table overflow"); - return -1; - } - { - char *c = calloc(strlen(s)+2,sizeof(char)); - c++; /* create mark space */ - lua_constant[lua_nconstant++] = strcpy(c,s); + 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 *); + } + t->constindex = lua_nconstant; + lua_constant[lua_nconstant] = &(t->ts); + lua_nconstant++; } - return (lua_nconstant-1); + return t->constindex; } @@ -164,7 +149,7 @@ int lua_findconstant (char *s) */ void lua_travsymbol (void (*fn)(Object *)) { - int i; + Word i; for (i=0; i<lua_ntable; i++) fn(&s_object(i)); } @@ -175,9 +160,9 @@ void lua_travsymbol (void (*fn)(Object *)) */ void lua_markobject (Object *o) { - if (tag(o) == T_STRING) - markstring (svalue(o)) = 1; - else if (tag(o) == T_ARRAY) + if (tag(o) == LUA_T_STRING && !tsvalue(o)->marked) + tsvalue(o)->marked = 1; + else if (tag(o) == LUA_T_ARRAY) lua_hashmark (avalue(o)); } @@ -188,87 +173,33 @@ void lua_markobject (Object *o) */ void lua_pack (void) { - /* mark stack strings */ - lua_travstack(lua_markobject); - - /* mark symbol table strings */ - lua_travsymbol(lua_markobject); - - lua_stringcollector(); - lua_hashcollector(); - - lua_nentity = 0; /* reset counter */ + 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 */ + recovered += lua_strcollector(); + recovered += lua_hashcollector(); + nentity = 0; /* reset counter */ + block=(16*block-7*recovered)/12; /* adapt block size */ + if (block < MIN_GARBAGE_BLOCK) block = MIN_GARBAGE_BLOCK; } -/* -** Garbage collection to atrings. -** Delete all unmarked strings -*/ -void lua_stringcollector (void) -{ - int i, j; - for (i=j=0; i<lua_nstring; i++) - if (markstring(lua_string[i]) == 1) - { - lua_string[j++] = lua_string[i]; - markstring(lua_string[i]) = 0; - } - else - { - free (lua_string[i]-1); - } - lua_nstring = j; -} - -/* -** Allocate a new string at string table. The given string is already -** allocated with mark space and the function puts it at the end of the -** table, checking overflow, and returns its own pointer, or NULL on error. -*/ -char *lua_createstring (char *s) -{ - int i; - if (s == NULL) return NULL; - - for (i=0; i<lua_nstring; i++) - if (streq(s,lua_string[i])) - { - free(s-1); - return lua_string[i]; - } - - if (lua_nentity == lua_block || lua_nstring >= MAXSTRING-1) - { - lua_pack (); - if (lua_nstring >= MAXSTRING-1) - { - lua_error ("string table overflow"); - return NULL; - } - } - lua_string[lua_nstring++] = s; - lua_nentity++; - return s; -} /* ** Add a file name at file table, checking overflow. This function also set ** the external variable "lua_filename" with the function filename set. -** Return 0 on success or 1 on error. +** Return 0 on success or error message on error. */ -int lua_addfile (char *fn) +char *lua_addfile (char *fn) { - if (lua_nfile >= MAXFILE-1) - { - lua_error ("too many files"); - return 1; - } - if ((lua_file[lua_nfile++] = strdup (fn)) == NULL) - { - lua_error ("not enough memory"); - return 1; - } - return 0; + if (lua_nfile >= MAXFILE) + return "too many files"; + if ((lua_file[lua_nfile++] = luaI_strdup (fn)) == NULL) + return "not enough memory"; + return NULL; } /* @@ -276,7 +207,7 @@ int lua_addfile (char *fn) */ int lua_delfile (void) { - lua_nfile--; + luaI_free(lua_file[--lua_nfile]); return 1; } @@ -291,47 +222,56 @@ char *lua_filename (void) /* ** Internal function: return next global variable */ -void lua_nextvar (void) +static void lua_nextvar (void) { - int index; - Object *o = lua_getparam (1); - if (o == NULL) - { lua_error ("too few arguments to function `nextvar'"); return; } - if (lua_getparam (2) != NULL) - { lua_error ("too many arguments to function `nextvar'"); return; } - if (tag(o) == T_NIL) + char *varname; + TreeNode *next; + lua_Object o = lua_getparam(1); + if (o == LUA_NOOBJECT) + lua_reportbug("too few arguments to function `nextvar'"); + if (lua_getparam(2) != LUA_NOOBJECT) + lua_reportbug("too many arguments to function `nextvar'"); + if (lua_isnil(o)) + varname = NULL; + else if (!lua_isstring(o)) { - index = 0; - } - else if (tag(o) != T_STRING) - { - lua_error ("incorrect argument to function `nextvar'"); - return; + lua_reportbug("incorrect argument to function `nextvar'"); + return; /* to avoid warnings */ } else + varname = lua_getstring(o); + next = lua_varnext(varname); + if (next == NULL) { - for (index=0; index<lua_ntable; index++) - if (streq(s_name(index),svalue(o))) break; - if (index == lua_ntable) - { - lua_error ("name not found in function `nextvar'"); - return; - } - index++; - while (index < lua_ntable && tag(&s_object(index)) == T_NIL) index++; - - if (index == lua_ntable) - { - lua_pushnil(); - lua_pushnil(); - return; - } + lua_pushnil(); + lua_pushnil(); } + else { Object name; - tag(&name) = T_STRING; - svalue(&name) = lua_createstring(lua_strdup(s_name(index))); - if (lua_pushobject (&name)) return; - if (lua_pushobject (&s_object(index))) return; + tag(&name) = LUA_T_STRING; + tsvalue(&name) = &(next->ts); + luaI_pushobject(&name); + luaI_pushobject(&s_object(next->varindex)); } } + + +static void setglobal (void) +{ + lua_Object name = lua_getparam(1); + lua_Object value = lua_getparam(2); + if (!lua_isstring(name)) + lua_reportbug("incorrect argument to function `setglobal'"); + lua_pushobject(value); + lua_storeglobal(lua_getstring(name)); +} + + +static void getglobal (void) +{ + lua_Object name = lua_getparam(1); + if (!lua_isstring(name)) + lua_reportbug("incorrect argument to function `getglobal'"); + lua_pushobject(lua_getglobal(lua_getstring(name))); +} diff --git a/src/table.h b/src/table.h index a1da6639..c25075c0 100644 --- a/src/table.h +++ b/src/table.h @@ -1,42 +1,31 @@ /* ** Module to control static tables ** TeCGraf - PUC-Rio -** $Id: table.h,v 2.1 1994/04/20 22:07:57 celes Exp $ +** $Id: table.h,v 2.10 1994/12/20 21:20:36 roberto Exp $ */ #ifndef table_h #define table_h -extern Symbol *lua_table; -extern Word lua_ntable; - -extern char **lua_constant; -extern Word lua_nconstant; - -extern char **lua_string; -extern Word lua_nstring; +#include "tree.h" +#include "opcode.h" -extern Hash **lua_array; -extern Word lua_narray; +extern Symbol *lua_table; +extern TaggedString **lua_constant; extern char *lua_file[]; extern int lua_nfile; -extern Word lua_block; -extern Word lua_nentity; - - -int lua_findsymbol (char *s); -int lua_findconstant (char *s); +void lua_initconstant (void); +Word luaI_findsymbolbyname (char *name); +Word luaI_findsymbol (TreeNode *t); +Word luaI_findconstant (TreeNode *t); void lua_travsymbol (void (*fn)(Object *)); void lua_markobject (Object *o); void lua_pack (void); -void lua_stringcollector (void); -char *lua_createstring (char *s); -int lua_addfile (char *fn); +char *lua_addfile (char *fn); int lua_delfile (void); char *lua_filename (void); -void lua_nextvar (void); #endif diff --git a/src/tree.c b/src/tree.c new file mode 100644 index 00000000..5dd9d78e --- /dev/null +++ b/src/tree.c @@ -0,0 +1,141 @@ +/* +** tree.c +** TecCGraf - PUC-Rio +*/ + +char *rcs_tree="$Id: tree.c,v 1.13 1995/01/12 14:19:04 roberto Exp $"; + + +#include <string.h> + +#include "mem.h" +#include "lua.h" +#include "tree.h" +#include "table.h" + + +#define lua_strcmp(a,b) (a[0]<b[0]?(-1):(a[0]>b[0]?(1):strcmp(a,b))) + + +typedef struct StringNode { + struct StringNode *next; + TaggedString ts; +} StringNode; + +static StringNode *string_root = NULL; + +static TreeNode *constant_root = NULL; + +/* +** Insert a new constant/variable at the tree. +*/ +static TreeNode *tree_create (TreeNode **node, 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; + } +} + +TaggedString *lua_createstring (char *str) +{ + 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); +} + + +TreeNode *lua_constcreate (char *str) +{ + return tree_create(&constant_root, str); +} + + +/* +** Garbage collection function. +** This function traverse the string list freeing unindexed strings +*/ +Long lua_strcollector (void) +{ + StringNode *curr = string_root, *prev = NULL; + Long counter = 0; + while (curr) + { + StringNode *next = curr->next; + if (!curr->ts.marked) + { + if (prev == NULL) string_root = next; + else prev->next = next; + luaI_free(curr); + ++counter; + } + else + { + curr->ts.marked = 0; + prev = curr; + } + curr = next; + } + return counter; +} + +/* +** Return next variable. +*/ +static TreeNode *tree_next (TreeNode *node, char *str) +{ + if (node == NULL) return NULL; + else if (str == NULL) return node; + else + { + int c = lua_strcmp(str, node->ts.str); + if (c == 0) + return node->left != NULL ? node->left : node->right; + else if (c < 0) + { + TreeNode *result = tree_next(node->left, str); + return result != NULL ? result : node->right; + } + else + return tree_next(node->right, str); + } +} + +TreeNode *lua_varnext (char *n) +{ + TreeNode *result; + char *name = n; + while (1) + { /* repeat until a valid (non nil) variable */ + result = tree_next(constant_root, name); + if (result == NULL) return NULL; + if (result->varindex != NOT_USED && + s_tag(result->varindex) != LUA_T_NIL) + return result; + name = result->ts.str; + } +} + diff --git a/src/tree.h b/src/tree.h new file mode 100644 index 00000000..849cd5a9 --- /dev/null +++ b/src/tree.h @@ -0,0 +1,37 @@ +/* +** tree.h +** TecCGraf - PUC-Rio +** $Id: tree.h,v 1.9 1995/01/12 14:19:04 roberto Exp $ +*/ + +#ifndef tree_h +#define tree_h + +#include "types.h" + +#define NOT_USED 0xFFFE + + +typedef struct TaggedString +{ + unsigned long hash; /* 0 if not initialized */ + char marked; /* for garbage collection */ + 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 *lua_varnext (char *n); + +#endif diff --git a/src/types.h b/src/types.h new file mode 100644 index 00000000..43684228 --- /dev/null +++ b/src/types.h @@ -0,0 +1,31 @@ +/* +** TeCGraf - PUC-Rio +** $Id: types.h,v 1.3 1995/02/06 19:32:43 roberto Exp $ +*/ + +#ifndef types_h +#define types_h + +#include <limits.h> + +#ifndef real +#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 */ + +#define Word lua_Word /* some systems have Word as a predefined type */ +typedef unsigned short Word; /* unsigned 16 bits */ + +#define MAX_WORD (USHRT_MAX-2) /* maximum value of a word (-2 for safety) */ +#define MAX_INT (INT_MAX-2) /* maximum value of a int (-2 for safety) */ + +#define Long lua_Long /* some systems have Long as a predefined type */ +typedef signed long Long; /* 32 bits */ + +typedef unsigned int IntPoint; /* unsigned with same size as a pointer (for hashing) */ + +#endif diff --git a/src/ugly.h b/src/ugly.h new file mode 100644 index 00000000..c7512255 --- /dev/null +++ b/src/ugly.h @@ -0,0 +1,36 @@ +/* +** 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/yacc/Makefile b/src/yacc/Makefile index 1d887e10..284d4ab5 100644 --- a/src/yacc/Makefile +++ b/src/yacc/Makefile @@ -1,27 +1,3 @@ -# makefile for lua - -LIB= $(LUA)/lib -INC= $(LUA)/inc - -CC= gcc -CFLAGS= -g -Wall -O2 -I$(INC) $(DEFS) -DEFS= -DMAXCODE=64000 -DMAXCONSTANT=1024 -DMAXSYMBOL=1024 -DMAXARRAY=1024 - -OBJS= hash.o inout.o lex.o opcode.o table.o y.tab.o -SLIB= $(LIB)/lua.a -DLIB= $(LIB)/liblua.so.1.1 - -libs: $(SLIB) $(DLIB) - -$(SLIB): y.tab.c $(OBJS) - ar ruvl $@ $(OBJS) - ranlib $(SLIB) - -$(DLIB): $(OBJS) - ld -o $@ $(OBJS) - -y.tab.c: lua.stx exscript - yacc -d lua.stx ; ex y.tab.c <exscript - -clean: - rm -f $(OBJS) $(SLIB) $(DLIB) +parser.c: + co -M lua.stx + yacc -d lua.stx ; mv -f y.tab.c ../parser.c ; mv -f y.tab.h ../parser.h diff --git a/src/yacc/exscript b/src/yacc/exscript deleted file mode 100644 index 0a0f2a9f..00000000 --- a/src/yacc/exscript +++ /dev/null @@ -1,3 +0,0 @@ -1d -x - diff --git a/src/yacc/lua.lex b/src/yacc/lua.lex deleted file mode 100644 index cbb0232a..00000000 --- a/src/yacc/lua.lex +++ /dev/null @@ -1,85 +0,0 @@ -%{ - -char *rcs_lualex = "$Id: lua.lex,v 1.1 1993/12/17 18:53:41 celes Exp $"; - -#include <stdlib.h> -#include <string.h> - -#include "opcode.h" -#include "hash.h" -#include "inout.h" -#include "table.h" -#include "y.tab.h" - -#undef input -#undef unput - -static Input input; -static Unput unput; - -void lua_setinput (Input fn) -{ - input = fn; -} - -void lua_setunput (Unput fn) -{ - unput = fn; -} - -char *lua_lasttext (void) -{ - return yytext; -} - -%} - - -%% -[ \t]* ; -^"$debug" {yylval.vInt = 1; return DEBUG;} -^"$nodebug" {yylval.vInt = 0; return DEBUG;} -\n lua_linenumber++; -"--".* ; -"local" return LOCAL; -"if" return IF; -"then" return THEN; -"else" return ELSE; -"elseif" return ELSEIF; -"while" return WHILE; -"do" return DO; -"repeat" return REPEAT; -"until" return UNTIL; -"function" { - yylval.vWord = lua_nfile-1; - return FUNCTION; - } -"end" return END; -"return" return RETURN; -"local" return LOCAL; -"nil" return NIL; -"and" return AND; -"or" return OR; -"not" return NOT; -"~=" return NE; -"<=" return LE; -">=" return GE; -".." return CONC; -\"[^\"]*\" | -\'[^\']*\' { - yylval.vWord = lua_findenclosedconstant (yytext); - return STRING; - } -[0-9]+("."[0-9]*)? | -([0-9]+)?"."[0-9]+ | -[0-9]+("."[0-9]*)?[dDeEgG][+-]?[0-9]+ | -([0-9]+)?"."[0-9]+[dDeEgG][+-]?[0-9]+ { - yylval.vFloat = atof(yytext); - return NUMBER; - } -[a-zA-Z_][a-zA-Z0-9_]* { - yylval.vWord = lua_findsymbol (yytext); - return NAME; - } -. return *yytext; - diff --git a/src/yacc/lua.stx b/src/yacc/lua.stx index 118a240c..9c818708 100644 --- a/src/yacc/lua.stx +++ b/src/yacc/lua.stx @@ -1,35 +1,43 @@ %{ -char *rcs_luastx = "$Id: lua.stx,v 2.4 1994/04/20 16:22:21 celes Exp $"; +char *rcs_luastx = "$Id: lua.stx,v 3.17 1995/01/13 22:11:12 roberto Exp $"; #include <stdio.h> #include <stdlib.h> #include <string.h> -#include "mm.h" - +#include "mem.h" #include "opcode.h" #include "hash.h" #include "inout.h" +#include "tree.h" #include "table.h" #include "lua.h" +/* to avoid warnings generated by yacc */ +int yyparse (void); +#define malloc luaI_malloc +#define realloc luaI_realloc +#define free luaI_free + +#ifndef LISTING #define LISTING 0 +#endif -#ifndef GAPCODE -#define GAPCODE 50 +#ifndef CODE_BLOCK +#define CODE_BLOCK 256 #endif -static Word maxcode; -static Word maxmain; -static Word maxcurr ; -static Byte *code = NULL; -static Byte *initcode; +static int maxcode; +static int maxmain; +static Long maxcurr; /* to allow maxcurr *= 2 without overflow */ +static Byte *funcCode = NULL; +static Byte **initcode; static Byte *basepc; -static Word maincode; -static Word pc; +static int maincode; +static int pc; #define MAXVAR 32 -static long varbuffer[MAXVAR]; /* variables in an assignment list; +static Long varbuffer[MAXVAR]; /* variables in an assignment list; it's long to store negative Word values */ static int nvarbuffer=0; /* number of variables at a list */ @@ -39,8 +47,7 @@ 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; -static int ntemp; /* number of temporary var into stack */ -static int err; /* flag to indicate error */ + /* Internal functions */ @@ -48,13 +55,12 @@ static void code_byte (Byte c) { if (pc>maxcurr-2) /* 1 byte free to code HALT of main code */ { - maxcurr += GAPCODE; - basepc = (Byte *)realloc(basepc, maxcurr*sizeof(Byte)); - if (basepc == NULL) - { - lua_error ("not enough memory"); - err = 1; - } + if (maxcurr >= MAX_INT) + lua_error("code size overflow"); + maxcurr *= 2; + if (maxcurr >= MAX_INT) + maxcurr = MAX_INT; + basepc = growvector(basepc, maxcurr, Byte); } basepc[pc++] = c; } @@ -77,6 +83,16 @@ static void code_float (float n) code_byte(code.m.c4); } +static void code_code (Byte *b) +{ + CodeCode code; + code.b = b; + code_byte(code.m.c1); + code_byte(code.m.c2); + code_byte(code.m.c3); + code_byte(code.m.c4); +} + static void code_word_at (Byte *p, Word n) { CodeWord code; @@ -90,10 +106,7 @@ static void push_field (Word name) if (nfields < STACKGAP-1) fields[nfields++] = name; else - { lua_error ("too many fields in a constructor"); - err = 1; - } } static void flush_record (int n) @@ -104,7 +117,6 @@ static void flush_record (int n) code_byte(n); for (i=0; i<n; i++) code_word(fields[--nfields]); - ntemp -= n; } static void flush_list (int m, int n) @@ -113,34 +125,22 @@ static void flush_list (int m, int n) if (m == 0) code_byte(STORELIST0); else + if (m < 255) { code_byte(STORELIST); code_byte(m); } + else + lua_error ("list constructor too long"); code_byte(n); - ntemp-=n; -} - -static void incr_ntemp (void) -{ - if (ntemp+nlocalvar+MAXVAR+1 < STACKGAP) - ntemp++; - else - { - lua_error ("stack overflow"); - err = 1; - } } static void add_nlocalvar (int n) { - if (ntemp+nlocalvar+MAXVAR+n < STACKGAP) + if (MAX_TEMPS+nlocalvar+MAXVAR+n < STACKGAP) nlocalvar += n; else - { - lua_error ("too many local variables or expression too complicate"); - err = 1; - } + lua_error ("too many local variables"); } static void incr_nvarbuffer (void) @@ -148,14 +148,12 @@ static void incr_nvarbuffer (void) if (nvarbuffer < MAXVAR-1) nvarbuffer++; else - { lua_error ("variable buffer overflow"); - err = 1; - } } static void code_number (float f) -{ Word i = (Word)f; +{ + Word i = (Word)f; if (f == (float)i) /* f has an (short) integer value */ { if (i <= 2) code_byte(PUSH0 + i); @@ -175,20 +173,204 @@ static void code_number (float f) code_byte(PUSHFLOAT); code_float(f); } - incr_ntemp(); } +/* +** Search a local name and if find return its index. If do not find return -1 +*/ +static int lua_localname (Word n) +{ + int i; + for (i=nlocalvar-1; i >= 0; i--) + if (n == localvar[i]) return i; /* local var */ + return -1; /* global var */ +} + +/* +** Push a variable given a number. If number is positive, push global variable +** indexed by (number -1). If negative, push local indexed by ABS(number)-1. +** Otherwise, if zero, push indexed variable (record). +*/ +static void lua_pushvar (Long number) +{ + if (number > 0) /* global var */ + { + code_byte(PUSHGLOBAL); + code_word(number-1); + } + else if (number < 0) /* local var */ + { + number = (-number) - 1; + if (number < 10) code_byte(PUSHLOCAL0 + number); + else + { + code_byte(PUSHLOCAL); + code_byte(number); + } + } + else + { + code_byte(PUSHINDEXED); + } +} + +static void lua_codeadjust (int n) +{ + if (n+nlocalvar == 0) + code_byte(ADJUST0); + else + { + code_byte(ADJUST); + code_byte(n+nlocalvar); + } +} + +static void init_function (TreeNode *func) +{ + if (funcCode == NULL) /* first function */ + { + funcCode = newvector(CODE_BLOCK, Byte); + maxcode = CODE_BLOCK; + } + pc=0; basepc=funcCode; maxcurr=maxcode; + nlocalvar=0; + if (lua_debug) + { + code_byte(SETFUNCTION); + code_code((Byte *)luaI_strdup(lua_file[lua_nfile-1])); + code_word(luaI_findconstant(func)); + } +} + +static void codereturn (void) +{ + if (lua_debug) code_byte(RESET); + if (nlocalvar == 0) + code_byte(RETCODE0); + else + { + code_byte(RETCODE); + code_byte(nlocalvar); + } +} + +static void codedebugline (void) +{ + if (lua_debug) + { + code_byte(SETLINE); + code_word(lua_linenumber); + } +} + +static void adjust_mult_assign (int vars, int exps, int temps) +{ + if (exps < 0) + { + int r = vars - (-exps-1); + if (r >= 0) + code_byte(r); + else + { + code_byte(0); + lua_codeadjust(temps); + } + } + else if (vars != exps) + lua_codeadjust(temps); +} + +static void lua_codestore (int i) +{ + if (varbuffer[i] > 0) /* global var */ + { + code_byte(STOREGLOBAL); + code_word(varbuffer[i]-1); + } + else if (varbuffer[i] < 0) /* local var */ + { + int number = (-varbuffer[i]) - 1; + if (number < 10) code_byte(STORELOCAL0 + number); + else + { + code_byte(STORELOCAL); + code_byte(number); + } + } + else /* indexed var */ + { + int j; + int upper=0; /* number of indexed variables upper */ + int param; /* number of itens until indexed expression */ + for (j=i+1; j <nvarbuffer; j++) + if (varbuffer[j] == 0) upper++; + param = upper*2 + i; + if (param == 0) + code_byte(STOREINDEXED0); + else + { + code_byte(STOREINDEXED); + code_byte(param); + } + } +} + +static void codeIf (Long thenAdd, Long elseAdd) +{ + Long elseinit = elseAdd+sizeof(Word)+1; + if (pc == elseinit) /* no else */ + { + pc -= sizeof(Word)+1; + elseinit = pc; + } + else + { + basepc[elseAdd] = JMP; + code_word_at(basepc+elseAdd+1, pc-elseinit); + } + basepc[thenAdd] = IFFJMP; + code_word_at(basepc+thenAdd+1,elseinit-(thenAdd+sizeof(Word)+1)); +} + +static void yyerror (char *s) +{ + static char msg[256]; + sprintf (msg,"%s near \"%s\" at line %d in file \"%s\"", + s, lua_lasttext (), lua_linenumber, lua_filename()); + lua_error (msg); +} + + +/* +** Parse LUA code. +*/ +void lua_parse (Byte **code) +{ + initcode = code; + *initcode = newvector(CODE_BLOCK, Byte); + maincode = 0; + maxmain = CODE_BLOCK; + if (yyparse ()) lua_error("parse error"); + (*initcode)[maincode++] = RETCODE0; +#if LISTING +{ static void PrintCode (Byte *c, Byte *end); + PrintCode(*initcode,*initcode+maincode); } +#endif +} + + %} %union { int vInt; - long vLong; float vFloat; char *pChar; Word vWord; + Long vLong; Byte *pByte; + TreeNode *pNode; } %start functionlist @@ -198,25 +380,27 @@ static void code_number (float f) %token IF THEN ELSE ELSEIF WHILE DO REPEAT UNTIL END %token RETURN %token LOCAL +%token FUNCTION %token <vFloat> NUMBER -%token <vWord> FUNCTION STRING -%token <pChar> NAME +%token <vWord> STRING +%token <pNode> NAME %token <vInt> DEBUG -%type <vWord> PrepJump -%type <vInt> expr, exprlist, exprlist1, varlist1, typeconstructor -%type <vInt> fieldlist, localdeclist -%type <vInt> ffieldlist, ffieldlist1 -%type <vInt> lfieldlist, lfieldlist1 -%type <vLong> var, objectname - +%type <vLong> PrepJump +%type <vInt> expr, exprlist, exprlist1, varlist1, funcParams, funcvalue +%type <vInt> fieldlist, localdeclist, decinit +%type <vInt> ffieldlist1 +%type <vInt> lfieldlist1 +%type <vLong> var, singlevar +%type <pByte> body %left AND OR -%left '=' NE '>' '<' LE GE +%left EQ NE '>' '<' LE GE %left CONC %left '+' '-' %left '*' '/' %left UNARY NOT +%right '^' %% /* beginning of rules section */ @@ -225,156 +409,115 @@ static void code_number (float f) functionlist : /* empty */ | functionlist { - pc=maincode; basepc=initcode; maxcurr=maxmain; + pc=maincode; basepc=*initcode; maxcurr=maxmain; nlocalvar=0; } stat sc { - maincode=pc; initcode=basepc; maxmain=maxcurr; + maincode=pc; *initcode=basepc; maxmain=maxcurr; } | functionlist function + | functionlist method | functionlist setdebug ; - + function : FUNCTION NAME + { + init_function($2); + } + body + { + Word func = luaI_findsymbol($2); + s_tag(func) = LUA_T_FUNCTION; + s_bvalue(func) = $4; + } + ; + +method : FUNCTION NAME ':' NAME { - if (code == NULL) /* first function */ - { - code = (Byte *) calloc(GAPCODE, sizeof(Byte)); - if (code == NULL) - { - lua_error("not enough memory"); - err = 1; - } - maxcode = GAPCODE; - } - pc=0; basepc=code; maxcurr=maxcode; - nlocalvar=0; - $<vWord>$ = lua_findsymbol($2); + init_function($4); + localvar[nlocalvar]=luaI_findsymbolbyname("self"); + add_nlocalvar(1); } - '(' parlist ')' + body { - if (lua_debug) - { - code_byte(SETFUNCTION); - code_word(lua_nfile-1); - code_word($<vWord>3); - } - lua_codeadjust (0); + /* assign function to table field */ + pc=maincode; basepc=*initcode; maxcurr=maxmain; + nlocalvar=0; + lua_pushvar(luaI_findsymbol($2)+1); + code_byte(PUSHSTRING); + code_word(luaI_findconstant($4)); + code_byte(PUSHFUNCTION); + code_code($6); + code_byte(STOREINDEXED0); + maincode=pc; *initcode=basepc; maxmain=maxcurr; } - block - END - { - if (lua_debug) code_byte(RESET); - code_byte(RETCODE); code_byte(nlocalvar); - s_tag($<vWord>3) = T_FUNCTION; - s_bvalue($<vWord>3) = calloc (pc, sizeof(Byte)); - if (s_bvalue($<vWord>3) == NULL) - { - lua_error("not enough memory"); - err = 1; - } - memcpy (s_bvalue($<vWord>3), basepc, pc*sizeof(Byte)); - code = basepc; maxcode=maxcurr; + ; + +body : '(' parlist ')' block END + { + codereturn(); + $$ = newvector(pc, Byte); + memcpy($$, basepc, pc*sizeof(Byte)); + funcCode = basepc; maxcode=maxcurr; #if LISTING -PrintCode(code,code+pc); + PrintCode(funcCode,funcCode+pc); #endif - } - ; + } + ; statlist : /* empty */ | statlist stat sc ; -stat : { - ntemp = 0; - if (lua_debug) - { - code_byte(SETLINE); code_word(lua_linenumber); - } - } - stat1 - sc : /* empty */ | ';' ; +stat : { codedebugline(); } stat1 ; + +cond : { codedebugline(); } expr1 ; stat1 : IF expr1 THEN PrepJump block PrepJump elsepart END - { - { - Word elseinit = $6+sizeof(Word)+1; - if (pc - elseinit == 0) /* no else */ - { - pc -= sizeof(Word)+1; - elseinit = pc; - } - else - { - basepc[$6] = JMP; - code_word_at(basepc+$6+1, pc - elseinit); - } - basepc[$4] = IFFJMP; - code_word_at(basepc+$4+1,elseinit-($4+sizeof(Word)+1)); - } - } - - | WHILE {$<vWord>$=pc;} expr1 DO PrepJump block PrepJump END - + { codeIf($4, $6); } + + | WHILE {$<vLong>$=pc;} expr1 DO PrepJump block PrepJump END { basepc[$5] = IFFJMP; code_word_at(basepc+$5+1, pc - ($5 + sizeof(Word)+1)); - basepc[$7] = UPJMP; - code_word_at(basepc+$7+1, pc - ($<vWord>2)); + code_word_at(basepc+$7+1, pc - ($<vLong>2)); } - | REPEAT {$<vWord>$=pc;} block UNTIL expr1 PrepJump - + | REPEAT {$<vLong>$=pc;} block UNTIL cond PrepJump { basepc[$6] = IFFUPJMP; - code_word_at(basepc+$6+1, pc - ($<vWord>2)); + code_word_at(basepc+$6+1, pc - ($<vLong>2)); } - | varlist1 '=' exprlist1 { { int i; - if ($3 == 0 || nvarbuffer != ntemp - $1 * 2) - lua_codeadjust ($1 * 2 + nvarbuffer); + adjust_mult_assign(nvarbuffer, $3, $1 * 2 + nvarbuffer); for (i=nvarbuffer-1; i>=0; i--) lua_codestore (i); if ($1 > 1 || ($1 == 1 && varbuffer[0] != 0)) lua_codeadjust (0); } } - | functioncall { lua_codeadjust (0); } - | typeconstructor { lua_codeadjust (0); } - | LOCAL localdeclist decinit { add_nlocalvar($2); lua_codeadjust (0); } + | functioncall { code_byte(0); } + | LOCAL localdeclist decinit + { add_nlocalvar($2); + adjust_mult_assign($2, $3, 0); + } ; elsepart : /* empty */ | ELSE block - | ELSEIF expr1 THEN PrepJump block PrepJump elsepart - { - { - Word elseinit = $6+sizeof(Word)+1; - if (pc - elseinit == 0) /* no else */ - { - pc -= sizeof(Word)+1; - elseinit = pc; - } - else - { - basepc[$6] = JMP; - code_word_at(basepc+$6+1, pc - elseinit); - } - basepc[$4] = IFFJMP; - code_word_at(basepc+$4+1, elseinit - ($4 + sizeof(Word)+1)); - } - } + | ELSEIF cond THEN PrepJump block PrepJump elsepart + { codeIf($4, $6); } ; -block : {$<vInt>$ = nlocalvar;} statlist {ntemp = 0;} ret +block : {$<vInt>$ = nlocalvar;} statlist ret { if (nlocalvar != $<vInt>1) { @@ -385,11 +528,10 @@ block : {$<vInt>$ = nlocalvar;} statlist {ntemp = 0;} ret ; ret : /* empty */ - | { if (lua_debug){code_byte(SETLINE);code_word(lua_linenumber);}} - RETURN exprlist sc - { - if (lua_debug) code_byte(RESET); - code_byte(RETCODE); code_byte(nlocalvar); + | RETURN { codedebugline(); } exprlist sc + { + if ($3 < 0) code_byte(MULT_RET); + codereturn(); } ; @@ -400,55 +542,42 @@ PrepJump : /* empty */ code_word (0); } -expr1 : expr { if ($1 == 0) {lua_codeadjust (ntemp+1); incr_ntemp();}} +expr1 : expr { if ($1 == 0) code_byte(1); } ; -expr : '(' expr ')' { $$ = $2; } - | expr1 '=' expr1 { code_byte(EQOP); $$ = 1; ntemp--;} - | expr1 '<' expr1 { code_byte(LTOP); $$ = 1; ntemp--;} - | expr1 '>' expr1 { code_byte(LEOP); code_byte(NOTOP); $$ = 1; ntemp--;} - | expr1 NE expr1 { code_byte(EQOP); code_byte(NOTOP); $$ = 1; ntemp--;} - | expr1 LE expr1 { code_byte(LEOP); $$ = 1; ntemp--;} - | expr1 GE expr1 { code_byte(LTOP); code_byte(NOTOP); $$ = 1; ntemp--;} - | expr1 '+' expr1 { code_byte(ADDOP); $$ = 1; ntemp--;} - | expr1 '-' expr1 { code_byte(SUBOP); $$ = 1; ntemp--;} - | expr1 '*' expr1 { code_byte(MULTOP); $$ = 1; ntemp--;} - | expr1 '/' expr1 { code_byte(DIVOP); $$ = 1; ntemp--;} - | expr1 CONC expr1 { code_byte(CONCOP); $$ = 1; ntemp--;} - | '+' expr1 %prec UNARY { $$ = 1; } +expr : '(' expr ')' { $$ = $2; } + | expr1 EQ expr1 { code_byte(EQOP); $$ = 1; } + | expr1 '<' expr1 { code_byte(LTOP); $$ = 1; } + | expr1 '>' expr1 { code_byte(GTOP); $$ = 1; } + | expr1 NE expr1 { code_byte(EQOP); code_byte(NOTOP); $$ = 1; } + | expr1 LE expr1 { code_byte(LEOP); $$ = 1; } + | expr1 GE expr1 { code_byte(GEOP); $$ = 1; } + | expr1 '+' expr1 { code_byte(ADDOP); $$ = 1; } + | expr1 '-' expr1 { code_byte(SUBOP); $$ = 1; } + | expr1 '*' expr1 { code_byte(MULTOP); $$ = 1; } + | expr1 '/' expr1 { code_byte(DIVOP); $$ = 1; } + | expr1 '^' expr1 { code_byte(POWOP); $$ = 1; } + | expr1 CONC expr1 { code_byte(CONCOP); $$ = 1; } | '-' expr1 %prec UNARY { code_byte(MINUSOP); $$ = 1;} - | typeconstructor { $$ = $1; } - | '@' '(' dimension ')' - { - code_byte(CREATEARRAY); - $$ = 1; - } - | var { lua_pushvar ($1); $$ = 1;} - | NUMBER { code_number($1); $$ = 1; } - | STRING + | table { $$ = 1; } + | varexp { $$ = 1;} + | NUMBER { code_number($1); $$ = 1; } + | STRING { code_byte(PUSHSTRING); code_word($1); $$ = 1; - incr_ntemp(); - } - | NIL {code_byte(PUSHNIL); $$ = 1; incr_ntemp();} - | functioncall - { - $$ = 0; - if (lua_debug) - { - code_byte(SETLINE); code_word(lua_linenumber); - } } + | NIL {code_byte(PUSHNIL); $$ = 1; } + | functioncall { $$ = 0; } | NOT expr1 { code_byte(NOTOP); $$ = 1;} - | expr1 AND PrepJump {code_byte(POP); ntemp--;} expr1 + | expr1 AND PrepJump {code_byte(POP); } expr1 { basepc[$3] = ONFJMP; code_word_at(basepc+$3+1, pc - ($3 + sizeof(Word)+1)); $$ = 1; } - | expr1 OR PrepJump {code_byte(POP); ntemp--;} expr1 + | expr1 OR PrepJump {code_byte(POP); } expr1 { basepc[$3] = ONTJMP; code_word_at(basepc+$3+1, pc - ($3 + sizeof(Word)+1)); @@ -456,92 +585,77 @@ expr : '(' expr ')' { $$ = $2; } } ; -typeconstructor: '@' +table : { - code_byte(PUSHBYTE); - $<vWord>$ = pc; code_byte(0); - incr_ntemp(); code_byte(CREATEARRAY); + $<vLong>$ = pc; code_word(0); } - objectname fieldlist + '{' fieldlist '}' { - basepc[$<vWord>2] = $4; - if ($3 < 0) /* there is no function to be called */ - { - $$ = 1; - } - else - { - lua_pushvar ($3+1); - code_byte(PUSHMARK); - incr_ntemp(); - code_byte(PUSHOBJECT); - incr_ntemp(); - code_byte(CALLFUNC); - ntemp -= 4; - $$ = 0; - if (lua_debug) - { - code_byte(SETLINE); code_word(lua_linenumber); - } - } + code_word_at(basepc+$<vLong>1, $3); } ; -dimension : /* empty */ { code_byte(PUSHNIL); incr_ntemp();} - | expr1 +functioncall : funcvalue funcParams + { code_byte(CALLFUNC); code_byte($1+$2); } ; - -functioncall : functionvalue {code_byte(PUSHMARK); $<vInt>$ = ntemp; incr_ntemp();} - '(' exprlist ')' { code_byte(CALLFUNC); ntemp = $<vInt>2-1;} -functionvalue : var {lua_pushvar ($1); } - ; - -exprlist : /* empty */ { $$ = 1; } +funcvalue : varexp { $$ = 0; } + | varexp ':' NAME + { + code_byte(PUSHSELF); + code_word(luaI_findconstant($3)); + $$ = 1; + } + ; + +funcParams : '(' exprlist ')' + { if ($2<0) { code_byte(1); $$ = -$2; } else $$ = $2; } + | table { $$ = 1; } + ; + +exprlist : /* empty */ { $$ = 0; } | exprlist1 { $$ = $1; } ; -exprlist1 : expr { $$ = $1; } - | exprlist1 ',' {if (!$1){lua_codeadjust (ntemp+1); incr_ntemp();}} - expr {$$ = $4;} +exprlist1 : expr { if ($1 == 0) $$ = -1; else $$ = 1; } + | exprlist1 ',' { if ($1 < 0) code_byte(1); } expr + { + int r = $1 < 0 ? -$1 : $1; + $$ = ($4 == 0) ? -(r+1) : r+1; + } ; -parlist : /* empty */ - | parlist1 +parlist : /* empty */ { lua_codeadjust(0); } + | parlist1 { lua_codeadjust(0); } ; parlist1 : NAME { - localvar[nlocalvar]=lua_findsymbol($1); + localvar[nlocalvar]=luaI_findsymbol($1); add_nlocalvar(1); } | parlist1 ',' NAME { - localvar[nlocalvar]=lua_findsymbol($3); + localvar[nlocalvar]=luaI_findsymbol($3); add_nlocalvar(1); } ; -objectname : /* empty */ {$$=-1;} - | NAME {$$=lua_findsymbol($1);} - ; - -fieldlist : '{' ffieldlist '}' - { - flush_record($2%FIELDS_PER_FLUSH); - $$ = $2; - } - | '[' lfieldlist ']' - { - flush_list($2/FIELDS_PER_FLUSH, $2%FIELDS_PER_FLUSH); - $$ = $2; - } +fieldlist : /* empty */ { $$ = 0; } + | lfieldlist1 lastcomma + { $$ = $1; flush_list($1/FIELDS_PER_FLUSH, $1%FIELDS_PER_FLUSH); } + | ffieldlist1 lastcomma + { $$ = $1; flush_record($1%FIELDS_PER_FLUSH); } + | lfieldlist1 ';' + { flush_list($1/FIELDS_PER_FLUSH, $1%FIELDS_PER_FLUSH); } + ffieldlist1 lastcomma + { $$ = $1+$4; flush_record($4%FIELDS_PER_FLUSH); } ; -ffieldlist : /* empty */ { $$ = 0; } - | ffieldlist1 { $$ = $1; } - ; +lastcomma : /* empty */ + | ',' + ; ffieldlist1 : ffield {$$=1;} | ffieldlist1 ',' ffield @@ -551,16 +665,12 @@ ffieldlist1 : ffield {$$=1;} } ; -ffield : NAME {$<vWord>$ = lua_findconstant($1);} '=' expr1 +ffield : NAME '=' expr1 { - push_field($<vWord>2); + push_field(luaI_findconstant($1)); } ; -lfieldlist : /* empty */ { $$ = 0; } - | lfieldlist1 { $$ = $1; } - ; - lfieldlist1 : expr1 {$$=1;} | lfieldlist1 ',' expr1 { @@ -583,169 +693,49 @@ varlist1 : var } ; -var : NAME - { - Word s = lua_findsymbol($1); - int local = lua_localname (s); - if (local == -1) /* global var */ - $$ = s + 1; /* return positive value */ - else - $$ = -(local+1); /* return negative value */ - } - - | var {lua_pushvar ($1);} '[' expr1 ']' +var : singlevar { $$ = $1; } + | varexp '[' expr1 ']' { $$ = 0; /* indexed variable */ } - | var {lua_pushvar ($1);} '.' NAME + | varexp '.' NAME { code_byte(PUSHSTRING); - code_word(lua_findconstant($4)); incr_ntemp(); + code_word(luaI_findconstant($3)); $$ = 0; /* indexed variable */ } ; -localdeclist : NAME {localvar[nlocalvar]=lua_findsymbol($1); $$ = 1;} +singlevar : NAME + { + Word s = luaI_findsymbol($1); + int local = lua_localname (s); + if (local == -1) /* global var */ + $$ = s + 1; /* return positive value */ + else + $$ = -(local+1); /* return negative value */ + } + ; + +varexp : var { lua_pushvar($1); } + ; + +localdeclist : NAME {localvar[nlocalvar]=luaI_findsymbol($1); $$ = 1;} | localdeclist ',' NAME { - localvar[nlocalvar+$1]=lua_findsymbol($3); + localvar[nlocalvar+$1]=luaI_findsymbol($3); $$ = $1+1; } ; -decinit : /* empty */ - | '=' exprlist1 +decinit : /* empty */ { $$ = 0; } + | '=' exprlist1 { $$ = $2; } ; setdebug : DEBUG {lua_debug = $1;} %% -/* -** Search a local name and if find return its index. If do not find return -1 -*/ -static int lua_localname (Word n) -{ - int i; - for (i=nlocalvar-1; i >= 0; i--) - if (n == localvar[i]) return i; /* local var */ - return -1; /* global var */ -} - -/* -** Push a variable given a number. If number is positive, push global variable -** indexed by (number -1). If negative, push local indexed by ABS(number)-1. -** Otherwise, if zero, push indexed variable (record). -*/ -static void lua_pushvar (long number) -{ - if (number > 0) /* global var */ - { - code_byte(PUSHGLOBAL); - code_word(number-1); - incr_ntemp(); - } - else if (number < 0) /* local var */ - { - number = (-number) - 1; - if (number < 10) code_byte(PUSHLOCAL0 + number); - else - { - code_byte(PUSHLOCAL); - code_byte(number); - } - incr_ntemp(); - } - else - { - code_byte(PUSHINDEXED); - ntemp--; - } -} - -static void lua_codeadjust (int n) -{ - code_byte(ADJUST); - code_byte(n + nlocalvar); -} - -static void lua_codestore (int i) -{ - if (varbuffer[i] > 0) /* global var */ - { - code_byte(STOREGLOBAL); - code_word(varbuffer[i]-1); - } - else if (varbuffer[i] < 0) /* local var */ - { - int number = (-varbuffer[i]) - 1; - if (number < 10) code_byte(STORELOCAL0 + number); - else - { - code_byte(STORELOCAL); - code_byte(number); - } - } - else /* indexed var */ - { - int j; - int upper=0; /* number of indexed variables upper */ - int param; /* number of itens until indexed expression */ - for (j=i+1; j <nvarbuffer; j++) - if (varbuffer[j] == 0) upper++; - param = upper*2 + i; - if (param == 0) - code_byte(STOREINDEXED0); - else - { - code_byte(STOREINDEXED); - code_byte(param); - } - } -} - -void yyerror (char *s) -{ - static char msg[256]; - sprintf (msg,"%s near \"%s\" at line %d in file \"%s\"", - s, lua_lasttext (), lua_linenumber, lua_filename()); - lua_error (msg); - err = 1; -} - -int yywrap (void) -{ - return 1; -} - - -/* -** Parse LUA code and execute global statement. -** Return 0 on success or 1 on error. -*/ -int lua_parse (void) -{ - Byte *init = initcode = (Byte *) calloc(GAPCODE, sizeof(Byte)); - maincode = 0; - maxmain = GAPCODE; - if (init == NULL) - { - lua_error("not enough memory"); - return 1; - } - err = 0; - if (yyparse () || (err==1)) return 1; - initcode[maincode++] = HALT; - init = initcode; -#if LISTING - PrintCode(init,init+maincode); -#endif - if (lua_execute (init)) return 1; - free(init); - return 0; -} - - #if LISTING static void PrintCode (Byte *code, Byte *end) @@ -792,6 +782,16 @@ static void PrintCode (Byte *code, Byte *end) 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.b); + } + break; + case PUSHLOCAL0: case PUSHLOCAL1: case PUSHLOCAL2: case PUSHLOCAL3: case PUSHLOCAL4: case PUSHLOCAL5: case PUSHLOCAL6: case PUSHLOCAL7: case PUSHLOCAL8: case PUSHLOCAL9: @@ -811,8 +811,6 @@ static void PrintCode (Byte *code, Byte *end) } break; case PUSHINDEXED: printf ("%d PUSHINDEXED\n", (p++)-code); break; - case PUSHMARK: printf ("%d PUSHMARK\n", (p++)-code); break; - case PUSHOBJECT: printf ("%d PUSHOBJECT\n", (p++)-code); break; case STORELOCAL0: case STORELOCAL1: case STORELOCAL2: case STORELOCAL3: case STORELOCAL4: case STORELOCAL5: case STORELOCAL6: case STORELOCAL7: case STORELOCAL8: case STORELOCAL9: @@ -832,6 +830,15 @@ static void PrintCode (Byte *code, Byte *end) 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++; @@ -848,11 +855,20 @@ static void PrintCode (Byte *code, Byte *end) 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: printf ("%d CREATEARRAY\n", (p++)-code); 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; @@ -860,6 +876,7 @@ static void PrintCode (Byte *code, Byte *end) 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; @@ -918,20 +935,24 @@ static void PrintCode (Byte *code, Byte *end) } break; case POP: printf ("%d POP\n", (p++)-code); break; - case CALLFUNC: printf ("%d CALLFUNC\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 HALT: printf ("%d HALT\n", (p++)-code); break; case SETFUNCTION: { - CodeWord c1, c2; + CodeCode c1; + CodeWord c2; int n = p-code; p++; - get_word(c1,p); + get_code(c1,p); get_word(c2,p); - printf ("%d SETFUNCTION %d %d\n", n, c1.w, c2.w); + printf ("%d SETFUNCTION %s %d\n", n, (char *)c1.b, c2.w); } break; case SETLINE: |