summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLua Team <team@lua.org>1997-07-01 12:00:00 +0000
committerrepogen <>1997-07-01 12:00:00 +0000
commit4f8c5d0f284e1f4da717aea5008915f185cd2e05 (patch)
tree5671acf8a2cacf0c0524ce96d22959590a3aa5af /src
parent47a298a24ad3a8202440051de5938618502302a0 (diff)
downloadlua-github-4f8c5d0f284e1f4da717aea5008915f185cd2e05.tar.gz
Lua 3.03.0
Diffstat (limited to 'src')
-rw-r--r--src/Makefile18
-rw-r--r--src/auxlib.c81
-rw-r--r--src/auxlib.h30
-rw-r--r--src/fallback.c395
-rw-r--r--src/fallback.h72
-rw-r--r--src/func.c42
-rw-r--r--src/func.h5
-rw-r--r--src/hash.c281
-rw-r--r--src/hash.h33
-rw-r--r--src/inout.c448
-rw-r--r--src/inout.h25
-rw-r--r--src/lex.c219
-rw-r--r--src/lex.h7
-rw-r--r--src/lua.stx63
-rw-r--r--src/luac/dump.c30
-rw-r--r--src/luac/luac.c139
-rw-r--r--src/luac/luac.h11
-rw-r--r--src/luac/print.c233
-rw-r--r--src/luac/print.h9
-rw-r--r--src/luamem.c159
-rw-r--r--src/luamem.h (renamed from src/mem.h)6
-rw-r--r--src/mem.c58
-rw-r--r--src/opcode.c886
-rw-r--r--src/opcode.h71
-rw-r--r--src/parser.c660
-rw-r--r--src/table.c180
-rw-r--r--src/table.h11
-rw-r--r--src/tree.c118
-rw-r--r--src/tree.h18
-rw-r--r--src/undump.c145
-rw-r--r--src/undump.h15
-rw-r--r--src/zio.c79
-rw-r--r--src/zio.h48
33 files changed, 2966 insertions, 1629 deletions
diff --git a/src/Makefile b/src/Makefile
index 1ac2ab85..9fe13c83 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -4,19 +4,23 @@ LUA= ..
include $(LUA)/config
-OBJS= fallback.o\
+OBJS= auxlib.o\
+ fallback.o\
func.o\
hash.o\
inout.o\
lex.o\
- mem.o\
+ luamem.o\
opcode.o\
parser.o\
table.o\
tree.o\
- undump.o
+ undump.o\
+ zio.o
-SRCS= fallback.c\
+SRCS= auxlib.c\
+ auxlib.h\
+ fallback.c\
fallback.h\
func.c\
func.h\
@@ -26,8 +30,8 @@ SRCS= fallback.c\
inout.h\
lex.c\
lex.h\
- mem.c\
- mem.h\
+ luamem.c\
+ luamem.h\
opcode.c\
opcode.h\
parser.c\
@@ -39,6 +43,8 @@ SRCS= fallback.c\
types.h\
undump.c\
undump.h\
+ zio.c\
+ zio.h\
lua.stx
SLIB= $(LIB)/liblua.a
diff --git a/src/auxlib.c b/src/auxlib.c
new file mode 100644
index 00000000..e6f71f29
--- /dev/null
+++ b/src/auxlib.c
@@ -0,0 +1,81 @@
+char *rcs_auxlib="$Id: auxlib.c,v 1.5 1997/04/14 15:30:03 roberto Exp $";
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "lua.h"
+#include "auxlib.h"
+#include "luadebug.h"
+
+
+
+int luaI_findstring (char *name, char *list[])
+{
+ int i;
+ for (i=0; list[i]; i++)
+ if (strcmp(list[i], name) == 0)
+ return i;
+ return -1; /* name not found */
+}
+
+
+void luaL_arg_check(int cond, int numarg, char *extramsg)
+{
+ if (!cond) {
+ char *funcname;
+ lua_getobjname(lua_stackedfunction(0), &funcname);
+ if (funcname == NULL)
+ funcname = "???";
+ if (extramsg == NULL)
+ luaL_verror("bad argument #%d to function `%s'", numarg, funcname);
+ else
+ luaL_verror("bad argument #%d to function `%s' (%s)",
+ numarg, funcname, extramsg);
+ }
+}
+
+char *luaL_check_string (int numArg)
+{
+ lua_Object o = lua_getparam(numArg);
+ luaL_arg_check(lua_isstring(o), numArg, "string expected");
+ return lua_getstring(o);
+}
+
+char *luaL_opt_string (int numArg, char *def)
+{
+ return (lua_getparam(numArg) == LUA_NOOBJECT) ? def :
+ luaL_check_string(numArg);
+}
+
+double luaL_check_number (int numArg)
+{
+ lua_Object o = lua_getparam(numArg);
+ luaL_arg_check(lua_isnumber(o), numArg, "number expected");
+ return lua_getnumber(o);
+}
+
+
+double luaL_opt_number (int numArg, double def)
+{
+ return (lua_getparam(numArg) == LUA_NOOBJECT) ? def :
+ luaL_check_number(numArg);
+}
+
+void luaL_openlib (struct luaL_reg *l, int n)
+{
+ int i;
+ for (i=0; i<n; i++)
+ lua_register(l[i].name, l[i].func);
+}
+
+
+void luaL_verror (char *fmt, ...)
+{
+ char buff[1000];
+ va_list argp;
+ va_start(argp, fmt);
+ vsprintf(buff, fmt, argp);
+ va_end(argp);
+ lua_error(buff);
+}
diff --git a/src/auxlib.h b/src/auxlib.h
new file mode 100644
index 00000000..09020b46
--- /dev/null
+++ b/src/auxlib.h
@@ -0,0 +1,30 @@
+/*
+** $Id: auxlib.h,v 1.3 1997/04/07 14:48:53 roberto Exp $
+*/
+
+#ifndef auxlib_h
+#define auxlib_h
+
+#include "lua.h"
+
+struct luaL_reg {
+ char *name;
+ lua_CFunction func;
+};
+
+void luaL_openlib (struct luaL_reg *l, int n);
+void luaL_arg_check(int cond, int numarg, char *extramsg);
+char *luaL_check_string (int numArg);
+char *luaL_opt_string (int numArg, char *def);
+double luaL_check_number (int numArg);
+double luaL_opt_number (int numArg, double def);
+void luaL_verror (char *fmt, ...);
+
+
+
+/* -- private part (only for Lua modules */
+
+int luaI_findstring (char *name, char *list[]);
+
+
+#endif
diff --git a/src/fallback.c b/src/fallback.c
index 5718f5c1..5a0b5a5b 100644
--- a/src/fallback.c
+++ b/src/fallback.c
@@ -3,130 +3,37 @@
** TecCGraf - PUC-Rio
*/
-char *rcs_fallback="$Id: fallback.c,v 1.25 1996/04/25 14:10:00 roberto Exp $";
+char *rcs_fallback="$Id: fallback.c,v 2.9 1997/06/23 18:27:53 roberto Exp $";
#include <stdio.h>
#include <string.h>
-#include "mem.h"
+#include "auxlib.h"
+#include "luamem.h"
#include "fallback.h"
#include "opcode.h"
#include "lua.h"
#include "table.h"
+#include "tree.h"
+#include "hash.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}}, 1, 0},
-{"index", {LUA_T_CFUNCTION, {indexFB}}, 2, 1},
-{"gettable", {LUA_T_CFUNCTION, {gettableFB}}, 2, 1},
-{"arith", {LUA_T_CFUNCTION, {arithFB}}, 3, 1},
-{"order", {LUA_T_CFUNCTION, {orderFB}}, 3, 1},
-{"concat", {LUA_T_CFUNCTION, {concatFB}}, 2, 1},
-{"settable", {LUA_T_CFUNCTION, {gettableFB}}, 3, 0},
-{"gc", {LUA_T_CFUNCTION, {GDFB}}, 1, 0},
-{"function", {LUA_T_CFUNCTION, {funcFB}}, -1, -1},
- /* no fixed number of params or results */
-{"getglobal", {LUA_T_CFUNCTION, {indexFB}}, 1, 1}
- /* same default behavior of index FB */
-};
-
-#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_error("incorrect argument to function `setfallback'");
- 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_error("incorrect argument to function `setfallback'");
-}
-
-
-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_error("indexed expression not a table");
-}
-
-
-static void arithFB (void)
-{
- lua_error("unexpected type at conversion to number");
-}
-
-static void concatFB (void)
-{
- lua_error("unexpected type at conversion to string");
-}
-
-
-static void orderFB (void)
-{
- lua_error("unexpected type at comparison");
-}
-
-static void GDFB (void) { }
-
-static void funcFB (void)
-{
- lua_error("call expression not a function");
-}
-
-
-/*
+/* -------------------------------------------
** Reference routines
*/
static struct ref {
- Object o;
+ TObject o;
enum {LOCK, HOLD, FREE, COLLECTED} status;
} *refArray = NULL;
static int refSize = 0;
-int luaI_ref (Object *object, int lock)
+int luaI_ref (TObject *object, int lock)
{
int i;
int oldSize;
- if (tag(object) == LUA_T_NIL)
+ if (ttype(object) == LUA_T_NIL)
return -1; /* special ref for nil */
for (i=0; i<refSize; i++)
if (refArray[i].status == FREE)
@@ -151,9 +58,9 @@ void lua_unref (int ref)
}
-Object *luaI_getref (int ref)
+TObject *luaI_getref (int ref)
{
- static Object nul = {LUA_T_NIL, {0}};
+ static TObject nul = {LUA_T_NIL, {0}};
if (ref == -1)
return &nul;
if (ref >= 0 && ref < refSize &&
@@ -164,7 +71,7 @@ Object *luaI_getref (int ref)
}
-void luaI_travlock (int (*fn)(Object *))
+void luaI_travlock (int (*fn)(TObject *))
{
int i;
for (i=0; i<refSize; i++)
@@ -181,11 +88,281 @@ void luaI_invalidaterefs (void)
refArray[i].status = COLLECTED;
}
-char *luaI_travfallbacks (int (*fn)(Object *))
+
+/* -------------------------------------------
+* Internal Methods
+*/
+
+char *luaI_eventname[] = { /* ORDER IM */
+ "gettable", "settable", "index", "getglobal", "setglobal", "add",
+ "sub", "mul", "div", "pow", "unm", "lt", "le", "gt", "ge",
+ "concat", "gc", "function",
+ NULL
+};
+
+
+
+static int luaI_checkevent (char *name, char *list[])
+{
+ int e = luaI_findstring(name, list);
+ if (e < 0)
+ luaL_verror("`%s' is not a valid event name", name);
+ return e;
+}
+
+
+struct IM *luaI_IMtable = NULL;
+
+static int IMtable_size = 0;
+static int last_tag = LUA_T_NIL; /* ORDER LUA_T */
+
+
+/* events in LUA_T_LINE are all allowed, since this is used as a
+* 'placeholder' for "default" fallbacks
+*/
+static char validevents[NUM_TYPES][IM_N] = { /* ORDER LUA_T, ORDER IM */
+{1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_T_USERDATA */
+{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* LUA_T_LINE */
+{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* LUA_T_CMARK */
+{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* LUA_T_MARK */
+{1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_CFUNCTION */
+{1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_FUNCTION */
+{0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* LUA_T_ARRAY */
+{1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_STRING */
+{1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_NUMBER */
+{1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} /* LUA_T_NIL */
+};
+
+static int validevent (lua_Type t, int e)
+{ /* ORDER LUA_T */
+ return (t < LUA_T_NIL) ? 1 : validevents[-t][e];
+}
+
+
+static void init_entry (int tag)
{
int i;
- for (i=0; i<N_FB; i++)
- if (fn(&luaI_fallBacks[i].function))
- return luaI_fallBacks[i].kind;
+ for (i=0; i<IM_N; i++)
+ ttype(luaI_getim(tag, i)) = LUA_T_NIL;
+}
+
+void luaI_initfallbacks (void)
+{
+ if (luaI_IMtable == NULL) {
+ int i;
+ IMtable_size = NUM_TYPES+10;
+ luaI_IMtable = newvector(IMtable_size, struct IM);
+ for (i=LUA_T_NIL; i<=LUA_T_USERDATA; i++)
+ init_entry(i);
+ }
+}
+
+int lua_newtag (void)
+{
+ --last_tag;
+ if ((-last_tag) >= IMtable_size) {
+ luaI_initfallbacks();
+ IMtable_size = growvector(&luaI_IMtable, IMtable_size,
+ struct IM, memEM, MAX_INT);
+ }
+ init_entry(last_tag);
+ return last_tag;
+}
+
+
+static void checktag (int tag)
+{
+ if (!(last_tag <= tag && tag <= 0))
+ luaL_verror("%d is not a valid tag", tag);
+}
+
+void luaI_realtag (int tag)
+{
+ if (!(last_tag <= tag && tag < LUA_T_NIL))
+ luaL_verror("tag %d is not result of `newtag'", tag);
+}
+
+
+void luaI_settag (int tag, TObject *o)
+{
+ luaI_realtag(tag);
+ switch (ttype(o)) {
+ case LUA_T_ARRAY:
+ o->value.a->htag = tag;
+ break;
+ case LUA_T_USERDATA:
+ o->value.ts->tag = tag;
+ break;
+ default:
+ luaL_verror("cannot change the tag of a %s", luaI_typenames[-ttype(o)]);
+ }
+}
+
+
+int luaI_efectivetag (TObject *o)
+{
+ lua_Type t = ttype(o);
+ if (t == LUA_T_USERDATA) {
+ int tag = o->value.ts->tag;
+ return (tag >= 0) ? LUA_T_USERDATA : tag;
+ }
+ else if (t == LUA_T_ARRAY)
+ return o->value.a->htag;
+ else return t;
+}
+
+
+void luaI_gettagmethod (void)
+{
+ int t = (int)luaL_check_number(1);
+ int e = luaI_checkevent(luaL_check_string(2), luaI_eventname);
+ checktag(t);
+ if (validevent(t, e))
+ luaI_pushobject(luaI_getim(t,e));
+}
+
+
+void luaI_settagmethod (void)
+{
+ int t = (int)luaL_check_number(1);
+ int e = luaI_checkevent(luaL_check_string(2), luaI_eventname);
+ lua_Object func = lua_getparam(3);
+ checktag(t);
+ if (!validevent(t, e))
+ luaL_verror("cannot change internal method `%s' for tag %d",
+ luaI_eventname[e], t);
+ luaL_arg_check(lua_isnil(func) || lua_isfunction(func),
+ 3, "function expected");
+ luaI_pushobject(luaI_getim(t,e));
+ *luaI_getim(t, e) = *luaI_Address(func);
+}
+
+
+static void stderrorim (void)
+{
+ lua_Object s = lua_getparam(1);
+ if (lua_isstring(s))
+ fprintf(stderr, "lua: %s\n", lua_getstring(s));
+}
+
+static TObject errorim = {LUA_T_CFUNCTION, {stderrorim}};
+
+
+TObject *luaI_geterrorim (void)
+{
+ return &errorim;
+}
+
+void luaI_seterrormethod (void)
+{
+ lua_Object func = lua_getparam(1);
+ luaL_arg_check(lua_isnil(func) || lua_isfunction(func),
+ 1, "function expected");
+ luaI_pushobject(&errorim);
+ errorim = *luaI_Address(func);
+}
+
+char *luaI_travfallbacks (int (*fn)(TObject *))
+{
+ int e;
+ if (fn(&errorim))
+ return "error";
+ for (e=IM_GETTABLE; e<=IM_FUNCTION; e++) { /* ORDER IM */
+ int t;
+ for (t=0; t>=last_tag; t--)
+ if (fn(luaI_getim(t,e)))
+ return luaI_eventname[e];
+ }
return NULL;
}
+
+
+/*
+* ===================================================================
+* compatibility with old fallback system
+*/
+#if LUA_COMPAT2_5
+
+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 nilFB (void) { }
+
+
+static void typeFB (void)
+{
+ lua_error("unexpected type");
+}
+
+
+static void fillvalids (IMS e, TObject *func)
+{
+ int t;
+ for (t=LUA_T_NIL; t<=LUA_T_USERDATA; t++)
+ if (validevent(t, e))
+ *luaI_getim(t, e) = *func;
+}
+
+
+void luaI_setfallback (void)
+{
+ static char *oldnames [] = {"error", "getglobal", "arith", "order", NULL};
+ TObject oldfunc;
+ lua_CFunction replace;
+ char *name = luaL_check_string(1);
+ lua_Object func = lua_getparam(2);
+ luaI_initfallbacks();
+ luaL_arg_check(lua_isfunction(func), 2, "function expected");
+ switch (luaI_findstring(name, oldnames)) {
+ case 0: /* old error fallback */
+ oldfunc = errorim;
+ errorim = *luaI_Address(func);
+ replace = errorFB;
+ break;
+ case 1: /* old getglobal fallback */
+ oldfunc = *luaI_getim(LUA_T_NIL, IM_GETGLOBAL);
+ *luaI_getim(LUA_T_NIL, IM_GETGLOBAL) = *luaI_Address(func);
+ replace = nilFB;
+ break;
+ case 2: { /* old arith fallback */
+ int i;
+ oldfunc = *luaI_getim(LUA_T_NUMBER, IM_POW);
+ for (i=IM_ADD; i<=IM_UNM; i++) /* ORDER IM */
+ fillvalids(i, luaI_Address(func));
+ replace = typeFB;
+ break;
+ }
+ case 3: { /* old order fallback */
+ int i;
+ oldfunc = *luaI_getim(LUA_T_LINE, IM_LT);
+ for (i=IM_LT; i<=IM_GE; i++) /* ORDER IM */
+ fillvalids(i, luaI_Address(func));
+ replace = typeFB;
+ break;
+ }
+ default: {
+ int e;
+ if ((e = luaI_findstring(name, luaI_eventname)) >= 0) {
+ oldfunc = *luaI_getim(LUA_T_LINE, e);
+ fillvalids(e, luaI_Address(func));
+ replace = (e == IM_GC || e == IM_INDEX) ? nilFB : typeFB;
+ }
+ else {
+ luaL_verror("`%s' is not a valid fallback name", name);
+ replace = NULL; /* to avoid warnings */
+ }
+ }
+ }
+ if (oldfunc.ttype != LUA_T_NIL)
+ luaI_pushobject(&oldfunc);
+ else
+ lua_pushcfunction(replace);
+}
+#endif
diff --git a/src/fallback.h b/src/fallback.h
index 71f150f7..7e314c9f 100644
--- a/src/fallback.h
+++ b/src/fallback.h
@@ -1,5 +1,5 @@
/*
-** $Id: fallback.h,v 1.13 1996/04/25 14:10:00 roberto Exp $
+** $Id: fallback.h,v 1.23 1997/04/24 22:59:57 roberto Exp $
*/
#ifndef fallback_h
@@ -8,30 +8,58 @@
#include "lua.h"
#include "opcode.h"
-extern struct FB {
- char *kind;
- Object function;
- int nParams;
- int nResults;
-} 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
-#define FB_GETGLOBAL 9
+/*
+* WARNING: if you change the order of this enumeration,
+* grep "ORDER IM"
+*/
+typedef enum {
+ IM_GETTABLE = 0,
+ IM_SETTABLE,
+ IM_INDEX,
+ IM_GETGLOBAL,
+ IM_SETGLOBAL,
+ IM_ADD,
+ IM_SUB,
+ IM_MUL,
+ IM_DIV,
+ IM_POW,
+ IM_UNM,
+ IM_LT,
+ IM_LE,
+ IM_GT,
+ IM_GE,
+ IM_CONCAT,
+ IM_GC,
+ IM_FUNCTION
+} IMS;
+
+#define IM_N 18
+
+
+extern struct IM {
+ TObject int_method[IM_N];
+} *luaI_IMtable;
+
+extern char *luaI_eventname[];
+
+#define luaI_getim(tag,event) (&luaI_IMtable[-(tag)].int_method[event])
+#define luaI_getimbyObj(o,e) (luaI_getim(luaI_efectivetag(o),(e)))
void luaI_setfallback (void);
-int luaI_ref (Object *object, int lock);
-Object *luaI_getref (int ref);
-void luaI_travlock (int (*fn)(Object *));
+int luaI_ref (TObject *object, int lock);
+TObject *luaI_getref (int ref);
+void luaI_travlock (int (*fn)(TObject *));
void luaI_invalidaterefs (void);
-char *luaI_travfallbacks (int (*fn)(Object *));
+char *luaI_travfallbacks (int (*fn)(TObject *));
+
+void luaI_settag (int tag, TObject *o);
+void luaI_realtag (int tag);
+TObject *luaI_geterrorim (void);
+int luaI_efectivetag (TObject *o);
+void luaI_settagmethod (void);
+void luaI_gettagmethod (void);
+void luaI_seterrormethod (void);
+void luaI_initfallbacks (void);
#endif
diff --git a/src/func.c b/src/func.c
index 0e15c2fc..36f7e19f 100644
--- a/src/func.c
+++ b/src/func.c
@@ -2,9 +2,10 @@
#include "luadebug.h"
#include "table.h"
-#include "mem.h"
+#include "luamem.h"
#include "func.h"
#include "opcode.h"
+#include "inout.h"
static TFunc *function_root = NULL;
@@ -23,7 +24,7 @@ void luaI_initTFunc (TFunc *f)
f->size = 0;
f->code = NULL;
f->lineDefined = 0;
- f->fileName = NULL;
+ f->fileName = lua_parsedfile;
f->locvars = NULL;
}
@@ -49,47 +50,56 @@ void luaI_freefunc (TFunc *f)
luaI_free (f);
}
+
+void luaI_funcfree (TFunc *l)
+{
+ while (l) {
+ TFunc *next = l->next;
+ luaI_freefunc(l);
+ l = next;
+ }
+}
+
/*
** Garbage collection function.
-** This function traverse the function list freeing unindexed functions
*/
-Long luaI_funccollector (void)
+TFunc *luaI_funccollector (long *acum)
{
TFunc *curr = function_root;
TFunc *prev = NULL;
- Long counter = 0;
- while (curr)
- {
+ TFunc *frees = NULL;
+ long counter = 0;
+ while (curr) {
TFunc *next = curr->next;
- if (!curr->marked)
- {
+ if (!curr->marked) {
if (prev == NULL)
function_root = next;
else
prev->next = next;
- luaI_freefunc (curr);
+ curr->next = frees;
+ frees = curr;
++counter;
}
- else
- {
+ else {
curr->marked = 0;
prev = curr;
}
curr = next;
}
- return counter;
+ *acum += counter;
+ return frees;
}
void lua_funcinfo (lua_Object func, char **filename, int *linedefined)
{
- Object *f = luaI_Address(func);
- if (f->tag == LUA_T_MARK || f->tag == LUA_T_FUNCTION)
+ TObject *f = luaI_Address(func);
+ if (f->ttype == LUA_T_MARK || f->ttype == LUA_T_FUNCTION)
{
*filename = f->value.tf->fileName;
*linedefined = f->value.tf->lineDefined;
}
- else if (f->tag == LUA_T_CMARK || f->tag == LUA_T_CFUNCTION)
+ else if (f->ttype == LUA_T_CMARK || f->ttype == LUA_T_CFUNCTION)
{
*filename = "(C)";
*linedefined = -1;
diff --git a/src/func.h b/src/func.h
index 2ee12103..c79bbb72 100644
--- a/src/func.h
+++ b/src/func.h
@@ -1,5 +1,5 @@
/*
-** $Id: func.h,v 1.8 1996/03/14 15:54:20 roberto Exp $
+** $Id: func.h,v 1.9 1997/05/14 18:38:29 roberto Exp $
*/
#ifndef func_h
@@ -30,7 +30,8 @@ typedef struct TFunc
LocVar *locvars;
} TFunc;
-Long luaI_funccollector (void);
+TFunc *luaI_funccollector (long *cont);
+void luaI_funcfree (TFunc *l);
void luaI_insertfunction (TFunc *f);
void luaI_initTFunc (TFunc *f);
diff --git a/src/hash.c b/src/hash.c
index 19ae7b12..b9276024 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -3,14 +3,15 @@
** hash manager for lua
*/
-char *rcs_hash="$Id: hash.c,v 2.32 1996/11/18 13:48:44 roberto Exp $";
+char *rcs_hash="$Id: hash.c,v 2.43 1997/05/14 18:38:29 roberto Exp $";
-#include "mem.h"
+#include "luamem.h"
#include "opcode.h"
#include "hash.h"
#include "table.h"
#include "lua.h"
+#include "auxlib.h"
#define nhash(t) ((t)->nhash)
@@ -24,13 +25,15 @@ char *rcs_hash="$Id: hash.c,v 2.32 1996/11/18 13:48:44 roberto Exp $";
#define REHASH_LIMIT 0.70 /* avoid more than this % full */
+#define TagDefault LUA_T_ARRAY;
+
static Hash *listhead = NULL;
/* hash dimensions values */
static Long dimensions[] =
- {3L, 5L, 7L, 11L, 23L, 47L, 97L, 197L, 397L, 797L, 1597L, 3203L, 6421L,
+ {5L, 11L, 23L, 47L, 97L, 197L, 397L, 797L, 1597L, 3203L, 6421L,
12853L, 25717L, 51437L, 102811L, 205619L, 411233L, 822433L,
1644817L, 3289613L, 6579211L, 13158023L, MAX_INT};
@@ -46,16 +49,32 @@ int luaI_redimension (int nhash)
return 0; /* to avoid warnings */
}
-static int hashindex (Hash *t, Object *ref) /* hash function */
+
+int lua_equalObj (TObject *t1, TObject *t2)
+{
+ if (ttype(t1) != ttype(t2)) return 0;
+ switch (ttype(t1))
+ {
+ case LUA_T_NIL: return 1;
+ case LUA_T_NUMBER: return nvalue(t1) == nvalue(t2);
+ case LUA_T_STRING: case LUA_T_USERDATA: return svalue(t1) == svalue(t2);
+ case LUA_T_ARRAY: return avalue(t1) == avalue(t2);
+ case LUA_T_FUNCTION: return t1->value.tf == t2->value.tf;
+ case LUA_T_CFUNCTION: return fvalue(t1) == fvalue(t2);
+ default:
+ lua_error("internal error in `lua_equalObj'");
+ return 0; /* UNREACHEABLE */
+ }
+}
+
+
+static long int hashindex (TObject *ref)
{
long int h;
- switch (tag(ref)) {
- case LUA_T_NIL:
- lua_error ("unexpected type to index table");
- h = 0; /* UNREACHEABLE */
+ switch (ttype(ref)) {
case LUA_T_NUMBER:
h = (long int)nvalue(ref); break;
- case LUA_T_STRING:
+ case LUA_T_STRING: case LUA_T_USERDATA:
h = tsvalue(ref)->hash; break;
case LUA_T_FUNCTION:
h = (IntPoint)ref->value.tf; break;
@@ -63,38 +82,29 @@ static int hashindex (Hash *t, Object *ref) /* hash function */
h = (IntPoint)fvalue(ref); break;
case LUA_T_ARRAY:
h = (IntPoint)avalue(ref); break;
- default: /* user data */
- h = (IntPoint)uvalue(ref); break;
+ default:
+ lua_error ("unexpected type to index table");
+ h = 0; /* UNREACHEABLE */
}
if (h < 0) h = -h;
- return h%nhash(t); /* make it a valid index */
+ return h;
}
-int lua_equalObj (Object *t1, Object *t2)
+
+static int present (Hash *t, TObject *key)
{
- 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 svalue(t1) == svalue(t2);
- case LUA_T_ARRAY: return avalue(t1) == avalue(t2);
- case LUA_T_FUNCTION: return t1->value.tf == t2->value.tf;
- case LUA_T_CFUNCTION: return fvalue(t1) == fvalue(t2);
- default: return uvalue(t1) == uvalue(t2);
+ long int h = hashindex(key);
+ int tsize = nhash(t);
+ int h1 = h%tsize;
+ TObject *rf = ref(node(t, h1));
+ if (ttype(rf) != LUA_T_NIL && !lua_equalObj(key, rf)) {
+ int h2 = h%(tsize-2) + 1;
+ do {
+ h1 = (h1+h2)%tsize;
+ rf = ref(node(t, h1));
+ } while (ttype(rf) != LUA_T_NIL && !lua_equalObj(key, rf));
}
-}
-
-static int present (Hash *t, Object *ref)
-{
- int h = hashindex(t, ref);
- while (tag(ref(node(t, h))) != LUA_T_NIL)
- {
- if (lua_equalObj(ref, ref(node(t, h))))
- return h;
- h = (h+1) % nhash(t);
- }
- return h;
+ return h1;
}
@@ -106,7 +116,7 @@ static Node *hashnodecreate (int nhash)
int i;
Node *v = newvector (nhash, Node);
for (i=0; i<nhash; i++)
- tag(ref(&v[i])) = LUA_T_NIL;
+ ttype(ref(&v[i])) = LUA_T_NIL;
return v;
}
@@ -121,6 +131,7 @@ static Hash *hashcreate (int nhash)
nhash(t) = nhash;
nuse(t) = 0;
markarray(t) = 0;
+ t->htag = TagDefault;
return t;
}
@@ -146,7 +157,7 @@ void lua_hashmark (Hash *h)
for (i=0; i<nhash(h); i++)
{
Node *n = node(h,i);
- if (tag(ref(n)) != LUA_T_NIL)
+ if (ttype(ref(n)) != LUA_T_NIL)
{
lua_markobject(&n->ref);
lua_markobject(&n->val);
@@ -156,49 +167,50 @@ void lua_hashmark (Hash *h)
}
-static void call_fallbacks (void)
+void luaI_hashcallIM (Hash *l)
{
- 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 */
+ TObject t;
+ ttype(&t) = LUA_T_ARRAY;
+ for (; l; l=l->next) {
+ avalue(&t) = l;
+ luaI_gcIM(&t);
+ }
}
-
-/*
-** Garbage collection to arrays
-** Delete all unmarked arrays.
-*/
-Long lua_hashcollector (void)
+
+void luaI_hashfree (Hash *frees)
{
- Hash *curr_array = listhead, *prev = NULL;
- Long counter = 0;
- call_fallbacks();
- while (curr_array != NULL)
- {
- Hash *next = curr_array->next;
- if (markarray(curr_array) != 1)
- {
- if (prev == NULL) listhead = next;
- else prev->next = next;
- hashdelete(curr_array);
- ++counter;
+ while (frees) {
+ Hash *next = frees->next;
+ hashdelete(frees);
+ frees = next;
}
- else
- {
- markarray(curr_array) = 0;
- prev = curr_array;
+}
+
+
+Hash *luaI_hashcollector (long *acum)
+{
+ Hash *curr_array = listhead, *prev = NULL, *frees = NULL;
+ long counter = 0;
+ while (curr_array != NULL) {
+ Hash *next = curr_array->next;
+ if (markarray(curr_array) != 1) {
+ if (prev == NULL)
+ listhead = next;
+ else
+ prev->next = next;
+ curr_array->next = frees;
+ frees = curr_array;
+ ++counter;
+ }
+ else {
+ markarray(curr_array) = 0;
+ prev = curr_array;
+ }
+ curr_array = next;
}
- curr_array = next;
- }
- return counter;
+ *acum += counter;
+ return frees;
}
@@ -220,32 +232,45 @@ Hash *lua_createarray (int nhash)
/*
-** Re-hash
+** Rehash:
+** Check if table has deleted slots. It it has, it does not need to
+** grow, since rehash will reuse them.
*/
+static int emptyslots (Hash *t)
+{
+ int i;
+ for (i=nhash(t)-1; i>=0; i--) {
+ Node *n = node(t, i);
+ if (ttype(ref(n)) != LUA_T_NIL && ttype(val(n)) == LUA_T_NIL)
+ return 1;
+ }
+ return 0;
+}
+
static void rehash (Hash *t)
{
- int i;
- int nold = nhash(t);
- Node *vold = nodevector(t);
- nhash(t) = luaI_redimension(nhash(t));
- nodevector(t) = hashnodecreate(nhash(t));
- for (i=0; i<nold; i++)
- {
- 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);
+ int nold = nhash(t);
+ Node *vold = nodevector(t);
+ int i;
+ if (!emptyslots(t))
+ nhash(t) = luaI_redimension(nhash(t));
+ nodevector(t) = hashnodecreate(nhash(t));
+ for (i=0; i<nold; i++) {
+ Node *n = vold+i;
+ if (ttype(ref(n)) != LUA_T_NIL && ttype(val(n)) != LUA_T_NIL)
+ *node(t, present(t, ref(n))) = *n; /* copy old node to new hash */
+ }
+ luaI_free(vold);
}
/*
** If the hash node is present, return its pointer, otherwise return
** null.
*/
-Object *lua_hashget (Hash *t, Object *ref)
+TObject *lua_hashget (Hash *t, TObject *ref)
{
int h = present(t, ref);
- if (tag(ref(node(t, h))) != LUA_T_NIL) return val(node(t, h));
+ if (ttype(ref(node(t, h))) != LUA_T_NIL) return val(node(t, h));
else return NULL;
}
@@ -254,25 +279,19 @@ Object *lua_hashget (Hash *t, Object *ref)
** If the hash node is present, return its pointer, otherwise create a new
** node for the given reference and also return its pointer.
*/
-Object *lua_hashdefine (Hash *t, Object *ref)
+TObject *lua_hashdefine (Hash *t, TObject *ref)
{
- int h;
- Node *n;
- h = present(t, ref);
- n = node(t, h);
- if (tag(ref(n)) == LUA_T_NIL)
- {
- nuse(t)++;
- if ((float)nuse(t) > (float)nhash(t)*REHASH_LIMIT)
- {
- rehash(t);
- h = present(t, ref);
- n = node(t, h);
+ Node *n = node(t, present(t, ref));
+ if (ttype(ref(n)) == LUA_T_NIL) {
+ nuse(t)++;
+ if ((float)nuse(t) > (float)nhash(t)*REHASH_LIMIT) {
+ rehash(t);
+ n = node(t, present(t, ref));
+ }
+ *ref(n) = *ref;
+ ttype(val(n)) = LUA_T_NIL;
}
- *ref(n) = *ref;
- tag(val(n)) = LUA_T_NIL;
- }
- return (val(n));
+ return (val(n));
}
@@ -284,36 +303,30 @@ Object *lua_hashdefine (Hash *t, Object *ref)
*/
static void hashnext (Hash *t, int i)
{
- if (i >= nhash(t))
- return;
- while (tag(ref(node(t,i))) == LUA_T_NIL || tag(val(node(t,i))) == LUA_T_NIL)
- {
- if (++i >= nhash(t))
- return;
- }
- luaI_pushobject(ref(node(t,i)));
- luaI_pushobject(val(node(t,i)));
+ Node *n;
+ int tsize = nhash(t);
+ if (i >= tsize)
+ return;
+ n = node(t, i);
+ while (ttype(ref(n)) == LUA_T_NIL || ttype(val(n)) == LUA_T_NIL) {
+ if (++i >= tsize)
+ return;
+ n = node(t, i);
+ }
+ luaI_pushobject(ref(node(t,i)));
+ luaI_pushobject(val(node(t,i)));
}
void lua_next (void)
{
- 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))
- {
- hashnext(t, 0);
- }
- else
- {
- int h = present (t, luaI_Address(r));
- hashnext(t, h+1);
- }
+ Hash *t;
+ lua_Object o = lua_getparam(1);
+ lua_Object r = lua_getparam(2);
+ luaL_arg_check(lua_istable(o), 1, "table expected");
+ luaL_arg_check(r != LUA_NOOBJECT, 2, "value expected");
+ t = avalue(luaI_Address(o));
+ if (lua_isnil(r))
+ hashnext(t, 0);
+ else
+ hashnext(t, present(t, luaI_Address(r))+1);
}
diff --git a/src/hash.h b/src/hash.h
index c2b52017..1bc758b7 100644
--- a/src/hash.h
+++ b/src/hash.h
@@ -1,7 +1,7 @@
/*
** hash.h
** hash manager for lua
-** $Id: hash.h,v 2.12 1996/05/06 14:30:27 roberto Exp $
+** $Id: hash.h,v 2.16 1997/05/14 18:38:29 roberto Exp $
*/
#ifndef hash_h
@@ -10,29 +10,30 @@
#include "types.h"
#include "opcode.h"
-typedef struct node
-{
- Object ref;
- Object val;
+typedef struct node {
+ TObject ref;
+ TObject val;
} Node;
-typedef struct Hash
-{
- struct Hash *next;
- Node *node;
- int nhash;
- int nuse;
- char mark;
+typedef struct Hash {
+ struct Hash *next;
+ Node *node;
+ int nhash;
+ int nuse;
+ int htag;
+ char mark;
} Hash;
-int lua_equalObj (Object *t1, Object *t2);
+int lua_equalObj (TObject *t1, TObject *t2);
int luaI_redimension (int nhash);
Hash *lua_createarray (int nhash);
void lua_hashmark (Hash *h);
-Long lua_hashcollector (void);
-Object *lua_hashget (Hash *t, Object *ref);
-Object *lua_hashdefine (Hash *t, Object *ref);
+Hash *luaI_hashcollector (long *count);
+void luaI_hashcallIM (Hash *l);
+void luaI_hashfree (Hash *frees);
+TObject *lua_hashget (Hash *t, TObject *ref);
+TObject *lua_hashdefine (Hash *t, TObject *ref);
void lua_next (void);
#endif
diff --git a/src/inout.c b/src/inout.c
index 0aa551c0..5d710610 100644
--- a/src/inout.c
+++ b/src/inout.c
@@ -5,18 +5,24 @@
** Also provides some predefined lua functions.
*/
-char *rcs_inout="$Id: inout.c,v 2.43 1996/09/25 12:57:22 roberto Exp $";
+char *rcs_inout="$Id: inout.c,v 2.69 1997/06/27 22:38:49 roberto Exp $";
#include <stdio.h>
#include <string.h>
+#include "auxlib.h"
+#include "fallback.h"
+#include "hash.h"
+#include "inout.h"
#include "lex.h"
+#include "lua.h"
+#include "luamem.h"
+#include "luamem.h"
#include "opcode.h"
-#include "inout.h"
#include "table.h"
#include "tree.h"
-#include "lua.h"
-#include "mem.h"
+#include "undump.h"
+#include "zio.h"
/* Exported variables */
@@ -24,92 +30,93 @@ Word lua_linenumber;
char *lua_parsedfile;
-static FILE *fp;
-static char *st;
+char *luaI_typenames[] = { /* ORDER LUA_T */
+ "userdata", "line", "cmark", "mark", "function",
+ "function", "table", "string", "number", "nil",
+ NULL
+};
-/*
-** Function to get the next character from the input file
-*/
-static int fileinput (void)
-{
- int c = fgetc(fp);
- return (c == EOF) ? 0 : c;
-}
-/*
-** Function to get the next character from the input string
-*/
-static int stringinput (void)
+
+void luaI_setparsedfile (char *name)
{
- return *st++;
+ lua_parsedfile = luaI_createfixedstring(name)->str;
}
-/*
-** Function to open a file to be input unit.
-** Return the file.
-*/
-FILE *lua_openfile (char *fn)
+
+int lua_doFILE (FILE *f, int bin)
{
- lua_setinput (fileinput);
- if (fn == NULL)
- {
- fp = stdin;
- fn = "(stdin)";
- }
- else
- fp = fopen (fn, "r");
- if (fp == NULL)
- return NULL;
- lua_parsedfile = luaI_createfixedstring(fn)->str;
- return fp;
-}
+ ZIO z;
+ luaZ_Fopen(&z, f);
+ if (bin)
+ return luaI_undump(&z);
+ else {
+ lua_setinput(&z);
+ return lua_domain();
+ }
+}
-/*
-** Function to close an opened file
-*/
-void lua_closefile (void)
+
+int lua_dofile (char *filename)
{
- if (fp != NULL && fp != stdin)
- {
- fclose (fp);
- fp = NULL;
- }
-}
+ int status;
+ int c;
+ FILE *f = (filename == NULL) ? stdin : fopen(filename, "r");
+ if (f == NULL)
+ return 2;
+ luaI_setparsedfile(filename?filename:"(stdin)");
+ c = fgetc(f);
+ ungetc(c, f);
+ if (c == ID_CHUNK) {
+ f = freopen(filename, "rb", f); /* set binary mode */
+ status = lua_doFILE(f, 1);
+ }
+ else {
+ if (c == '#')
+ while ((c=fgetc(f)) != '\n') /* skip first line */;
+ status = lua_doFILE(f, 0);
+ }
+ if (f != stdin)
+ fclose(f);
+ return status;
+}
+
+
-/*
-** Function to open a string to be input unit
-*/
#define SIZE_PREF 20 /* size of string prefix to appear in error messages */
-void lua_openstring (char *s)
-{
- char buff[SIZE_PREF+25];
- lua_setinput(stringinput);
- st = s;
- strcpy(buff, "(dostring) >> ");
- strncat(buff, s, SIZE_PREF);
- if (strlen(s) > SIZE_PREF) strcat(buff, "...");
- lua_parsedfile = luaI_createfixedstring(buff)->str;
-}
-/*
-** Function to close an opened string
-*/
-void lua_closestring (void)
+
+int lua_dobuffer (char *buff, int size)
{
+ int status;
+ ZIO z;
+ luaI_setparsedfile("(buffer)");
+ luaZ_mopen(&z, buff, size);
+ status = luaI_undump(&z);
+ return status;
}
-static void check_arg (int cond, char *func)
+int lua_dostring (char *str)
{
- if (!cond)
- {
- char buff[100];
- sprintf(buff, "incorrect argument to function `%s'", func);
- lua_error(buff);
- }
+ int status;
+ char buff[SIZE_PREF+25];
+ char *temp;
+ ZIO z;
+ if (str == NULL) return 1;
+ sprintf(buff, "(dostring) >> %.20s", str);
+ temp = strchr(buff, '\n');
+ if (temp) *temp = 0; /* end string after first line */
+ luaI_setparsedfile(buff);
+ luaZ_sopen(&z, str);
+ lua_setinput(&z);
+ status = lua_domain();
+ return status;
}
+
+
static int passresults (void)
{
int arg = 0;
@@ -118,30 +125,53 @@ static int passresults (void)
lua_pushobject(obj);
return arg-1;
}
+
+
+static void packresults (void)
+{
+ int arg = 0;
+ lua_Object obj;
+ lua_Object table = lua_createtable();
+ while ((obj = lua_getresult(++arg)) != LUA_NOOBJECT) {
+ lua_pushobject(table);
+ lua_pushnumber(arg);
+ lua_pushobject(obj);
+ lua_rawsettable();
+ }
+ lua_pushobject(table);
+ lua_pushstring("n");
+ lua_pushnumber(arg-1);
+ lua_rawsettable();
+ lua_pushobject(table); /* final result */
+}
/*
** Internal function: do a string
*/
-void lua_internaldostring (void)
+static void lua_internaldostring (void)
{
- lua_Object obj = lua_getparam (1);
- if (lua_isstring(obj) && lua_dostring(lua_getstring(obj)) == 0)
+ lua_Object err = lua_getparam(2);
+ if (err != LUA_NOOBJECT) { /* set new error method */
+ luaL_arg_check(lua_isnil(err) || lua_isfunction(err), 2,
+ "must be a valid error handler");
+ lua_pushobject(err);
+ err = lua_seterrormethod();
+ }
+ if (lua_dostring(luaL_check_string(1)) == 0)
if (passresults() == 0)
lua_pushuserdata(NULL); /* at least one result to signal no errors */
+ if (err != LUA_NOOBJECT) { /* restore old error method */
+ lua_pushobject(err);
+ lua_seterrormethod();
+ }
}
/*
** Internal function: do a file
*/
-void lua_internaldofile (void)
+static void lua_internaldofile (void)
{
- lua_Object obj = lua_getparam (1);
- char *fname = NULL;
- if (lua_isstring(obj))
- fname = lua_getstring(obj);
- else if (obj != LUA_NOOBJECT)
- lua_error("invalid argument to function `dofile'");
- /* else fname = NULL */
+ char *fname = luaL_opt_string(1, NULL);
if (lua_dofile(fname) == 0)
if (passresults() == 0)
lua_pushuserdata(NULL); /* at least one result to signal no errors */
@@ -150,36 +180,28 @@ void lua_internaldofile (void)
static char *tostring (lua_Object obj)
{
- char *buff = luaI_buffer(20);
- if (lua_isstring(obj)) /* get strings and numbers */
- return lua_getstring(obj);
- else switch(lua_type(obj))
- {
- case LUA_T_FUNCTION:
- sprintf(buff, "function: %p", (luaI_Address(obj))->value.tf);
- break;
- case LUA_T_CFUNCTION:
- sprintf(buff, "cfunction: %p", lua_getcfunction(obj));
- break;
- case LUA_T_ARRAY:
- sprintf(buff, "table: %p", avalue(luaI_Address(obj)));
- break;
- case LUA_T_NIL:
- sprintf(buff, "nil");
- break;
- default:
- sprintf(buff, "userdata: %p", lua_getuserdata(obj));
- break;
+ TObject *o = luaI_Address(obj);
+ switch (ttype(o)) {
+ case LUA_T_NUMBER: case LUA_T_STRING:
+ return lua_getstring(obj);
+ case LUA_T_ARRAY: case LUA_T_FUNCTION:
+ case LUA_T_CFUNCTION: case LUA_T_NIL:
+ return luaI_typenames[-ttype(o)];
+ case LUA_T_USERDATA: {
+ char *buff = luaI_buffer(30);
+ sprintf(buff, "userdata: %p", o->value.ts->u.v);
+ return buff;
+ }
+ default: return "<unknown object>";
}
- return buff;
}
-void luaI_tostring (void)
+static void luaI_tostring (void)
{
lua_pushstring(tostring(lua_getparam(1)));
}
-void luaI_print (void)
+static void luaI_print (void)
{
int i = 1;
lua_Object obj;
@@ -187,45 +209,18 @@ void luaI_print (void)
printf("%s\n", tostring(obj));
}
-/*
-** Internal function: return an object type.
-*/
-void luaI_type (void)
+static void luaI_type (void)
{
lua_Object o = lua_getparam(1);
- int t;
- if (o == LUA_NOOBJECT)
- lua_error("no parameter to function 'type'");
- t = lua_type(o);
- switch (t)
- {
- 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 :
- case LUA_T_CFUNCTION :
- lua_pushliteral("function");
- break;
- default :
- lua_pushliteral("userdata");
- break;
- }
- lua_pushnumber(t);
+ luaL_arg_check(o != LUA_NOOBJECT, 1, "no argument");
+ lua_pushstring(luaI_typenames[-ttype(luaI_Address(o))]);
+ lua_pushnumber(lua_tag(o));
}
-
+
/*
** Internal function: convert an object to a number
*/
-void lua_obj2number (void)
+static void lua_obj2number (void)
{
lua_Object o = lua_getparam(1);
if (lua_isnumber(o))
@@ -233,68 +228,181 @@ void lua_obj2number (void)
}
-void luaI_error (void)
+static void luaI_error (void)
{
char *s = lua_getstring(lua_getparam(1));
if (s == NULL) s = "(no message)";
lua_error(s);
}
-void luaI_assert (void)
+static void luaI_assert (void)
{
lua_Object p = lua_getparam(1);
if (p == LUA_NOOBJECT || lua_isnil(p))
lua_error("assertion failed!");
}
-void luaI_setglobal (void)
+static void luaI_setglobal (void)
+{
+ lua_Object value = lua_getparam(2);
+ luaL_arg_check(value != LUA_NOOBJECT, 2, NULL);
+ lua_pushobject(value);
+ lua_setglobal(luaL_check_string(1));
+ lua_pushobject(value); /* return given value */
+}
+
+static void luaI_rawsetglobal (void)
{
- lua_Object name = lua_getparam(1);
lua_Object value = lua_getparam(2);
- check_arg(lua_isstring(name), "setglobal");
+ luaL_arg_check(value != LUA_NOOBJECT, 2, NULL);
lua_pushobject(value);
- lua_storeglobal(lua_getstring(name));
+ lua_rawsetglobal(luaL_check_string(1));
lua_pushobject(value); /* return given value */
}
-void luaI_getglobal (void)
+static void luaI_getglobal (void)
{
- lua_Object name = lua_getparam(1);
- check_arg(lua_isstring(name), "getglobal");
- lua_pushobject(lua_getglobal(lua_getstring(name)));
+ lua_pushobject(lua_getglobal(luaL_check_string(1)));
}
-#define MAXPARAMS 256
-void luaI_call (void)
+static void luaI_rawgetglobal (void)
+{
+ lua_pushobject(lua_rawgetglobal(luaL_check_string(1)));
+}
+
+static void luatag (void)
+{
+ lua_pushnumber(lua_tag(lua_getparam(1)));
+}
+
+
+static int getnarg (lua_Object table)
+{
+ lua_Object temp;
+ /* temp = table.n */
+ lua_pushobject(table); lua_pushstring("n"); temp = lua_gettable();
+ return (lua_isnumber(temp) ? lua_getnumber(temp) : MAX_WORD);
+}
+
+static void luaI_call (void)
{
lua_Object f = lua_getparam(1);
lua_Object arg = lua_getparam(2);
- lua_Object temp, params[MAXPARAMS];
+ int withtable = (strcmp(luaL_opt_string(3, ""), "pack") == 0);
int narg, i;
- check_arg(lua_istable(arg), "call");
- check_arg(lua_isfunction(f), "call");
- /* narg = arg.n */
- lua_pushobject(arg);
- lua_pushstring("n");
- temp = lua_getsubscript();
- narg = lua_isnumber(temp) ? lua_getnumber(temp) : MAXPARAMS+1;
- /* read arg[1...n] */
+ luaL_arg_check(lua_isfunction(f), 1, "function expected");
+ luaL_arg_check(lua_istable(arg), 2, "table expected");
+ narg = getnarg(arg);
+ /* push arg[1...n] */
for (i=0; i<narg; i++) {
- if (i>=MAXPARAMS)
- lua_error("argument list too long in function `call'");
- lua_pushobject(arg);
- lua_pushnumber(i+1);
- params[i] = lua_getsubscript();
- if (narg == MAXPARAMS+1 && lua_isnil(params[i])) {
- narg = i;
+ lua_Object temp;
+ /* temp = arg[i+1] */
+ lua_pushobject(arg); lua_pushnumber(i+1); temp = lua_gettable();
+ if (narg == MAX_WORD && lua_isnil(temp))
break;
- }
+ lua_pushobject(temp);
}
- /* push parameters and do the call */
- for (i=0; i<narg; i++)
- lua_pushobject(params[i]);
if (lua_callfunction(f))
lua_error(NULL);
+ else if (withtable)
+ packresults();
else
passresults();
}
+
+static void luaIl_settag (void)
+{
+ lua_Object o = lua_getparam(1);
+ luaL_arg_check(lua_istable(o), 1, "table expected");
+ lua_pushobject(o);
+ lua_settag(luaL_check_number(2));
+}
+
+static void luaIl_newtag (void)
+{
+ lua_pushnumber(lua_newtag());
+}
+
+static void rawgettable (void)
+{
+ lua_Object t = lua_getparam(1);
+ lua_Object i = lua_getparam(2);
+ luaL_arg_check(t != LUA_NOOBJECT, 1, NULL);
+ luaL_arg_check(i != LUA_NOOBJECT, 2, NULL);
+ lua_pushobject(t);
+ lua_pushobject(i);
+ lua_pushobject(lua_rawgettable());
+}
+
+static void rawsettable (void)
+{
+ lua_Object t = lua_getparam(1);
+ lua_Object i = lua_getparam(2);
+ lua_Object v = lua_getparam(3);
+ luaL_arg_check(t != LUA_NOOBJECT && i != LUA_NOOBJECT && v != LUA_NOOBJECT,
+ 0, NULL);
+ lua_pushobject(t);
+ lua_pushobject(i);
+ lua_pushobject(v);
+ lua_rawsettable();
+}
+
+
+static void luaI_collectgarbage (void)
+{
+ lua_pushnumber(lua_collectgarbage(luaL_opt_number(1, 0)));
+}
+
+
+/*
+** Internal functions
+*/
+static struct {
+ char *name;
+ lua_CFunction func;
+} int_funcs[] = {
+ {"assert", luaI_assert},
+ {"call", luaI_call},
+ {"collectgarbage", luaI_collectgarbage},
+ {"dofile", lua_internaldofile},
+ {"dostring", lua_internaldostring},
+ {"error", luaI_error},
+ {"getglobal", luaI_getglobal},
+ {"newtag", luaIl_newtag},
+ {"next", lua_next},
+ {"nextvar", luaI_nextvar},
+ {"print", luaI_print},
+ {"rawgetglobal", luaI_rawgetglobal},
+ {"rawgettable", rawgettable},
+ {"rawsetglobal", luaI_rawsetglobal},
+ {"rawsettable", rawsettable},
+ {"seterrormethod", luaI_seterrormethod},
+#if LUA_COMPAT2_5
+ {"setfallback", luaI_setfallback},
+#endif
+ {"setglobal", luaI_setglobal},
+ {"settagmethod", luaI_settagmethod},
+ {"gettagmethod", luaI_gettagmethod},
+ {"settag", luaIl_settag},
+ {"tonumber", lua_obj2number},
+ {"tostring", luaI_tostring},
+ {"tag", luatag},
+ {"type", luaI_type}
+};
+
+#define INTFUNCSIZE (sizeof(int_funcs)/sizeof(int_funcs[0]))
+
+
+void luaI_predefine (void)
+{
+ int i;
+ Word n;
+ for (i=0; i<INTFUNCSIZE; i++) {
+ n = luaI_findsymbolbyname(int_funcs[i].name);
+ s_ttype(n) = LUA_T_CFUNCTION; s_fvalue(n) = int_funcs[i].func;
+ }
+ n = luaI_findsymbolbyname("_VERSION");
+ s_ttype(n) = LUA_T_STRING; s_tsvalue(n) = lua_createstring(LUA_VERSION);
+}
+
+
diff --git a/src/inout.h b/src/inout.h
index a26f8e99..b2fb2cd2 100644
--- a/src/inout.h
+++ b/src/inout.h
@@ -1,5 +1,5 @@
/*
-** $Id: inout.h,v 1.16 1996/05/28 21:07:32 roberto Exp $
+** $Id: inout.h,v 1.20 1997/06/19 18:04:34 roberto Exp $
*/
@@ -14,21 +14,12 @@ extern Word lua_linenumber;
extern Word lua_debugline;
extern char *lua_parsedfile;
-FILE *lua_openfile (char *fn);
-void lua_closefile (void);
-void lua_openstring (char *s);
-void lua_closestring (void);
-
-void lua_internaldofile (void);
-void lua_internaldostring (void);
-void luaI_tostring (void);
-void luaI_print (void);
-void luaI_type (void);
-void lua_obj2number (void);
-void luaI_error (void);
-void luaI_assert (void);
-void luaI_setglobal (void);
-void luaI_getglobal (void);
-void luaI_call (void);
+void luaI_setparsedfile (char *name);
+
+void luaI_predefine (void);
+
+int lua_dobuffer (char *buff, int size);
+int lua_doFILE (FILE *f, int bin);
+
#endif
diff --git a/src/lex.c b/src/lex.c
index bd3233a0..5f19dd06 100644
--- a/src/lex.c
+++ b/src/lex.c
@@ -1,10 +1,11 @@
-char *rcs_lex = "$Id: lex.c,v 2.39 1996/11/08 19:08:30 roberto Exp $";
+char *rcs_lex = "$Id: lex.c,v 3.5 1997/06/16 16:50:22 roberto Exp $";
#include <ctype.h>
#include <string.h>
-#include "mem.h"
+#include "auxlib.h"
+#include "luamem.h"
#include "tree.h"
#include "table.h"
#include "lex.h"
@@ -12,33 +13,58 @@ char *rcs_lex = "$Id: lex.c,v 2.39 1996/11/08 19:08:30 roberto Exp $";
#include "luadebug.h"
#include "parser.h"
-#define MINBUFF 260
+#define MINBUFF 250
-#define next() (current = input())
+static int current; /* look ahead character */
+static ZIO *lex_z;
+
+
+#define next() (current = zgetc(lex_z))
#define save(x) (yytext[tokensize++] = (x))
#define save_and_next() (save(current), next())
-static int current; /* look ahead character */
-static Input input; /* input function */
+#define MAX_IFS 5
+
+/* "ifstate" keeps the state of each nested $if the lexical is dealing with. */
+
+static struct {
+ int elsepart; /* true if its in the $else part */
+ int condition; /* true if $if condition is true */
+ int skip; /* true if part must be skiped */
+} ifstate[MAX_IFS];
+
+static int iflevel; /* level of nested $if's */
-void lua_setinput (Input fn)
+void lua_setinput (ZIO *z)
{
current = '\n';
lua_linenumber = 0;
- input = fn;
+ iflevel = 0;
+ ifstate[0].skip = 0;
+ ifstate[0].elsepart = 1; /* to avoid a free $else */
+ lex_z = z;
}
-void luaI_syntaxerror (char *s)
+
+static void luaI_auxsyntaxerror (char *s)
+{
+ luaL_verror("%s;\n> at line %d in file %s",
+ s, lua_linenumber, lua_parsedfile);
+}
+
+static void luaI_auxsynterrbf (char *s, char *token)
{
- char msg[256];
- char *token = luaI_buffer(1);
if (token[0] == 0)
token = "<eof>";
- sprintf (msg,"%s;\n> last token read: \"%s\" at line %d in file %s",
+ luaL_verror("%s;\n> last token read: \"%s\" at line %d in file %s",
s, token, lua_linenumber, lua_parsedfile);
- lua_error (msg);
+}
+
+void luaI_syntaxerror (char *s)
+{
+ luaI_auxsynterrbf(s, luaI_buffer(1));
}
@@ -78,26 +104,122 @@ void luaI_addReserved (void)
}
}
-static int inclinenumber (int pragma_allowed)
+
+/*
+** Pragma handling
+*/
+
+#define PRAGMASIZE 20
+
+static void skipspace (void)
+{
+ while (current == ' ' || current == '\t') next();
+}
+
+
+static int checkcond (char *buff)
+{
+ static char *opts[] = {"nil", "1"};
+ int i = luaI_findstring(buff, opts);
+ if (i >= 0) return i;
+ else if (isalpha((unsigned char)buff[0]) || buff[0] == '_')
+ return luaI_globaldefined(buff);
+ else {
+ luaI_auxsynterrbf("invalid $if condition", buff);
+ return 0; /* to avoid warnings */
+ }
+}
+
+
+static void readname (char *buff)
+{
+ int i = 0;
+ skipspace();
+ while (isalnum((unsigned char)current) || current == '_') {
+ if (i >= PRAGMASIZE) {
+ buff[PRAGMASIZE] = 0;
+ luaI_auxsynterrbf("pragma too long", buff);
+ }
+ buff[i++] = current;
+ next();
+ }
+ buff[i] = 0;
+}
+
+
+static void inclinenumber (void);
+
+
+static void ifskip (void)
+{
+ while (ifstate[iflevel].skip) {
+ if (current == '\n')
+ inclinenumber();
+ else if (current == EOZ)
+ luaI_auxsyntaxerror("input ends inside a $if");
+ else next();
+ }
+}
+
+
+static void inclinenumber (void)
{
+ static char *pragmas [] =
+ {"debug", "nodebug", "endinput", "end", "ifnot", "if", "else", NULL};
+ next(); /* skip '\n' */
++lua_linenumber;
- if (pragma_allowed && current == '$') { /* is a pragma? */
- char *buff = luaI_buffer(MINBUFF+1);
- int i = 0;
+ if (current == '$') { /* is a pragma? */
+ char buff[PRAGMASIZE+1];
+ int ifnot = 0;
+ int skip = ifstate[iflevel].skip;
next(); /* skip $ */
- while (isalnum(current)) {
- if (i >= MINBUFF) luaI_syntaxerror("pragma too long");
- buff[i++] = current;
- next();
+ readname(buff);
+ switch (luaI_findstring(buff, pragmas)) {
+ case 0: /* debug */
+ if (!skip) lua_debug = 1;
+ break;
+ case 1: /* nodebug */
+ if (!skip) lua_debug = 0;
+ break;
+ case 2: /* endinput */
+ if (!skip) {
+ current = EOZ;
+ iflevel = 0; /* to allow $endinput inside a $if */
+ }
+ break;
+ case 3: /* end */
+ if (iflevel-- == 0)
+ luaI_auxsyntaxerror("unmatched $endif");
+ break;
+ case 4: /* ifnot */
+ ifnot = 1;
+ /* go through */
+ case 5: /* if */
+ if (iflevel == MAX_IFS-1)
+ luaI_auxsyntaxerror("too many nested `$ifs'");
+ readname(buff);
+ iflevel++;
+ ifstate[iflevel].elsepart = 0;
+ ifstate[iflevel].condition = checkcond(buff) ? !ifnot : ifnot;
+ ifstate[iflevel].skip = skip || !ifstate[iflevel].condition;
+ break;
+ case 6: /* else */
+ if (ifstate[iflevel].elsepart)
+ luaI_auxsyntaxerror("unmatched $else");
+ ifstate[iflevel].elsepart = 1;
+ ifstate[iflevel].skip =
+ ifstate[iflevel-1].skip || ifstate[iflevel].condition;
+ break;
+ default:
+ luaI_auxsynterrbf("invalid pragma", buff);
}
- buff[i] = 0;
- if (strcmp(buff, "debug") == 0)
- lua_debug = 1;
- else if (strcmp(buff, "nodebug") == 0)
- lua_debug = 0;
- else luaI_syntaxerror("invalid pragma");
+ skipspace();
+ if (current == '\n') /* pragma must end with a '\n' ... */
+ inclinenumber();
+ else if (current != EOZ) /* or eof */
+ luaI_auxsyntaxerror("invalid pragma format");
+ ifskip();
}
- return lua_linenumber;
}
static int read_long_string (char *yytext, int buffsize)
@@ -110,7 +232,7 @@ static int read_long_string (char *yytext, int buffsize)
yytext = luaI_buffer(buffsize *= 2);
switch (current)
{
- case 0:
+ case EOZ:
save(0);
return WRONGTOKEN;
case '[':
@@ -131,8 +253,8 @@ static int read_long_string (char *yytext, int buffsize)
}
continue;
case '\n':
- save_and_next();
- inclinenumber(0);
+ save('\n');
+ inclinenumber();
continue;
default:
save_and_next();
@@ -162,8 +284,8 @@ int luaY_lex (void)
switch (current)
{
case '\n':
- next();
- linelasttoken = inclinenumber(1);
+ inclinenumber();
+ linelasttoken = lua_linenumber;
continue;
case ' ': case '\t': case '\r': /* CR: to avoid problems with DOS */
@@ -173,7 +295,7 @@ int luaY_lex (void)
case '-':
save_and_next();
if (current != '-') return '-';
- do { next(); } while (current != '\n' && current != 0);
+ do { next(); } while (current != '\n' && current != EOZ);
continue;
case '[':
@@ -216,7 +338,7 @@ int luaY_lex (void)
yytext = luaI_buffer(buffsize *= 2);
switch (current)
{
- case 0:
+ case EOZ:
case '\n':
save(0);
return WRONGTOKEN;
@@ -227,7 +349,7 @@ int luaY_lex (void)
case 'n': save('\n'); next(); break;
case 't': save('\t'); next(); break;
case 'r': save('\r'); next(); break;
- case '\n': save_and_next(); inclinenumber(0); break;
+ case '\n': save('\n'); inclinenumber(); break;
default : save_and_next(); break;
}
break;
@@ -258,7 +380,9 @@ int luaY_lex (void)
case '_':
{
TaggedString *ts;
- do { save_and_next(); } while (isalnum(current) || current == '_');
+ do {
+ save_and_next();
+ } while (isalnum((unsigned char)current) || current == '_');
save(0);
ts = lua_createstring(yytext);
if (ts->marked > 2)
@@ -280,7 +404,7 @@ int luaY_lex (void)
}
else return CONC; /* .. */
}
- else if (!isdigit(current)) return '.';
+ else if (!isdigit((unsigned char)current)) return '.';
/* current is a digit: goes through to number */
a=0.0;
goto fraction;
@@ -291,7 +415,7 @@ int luaY_lex (void)
do {
a=10.0*a+(current-'0');
save_and_next();
- } while (isdigit(current));
+ } while (isdigit((unsigned char)current));
if (current == '.') {
save_and_next();
if (current == '.')
@@ -300,7 +424,7 @@ int luaY_lex (void)
}
fraction:
{ double da=0.1;
- while (isdigit(current))
+ while (isdigit((unsigned char)current))
{
a+=(current-'0')*da;
da/=10.0;
@@ -314,11 +438,12 @@ int luaY_lex (void)
save_and_next();
neg=(current=='-');
if (current == '+' || current == '-') save_and_next();
- if (!isdigit(current)) { save(0); return WRONGTOKEN; }
+ if (!isdigit((unsigned char)current)) {
+ save(0); return WRONGTOKEN; }
do {
e=10.0*e+(current-'0');
save_and_next();
- } while (isdigit(current));
+ } while (isdigit((unsigned char)current));
for (ea=neg?0.1:10.0; e>0; e>>=1)
{
if (e & 1) a*=ea;
@@ -330,11 +455,15 @@ int luaY_lex (void)
return NUMBER;
}
- default: /* also end of program (0) */
- {
+ case EOZ:
+ save(0);
+ if (iflevel > 0)
+ luaI_syntaxerror("missing $endif");
+ return 0;
+
+ default:
save_and_next();
return yytext[0];
- }
}
}
}
diff --git a/src/lex.h b/src/lex.h
index 5245d062..a942cf6d 100644
--- a/src/lex.h
+++ b/src/lex.h
@@ -1,16 +1,15 @@
/*
** lex.h
** TecCGraf - PUC-Rio
-** $Id: lex.h,v 1.3 1996/11/08 12:49:35 roberto Exp $
+** $Id: lex.h,v 1.4 1997/06/16 16:50:22 roberto Exp $
*/
#ifndef lex_h
#define lex_h
+#include "zio.h"
-typedef int (*Input) (void);
-
-void lua_setinput (Input fn);
+void lua_setinput (ZIO *z);
void luaI_syntaxerror (char *s);
int luaY_lex (void);
void luaI_addReserved (void);
diff --git a/src/lua.stx b/src/lua.stx
index 00752604..3a1bf62c 100644
--- a/src/lua.stx
+++ b/src/lua.stx
@@ -1,13 +1,13 @@
%{
-char *rcs_luastx = "$Id: lua.stx,v 3.41 1996/11/08 12:49:35 roberto Exp $";
+char *rcs_luastx = "$Id: lua.stx,v 3.47 1997/06/19 17:46:12 roberto Exp $";
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "luadebug.h"
-#include "mem.h"
+#include "luamem.h"
#include "lex.h"
#include "opcode.h"
#include "hash.h"
@@ -50,8 +50,6 @@ static TaggedString *localvar[MAXLOCALS]; /* store local variable names */
static int nlocalvar=0; /* number of local variables */
#define MAXFIELDS FIELDS_PER_FLUSH*2
-static Word fields[MAXFIELDS]; /* fieldnames to be flushed */
-static int nfields=0;
int lua_debug = 0;
@@ -103,22 +101,11 @@ static void code_word_at (Byte *p, int n)
memcpy(p, &w, sizeof(Word));
}
-static void push_field (Word name)
-{
- if (nfields < MAXFIELDS)
- fields[nfields++] = name;
- else
- yyerror ("too many fields in nested constructors");
-}
-
static void flush_record (int n)
{
- int i;
if (n == 0) return;
- code_byte(STORERECORD);
+ code_byte(STOREMAP);
code_byte(n);
- for (i=0; i<n; i++)
- code_word(fields[--nfields]);
}
static void flush_list (int m, int n)
@@ -161,11 +148,22 @@ static void add_varbuffer (Long var)
yyerror ("variable buffer overflow");
}
+static void code_string (Word w)
+{
+ code_byte(PUSHSTRING);
+ code_word(w);
+}
+
+static void code_constant (TaggedString *s)
+{
+ code_string(luaI_findconstant(s));
+}
+
static void code_number (float f)
{
- Word i = (Word)f;
- if (f == (float)i) /* f has an (short) integer value */
- {
+ Word i;
+ if (f >= 0 && f <= (float)MAX_WORD && (float)(i=(Word)f) == f) {
+ /* f has an (short) integer value */
if (i <= 2) code_byte(PUSH0 + i);
else if (i <= 255)
{
@@ -459,7 +457,7 @@ void lua_parse (TFunc *tf)
%% /* beginning of rules section */
-chunk : chunklist ret
+chunk : chunklist ret ;
chunklist : /* empty */
| chunklist stat sc
@@ -477,8 +475,7 @@ function : FUNCTION funcname body
funcname : var { $$ =$1; init_func(); }
| varexp ':' NAME
{
- code_byte(PUSHSTRING);
- code_word(luaI_findconstant($3));
+ code_constant($3);
$$ = 0; /* indexed variable */
init_func();
add_localvar(luaI_createfixedstring("self"));
@@ -492,7 +489,6 @@ body : '(' parlist ')' block END
luaI_initTFunc($$);
$$->size = pc;
$$->code = newvector(pc, Byte);
- $$->fileName = lua_parsedfile;
$$->lineDefined = $2;
memcpy($$->code, basepc, pc*sizeof(Byte));
if (lua_debug)
@@ -540,7 +536,7 @@ stat : IF expr1 THEN PrepJump block PrepJump elsepart END
lua_codeadjust (0);
}
}
- | functioncall
+ | functioncall {;}
| LOCAL localdeclist decinit
{ nlocalvar += $2;
adjust_mult_assign($2, $3, 0);
@@ -605,9 +601,8 @@ expr : '(' expr ')' { $$ = $2; }
| NUMBER { code_number($1); $$ = 0; }
| STRING
{
- code_byte(PUSHSTRING);
- code_word($1);
- $$ = 0;
+ code_string($1);
+ $$ = 0;
}
| NIL {code_byte(PUSHNIL); $$ = 0; }
| functioncall { $$ = $1; }
@@ -723,12 +718,13 @@ ffieldlist1 : ffield {$$=1;}
}
;
-ffield : NAME '=' expr1
- {
- push_field(luaI_findconstant($1));
- }
+ffield : ffieldkey '=' expr1
;
+ffieldkey : '[' expr1 ']'
+ | NAME { code_constant($1); }
+ ;
+
lfieldlist : /* empty */ { $$ = 0; }
| lfieldlist1 lastcomma { $$ = $1; }
;
@@ -762,9 +758,8 @@ var : singlevar { $$ = $1; }
}
| varexp '.' NAME
{
- code_byte(PUSHSTRING);
- code_word(luaI_findconstant($3));
- $$ = 0; /* indexed variable */
+ code_constant($3);
+ $$ = 0; /* indexed variable */
}
;
diff --git a/src/luac/dump.c b/src/luac/dump.c
index 656cc293..73839f38 100644
--- a/src/luac/dump.c
+++ b/src/luac/dump.c
@@ -3,15 +3,13 @@
** thread and save bytecodes to file
*/
-char* rcs_dump="$Id: dump.c,v 1.17 1996/11/18 11:18:29 lhf Exp $";
+char* rcs_dump="$Id: dump.c,v 1.20 1997/06/19 14:56:04 lhf Exp $";
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "luac.h"
-static TFunc* lastF=NULL; /* list of functions seen in code */
-
static int SawVar(int i, int at)
{
int old=VarLoc(i);
@@ -34,7 +32,7 @@ static void ThreadCode(Byte* code, Byte* end)
for (i=0; i<lua_nconstant; i++) StrLoc(i)=0;
for (p=code; p!=end;)
{
- OpCode op=(OpCode)*p;
+ int op=*p;
int at=p-code+1;
switch (op)
{
@@ -89,6 +87,8 @@ static void ThreadCode(Byte* code, Byte* end)
case STORELIST0:
case ADJUST:
case RETCODE:
+ case VARARGS:
+ case STOREMAP:
p+=2;
break;
case PUSHWORD:
@@ -107,8 +107,11 @@ static void ThreadCode(Byte* code, Byte* end)
case PUSHFLOAT:
p+=5; /* assumes sizeof(float)==4 */
break;
- case PUSHSELF:
+ case PUSHFUNCTION:
+ p+=sizeof(TFunc*)+1;
+ break;
case PUSHSTRING:
+ case PUSHSELF:
{
Word w;
p++;
@@ -117,16 +120,6 @@ static void ThreadCode(Byte* code, Byte* end)
memcpy(p-2,&w,sizeof(w));
break;
}
- case PUSHFUNCTION:
- {
- TFunc* tf;
- p++;
- get_code(tf,p);
- tf->marked=at;
- tf->next=NULL; /* TODO: remove? */
- lastF=lastF->next=tf;
- break;
- }
case PUSHGLOBAL:
case STOREGLOBAL:
{
@@ -151,8 +144,8 @@ static void ThreadCode(Byte* code, Byte* end)
}
break;
}
- default:
- fprintf(stderr,"luac: cannot happen: opcode=%d",*p);
+ default: /* cannot happen */
+ fprintf(stderr,"luac: bad opcode %d at %d\n",*p,(int)(p-code));
exit(1);
break;
}
@@ -186,7 +179,7 @@ static void DumpString(char* s, FILE* D)
int n=strlen(s)+1;
if ((Word)n != n)
{
- fprintf(stderr,"luac: string too long: \"%.32s...\"\n",s);
+ fprintf(stderr,"luac: string too long (%d bytes): \"%.32s...\"\n",n,s);
exit(1);
}
DumpWord(n,D);
@@ -220,7 +213,6 @@ static void DumpStrings(FILE* D)
void DumpFunction(TFunc* tf, FILE* D)
{
- lastF=tf;
ThreadCode(tf->code,tf->code+tf->size);
fputc(ID_FUN,D);
DumpSize(tf->size,D);
diff --git a/src/luac/luac.c b/src/luac/luac.c
index 7546c1bb..713da1fb 100644
--- a/src/luac/luac.c
+++ b/src/luac/luac.c
@@ -1,25 +1,39 @@
/*
** luac.c
-** lua compiler (saves bytecodes to files)
+** lua compiler (saves bytecodes to files; also list binary files)
*/
-char* rcs_luac="$Id: luac.c,v 1.18 1996/11/16 20:14:23 lhf Exp $";
+char* rcs_luac="$Id: luac.c,v 1.23 1997/06/20 20:34:04 lhf Exp $";
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "luac.h"
+#include "lex.h"
+#include "zio.h"
static void compile(char* filename);
+static void undump(char* filename);
static int listing=0; /* list bytecodes? */
static int dumping=1; /* dump bytecodes? */
+static int undumping=0; /* undump bytecodes? */
static FILE* D; /* output file */
static void usage(void)
{
- fprintf(stderr,"usage: luac [-dlpv] [-o output] file ...\n");
- exit(0);
+ fprintf(stderr,
+ "usage: luac [-c | -u] [-d] [-l] [-p] [-q] [-v] [-o output] file ...\n"
+ " -c\tcompile (default)\n"
+ " -u\tundump\n"
+ " -d\tgenerate debugging information\n"
+ " -l\tlist (default for -u)\n"
+ " -o\toutput file for -c (default \"luac.out\")\n"
+ " -p\tparse only\n"
+ " -q\tquiet (default for -c)\n"
+ " -v\tshow version information\n"
+ );
+ exit(1);
}
#define IS(s) (strcmp(argv[i],s)==0)
@@ -34,6 +48,11 @@ int main(int argc, char* argv[])
break;
else if (IS("-")) /* use stdin */
break;
+ else if (IS("-c")) /* compile (and dump) */
+ {
+ dumping=1;
+ undumping=0;
+ }
else if (IS("-d")) /* debug */
lua_debug=1;
else if (IS("-l")) /* list */
@@ -42,6 +61,14 @@ int main(int argc, char* argv[])
d=argv[++i];
else if (IS("-p")) /* parse only (for timing purposes) */
dumping=0;
+ else if (IS("-q")) /* quiet */
+ listing=0;
+ else if (IS("-u")) /* undump */
+ {
+ dumping=0;
+ undumping=1;
+ listing=1;
+ }
else if (IS("-v")) /* show version */
printf("%s %s\n(written by %s)\n\n",LUA_VERSION,LUA_COPYRIGHT,LUA_AUTHORS);
else /* unknown option */
@@ -50,56 +77,114 @@ int main(int argc, char* argv[])
--i; /* fake new argv[0] */
argc-=i;
argv+=i;
- if (argc<2) usage();
- for (i=1; i<argc; i++)
- if (IS(d))
+ if (dumping)
+ {
+ if (argc<2) usage();
+ for (i=1; i<argc; i++) /* play safe with output file */
+ if (IS(d))
+ {
+ fprintf(stderr,"luac: will not overwrite input file \"%s\"\n",d);
+ exit(1);
+ }
+ D=fopen(d,"wb"); /* must open in binary mode */
+ if (D==NULL)
{
- fprintf(stderr,"luac: will not overwrite input file \"%s\"\n",d);
+ fprintf(stderr,"luac: cannot open ");
+ perror(d);
exit(1);
}
- D=(dumping) ? fopen(d,"wb") : stdout; /* must open in binary mode */
- if (D==NULL)
+ for (i=1; i<argc; i++) compile(IS("-")? NULL : argv[i]);
+ fclose(D);
+ }
+ if (undumping)
{
- fprintf(stderr,"luac: cannot open ");
- perror(d);
- exit(1);
+ if (argc<2)
+ undump("luac.out");
+ else
+ for (i=1; i<argc; i++) undump(IS("-")? NULL : argv[i]);
}
- for (i=1; i<argc; i++) compile(IS("-")? NULL : argv[i]);
- fclose(D);
return 0;
}
-static void do_dump(TFunc* tf) /* only for tf==main */
+static void do_dump(TFunc* Main)
{
- if (dumping) DumpHeader(D);
- while (tf!=NULL)
+ TFunc* tf;
+ LinkFunctions(Main);
+ if (listing)
+ {
+ for (tf=Main; tf!=NULL; tf=tf->next) PrintFunction(tf,Main);
+ }
+ if (dumping)
{
- TFunc* nf;
- if (listing) PrintFunction(tf);
- if (dumping) DumpFunction(tf,D);
- nf=tf->next; /* list only built after first main */
+ DumpHeader(D);
+ for (tf=Main; tf!=NULL; tf=tf->next) DumpFunction(tf,D);
+ }
+ for (tf=Main; tf!=NULL; )
+ {
+ TFunc* nf=tf->next;
luaI_freefunc(tf);
tf=nf;
}
}
-static void do_compile(void)
+static void do_compile(ZIO* z)
{
TFunc* tf=new(TFunc);
+ lua_setinput(z);
luaI_initTFunc(tf);
- tf->fileName = lua_parsedfile;
+ tf->fileName=lua_parsedfile;
lua_parse(tf);
do_dump(tf);
}
static void compile(char* filename)
{
- if (lua_openfile(filename)==NULL)
+ FILE* f= (filename==NULL) ? stdin : fopen(filename, "r");
+ if (f==NULL)
+ {
+ fprintf(stderr,"luac: cannot open ");
+ perror(filename);
+ exit(1);
+ }
+ else
+ {
+ ZIO z;
+ zFopen(&z,f);
+ luaI_setparsedfile(filename?filename:"(stdin)");
+ do_compile(&z);
+ fclose(f);
+ }
+}
+
+static void do_undump(ZIO* z)
+{
+ TFunc* Main;
+ while ((Main=luaI_undump1(z)))
+ {
+ if (listing)
+ {
+ TFunc* tf;
+ for (tf=Main; tf!=NULL; tf=tf->next)
+ PrintFunction(tf,Main);
+ }
+ luaI_freefunc(Main); /* TODO: free others */
+ }
+}
+
+static void undump(char* filename)
+{
+ FILE* f= (filename==NULL) ? stdin : fopen(filename, "rb");
+ if (f==NULL)
{
fprintf(stderr,"luac: cannot open ");
perror(filename);
exit(1);
}
- do_compile();
- lua_closefile();
+ else
+ {
+ ZIO z;
+ zFopen(&z,f);
+ do_undump(&z);
+ fclose(f);
+ }
}
diff --git a/src/luac/luac.h b/src/luac/luac.h
index ceb311b8..815824ca 100644
--- a/src/luac/luac.h
+++ b/src/luac/luac.h
@@ -1,24 +1,25 @@
/*
** luac.h
** definitions for luac compiler
-** $Id: luac.h,v 1.5 1996/03/08 21:41:47 lhf Exp $
+** $Id: luac.h,v 1.8 1997/06/19 17:32:08 lhf Exp $
*/
#include "inout.h"
-#include "mem.h"
+#include "luamem.h"
#include "opcode.h"
#include "table.h"
#include "undump.h"
#define VarStr(i) (lua_table[i].varname->str)
-#define VarLoc(i) (lua_table[i].varname->varindex)
+#define VarLoc(i) (lua_table[i].varname->u.s.varindex)
#define StrStr(i) (lua_constant[i]->str)
-#define StrLoc(i) (lua_constant[i]->constindex)
+#define StrLoc(i) (lua_constant[i]->u.s.constindex)
extern Word lua_ntable;
extern Word lua_nconstant;
extern int lua_debug;
+void LinkFunctions(TFunc* tf);
+void PrintFunction(TFunc* tf, TFunc* Main);
void DumpHeader(FILE* D);
void DumpFunction(TFunc* tf, FILE* D);
-void PrintFunction(TFunc* tf);
diff --git a/src/luac/print.c b/src/luac/print.c
index 0e1d2569..fb7bf8a7 100644
--- a/src/luac/print.c
+++ b/src/luac/print.c
@@ -3,7 +3,7 @@
** print bytecodes
*/
-char* rcs_print="$Id: print.c,v 1.11 1996/11/18 11:24:16 lhf Exp $";
+char* rcs_print="$Id: print.c,v 1.17 1997/06/25 17:07:28 lhf Exp $";
#include <stdio.h>
#include <stdlib.h>
@@ -11,20 +11,134 @@ char* rcs_print="$Id: print.c,v 1.11 1996/11/18 11:24:16 lhf Exp $";
#include "luac.h"
#include "print.h"
-static LocVar* V=NULL;
-
-static char* LocStr(int i)
+void LinkFunctions(TFunc* m)
{
- if (V==NULL) return ""; else return V[i].varname->str;
+ static TFunc* lastF; /* list of functions seen in code */
+ Byte* code=m->code;
+ Byte* end=code+m->size;
+ Byte* p;
+ if (IsMain(m)) lastF=m;
+ for (p=code; p!=end;)
+ {
+ int op=*p;
+ int at=p-code+1;
+ switch (op)
+ {
+ case PUSHNIL:
+ case PUSH0:
+ case PUSH1:
+ case PUSH2:
+ case PUSHLOCAL0:
+ case PUSHLOCAL1:
+ case PUSHLOCAL2:
+ case PUSHLOCAL3:
+ case PUSHLOCAL4:
+ case PUSHLOCAL5:
+ case PUSHLOCAL6:
+ case PUSHLOCAL7:
+ case PUSHLOCAL8:
+ case PUSHLOCAL9:
+ case PUSHINDEXED:
+ case STORELOCAL0:
+ case STORELOCAL1:
+ case STORELOCAL2:
+ case STORELOCAL3:
+ case STORELOCAL4:
+ case STORELOCAL5:
+ case STORELOCAL6:
+ case STORELOCAL7:
+ case STORELOCAL8:
+ case STORELOCAL9:
+ case STOREINDEXED0:
+ case ADJUST0:
+ case EQOP:
+ case LTOP:
+ case LEOP:
+ case GTOP:
+ case GEOP:
+ case ADDOP:
+ case SUBOP:
+ case MULTOP:
+ case DIVOP:
+ case POWOP:
+ case CONCOP:
+ case MINUSOP:
+ case NOTOP:
+ case POP:
+ case RETCODE0:
+ p++;
+ break;
+ case PUSHBYTE:
+ case PUSHLOCAL:
+ case STORELOCAL:
+ case STOREINDEXED:
+ case STORELIST0:
+ case ADJUST:
+ case RETCODE:
+ case VARARGS:
+ case STOREMAP:
+ p+=2;
+ break;
+ case PUSHWORD:
+ case PUSHSTRING:
+ case PUSHGLOBAL:
+ case PUSHSELF:
+ case STOREGLOBAL:
+ case CREATEARRAY:
+ case ONTJMP:
+ case ONFJMP:
+ case JMP:
+ case UPJMP:
+ case IFFJMP:
+ case IFFUPJMP:
+ case CALLFUNC:
+ case SETLINE:
+ case STORELIST:
+ p+=3;
+ break;
+ case PUSHFLOAT:
+ p+=5; /* assumes sizeof(float)==4 */
+ break;
+ case PUSHFUNCTION:
+ {
+ TFunc* tf;
+ p++;
+ get_code(tf,p);
+ tf->marked=at;
+ tf->next=NULL; /* TODO: remove? */
+ lastF=lastF->next=tf;
+ break;
+ }
+ case STORERECORD:
+ {
+ int n=*++p;
+ p+=2*n+1;
+ break;
+ }
+ default: /* cannot happen */
+ fprintf(stderr,"luac: bad opcode %d at %d\n",*p,(int)(p-code));
+ exit(1);
+ break;
+ }
+ }
}
-static void PrintCode(Byte* code, Byte* end)
+#define LocStr(i) luaI_getlocalname(tf,i+1,line)
+
+static void PrintCode(TFunc* tf)
{
+ Byte* code=tf->code;
+ Byte* end=code+tf->size;
Byte* p;
+ int line=0;
for (p=code; p!=end;)
{
- OpCode op=(OpCode)*p;
- if (op>SETLINE) op=SETLINE+1;
+ int op=*p;
+ if (op>=NOPCODES)
+ {
+ fprintf(stderr,"luac: bad opcode %d at %d\n",op,(int)(p-code));
+ exit(1);
+ }
printf("%6d\t%s",(int)(p-code),OpCodeName[op]);
switch (op)
{
@@ -64,7 +178,7 @@ static void PrintCode(Byte* code, Byte* end)
case PUSHLOCAL9:
{
int i=op-PUSHLOCAL0;
- printf("\t%d\t; %s",i,LocStr(i));
+ if (tf->locvars) printf("\t\t; %s",LocStr(i));
p++;
break;
}
@@ -80,7 +194,7 @@ static void PrintCode(Byte* code, Byte* end)
case STORELOCAL9:
{
int i=op-STORELOCAL0;
- printf("\t%d\t; %s",i,LocStr(i));
+ if (tf->locvars) printf("\t\t; %s",LocStr(i));
p++;
break;
}
@@ -88,7 +202,7 @@ static void PrintCode(Byte* code, Byte* end)
case STORELOCAL:
{
int i=*(p+1);
- printf("\t%d\t; %s",i,LocStr(i));
+ if (tf->locvars) printf("\t%d\t; %s",i,LocStr(i));
p+=2;
break;
}
@@ -97,23 +211,40 @@ static void PrintCode(Byte* code, Byte* end)
case STORELIST0:
case ADJUST:
case RETCODE:
+ case VARARGS:
+ case STOREMAP:
printf("\t%d",*(p+1));
p+=2;
break;
case PUSHWORD:
case CREATEARRAY:
+ case SETLINE:
+ {
+ Word w;
+ p++;
+ get_word(w,p);
+ printf("\t%d",w);
+ if (op==SETLINE) line=w;
+ break;
+ }
case ONTJMP:
case ONFJMP:
case JMP:
- case UPJMP:
case IFFJMP:
+ { /* suggested by Norman Ramsey <nr@cs.virginia.edu> */
+ Word w;
+ p++;
+ get_word(w,p);
+ printf("\t%d\t\t; to %d",w,(int)(p-code)+w);
+ break;
+ }
+ case UPJMP:
case IFFUPJMP:
- case SETLINE:
- {
+ { /* suggested by Norman Ramsey <nr@cs.virginia.edu> */
Word w;
p++;
get_word(w,p);
- printf("\t%d",w);
+ printf("\t%d\t\t; to %d",w,(int)(p-code)-w);
break;
}
case PUSHFLOAT:
@@ -170,7 +301,8 @@ static void PrintCode(Byte* code, Byte* end)
break;
}
default:
- printf("\tcannot happen: opcode=%d",*p);
+ printf("\tcannot happen: opcode=%d\n",*p);
+ fprintf(stderr,"luac: bad opcode %d at %d\n",op,(int)(p-code));
exit(1);
break;
}
@@ -178,13 +310,74 @@ static void PrintCode(Byte* code, Byte* end)
}
}
-void PrintFunction(TFunc* tf)
+#undef LocStr
+
+static void PrintLocals(LocVar* v, int n)
{
+ int i=0;
+ if (v==NULL || v->varname==NULL) return;
+ if (n>0)
+ {
+ printf("parameters:");
+ for (i=0; i<n; v++,i++) printf(" %s[%d@%d]",v->varname->str,i,v->line);
+ printf("\n");
+ }
+ if (v->varname!=NULL)
+ {
+ printf("locals:");
+ for (; v->line>=0; v++)
+ {
+ if (v->varname==NULL)
+#if 0
+ printf(" %s[%d@%d]","*",--i,v->line);
+#else
+ --i;
+#endif
+ else
+ printf(" %s[%d@%d]",v->varname->str,i++,v->line);
+ }
+ printf("\n");
+ }
+}
+
+void PrintFunction(TFunc* tf, TFunc* Main)
+{
+ int n=0;
if (IsMain(tf))
printf("\nmain of \"%s\" (%d bytes at %p)\n",tf->fileName,tf->size,tf);
else
- printf("\nfunction \"%s\":%d (%d bytes at %p); used at main+%d\n",
+ {
+ Byte* p;
+ p=tf->code; /* get number of parameters */
+ while (*p==SETLINE) p+=3;
+ if (*p==ADJUST) n=p[1];
+ p=Main->code+tf->marked+sizeof(TFunc*);
+ printf("\nfunction ");
+ switch (*p) /* try to get name */
+ {
+ case STOREGLOBAL:
+ {
+ Word w;
+ p++; get_word(w,p); printf("%s defined at ",VarStr(w));
+ break;
+ }
+ case STOREINDEXED0: /* try method definition */
+ {
+ if (p[-11]==PUSHGLOBAL && p[-8]==PUSHSTRING)
+ {
+ Word w;
+ Byte* op=p;
+ int c=(tf->locvars && n>0 && strcmp(tf->locvars->varname->str,"self")==0)
+ ? ':' : '.';
+ p=op-11; p++; get_word(w,p); printf("%s%c",VarStr(w),c);
+ p=op-8; p++; get_word(w,p); printf("%s defined at ",StrStr(w));
+ }
+ break;
+ }
+ }
+ printf("\"%s\":%d (%d bytes at %p); used at main+%d\n",
tf->fileName,tf->lineDefined,tf->size,tf,tf->marked);
- V=tf->locvars;
- PrintCode(tf->code,tf->code+tf->size);
+ }
+ PrintLocals(tf->locvars,n);
+ PrintCode(tf);
}
diff --git a/src/luac/print.h b/src/luac/print.h
index 31e2bb89..00e344ca 100644
--- a/src/luac/print.h
+++ b/src/luac/print.h
@@ -1,10 +1,10 @@
/*
** print.h
** opcode names
-** $Id: print.h,v 1.1 1996/02/23 19:04:13 lhf Exp $
+** $Id: print.h,v 1.3 1997/04/14 14:42:50 lhf Exp $
*/
-static char* OpCodeName[]={ /* attention: same order as enum in opcode.h */
+static char* OpCodeName[]={ /* ATTENTION: same order as enum in opcode.h */
"PUSHNIL",
"PUSH0",
"PUSH1",
@@ -72,5 +72,8 @@ static char* OpCodeName[]={ /* attention: same order as enum in opcode.h */
"RETCODE0",
"RETCODE",
"SETLINE",
- ""
+ "VARARGS",
+ "STOREMAP"
};
+
+#define NOPCODES (sizeof(OpCodeName)/sizeof(OpCodeName[0]))
diff --git a/src/luamem.c b/src/luamem.c
new file mode 100644
index 00000000..e4cdd6d9
--- /dev/null
+++ b/src/luamem.c
@@ -0,0 +1,159 @@
+/*
+** mem.c
+** TecCGraf - PUC-Rio
+*/
+
+char *rcs_luamem = "$Id: luamem.c,v 1.16 1997/04/01 21:23:20 roberto Exp $";
+
+#include <stdlib.h>
+
+#include "luamem.h"
+#include "lua.h"
+
+
+#define DEBUG 0
+
+#if !DEBUG
+
+void luaI_free (void *block)
+{
+ if (block)
+ {
+ *((char *)block) = -1; /* to catch errors */
+ free(block);
+ }
+}
+
+
+void *luaI_realloc (void *oldblock, unsigned long size)
+{
+ void *block;
+ size_t s = (size_t)size;
+ if (s != size)
+ lua_error("Allocation Error: Block too big");
+ block = oldblock ? realloc(oldblock, s) : malloc(s);
+ if (block == NULL)
+ lua_error(memEM);
+ return block;
+}
+
+
+int luaI_growvector (void **block, unsigned long nelems, int size,
+ char *errormsg, unsigned long limit)
+{
+ if (nelems >= limit)
+ lua_error(errormsg);
+ nelems = (nelems == 0) ? 20 : nelems*2;
+ if (nelems > limit)
+ nelems = limit;
+ *block = luaI_realloc(*block, nelems*size);
+ return (int)nelems;
+}
+
+
+void* luaI_buffer (unsigned long size)
+{
+ static unsigned long buffsize = 0;
+ static char* buffer = NULL;
+ if (size > buffsize)
+ buffer = luaI_realloc(buffer, buffsize=size);
+ return buffer;
+}
+
+#else
+/* DEBUG */
+
+#include <stdio.h>
+
+# define assert(ex) {if (!(ex)){(void)fprintf(stderr, \
+ "Assertion failed: file \"%s\", line %d\n", __FILE__, __LINE__);exit(1);}}
+
+#define MARK 55
+
+static unsigned long numblocks = 0;
+static unsigned long totalmem = 0;
+
+
+static void message (void)
+{
+#define inrange(x,y) ((x) < (((y)*3)/2) && (x) > (((y)*2)/3))
+ static int count = 0;
+ static unsigned long lastnumblocks = 0;
+ static unsigned long lasttotalmem = 0;
+ if (!inrange(numblocks, lastnumblocks) || !inrange(totalmem, lasttotalmem)
+ || count++ >= 5000)
+ {
+ fprintf(stderr,"blocks = %lu mem = %luK\n", numblocks, totalmem/1000);
+ count = 0;
+ lastnumblocks = numblocks;
+ lasttotalmem = totalmem;
+ }
+}
+
+
+void luaI_free (void *block)
+{
+ if (block)
+ {
+ unsigned long *b = (unsigned long *)block - 1;
+ unsigned long size = *b;
+ assert(*(((char *)b)+size+sizeof(unsigned long)) == MARK);
+ numblocks--;
+ totalmem -= size;
+ free(b);
+ message();
+ }
+}
+
+
+void *luaI_realloc (void *oldblock, unsigned long size)
+{
+ unsigned long *block;
+ unsigned long realsize = sizeof(unsigned long)+size+sizeof(char);
+ if (realsize != (size_t)realsize)
+ lua_error("Allocation Error: Block too big");
+ if (oldblock)
+ {
+ unsigned long *b = (unsigned long *)oldblock - 1;
+ unsigned long oldsize = *b;
+ assert(*(((char *)b)+oldsize+sizeof(unsigned long)) == MARK);
+ totalmem -= oldsize;
+ numblocks--;
+ block = (unsigned long *)realloc(b, realsize);
+ }
+ else
+ block = (unsigned long *)malloc(realsize);
+ if (block == NULL)
+ lua_error("not enough memory");
+ totalmem += size;
+ numblocks++;
+ *block = size;
+ *(((char *)block)+size+sizeof(unsigned long)) = MARK;
+ message();
+ return block+1;
+}
+
+
+int luaI_growvector (void **block, unsigned long nelems, int size,
+ char *errormsg, unsigned long limit)
+{
+ if (nelems >= limit)
+ lua_error(errormsg);
+ nelems = (nelems == 0) ? 20 : nelems*2;
+ if (nelems > limit)
+ nelems = limit;
+ *block = luaI_realloc(*block, nelems*size);
+ return (int)nelems;
+}
+
+
+void* luaI_buffer (unsigned long size)
+{
+ static unsigned long buffsize = 0;
+ static char* buffer = NULL;
+ if (size > buffsize)
+ buffer = luaI_realloc(buffer, buffsize=size);
+ return buffer;
+}
+
+#endif
diff --git a/src/mem.h b/src/luamem.h
index 86f024fc..86b7c8f0 100644
--- a/src/mem.h
+++ b/src/luamem.h
@@ -1,11 +1,11 @@
/*
** mem.c
** memory manager for lua
-** $Id: mem.h,v 1.8 1996/05/24 14:31:10 roberto Exp $
+** $Id: luamem.h,v 1.9 1997/03/31 14:10:11 roberto Exp $
*/
-#ifndef mem_h
-#define mem_h
+#ifndef luamem_h
+#define luamem_h
#ifndef NULL
#define NULL 0
diff --git a/src/mem.c b/src/mem.c
deleted file mode 100644
index 4e3bcc52..00000000
--- a/src/mem.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-** mem.c
-** TecCGraf - PUC-Rio
-*/
-
-char *rcs_mem = "$Id: mem.c,v 1.13 1996/05/24 14:31:10 roberto Exp $";
-
-#include <stdlib.h>
-
-#include "mem.h"
-#include "lua.h"
-
-
-void luaI_free (void *block)
-{
- if (block)
- {
- *((int *)block) = -1; /* to catch errors */
- free(block);
- }
-}
-
-
-void *luaI_realloc (void *oldblock, unsigned long size)
-{
- void *block;
- size_t s = (size_t)size;
- if (s != size)
- lua_error("Allocation Error: Block too big");
- block = oldblock ? realloc(oldblock, s) : malloc(s);
- if (block == NULL)
- lua_error(memEM);
- return block;
-}
-
-
-int luaI_growvector (void **block, unsigned long nelems, int size,
- char *errormsg, unsigned long limit)
-{
- if (nelems >= limit)
- lua_error(errormsg);
- nelems = (nelems == 0) ? 20 : nelems*2;
- if (nelems > limit)
- nelems = limit;
- *block = luaI_realloc(*block, nelems*size);
- return (int)nelems;
-}
-
-
-void* luaI_buffer (unsigned long size)
-{
- static unsigned long buffsize = 0;
- static char* buffer = NULL;
- if (size > buffsize)
- buffer = luaI_realloc(buffer, buffsize=size);
- return buffer;
-}
-
diff --git a/src/opcode.c b/src/opcode.c
index c3bcf54c..ea18f9ea 100644
--- a/src/opcode.c
+++ b/src/opcode.c
@@ -3,7 +3,7 @@
** TecCGraf - PUC-Rio
*/
-char *rcs_opcode="$Id: opcode.c,v 3.77 1996/11/18 13:48:44 roberto Exp $";
+char *rcs_opcode="$Id: opcode.c,v 4.15 1997/06/26 21:40:57 roberto Exp $";
#include <setjmp.h>
#include <stdio.h>
@@ -11,17 +11,18 @@ char *rcs_opcode="$Id: opcode.c,v 3.77 1996/11/18 13:48:44 roberto Exp $";
#include <stdlib.h>
#include "luadebug.h"
-#include "mem.h"
+#include "luamem.h"
#include "opcode.h"
#include "hash.h"
#include "inout.h"
#include "table.h"
#include "lua.h"
#include "fallback.h"
-#include "undump.h"
+#include "auxlib.h"
+#include "lex.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 tonumber(o) ((ttype(o) != LUA_T_NUMBER) && (lua_tonumber(o) != 0))
+#define tostring(o) ((ttype(o) != LUA_T_STRING) && (lua_tostring(o) != 0))
#define STACK_SIZE 128
@@ -32,14 +33,14 @@ char *rcs_opcode="$Id: opcode.c,v 3.77 1996/11/18 13:48:44 roberto Exp $";
typedef int StkId; /* index to stack elements */
-static Object initial_stack;
+static TObject initial_stack;
-static Object *stackLimit = &initial_stack+1;
-static Object *stack = &initial_stack;
-static Object *top = &initial_stack;
+static TObject *stackLimit = &initial_stack+1;
+static TObject *stack = &initial_stack;
+static TObject *top = &initial_stack;
-/* macros to convert from lua_Object to (Object *) and back */
+/* macros to convert from lua_Object to (TObject *) and back */
#define Address(lo) ((lo)+stack-1)
#define Ref(st) ((st)-stack+1)
@@ -51,13 +52,13 @@ static Object *top = &initial_stack;
#define incr_top if (++top >= stackLimit) growstack()
struct C_Lua_Stack {
- StkId base; /* when Lua calls C or C calls Lua, points to */
- /* the first slot after the last parameter. */
- int num; /* when Lua calls C, has the number of parameters; */
- /* when C calls Lua, has the number of results. */
+ StkId base; /* when Lua calls C or C calls Lua, points to */
+ /* the first slot after the last parameter. */
+ StkId lua2C; /* points to first element of "array" lua2C */
+ int num; /* size of "array" lua2C */
};
-static struct C_Lua_Stack CLS_current = {0, 0};
+static struct C_Lua_Stack CLS_current = {0, 0, 0};
static jmp_buf *errorJmp = NULL; /* current error recover point */
@@ -72,7 +73,7 @@ static void do_call (StkId base, int nResults);
-Object *luaI_Address (lua_Object o)
+TObject *luaI_Address (lua_Object o)
{
return Address(o);
}
@@ -84,7 +85,7 @@ Object *luaI_Address (lua_Object o)
static void lua_initstack (void)
{
Long maxstack = STACK_SIZE;
- stack = newvector(maxstack, Object);
+ stack = newvector(maxstack, TObject);
stackLimit = stack+maxstack;
top = stack;
*(top++) = initial_stack;
@@ -105,7 +106,7 @@ static void growstack (void)
static int limit = STACK_LIMIT;
StkId t = top-stack;
Long stacksize = stackLimit - stack;
- stacksize = growvector(&stack, stacksize, Object, stackEM, limit+100);
+ stacksize = growvector(&stack, stacksize, TObject, stackEM, limit+100);
stackLimit = stack+stacksize;
top = stack + t;
if (stacksize >= limit)
@@ -134,16 +135,16 @@ static char *lua_strconc (char *l, char *r)
** Convert, if possible, to a number object.
** Return 0 if success, not 0 if error.
*/
-static int lua_tonumber (Object *obj)
+static int lua_tonumber (TObject *obj)
{
float t;
char c;
- if (tag(obj) != LUA_T_STRING)
+ if (ttype(obj) != LUA_T_STRING)
return 1;
else if (sscanf(svalue(obj), "%f %c",&t, &c) == 1)
{
nvalue(obj) = t;
- tag(obj) = LUA_T_NUMBER;
+ ttype(obj) = LUA_T_NUMBER;
return 0;
}
else
@@ -152,39 +153,54 @@ static int lua_tonumber (Object *obj)
/*
-** Convert, if possible, to a string tag
+** Convert, if possible, to a string ttype
** Return 0 in success or not 0 on error.
*/
-static int lua_tostring (Object *obj)
+static int lua_tostring (TObject *obj)
{
- char s[256];
- if (tag(obj) != LUA_T_NUMBER)
- return 1;
- if ((int) nvalue(obj) == nvalue(obj))
- sprintf (s, "%d", (int) nvalue(obj));
- else
- sprintf (s, "%g", nvalue(obj));
- tsvalue(obj) = lua_createstring(s);
- tag(obj) = LUA_T_STRING;
- return 0;
+ if (ttype(obj) != LUA_T_NUMBER)
+ return 1;
+ else {
+ char s[60];
+ real f = nvalue(obj);
+ int i;
+ if ((real)(-MAX_INT) <= f && f <= (real)MAX_INT && (real)(i=(int)f) == f)
+ sprintf (s, "%d", i);
+ else
+ sprintf (s, "%g", nvalue(obj));
+ tsvalue(obj) = lua_createstring(s);
+ ttype(obj) = LUA_T_STRING;
+ return 0;
+ }
}
/*
** Adjust stack. Set top to the given value, pushing NILs if needed.
*/
-static void adjust_top (StkId newtop)
+static void adjust_top_aux (StkId newtop)
{
- Object *nt;
+ TObject *nt;
lua_checkstack(stack+newtop);
nt = stack+newtop; /* warning: previous call may change stack */
- while (top < nt) tag(top++) = LUA_T_NIL;
- top = nt; /* top could be bigger than newtop */
+ while (top < nt) ttype(top++) = LUA_T_NIL;
}
+
+#define adjust_top(newtop) { if (newtop <= top-stack) \
+ top = stack+newtop; \
+ else adjust_top_aux(newtop); }
+
#define adjustC(nParams) adjust_top(CLS_current.base+nParams)
+static void checkCparams (int nParams)
+{
+ if (top-stack < CLS_current.base+nParams)
+ lua_error("API error - wrong number of arguments in C2lua stack");
+}
+
+
/*
** Open a hole below "nelems" from the top.
*/
@@ -197,13 +213,37 @@ static void open_stack (int nelems)
}
+static lua_Object put_luaObject (TObject *o)
+{
+ open_stack((top-stack)-CLS_current.base);
+ stack[CLS_current.base++] = *o;
+ return CLS_current.base; /* this is +1 real position (see Ref) */
+}
+
+
+static lua_Object put_luaObjectonTop (void)
+{
+ open_stack((top-stack)-CLS_current.base);
+ stack[CLS_current.base++] = *(--top);
+ return CLS_current.base; /* this is +1 real position (see Ref) */
+}
+
+
+lua_Object lua_pop (void)
+{
+ checkCparams(1);
+ return put_luaObjectonTop();
+}
+
+
+
/*
** call Line hook
*/
static void lineHook (int line)
{
struct C_Lua_Stack oldCLS = CLS_current;
- StkId old_top = CLS_current.base = top-stack;
+ StkId old_top = CLS_current.lua2C = CLS_current.base = top-stack;
CLS_current.num = 0;
(*lua_linehook)(line);
top = stack+old_top;
@@ -218,13 +258,13 @@ static void lineHook (int line)
static void callHook (StkId base, lua_Type type, int isreturn)
{
struct C_Lua_Stack oldCLS = CLS_current;
- StkId old_top = CLS_current.base = top-stack;
+ StkId old_top = CLS_current.lua2C = CLS_current.base = top-stack;
CLS_current.num = 0;
if (isreturn)
(*lua_callhook)(LUA_NOOBJECT, "(return)", 0);
else
{
- Object *f = stack+base-1;
+ TObject *f = stack+base-1;
if (type == LUA_T_MARK)
(*lua_callhook)(Ref(f), f->value.tf->fileName, f->value.tf->lineDefined);
else
@@ -246,6 +286,7 @@ static StkId callC (lua_CFunction func, StkId base)
StkId firstResult;
CLS_current.num = (top-stack) - base;
/* incorporate parameters on the stack */
+ CLS_current.lua2C = base;
CLS_current.base = base+CLS_current.num; /* == top-stack */
if (lua_callhook)
callHook(base, LUA_T_CMARK, 0);
@@ -257,15 +298,11 @@ static StkId callC (lua_CFunction func, StkId base)
return firstResult;
}
-/*
-** Call the specified fallback, putting it on the stack below its arguments
-*/
-static void callFB (int fb)
+static void callIM (TObject *f, int nParams, int nResults)
{
- int nParams = luaI_fallBacks[fb].nParams;
open_stack(nParams);
- *(top-nParams-1) = luaI_fallBacks[fb].function;
- do_call((top-stack)-nParams, luaI_fallBacks[fb].nResults);
+ *(top-nParams-1) = *f;
+ do_call((top-stack)-nParams, nResults);
}
@@ -278,28 +315,28 @@ static void callFB (int fb)
static void do_call (StkId base, int nResults)
{
StkId firstResult;
- Object *func = stack+base-1;
+ TObject *func = stack+base-1;
int i;
- if (tag(func) == LUA_T_CFUNCTION)
- {
- tag(func) = LUA_T_CMARK;
+ if (ttype(func) == LUA_T_CFUNCTION) {
+ ttype(func) = LUA_T_CMARK;
firstResult = callC(fvalue(func), base);
}
- else if (tag(func) == LUA_T_FUNCTION)
- {
- tag(func) = LUA_T_MARK;
+ else if (ttype(func) == LUA_T_FUNCTION) {
+ ttype(func) = LUA_T_MARK;
firstResult = lua_execute(func->value.tf->code, base);
}
- else
- { /* func is not a function */
- /* Call the fallback for invalid functions */
+ else { /* func is not a function */
+ /* Check the tag method for invalid functions */
+ TObject *im = luaI_getimbyObj(func, IM_FUNCTION);
+ if (ttype(im) == LUA_T_NIL)
+ lua_error("call expression not a function");
open_stack((top-stack)-(base-1));
- stack[base-1] = luaI_fallBacks[FB_FUNCTION].function;
+ stack[base-1] = *im;
do_call(base, nResults);
return;
}
/* adjust the number of results */
- if (nResults != MULT_RET && top - (stack+firstResult) != nResults)
+ if (nResults != MULT_RET)
adjust_top(firstResult+nResults);
/* move results to base-1 (to erase parameters and function) */
base--;
@@ -316,58 +353,110 @@ static void do_call (StkId base, int nResults)
*/
static void pushsubscript (void)
{
- if (tag(top-2) != LUA_T_ARRAY)
- callFB(FB_GETTABLE);
- else
- {
- Object *h = lua_hashget(avalue(top-2), top-1);
- if (h == NULL || tag(h) == LUA_T_NIL)
- callFB(FB_INDEX);
- else
- {
- --top;
- *(top-1) = *h;
+ TObject *im;
+ if (ttype(top-2) != LUA_T_ARRAY) /* not a table, get "gettable" method */
+ im = luaI_getimbyObj(top-2, IM_GETTABLE);
+ else { /* object is a table... */
+ int tg = (top-2)->value.a->htag;
+ im = luaI_getim(tg, IM_GETTABLE);
+ if (ttype(im) == LUA_T_NIL) { /* and does not have a "gettable" method */
+ TObject *h = lua_hashget(avalue(top-2), top-1);
+ if (h != NULL && ttype(h) != LUA_T_NIL) {
+ --top;
+ *(top-1) = *h;
+ }
+ else if (ttype(im=luaI_getim(tg, IM_INDEX)) != LUA_T_NIL)
+ callIM(im, 2, 1);
+ else {
+ --top;
+ ttype(top-1) = LUA_T_NIL;
+ }
+ return;
}
+ /* else it has a "gettable" method, go through to next command */
+ }
+ /* object is not a table, or it has a "gettable" method */
+ if (ttype(im) != LUA_T_NIL)
+ callIM(im, 2, 1);
+ else
+ lua_error("indexed expression not a table");
+}
+
+
+lua_Object lua_rawgettable (void)
+{
+ checkCparams(2);
+ if (ttype(top-2) != LUA_T_ARRAY)
+ lua_error("indexed expression not a table in raw gettable");
+ else {
+ TObject *h = lua_hashget(avalue(top-2), top-1);
+ --top;
+ if (h != NULL)
+ *(top-1) = *h;
+ else
+ ttype(top-1) = LUA_T_NIL;
}
+ return put_luaObjectonTop();
}
/*
** Function to store indexed based on values at the top
+** mode = 0: raw store (without internal methods)
+** mode = 1: normal store (with internal methods)
+** mode = 2: "deep stack" store (with internal methods)
*/
-static void storesubscript (void)
+static void storesubscript (TObject *t, int mode)
{
- if (tag(top-3) != LUA_T_ARRAY)
- callFB(FB_SETTABLE);
- else
- {
- Object *h = lua_hashdefine (avalue(top-3), top-2);
- *h = *(top-1);
- top -= 3;
- }
+ TObject *im = (mode == 0) ? NULL : luaI_getimbyObj(t, IM_SETTABLE);
+ if (ttype(t) == LUA_T_ARRAY && (im == NULL || ttype(im) == LUA_T_NIL)) {
+ TObject *h = lua_hashdefine(avalue(t), t+1);
+ *h = *(top-1);
+ top -= (mode == 2) ? 1 : 3;
+ }
+ else { /* object is not a table, and/or has a specific "settable" method */
+ if (im && ttype(im) != LUA_T_NIL) {
+ if (mode == 2) {
+ lua_checkstack(top+2);
+ *(top+1) = *(top-1);
+ *(top) = *(t+1);
+ *(top-1) = *t;
+ top += 2;
+ }
+ callIM(im, 3, 0);
+ }
+ else
+ lua_error("indexed expression not a table");
+ }
}
static void getglobal (Word n)
{
- *top = lua_table[n].object;
- incr_top;
- if (tag(top-1) == LUA_T_NIL)
- { /* must call getglobal fallback */
- tag(top-1) = LUA_T_STRING;
- tsvalue(top-1) = lua_table[n].varname;
- callFB(FB_GETGLOBAL);
+ TObject *value = &lua_table[n].object;
+ TObject *im = luaI_getimbyObj(value, IM_GETGLOBAL);
+ if (ttype(im) == LUA_T_NIL) { /* default behavior */
+ *top = *value;
+ incr_top;
}
+ else {
+ ttype(top) = LUA_T_STRING;
+ tsvalue(top) = lua_table[n].varname;
+ incr_top;
+ *top = *value;
+ incr_top;
+ callIM(im, 2, 1);
+ }
}
/*
** Traverse all objects on stack
*/
-void lua_travstack (int (*fn)(Object *))
+void lua_travstack (int (*fn)(TObject *))
{
- Object *o;
- for (o = top-1; o >= stack; o--)
- fn (o);
+ StkId i;
+ for (i = (top-1)-stack; i>=0; i--)
+ fn (stack+i);
}
@@ -377,8 +466,11 @@ void lua_travstack (int (*fn)(Object *))
static void lua_message (char *s)
{
- lua_pushstring(s);
- callFB(FB_ERROR);
+ TObject *im = luaI_geterrorim();
+ if (ttype(im) != LUA_T_NIL) {
+ lua_pushstring(s);
+ callIM(im, 1, 0);
+ }
}
/*
@@ -399,25 +491,25 @@ void lua_error (char *s)
lua_Function lua_stackedfunction (int level)
{
- Object *p = top;
- while (--p >= stack)
- if (p->tag == LUA_T_MARK || p->tag == LUA_T_CMARK)
+ StkId i;
+ for (i = (top-1)-stack; i>=0; i--)
+ if (stack[i].ttype == LUA_T_MARK || stack[i].ttype == LUA_T_CMARK)
if (level-- == 0)
- return Ref(p);
+ return Ref(stack+i);
return LUA_NOOBJECT;
}
int lua_currentline (lua_Function func)
{
- Object *f = Address(func);
- return (f+1 < top && (f+1)->tag == LUA_T_LINE) ? (f+1)->value.i : -1;
+ TObject *f = Address(func);
+ return (f+1 < top && (f+1)->ttype == LUA_T_LINE) ? (f+1)->value.i : -1;
}
lua_Object lua_getlocal (lua_Function func, int local_number, char **name)
{
- Object *f = luaI_Address(func);
+ TObject *f = luaI_Address(func);
*name = luaI_getlocalname(f->value.tf, local_number, lua_currentline(func));
if (*name)
{
@@ -431,9 +523,9 @@ lua_Object lua_getlocal (lua_Function func, int local_number, char **name)
int lua_setlocal (lua_Function func, int local_number)
{
- Object *f = Address(func);
+ TObject *f = Address(func);
char *name = luaI_getlocalname(f->value.tf, local_number, lua_currentline(func));
- adjustC(1);
+ checkCparams(1);
--top;
if (name)
{
@@ -446,6 +538,29 @@ int lua_setlocal (lua_Function func, int local_number)
return 0;
}
+/*
+** Call the function at CLS_current.base, and incorporate results on
+** the Lua2C structure.
+*/
+static void do_callinc (int nResults)
+{
+ StkId base = CLS_current.base;
+ do_call(base+1, nResults);
+ CLS_current.lua2C = base; /* position of the new results */
+ CLS_current.num = (top-stack) - base; /* number of results */
+ CLS_current.base = base + CLS_current.num; /* incorporate results on stack */
+}
+
+
+static void do_unprotectedrun (lua_CFunction f, int nParams, int nResults)
+{
+ StkId base = (top-stack)-nParams;
+ open_stack(nParams);
+ stack[base].ttype = LUA_T_CFUNCTION;
+ stack[base].value.f = f;
+ do_call(base+1, nResults);
+}
+
/*
** Execute a protected call. Assumes that function is at CLS_current.base and
@@ -458,15 +573,11 @@ static int do_protectedrun (int nResults)
struct C_Lua_Stack oldCLS = CLS_current;
jmp_buf *oldErr = errorJmp;
errorJmp = &myErrorJmp;
- if (setjmp(myErrorJmp) == 0)
- {
- do_call(CLS_current.base+1, nResults);
- CLS_current.num = (top-stack) - CLS_current.base; /* number of results */
- CLS_current.base += CLS_current.num; /* incorporate results on the stack */
+ if (setjmp(myErrorJmp) == 0) {
+ do_callinc(nResults);
status = 0;
}
- else
- { /* an error occurred: restore CLS_current and top */
+ else { /* an error occurred: restore CLS_current and top */
CLS_current = oldCLS;
top = stack+CLS_current.base;
status = 1;
@@ -479,13 +590,14 @@ int luaI_dorun (TFunc *tf)
{
int status;
adjustC(1); /* one slot for the pseudo-function */
- stack[CLS_current.base].tag = LUA_T_FUNCTION;
+ stack[CLS_current.base].ttype = LUA_T_FUNCTION;
stack[CLS_current.base].value.tf = tf;
status = do_protectedrun(MULT_RET);
return status;
}
-static int do_protectedmain (void)
+
+int lua_domain (void)
{
TFunc tf;
int status;
@@ -493,23 +605,21 @@ static int do_protectedmain (void)
jmp_buf *oldErr = errorJmp;
errorJmp = &myErrorJmp;
luaI_initTFunc(&tf);
- tf.fileName = lua_parsedfile;
- if (setjmp(myErrorJmp) == 0)
- {
+ if (setjmp(myErrorJmp) == 0) {
lua_parse(&tf);
- status = luaI_dorun(&tf);
+ status = 0;
}
- else
- {
- status = 1;
+ else {
adjustC(0); /* erase extra slot */
+ status = 1;
}
+ if (status == 0)
+ status = luaI_dorun(&tf);
errorJmp = oldErr;
luaI_free(tf.code);
return status;
}
-
/*
** Execute the given lua function. Return 0 on success or 1 on error.
*/
@@ -526,71 +636,31 @@ int lua_callfunction (lua_Object function)
}
-int lua_call (char *funcname)
+lua_Object lua_gettagmethod (int tag, char *event)
{
- Word n = luaI_findsymbolbyname(funcname);
- open_stack((top-stack)-CLS_current.base);
- stack[CLS_current.base] = s_object(n);
- return do_protectedrun(MULT_RET);
+ lua_pushnumber(tag);
+ lua_pushstring(event);
+ do_unprotectedrun(luaI_gettagmethod, 2, 1);
+ return put_luaObjectonTop();
}
-
-/*
-** Open file, generate opcode and execute global statement. Return 0 on
-** success or non 0 on error.
-*/
-int lua_dofile (char *filename)
+lua_Object lua_settagmethod (int tag, char *event)
{
- int status;
- int c;
- FILE *f = lua_openfile(filename);
- if (f == NULL)
- return 2;
- c = fgetc(f);
- ungetc(c, f);
- if (c == ID_CHUNK) {
- f = freopen(filename, "rb", f); /* set binary mode */
- status = luaI_undump(f);
- }
- else {
- if (c == '#')
- while ((c=fgetc(f)) != '\n') /* skip first line */;
- status = do_protectedmain();
- }
- lua_closefile();
- return status;
+ TObject newmethod;
+ checkCparams(1);
+ newmethod = *(--top);
+ lua_pushnumber(tag);
+ lua_pushstring(event);
+ *top = newmethod; incr_top;
+ do_unprotectedrun(luaI_settagmethod, 3, 1);
+ return put_luaObjectonTop();
}
-/*
-** Generate opcode stored on string and execute global statement. Return 0 on
-** success or non 0 on error.
-*/
-int lua_dostring (char *str)
+lua_Object lua_seterrormethod (void)
{
- int status;
- if (str == NULL)
- return 1;
- lua_openstring(str);
- status = do_protectedmain();
- lua_closestring();
- return status;
-}
-
-
-/*
-** API: set a function as a fallback
-*/
-lua_Object lua_setfallback (char *name, lua_CFunction fallback)
-{
- adjustC(1); /* one slot for the pseudo-function */
- stack[CLS_current.base].tag = LUA_T_CFUNCTION;
- stack[CLS_current.base].value.f = luaI_setfallback;
- lua_pushstring(name);
- lua_pushcfunction(fallback);
- if (do_protectedrun(1) == 0)
- return (Ref(top-1));
- else
- return LUA_NOOBJECT;
+ checkCparams(1);
+ do_unprotectedrun(luaI_seterrormethod, 1, 1);
+ return put_luaObjectonTop();
}
@@ -598,12 +668,11 @@ lua_Object lua_setfallback (char *name, lua_CFunction fallback)
** API: receives on the stack the table and the index.
** returns the value.
*/
-lua_Object lua_getsubscript (void)
+lua_Object lua_gettable (void)
{
- adjustC(2);
+ checkCparams(2);
pushsubscript();
- CLS_current.base++; /* incorporate object in the stack */
- return (Ref(top-1));
+ return put_luaObjectonTop();
}
@@ -633,13 +702,25 @@ void lua_endblock (void)
adjustC(0);
}
+void lua_settag (int tag)
+{
+ checkCparams(1);
+ luaI_settag(tag, --top);
+}
+
/*
** API: receives on the stack the table, the index, and the new value.
*/
-void lua_storesubscript (void)
+void lua_settable (void)
{
- adjustC(3);
- storesubscript();
+ checkCparams(3);
+ storesubscript(top-3, 1);
+}
+
+void lua_rawsettable (void)
+{
+ checkCparams(3);
+ storesubscript(top-3, 0);
}
/*
@@ -647,40 +728,59 @@ void lua_storesubscript (void)
*/
lua_Object lua_createtable (void)
{
- adjustC(0);
- avalue(top) = lua_createarray(0);
- tag(top) = LUA_T_ARRAY;
- incr_top;
- CLS_current.base++; /* incorporate object in the stack */
- return Ref(top-1);
+ TObject o;
+ avalue(&o) = lua_createarray(0);
+ ttype(&o) = LUA_T_ARRAY;
+ return put_luaObject(&o);
}
/*
** 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)
+lua_Object lua_lua2C (int number)
+{
+ if (number <= 0 || number > CLS_current.num) return LUA_NOOBJECT;
+ /* Ref(stack+(CLS_current.lua2C+number-1)) ==
+ stack+(CLS_current.lua2C+number-1)-stack+1 == */
+ return CLS_current.lua2C+number;
+}
+
+int lua_isnil (lua_Object o)
+{
+ return (o!= LUA_NOOBJECT) && (ttype(Address(o)) == LUA_T_NIL);
+}
+
+int lua_istable (lua_Object o)
+{
+ return (o!= LUA_NOOBJECT) && (ttype(Address(o)) == LUA_T_ARRAY);
+}
+
+int lua_isuserdata (lua_Object o)
{
- if (number <= 0 || number > CLS_current.num) return LUA_NOOBJECT;
- /* Ref(stack+(CLS_current.base-CLS_current.num+number-1)) ==
- stack+(CLS_current.base-CLS_current.num+number-1)-stack+1 == */
- return CLS_current.base-CLS_current.num+number;
+ return (o!= LUA_NOOBJECT) && (ttype(Address(o)) == LUA_T_USERDATA);
}
-int lua_isnumber (lua_Object object)
+int lua_iscfunction (lua_Object o)
{
- return (object != LUA_NOOBJECT) && (tonumber(Address(object)) == 0);
+ int t = lua_tag(o);
+ return (t == LUA_T_CMARK) || (t == LUA_T_CFUNCTION);
}
-int lua_isstring (lua_Object object)
+int lua_isnumber (lua_Object o)
{
- int t = lua_type(object);
+ return (o!= LUA_NOOBJECT) && (tonumber(Address(o)) == 0);
+}
+
+int lua_isstring (lua_Object o)
+{
+ int t = lua_tag(o);
return (t == LUA_T_STRING) || (t == LUA_T_NUMBER);
}
-int lua_isfunction (lua_Object object)
+int lua_isfunction (lua_Object o)
{
- int t = lua_type(object);
+ int t = lua_tag(o);
return (t == LUA_T_FUNCTION) || (t == LUA_T_CFUNCTION) ||
(t == LUA_T_MARK) || (t == LUA_T_CMARK);
}
@@ -700,57 +800,44 @@ real lua_getnumber (lua_Object object)
*/
char *lua_getstring (lua_Object object)
{
- if (object == LUA_NOOBJECT) return NULL;
- if (tostring (Address(object))) return NULL;
- else return (svalue(Address(object)));
+ if (object == LUA_NOOBJECT || 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)
+
+void *lua_getuserdata (lua_Object object)
{
- if (object == LUA_NOOBJECT || ((tag(Address(object)) != LUA_T_CFUNCTION) &&
- (tag(Address(object)) != LUA_T_CMARK)))
- return NULL;
- else return (fvalue(Address(object)));
+ if (object == LUA_NOOBJECT || ttype(Address(object)) != LUA_T_USERDATA)
+ return NULL;
+ else return tsvalue(Address(object))->u.v;
}
+
/*
-** Given an object handle, return its user data. On error, return NULL.
+** Given an object handle, return its cfuntion pointer. On error, return NULL.
*/
-void *lua_getuserdata (lua_Object object)
+lua_CFunction lua_getcfunction (lua_Object object)
{
- if (object == LUA_NOOBJECT || tag(Address(object)) < LUA_T_USERDATA)
+ if (object == LUA_NOOBJECT || ((ttype(Address(object)) != LUA_T_CFUNCTION) &&
+ (ttype(Address(object)) != LUA_T_CMARK)))
return NULL;
- else return (uvalue(Address(object)));
+ else return (fvalue(Address(object)));
}
lua_Object lua_getref (int ref)
{
- Object *o = luaI_getref(ref);
+ TObject *o = luaI_getref(ref);
if (o == NULL)
return LUA_NOOBJECT;
- adjustC(0);
- luaI_pushobject(o);
- CLS_current.base++; /* incorporate object in the stack */
- return Ref(top-1);
-}
-
-
-void lua_pushref (int ref)
-{
- Object *o = luaI_getref(ref);
- if (o == NULL)
- lua_error("access to invalid (possibly garbage collected) reference");
- luaI_pushobject(o);
+ return put_luaObject(o);
}
int lua_ref (int lock)
{
- adjustC(1);
+ checkCparams(1);
return luaI_ref(--top, lock);
}
@@ -761,20 +848,50 @@ int lua_ref (int lock)
*/
lua_Object lua_getglobal (char *name)
{
- adjustC(0);
- getglobal(luaI_findsymbolbyname(name));
- CLS_current.base++; /* incorporate object in the stack */
- return Ref(top-1);
+ getglobal(luaI_findsymbolbyname(name));
+ return put_luaObjectonTop();
+}
+
+
+lua_Object lua_rawgetglobal (char *name)
+{
+ return put_luaObject(&lua_table[luaI_findsymbolbyname(name)].object);
}
+
/*
** Store top of the stack at a global variable array field.
*/
-void lua_storeglobal (char *name)
+static void setglobal (Word n)
+{
+ TObject *oldvalue = &lua_table[n].object;
+ TObject *im = luaI_getimbyObj(oldvalue, IM_SETGLOBAL);
+ if (ttype(im) == LUA_T_NIL) /* default behavior */
+ s_object(n) = *(--top);
+ else {
+ TObject newvalue = *(top-1);
+ ttype(top-1) = LUA_T_STRING;
+ tsvalue(top-1) = lua_table[n].varname;
+ *top = *oldvalue;
+ incr_top;
+ *top = newvalue;
+ incr_top;
+ callIM(im, 3, 0);
+ }
+}
+
+
+void lua_setglobal (char *name)
{
- Word n = luaI_findsymbolbyname(name);
- adjustC(1);
- s_object(n) = *(--top);
+ checkCparams(1);
+ setglobal(luaI_findsymbolbyname(name));
+}
+
+void lua_rawsetglobal (char *name)
+{
+ Word n = luaI_findsymbolbyname(name);
+ checkCparams(1);
+ s_object(n) = *(--top);
}
/*
@@ -782,60 +899,59 @@ void lua_storeglobal (char *name)
*/
void lua_pushnil (void)
{
- tag(top) = LUA_T_NIL;
- incr_top;
+ ttype(top) = LUA_T_NIL;
+ incr_top;
}
/*
-** Push an object (tag=number) to stack.
+** Push an object (ttype=number) to stack.
*/
void lua_pushnumber (real n)
{
- tag(top) = LUA_T_NUMBER; nvalue(top) = n;
+ ttype(top) = LUA_T_NUMBER; nvalue(top) = n;
incr_top;
}
/*
-** Push an object (tag=string) to stack.
+** Push an object (ttype=string) to stack.
*/
void lua_pushstring (char *s)
{
if (s == NULL)
- tag(top) = LUA_T_NIL;
+ ttype(top) = LUA_T_NIL;
else
{
tsvalue(top) = lua_createstring(s);
- tag(top) = LUA_T_STRING;
+ ttype(top) = LUA_T_STRING;
}
incr_top;
}
-/*>>>>>>>>>#undef lua_pushliteral
-void lua_pushliteral(char *s) { lua_pushstring(s); }*/
+
/*
-** Push an object (tag=cfunction) to stack.
+** Push an object (ttype=cfunction) to stack.
*/
void lua_pushcfunction (lua_CFunction fn)
{
- tag(top) = LUA_T_CFUNCTION; fvalue(top) = fn;
+ ttype(top) = LUA_T_CFUNCTION; fvalue(top) = fn;
incr_top;
}
-/*
-** Push an object (tag=userdata) to stack.
-*/
+
+
void lua_pushusertag (void *u, int tag)
{
- if (tag < LUA_T_USERDATA)
- lua_error("invalid tag in `lua_pushusertag'");
- tag(top) = tag; uvalue(top) = u;
- incr_top;
+ if (tag < 0 && tag != LUA_ANYTAG)
+ luaI_realtag(tag); /* error if tag is not valid */
+ tsvalue(top) = luaI_createudata(u, tag);
+ ttype(top) = LUA_T_USERDATA;
+ incr_top;
}
/*
** Push an object on the stack.
*/
-void luaI_pushobject (Object *o)
+void luaI_pushobject (TObject *o)
{
*top = *o;
incr_top;
@@ -847,78 +963,102 @@ void luaI_pushobject (Object *o)
void lua_pushobject (lua_Object o)
{
if (o == LUA_NOOBJECT)
- lua_error("attempt to push a NOOBJECT");
+ lua_error("API error - attempt to push a NOOBJECT");
*top = *Address(o);
- if (tag(top) == LUA_T_MARK) tag(top) = LUA_T_FUNCTION;
- else if (tag(top) == LUA_T_CMARK) tag(top) = LUA_T_CFUNCTION;
+ if (ttype(top) == LUA_T_MARK) ttype(top) = LUA_T_FUNCTION;
+ else if (ttype(top) == LUA_T_CMARK) ttype(top) = LUA_T_CFUNCTION;
incr_top;
}
-int lua_type (lua_Object o)
+int lua_tag (lua_Object lo)
{
- if (o == LUA_NOOBJECT)
- return LUA_T_NIL;
- else
- return tag(Address(o));
+ if (lo == LUA_NOOBJECT) return LUA_T_NIL;
+ else {
+ TObject *o = Address(lo);
+ lua_Type t = ttype(o);
+ if (t == LUA_T_USERDATA)
+ return o->value.ts->tag;
+ else if (t == LUA_T_ARRAY)
+ return o->value.a->htag;
+ else return t;
+ }
}
-void luaI_gcFB (Object *o)
+void luaI_gcIM (TObject *o)
{
- *top = *o;
- incr_top;
- callFB(FB_GC);
+ TObject *im = luaI_getimbyObj(o, IM_GC);
+ if (ttype(im) != LUA_T_NIL) {
+ *top = *o;
+ incr_top;
+ callIM(im, 1, 0);
+ }
+}
+
+
+static void call_binTM (IMS event, char *msg)
+{
+ TObject *im = luaI_getimbyObj(top-2, event); /* try first operand */
+ if (ttype(im) == LUA_T_NIL) {
+ im = luaI_getimbyObj(top-1, event); /* try second operand */
+ if (ttype(im) == LUA_T_NIL) {
+ im = luaI_getim(0, event); /* try a 'global' i.m. */
+ if (ttype(im) == LUA_T_NIL)
+ lua_error(msg);
+ }
+ }
+ lua_pushstring(luaI_eventname[event]);
+ callIM(im, 3, 1);
}
-static void call_arith (char *op)
+static void call_arith (IMS event)
{
- lua_pushstring(op);
- callFB(FB_ARITH);
+ call_binTM(event, "unexpected type at arithmetic operation");
}
-static void comparison (lua_Type tag_less, lua_Type tag_equal,
- lua_Type tag_great, char *op)
+
+static void comparison (lua_Type ttype_less, lua_Type ttype_equal,
+ lua_Type ttype_great, IMS op)
{
- Object *l = top-2;
- Object *r = top-1;
+ TObject *l = top-2;
+ TObject *r = top-1;
int result;
- if (tag(l) == LUA_T_NUMBER && tag(r) == LUA_T_NUMBER)
+ if (ttype(l) == LUA_T_NUMBER && ttype(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);
- callFB(FB_ORDER);
+ else if (ttype(l) == LUA_T_STRING && ttype(r) == LUA_T_STRING)
+ result = strcmp(svalue(l), svalue(r));
+ else {
+ call_binTM(op, "unexpected type at comparison");
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;
+ ttype(top-1) = (result < 0) ? ttype_less :
+ (result == 0) ? ttype_equal : ttype_great;
}
static void adjust_varargs (StkId first_extra_arg)
{
- Object arg;
- Object *firstelem = stack+first_extra_arg;
+ TObject arg;
+ TObject *firstelem = stack+first_extra_arg;
int nvararg = top-firstelem;
int i;
if (nvararg < 0) nvararg = 0;
avalue(&arg) = lua_createarray(nvararg+1); /* +1 for field 'n' */
- tag(&arg) = LUA_T_ARRAY;
+ ttype(&arg) = LUA_T_ARRAY;
for (i=0; i<nvararg; i++) {
- Object index;
- tag(&index) = LUA_T_NUMBER;
+ TObject index;
+ ttype(&index) = LUA_T_NUMBER;
nvalue(&index) = i+1;
*(lua_hashdefine(avalue(&arg), &index)) = *(firstelem+i);
}
/* store counter in field "n" */ {
- Object index, extra;
- tag(&index) = LUA_T_STRING;
+ TObject index, extra;
+ ttype(&index) = LUA_T_STRING;
tsvalue(&index) = lua_createstring("n");
- tag(&extra) = LUA_T_NUMBER;
+ ttype(&extra) = LUA_T_NUMBER;
nvalue(&extra) = nvararg;
*(lua_hashdefine(avalue(&arg), &index)) = extra;
}
@@ -942,22 +1082,22 @@ static StkId lua_execute (Byte *pc, StkId base)
OpCode opcode;
switch (opcode = (OpCode)*pc++)
{
- case PUSHNIL: tag(top) = LUA_T_NIL; incr_top; break;
+ case PUSHNIL: ttype(top) = LUA_T_NIL; incr_top; break;
case PUSH0: case PUSH1: case PUSH2:
- tag(top) = LUA_T_NUMBER;
+ ttype(top) = LUA_T_NUMBER;
nvalue(top) = opcode-PUSH0;
incr_top;
break;
case PUSHBYTE:
- tag(top) = LUA_T_NUMBER; nvalue(top) = *pc++; incr_top; break;
+ ttype(top) = LUA_T_NUMBER; nvalue(top) = *pc++; incr_top; break;
case PUSHWORD:
{
Word w;
get_word(w,pc);
- tag(top) = LUA_T_NUMBER; nvalue(top) = w;
+ ttype(top) = LUA_T_NUMBER; nvalue(top) = w;
incr_top;
}
break;
@@ -966,7 +1106,7 @@ static StkId lua_execute (Byte *pc, StkId base)
{
real num;
get_float(num,pc);
- tag(top) = LUA_T_NUMBER; nvalue(top) = num;
+ ttype(top) = LUA_T_NUMBER; nvalue(top) = num;
incr_top;
}
break;
@@ -975,7 +1115,7 @@ static StkId lua_execute (Byte *pc, StkId base)
{
Word w;
get_word(w,pc);
- tag(top) = LUA_T_STRING; tsvalue(top) = lua_constant[w];
+ ttype(top) = LUA_T_STRING; tsvalue(top) = lua_constant[w];
incr_top;
}
break;
@@ -985,7 +1125,7 @@ static StkId lua_execute (Byte *pc, StkId base)
TFunc *f;
get_code(f,pc);
luaI_insertfunction(f); /* may take part in GC */
- top->tag = LUA_T_FUNCTION;
+ top->ttype = LUA_T_FUNCTION;
top->value.tf = f;
incr_top;
}
@@ -1013,10 +1153,10 @@ static StkId lua_execute (Byte *pc, StkId base)
case PUSHSELF:
{
- Object receiver = *(top-1);
+ TObject receiver = *(top-1);
Word w;
get_word(w,pc);
- tag(top) = LUA_T_STRING; tsvalue(top) = lua_constant[w];
+ ttype(top) = LUA_T_STRING; tsvalue(top) = lua_constant[w];
incr_top;
pushsubscript();
*top = receiver;
@@ -1037,47 +1177,32 @@ static StkId lua_execute (Byte *pc, StkId base)
{
Word w;
get_word(w,pc);
- s_object(w) = *(--top);
+ setglobal(w);
}
break;
case STOREINDEXED0:
- storesubscript();
+ storesubscript(top-3, 1);
break;
- case STOREINDEXED:
- {
- int n = *pc++;
- if (tag(top-3-n) != LUA_T_ARRAY)
- {
- lua_checkstack(top+2);
- *(top+1) = *(top-1);
- *(top) = *(top-2-n);
- *(top-1) = *(top-3-n);
- top += 2;
- callFB(FB_SETTABLE);
- }
- else
- {
- Object *h = lua_hashdefine (avalue(top-3-n), top-2-n);
- *h = *(top-1);
- top--;
- }
+ case STOREINDEXED: {
+ int n = *pc++;
+ storesubscript(top-3-n, 2);
+ break;
}
- break;
case STORELIST0:
case STORELIST:
{
int m, n;
- Object *arr;
+ TObject *arr;
if (opcode == STORELIST0) m = 0;
else m = *(pc++) * FIELDS_PER_FLUSH;
n = *(pc++);
arr = top-n-1;
while (n)
{
- tag(top) = LUA_T_NUMBER; nvalue(top) = n+m;
+ ttype(top) = LUA_T_NUMBER; nvalue(top) = n+m;
*(lua_hashdefine (avalue(arr), top)) = *(top-1);
top--;
n--;
@@ -1085,15 +1210,15 @@ static StkId lua_execute (Byte *pc, StkId base)
}
break;
- case STORERECORD:
+ case STORERECORD: /* opcode obsolete: supersed by STOREMAP */
{
int n = *(pc++);
- Object *arr = top-n-1;
+ TObject *arr = top-n-1;
while (n)
{
Word w;
get_word(w,pc);
- tag(top) = LUA_T_STRING; tsvalue(top) = lua_constant[w];
+ ttype(top) = LUA_T_STRING; tsvalue(top) = lua_constant[w];
*(lua_hashdefine (avalue(arr), top)) = *(top-1);
top--;
n--;
@@ -1101,13 +1226,25 @@ static StkId lua_execute (Byte *pc, StkId base)
}
break;
+ case STOREMAP: {
+ int n = *(pc++);
+ TObject *arr = top-(2*n)-1;
+ while (n--) {
+ *(lua_hashdefine (avalue(arr), top-2)) = *(top-1);
+ top-=2;
+ }
+ }
+ break;
+
case ADJUST0:
adjust_top(base);
break;
- case ADJUST:
- adjust_top(base + *(pc++));
+ case ADJUST: {
+ StkId newtop = base + *(pc++);
+ adjust_top(newtop);
break;
+ }
case VARARGS:
adjust_varargs(base + *(pc++));
@@ -1118,7 +1255,7 @@ static StkId lua_execute (Byte *pc, StkId base)
Word size;
get_word(size,pc);
avalue(top) = lua_createarray(size);
- tag(top) = LUA_T_ARRAY;
+ ttype(top) = LUA_T_ARRAY;
incr_top;
}
break;
@@ -1127,33 +1264,33 @@ static StkId lua_execute (Byte *pc, StkId base)
{
int res = lua_equalObj(top-2, top-1);
--top;
- tag(top-1) = res ? LUA_T_NUMBER : LUA_T_NIL;
+ ttype(top-1) = res ? LUA_T_NUMBER : LUA_T_NIL;
nvalue(top-1) = 1;
}
break;
case LTOP:
- comparison(LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, "lt");
+ comparison(LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT);
break;
case LEOP:
- comparison(LUA_T_NUMBER, LUA_T_NUMBER, LUA_T_NIL, "le");
+ comparison(LUA_T_NUMBER, LUA_T_NUMBER, LUA_T_NIL, IM_LE);
break;
case GTOP:
- comparison(LUA_T_NIL, LUA_T_NIL, LUA_T_NUMBER, "gt");
+ comparison(LUA_T_NIL, LUA_T_NIL, LUA_T_NUMBER, IM_GT);
break;
case GEOP:
- comparison(LUA_T_NIL, LUA_T_NUMBER, LUA_T_NUMBER, "ge");
+ comparison(LUA_T_NIL, LUA_T_NUMBER, LUA_T_NUMBER, IM_GE);
break;
case ADDOP:
{
- Object *l = top-2;
- Object *r = top-1;
+ TObject *l = top-2;
+ TObject *r = top-1;
if (tonumber(r) || tonumber(l))
- call_arith("add");
+ call_arith(IM_ADD);
else
{
nvalue(l) += nvalue(r);
@@ -1164,10 +1301,10 @@ static StkId lua_execute (Byte *pc, StkId base)
case SUBOP:
{
- Object *l = top-2;
- Object *r = top-1;
+ TObject *l = top-2;
+ TObject *r = top-1;
if (tonumber(r) || tonumber(l))
- call_arith("sub");
+ call_arith(IM_SUB);
else
{
nvalue(l) -= nvalue(r);
@@ -1178,10 +1315,10 @@ static StkId lua_execute (Byte *pc, StkId base)
case MULTOP:
{
- Object *l = top-2;
- Object *r = top-1;
+ TObject *l = top-2;
+ TObject *r = top-1;
if (tonumber(r) || tonumber(l))
- call_arith("mul");
+ call_arith(IM_MUL);
else
{
nvalue(l) *= nvalue(r);
@@ -1192,10 +1329,10 @@ static StkId lua_execute (Byte *pc, StkId base)
case DIVOP:
{
- Object *l = top-2;
- Object *r = top-1;
+ TObject *l = top-2;
+ TObject *r = top-1;
if (tonumber(r) || tonumber(l))
- call_arith("div");
+ call_arith(IM_DIV);
else
{
nvalue(l) /= nvalue(r);
@@ -1205,36 +1342,34 @@ static StkId lua_execute (Byte *pc, StkId base)
break;
case POWOP:
- call_arith("pow");
+ call_arith(IM_POW);
break;
- case CONCOP:
- {
- Object *l = top-2;
- Object *r = top-1;
- if (tostring(r) || tostring(l))
- callFB(FB_CONCAT);
- else
- {
- tsvalue(l) = lua_createstring (lua_strconc(svalue(l),svalue(r)));
- --top;
- }
+ case CONCOP: {
+ TObject *l = top-2;
+ TObject *r = top-1;
+ if (tostring(l) || tostring(r))
+ call_binTM(IM_CONCAT, "unexpected type for concatenation");
+ else {
+ tsvalue(l) = lua_createstring(lua_strconc(svalue(l),svalue(r)));
+ --top;
+ }
}
break;
case MINUSOP:
if (tonumber(top-1))
{
- tag(top) = LUA_T_NIL;
+ ttype(top) = LUA_T_NIL;
incr_top;
- call_arith("unm");
+ call_arith(IM_UNM);
}
else
nvalue(top-1) = - nvalue(top-1);
break;
case NOTOP:
- tag(top-1) = (tag(top-1) == LUA_T_NIL) ? LUA_T_NUMBER : LUA_T_NIL;
+ ttype(top-1) = (ttype(top-1) == LUA_T_NIL) ? LUA_T_NUMBER : LUA_T_NIL;
nvalue(top-1) = 1;
break;
@@ -1242,15 +1377,15 @@ static StkId lua_execute (Byte *pc, StkId base)
{
Word w;
get_word(w,pc);
- if (tag(top-1) != LUA_T_NIL) pc += w;
+ if (ttype(top-1) != LUA_T_NIL) pc += w;
}
break;
- case ONFJMP:
+ case ONFJMP:
{
Word w;
get_word(w,pc);
- if (tag(top-1) == LUA_T_NIL) pc += w;
+ if (ttype(top-1) == LUA_T_NIL) pc += w;
}
break;
@@ -1275,7 +1410,7 @@ static StkId lua_execute (Byte *pc, StkId base)
Word w;
get_word(w,pc);
top--;
- if (tag(top) == LUA_T_NIL) pc += w;
+ if (ttype(top) == LUA_T_NIL) pc += w;
}
break;
@@ -1284,7 +1419,7 @@ static StkId lua_execute (Byte *pc, StkId base)
Word w;
get_word(w,pc);
top--;
- if (tag(top) == LUA_T_NIL) pc -= w;
+ if (ttype(top) == LUA_T_NIL) pc -= w;
}
break;
@@ -1309,12 +1444,12 @@ static StkId lua_execute (Byte *pc, StkId base)
{
Word line;
get_word(line,pc);
- if ((stack+base-1)->tag != LUA_T_LINE)
+ if ((stack+base-1)->ttype != LUA_T_LINE)
{
/* open space for LINE value */
open_stack((top-stack)-base);
base++;
- (stack+base-1)->tag = LUA_T_LINE;
+ (stack+base-1)->ttype = LUA_T_LINE;
}
(stack+base-1)->value.i = line;
if (lua_linehook)
@@ -1328,3 +1463,16 @@ static StkId lua_execute (Byte *pc, StkId base)
}
}
+
+#if COMPAT2_5
+/*
+** API: set a function as a fallback
+*/
+lua_Object lua_setfallback (char *name, lua_CFunction fallback)
+{
+ lua_pushstring(name);
+ lua_pushcfunction(fallback);
+ do_unprotectedrun(luaI_setfallback, 2, 1);
+ return put_luaObjectonTop();
+}
+#endif
diff --git a/src/opcode.h b/src/opcode.h
index 381efbc8..0b63de96 100644
--- a/src/opcode.h
+++ b/src/opcode.h
@@ -1,6 +1,6 @@
/*
** TeCGraf - PUC-Rio
-** $Id: opcode.h,v 3.24 1996/11/01 12:46:59 roberto Exp $
+** $Id: opcode.h,v 3.34 1997/06/16 16:50:22 roberto Exp $
*/
#ifndef opcode_h
@@ -14,6 +14,28 @@
#define FIELDS_PER_FLUSH 40
+/*
+* WARNING: if you change the order of this enumeration,
+* grep "ORDER LUA_T"
+*/
+typedef enum
+{
+ LUA_T_NIL = -9,
+ LUA_T_NUMBER = -8,
+ LUA_T_STRING = -7,
+ LUA_T_ARRAY = -6, /* array==table */
+ LUA_T_FUNCTION = -5,
+ LUA_T_CFUNCTION= -4,
+ LUA_T_MARK = -3,
+ LUA_T_CMARK = -2,
+ LUA_T_LINE = -1,
+ LUA_T_USERDATA = 0
+} lua_Type;
+
+#define NUM_TYPES 10
+
+
+extern char *luaI_typenames[];
typedef enum {
/* name parm before after side effect
@@ -38,7 +60,7 @@ PUSHLOCAL6,/* - LOC[6] */
PUSHLOCAL7,/* - LOC[7] */
PUSHLOCAL8,/* - LOC[8] */
PUSHLOCAL9,/* - LOC[9] */
-PUSHLOCAL,/* w - LOC[w] */
+PUSHLOCAL,/* b - LOC[b] */
PUSHGLOBAL,/* w - VAR[w] */
PUSHINDEXED,/* i t t[i] */
PUSHSELF,/* w t t t[STR[w]] */
@@ -52,14 +74,14 @@ STORELOCAL6,/* x - LOC[6]=x */
STORELOCAL7,/* x - LOC[7]=x */
STORELOCAL8,/* x - LOC[8]=x */
STORELOCAL9,/* x - LOC[9]=x */
-STORELOCAL,/* w x - LOC[w]=x */
+STORELOCAL,/* b x - LOC[b]=x */
STOREGLOBAL,/* w x - VAR[w]=x */
STOREINDEXED0,/* v i t - t[i]=v */
STOREINDEXED,/* b v a_b...a_1 i t a_b...a_1 i t t[i]=v */
-STORELIST0,/* w v_w...v_1 t - t[i]=v_i */
-STORELIST,/* w n v_w...v_1 t - t[i+n*FPF]=v_i */
-STORERECORD,/* n
- w_n...w_1 v_n...v_1 t - t[STR[w_i]]=v_i */
+STORELIST0,/* b v_b...v_1 t - t[i]=v_i */
+STORELIST,/* b c v_b...v_1 t - t[i+c*FPF]=v_i */
+STORERECORD,/* b
+ w_b...w_1 v_b...v_1 t - t[STR[w_i]]=v_i */
ADJUST0,/* - - TOP=BASE */
ADJUST,/* b - - TOP=BASE+b */
CREATEARRAY,/* w - newarray(size = w) */
@@ -76,19 +98,19 @@ POWOP,/* y x x^y */
CONCOP,/* y x x..y */
MINUSOP,/* x -x */
NOTOP,/* x (x==nil)? 1 : nil */
-ONTJMP,/* w x - (x!=nil)? PC+=w */
-ONFJMP,/* w x - (x==nil)? PC+=w */
+ONTJMP,/* w x - (x!=nil)? PC+=w */
+ONFJMP,/* w x - (x==nil)? PC+=w */
JMP,/* w - - PC+=w */
-UPJMP,/* w - - PC-=w */
-IFFJMP,/* w x - (x==nil)? PC+=w */
+UPJMP,/* w - - PC-=w */
+IFFJMP,/* w x - (x==nil)? PC+=w */
IFFUPJMP,/* w x - (x==nil)? PC-=w */
POP,/* x - */
-CALLFUNC,/* n m v_n...v_1 f r_m...r_1 f(v1,...,v_n) */
+CALLFUNC,/* b c v_b...v_1 f r_c...r_1 f(v1,...,v_b) */
RETCODE0,
RETCODE,/* b - - */
SETLINE,/* w - - LINE=w */
-VARARGS/* b v_n...v_1 {v_1...v_n;n=n} */
-
+VARARGS,/* b v_b...v_1 {v_1...v_b;n=b} */
+STOREMAP/* b v_b k_b ...v_1 k_1 t - t[k_i]=v_i */
} OpCode;
@@ -102,29 +124,27 @@ typedef union
TaggedString *ts;
TFunc *tf;
struct Hash *a;
- void *u;
int i;
} Value;
-typedef struct Object
+typedef struct TObject
{
- lua_Type tag;
+ lua_Type ttype;
Value value;
-} Object;
+} TObject;
/* Macros to access structure members */
-#define tag(o) ((o)->tag)
+#define ttype(o) ((o)->ttype)
#define nvalue(o) ((o)->value.n)
#define svalue(o) ((o)->value.ts->str)
#define tsvalue(o) ((o)->value.ts)
#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_object(i) (lua_table[i].object)
-#define s_tag(i) (tag(&s_object(i)))
+#define s_ttype(i) (ttype(&s_object(i)))
#define s_nvalue(i) (nvalue(&s_object(i)))
#define s_svalue(i) (svalue(&s_object(i)))
#define s_tsvalue(i) (tsvalue(&s_object(i)))
@@ -141,10 +161,11 @@ typedef struct Object
/* Exported functions */
void lua_parse (TFunc *tf); /* from "lua.stx" module */
void luaI_codedebugline (int line); /* from "lua.stx" module */
-void lua_travstack (int (*fn)(Object *));
-Object *luaI_Address (lua_Object o);
-void luaI_pushobject (Object *o);
-void luaI_gcFB (Object *o);
+void lua_travstack (int (*fn)(TObject *));
+TObject *luaI_Address (lua_Object o);
+void luaI_pushobject (TObject *o);
+void luaI_gcIM (TObject *o);
int luaI_dorun (TFunc *tf);
+int lua_domain (void);
#endif
diff --git a/src/parser.c b/src/parser.c
index c91ee00e..ad5f8d68 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -10,14 +10,14 @@ static char luaY_sccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93";
#define YYPREFIX "luaY_"
#line 2 "lua.stx"
-char *rcs_luastx = "$Id: parser.c,v 1.1 1996/11/21 16:11:40 lhf Exp $";
+char *rcs_luastx = "$Id: parser.c,v 1.1 1997/06/30 18:59:03 lhf Exp $";
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "luadebug.h"
-#include "mem.h"
+#include "luamem.h"
#include "lex.h"
#include "opcode.h"
#include "hash.h"
@@ -60,8 +60,6 @@ static TaggedString *localvar[MAXLOCALS]; /* store local variable names */
static int nlocalvar=0; /* number of local variables */
#define MAXFIELDS FIELDS_PER_FLUSH*2
-static Word fields[MAXFIELDS]; /* fieldnames to be flushed */
-static int nfields=0;
int lua_debug = 0;
@@ -113,22 +111,11 @@ static void code_word_at (Byte *p, int n)
memcpy(p, &w, sizeof(Word));
}
-static void push_field (Word name)
-{
- if (nfields < MAXFIELDS)
- fields[nfields++] = name;
- else
- luaY_error ("too many fields in nested constructors");
-}
-
static void flush_record (int n)
{
- int i;
if (n == 0) return;
- code_byte(STORERECORD);
+ code_byte(STOREMAP);
code_byte(n);
- for (i=0; i<n; i++)
- code_word(fields[--nfields]);
}
static void flush_list (int m, int n)
@@ -171,11 +158,22 @@ static void add_varbuffer (Long var)
luaY_error ("variable buffer overflow");
}
+static void code_string (Word w)
+{
+ code_byte(PUSHSTRING);
+ code_word(w);
+}
+
+static void code_constant (TaggedString *s)
+{
+ code_string(luaI_findconstant(s));
+}
+
static void code_number (float f)
{
- Word i = (Word)f;
- if (f == (float)i) /* f has an (short) integer value */
- {
+ Word i;
+ if (f >= 0 && f <= (float)MAX_WORD && (float)(i=(Word)f) == f) {
+ /* f has an (short) integer value */
if (i <= 2) code_byte(PUSH0 + i);
else if (i <= 255)
{
@@ -418,7 +416,7 @@ void lua_parse (TFunc *tf)
}
-#line 414 "lua.stx"
+#line 412 "lua.stx"
typedef union
{
int vInt;
@@ -429,7 +427,7 @@ typedef union
TFunc *pFunc;
TaggedString *pTStr;
} YYSTYPE;
-#line 433 "y.tab.c"
+#line 431 "y.tab.c"
#define WRONGTOKEN 257
#define NIL 258
#define IF 259
@@ -467,8 +465,9 @@ short luaY_lhs[] = { -1,
38, 5, 39, 5, 40, 37, 4, 8, 8, 7,
7, 2, 2, 3, 41, 3, 17, 17, 18, 18,
19, 19, 42, 9, 9, 14, 14, 43, 43, 12,
- 12, 13, 13, 44, 15, 15, 16, 16, 6, 6,
- 20, 20, 20, 21, 29, 10, 10, 11, 11,
+ 12, 13, 13, 44, 45, 45, 15, 15, 16, 16,
+ 6, 6, 20, 20, 20, 21, 29, 10, 10, 11,
+ 11,
};
short luaY_len[] = { 2,
2, 0, 3, 2, 3, 1, 3, 5, 0, 3,
@@ -479,113 +478,114 @@ short luaY_len[] = { 2,
0, 5, 0, 5, 0, 4, 2, 1, 3, 3,
1, 0, 1, 1, 0, 4, 0, 1, 1, 3,
1, 1, 0, 3, 2, 0, 2, 0, 1, 0,
- 2, 1, 3, 3, 0, 2, 1, 3, 1, 3,
- 1, 4, 3, 1, 1, 1, 3, 0, 2,
+ 2, 1, 3, 3, 3, 1, 0, 2, 1, 3,
+ 1, 3, 1, 4, 3, 1, 1, 1, 3, 0,
+ 2,
};
short luaY_defred[] = { 2,
- 0, 0, 0, 14, 16, 0, 0, 0, 94, 19,
- 0, 0, 0, 91, 1, 0, 4, 0, 48, 46,
- 47, 0, 0, 0, 49, 29, 95, 0, 0, 44,
- 0, 0, 24, 0, 0, 0, 0, 96, 0, 0,
+ 0, 0, 0, 14, 16, 0, 0, 0, 96, 19,
+ 0, 0, 0, 93, 1, 0, 4, 0, 48, 46,
+ 47, 0, 0, 0, 49, 29, 97, 0, 0, 44,
+ 0, 0, 24, 0, 0, 0, 0, 98, 0, 0,
0, 0, 0, 0, 0, 57, 61, 12, 3, 0,
0, 0, 0, 0, 0, 28, 28, 28, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 9, 27, 65, 0, 0, 20, 0,
- 5, 0, 0, 0, 0, 0, 59, 0, 93, 30,
+ 5, 0, 0, 0, 0, 0, 59, 0, 95, 30,
24, 51, 53, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 73, 0,
- 0, 82, 28, 0, 0, 0, 0, 97, 72, 71,
- 0, 0, 69, 7, 60, 92, 28, 0, 0, 0,
- 56, 0, 75, 0, 0, 86, 24, 0, 25, 0,
- 0, 24, 0, 0, 0, 0, 0, 0, 83, 0,
- 74, 0, 28, 17, 10, 0, 70, 24, 0, 0,
- 77, 0, 0, 8, 22, 0, 13, 81, 15, 28,
- 24, 28, 0, 23,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 73,
+ 0, 0, 82, 0, 28, 0, 0, 0, 0, 99,
+ 72, 71, 0, 0, 69, 7, 60, 94, 28, 0,
+ 0, 0, 56, 0, 75, 0, 0, 88, 0, 24,
+ 0, 25, 0, 0, 24, 0, 0, 0, 0, 85,
+ 86, 83, 0, 74, 0, 0, 28, 17, 10, 0,
+ 70, 24, 0, 0, 77, 0, 0, 8, 22, 0,
+ 13, 81, 15, 28, 24, 28, 0, 23,
};
short luaY_dgoto[] = { 1,
- 91, 34, 35, 25, 26, 11, 46, 12, 107, 39,
- 79, 161, 108, 151, 109, 110, 121, 122, 123, 27,
+ 91, 34, 35, 25, 26, 11, 46, 12, 108, 39,
+ 79, 165, 109, 154, 110, 111, 123, 124, 125, 27,
14, 41, 81, 2, 15, 16, 49, 17, 28, 73,
- 115, 37, 160, 32, 33, 74, 30, 128, 129, 31,
- 116, 134, 133, 112,
+ 117, 37, 164, 32, 33, 74, 30, 130, 131, 31,
+ 118, 136, 135, 113, 114,
};
short luaY_sindex[] = { 0,
- 0, 332, -38, 0, 0, -38, -239, -223, 0, 0,
- -23, 17, 0, 0, 0, 3, 0, 137, 0, 0,
- 0, -38, -38, -38, 0, 0, 0, 137, 547, 0,
- -25, -38, 0, 3, 45, 0, 212, 0, -22, 0,
- 52, 140, -38, -223, -38, 0, 0, 0, 0, -166,
- -38, -154, 40, 40, 102, 0, 0, 0, -38, -38,
- -38, -38, -38, -38, -38, -38, -38, -38, -38, -38,
- -34, 481, -130, 0, 0, 0, -38, -129, 0, -194,
- 0, -123, 45, 0, -17, 103, 0, 753, 0, 0,
- 0, 0, 0, -30, -30, -30, -30, -30, -30, 95,
- 11, 11, 40, 40, 40, 97, 41, 123, 0, 124,
- 212, 0, 0, -38, -59, -38, 45, 0, 0, 0,
- 128, 131, 0, 0, 0, 0, 0, -38, -38, -38,
- 0, -97, 0, 120, -38, 0, 0, 212, 0, 3,
- 0, 0, -194, -183, 118, 118, 212, 97, 0, -97,
- 0, 212, 0, 0, 0, -85, 0, 0, -38, -82,
- 0, 123, -80, 0, 0, 1105, 0, 0, 0, 0,
- 0, 0, -183, 0,
+ 0, 288, -34, 0, 0, -34, -238, -223, 0, 0,
+ -6, 22, 0, 0, 0, 14, 0, 150, 0, 0,
+ 0, -34, -34, -34, 0, 0, 0, 150, 547, 0,
+ -46, -34, 0, 14, 34, 0, 212, 0, -5, 0,
+ 39, 156, -34, -223, -34, 0, 0, 0, 0, -194,
+ -34, -193, -4, -4, 48, 0, 0, 0, -34, -34,
+ -34, -34, -34, -34, -34, -34, -34, -34, -34, -34,
+ -38, 481, -173, 0, 0, 0, -34, -146, 0, -234,
+ 0, -138, 34, 0, -15, 96, 0, 753, 0, 0,
+ 0, 0, 0, -30, -30, -30, -30, -30, -30, -20,
+ -12, -12, -4, -4, -4, 0, -34, 16, 95, 0,
+ 98, 212, 0, 82, 0, -34, 328, -34, 34, 0,
+ 0, 0, 103, 101, 0, 0, 0, 0, 0, -34,
+ -34, 1181, 0, -91, 0, 92, -34, 0, -34, 0,
+ 212, 0, 14, 0, 0, -234, -233, 118, 118, 0,
+ 0, 0, -91, 0, 212, 212, 0, 0, 0, -105,
+ 0, 0, -34, -103, 0, 95, -101, 0, 0, 1105,
+ 0, 0, 0, 0, 0, 0, -233, 0,
};
short luaY_rindex[] = { 0,
- 0, 191, 69, 0, 0, 173, 0, 0, 0, 0,
- 0, 69, 150, 0, 0, 146, 0, -36, 0, 0,
- 0, 69, 69, 69, 0, 0, 0, 1, 0, 0,
- 0, 69, 0, 47, 461, 436, 0, 0, 197, 130,
- 0, 0, 69, 0, -33, 0, 0, 0, 0, 0,
- 69, 0, 24, 59, 1181, 0, 0, 0, 69, 69,
- 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
- -50, 0, 0, 0, 0, 0, 69, 0, 0, 152,
- 0, 0, 311, -21, 0, 0, 0, 0, 0, 0,
+ 0, 169, 52, 0, 0, 173, 0, 0, 0, 0,
+ 0, 52, 508, 0, 0, 146, 0, -36, 0, 0,
+ 0, 52, 52, 52, 0, 0, 0, 1, 0, 0,
+ 0, 52, 0, 47, 461, 436, 0, 0, 197, 76,
+ 0, 0, 52, 0, -32, 0, 0, 0, 0, 0,
+ 52, 0, 24, 59, 1195, 0, 0, 0, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ -27, 0, 0, 0, 0, 0, 52, 0, 0, 129,
+ 0, 0, 311, 142, 0, 0, 0, 0, 0, 0,
0, 0, 0, 746, 776, 799, 821, 844, 866, 505,
- 383, 410, 88, 112, 359, 1174, 0, 74, 0, -40,
- -26, 0, 0, 69, -230, 69, 921, 0, 0, 0,
- 0, 160, 0, 0, 0, 0, 0, 69, 69, 69,
- 0, 77, 0, 78, -9, 0, 0, 939, 0, 289,
- 474, 0, 0, -60, 894, 1137, -16, 0, 0, 89,
- 0, -10, 0, 0, 0, 0, 0, 0, 69, 0,
- 0, 74, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, -60, 0,
+ 383, 410, 88, 112, 359, 1174, 52, 0, 51, 0,
+ -40, -10, 0, 0, 0, 52, -153, 52, 921, 0,
+ 0, 0, 0, 144, 0, 0, 0, 0, 0, 52,
+ 52, 0, 0, 62, 0, 64, -26, 0, 52, 0,
+ 939, 0, 682, 474, 0, 0, -77, 894, 1137, 0,
+ 0, 0, 66, 0, 13, -18, 0, 0, 0, 0,
+ 0, 0, 52, 0, 0, 51, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, -77, 0,
};
short luaY_gindex[] = { 0,
- -31, 171, 85, -2, 48, 0, 0, 0, 0, 0,
- 0, 0, 67, 0, 0, 0, 0, 0, 75, 8,
- 0, 0, 0, 0, 104, 107, -29, 0, 12, -61,
- 0, 1260, 50, 0, 0, 0, 213, 0, 0, 0,
- 0, 0, -107, 94,
+ 53, 147, -23, 3, 134, 0, 0, 0, 0, 0,
+ 0, 0, 40, 0, 0, 0, 0, 0, 49, 6,
+ 0, 0, 0, 0, 81, 83, -16, 0, 8, -70,
+ 0, 1445, 27, 0, 0, 0, 187, 0, 0, 0,
+ 0, 0, -108, 67, 0,
};
-#define YYTABLESIZE 1462
-short luaY_table[] = { 10,
- 45, 24, 136, 58, 75, 24, 22, 62, 85, 13,
- 22, 68, 66, 18, 67, 40, 69, 87, 78, 42,
- 44, 78, 90, 43, 95, 92, 93, 84, 52, 127,
- 26, 26, 87, 88, 38, 26, 26, 43, 77, 90,
- 58, 45, 45, 45, 45, 45, 11, 45, 88, 79,
- 9, 84, 68, 36, 168, 85, 45, 69, 50, 45,
- 45, 48, 45, 70, 43, 43, 43, 43, 43, 95,
- 43, 55, 55, 51, 85, 153, 119, 158, 159, 120,
- 156, 137, 43, 43, 78, 43, 58, 39, 76, 55,
- 36, 80, 36, 45, 45, 144, 165, 71, 87, 50,
- 50, 50, 50, 50, 70, 50, 154, 87, 84, 172,
- 155, 40, 10, 55, 88, 79, 43, 50, 50, 89,
- 50, 163, 13, 58, 36, 45, 18, 83, 39, 39,
- 39, 39, 39, 70, 39, 114, 68, 66, 171, 67,
- 173, 69, 90, 125, 118, 11, 39, 39, 43, 39,
- 124, 50, 40, 40, 40, 40, 40, 130, 40, 68,
- 66, 117, 67, 141, 69, 131, 132, 135, 142, 6,
- 40, 40, 62, 40, 143, 95, 148, 62, 150, 61,
- 39, 164, 52, 50, 167, 52, 169, 95, 70, 95,
- 26, 55, 67, 89, 50, 95, 98, 82, 78, 3,
- 68, 79, 76, 4, 40, 5, 21, 95, 6, 7,
- 89, 70, 39, 80, 9, 86, 162, 157, 139, 19,
- 95, 140, 174, 19, 47, 149, 0, 51, 0, 0,
- 51, 62, 0, 20, 21, 9, 40, 20, 21, 106,
- 95, 0, 0, 0, 23, 0, 0, 0, 23, 0,
- 65, 0, 0, 68, 66, 98, 67, 0, 69, 45,
+#define YYTABLESIZE 1608
+short luaY_table[] = { 107,
+ 45, 24, 138, 58, 10, 24, 22, 13, 62, 18,
+ 22, 68, 66, 40, 67, 42, 69, 75, 78, 83,
+ 129, 68, 66, 43, 67, 84, 69, 162, 163, 68,
+ 52, 87, 79, 89, 69, 38, 121, 44, 78, 122,
+ 58, 45, 45, 45, 45, 45, 11, 45, 89, 84,
+ 9, 85, 107, 119, 43, 77, 90, 172, 50, 45,
+ 45, 45, 45, 70, 43, 43, 43, 43, 43, 157,
+ 43, 90, 48, 70, 160, 51, 71, 76, 80, 87,
+ 89, 70, 43, 43, 78, 43, 58, 39, 90, 70,
+ 55, 169, 116, 45, 45, 55, 55, 87, 79, 50,
+ 50, 50, 50, 50, 176, 50, 84, 26, 26, 92,
+ 93, 40, 26, 26, 89, 6, 43, 50, 50, 10,
+ 50, 97, 13, 58, 18, 45, 159, 120, 39, 39,
+ 39, 39, 39, 97, 39, 126, 127, 90, 134, 36,
+ 133, 137, 139, 145, 146, 11, 39, 39, 43, 39,
+ 153, 50, 40, 40, 40, 40, 40, 55, 40, 68,
+ 66, 168, 67, 171, 69, 173, 97, 140, 26, 67,
+ 40, 40, 62, 40, 55, 78, 36, 62, 36, 61,
+ 39, 147, 151, 50, 68, 92, 79, 97, 76, 21,
+ 80, 86, 166, 158, 161, 52, 100, 142, 47, 143,
+ 152, 52, 92, 178, 40, 0, 0, 50, 0, 167,
+ 36, 70, 39, 82, 0, 0, 0, 0, 0, 19,
+ 0, 0, 0, 19, 0, 0, 175, 0, 177, 0,
+ 0, 62, 97, 20, 21, 106, 40, 20, 21, 9,
+ 51, 0, 0, 0, 23, 0, 51, 0, 23, 0,
+ 65, 144, 0, 68, 66, 100, 67, 0, 69, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
- 45, 62, 95, 61, 45, 45, 45, 45, 45, 45,
+ 45, 62, 0, 61, 45, 45, 45, 45, 45, 45,
45, 45, 43, 43, 43, 43, 43, 43, 43, 43,
43, 43, 43, 43, 0, 55, 0, 43, 43, 43,
43, 43, 43, 43, 43, 70, 0, 11, 11, 0,
@@ -603,25 +603,25 @@ short luaY_table[] = { 10,
41, 0, 0, 37, 0, 37, 37, 37, 0, 0,
0, 0, 0, 62, 62, 64, 0, 0, 62, 62,
0, 37, 37, 0, 37, 0, 0, 0, 0, 0,
- 38, 41, 38, 38, 38, 98, 0, 98, 98, 98,
- 63, 98, 98, 98, 98, 98, 98, 0, 38, 38,
- 98, 38, 0, 66, 0, 37, 64, 29, 29, 64,
+ 38, 41, 38, 38, 38, 100, 0, 100, 100, 100,
+ 63, 100, 100, 100, 100, 100, 100, 0, 38, 38,
+ 100, 38, 0, 66, 0, 37, 64, 29, 29, 64,
29, 0, 29, 41, 0, 0, 57, 58, 59, 60,
63, 64, 65, 0, 64, 29, 0, 29, 0, 0,
0, 63, 38, 0, 42, 0, 0, 37, 0, 0,
0, 0, 0, 0, 66, 29, 29, 66, 29, 63,
29, 0, 68, 66, 0, 67, 0, 69, 0, 29,
0, 0, 66, 29, 38, 29, 0, 0, 0, 0,
- 62, 0, 61, 0, 0, 42, 0, 11, 42, 11,
- 11, 11, 0, 11, 11, 11, 11, 11, 0, 0,
- 0, 0, 11, 42, 42, 0, 42, 29, 0, 18,
+ 62, 0, 61, 0, 0, 42, 3, 97, 42, 0,
+ 4, 91, 5, 97, 0, 6, 7, 8, 0, 0,
+ 0, 9, 0, 42, 42, 97, 42, 29, 91, 18,
0, 18, 18, 18, 70, 18, 18, 18, 18, 18,
- 18, 0, 0, 0, 18, 0, 0, 0, 68, 66,
- 3, 67, 0, 69, 4, 0, 5, 42, 0, 6,
- 7, 8, 0, 0, 0, 9, 62, 0, 61, 0,
+ 18, 0, 0, 0, 18, 0, 3, 0, 68, 66,
+ 4, 67, 5, 69, 0, 6, 7, 42, 97, 0,
+ 0, 9, 0, 0, 0, 0, 62, 0, 61, 0,
0, 0, 0, 0, 0, 0, 0, 41, 41, 41,
41, 41, 41, 41, 41, 41, 41, 41, 41, 42,
- 0, 0, 41, 41, 41, 41, 41, 41, 41, 41,
+ 97, 0, 41, 41, 41, 41, 41, 41, 41, 41,
70, 37, 37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 0, 0, 0, 37, 37, 37, 37,
37, 37, 37, 37, 0, 0, 0, 0, 38, 38,
@@ -632,7 +632,7 @@ short luaY_table[] = { 10,
29, 29, 29, 29, 29, 29, 29, 0, 0, 0,
0, 63, 63, 0, 0, 0, 63, 63, 0, 0,
0, 0, 66, 0, 66, 66, 66, 0, 66, 66,
- 66, 66, 66, 66, 113, 31, 0, 66, 29, 29,
+ 66, 66, 66, 66, 115, 31, 0, 66, 29, 29,
29, 29, 29, 29, 29, 57, 58, 59, 60, 63,
64, 65, 0, 42, 42, 42, 42, 42, 42, 42,
42, 42, 42, 42, 42, 34, 0, 0, 42, 42,
@@ -642,7 +642,7 @@ short luaY_table[] = { 10,
0, 0, 62, 0, 61, 0, 34, 0, 0, 34,
32, 57, 58, 59, 60, 63, 64, 65, 0, 0,
0, 0, 0, 0, 34, 34, 0, 34, 31, 33,
- 0, 0, 33, 35, 0, 126, 70, 0, 0, 0,
+ 0, 0, 33, 35, 0, 128, 70, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 33, 33, 0,
33, 32, 0, 0, 32, 36, 0, 0, 34, 0,
31, 0, 0, 0, 0, 0, 0, 0, 0, 32,
@@ -650,12 +650,12 @@ short luaY_table[] = { 10,
0, 33, 0, 52, 0, 0, 0, 0, 0, 0,
34, 0, 35, 35, 0, 35, 36, 0, 0, 36,
0, 0, 0, 32, 0, 0, 0, 0, 0, 0,
- 99, 0, 0, 33, 36, 36, 0, 36, 0, 0,
+ 101, 0, 0, 33, 36, 36, 0, 36, 0, 0,
0, 0, 0, 0, 52, 0, 35, 52, 28, 0,
- 0, 0, 0, 0, 0, 32, 0, 0, 0, 0,
- 0, 0, 52, 0, 0, 0, 0, 0, 36, 0,
+ 11, 0, 11, 11, 11, 32, 11, 11, 11, 11,
+ 11, 0, 52, 0, 0, 11, 0, 0, 36, 0,
0, 0, 0, 0, 0, 0, 0, 0, 35, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 99,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 101,
0, 0, 0, 0, 0, 0, 52, 0, 0, 0,
36, 0, 0, 0, 0, 0, 0, 28, 0, 0,
0, 0, 0, 0, 31, 31, 31, 31, 31, 31,
@@ -675,66 +675,80 @@ short luaY_table[] = { 10,
36, 36, 36, 36, 36, 36, 68, 66, 0, 67,
0, 69, 52, 52, 52, 52, 52, 52, 52, 52,
52, 52, 52, 52, 62, 0, 61, 52, 52, 52,
- 0, 0, 0, 0, 0, 0, 0, 54, 0, 99,
- 54, 99, 99, 99, 0, 99, 99, 99, 99, 99,
- 99, 0, 0, 0, 99, 54, 0, 28, 70, 28,
+ 0, 0, 0, 0, 0, 0, 0, 54, 0, 101,
+ 54, 101, 101, 101, 0, 101, 101, 101, 101, 101,
+ 101, 0, 0, 0, 101, 54, 0, 28, 70, 28,
28, 28, 0, 28, 28, 28, 28, 28, 28, 0,
- 0, 0, 28, 94, 0, 94, 94, 94, 94, 94,
- 94, 0, 29, 29, 0, 29, 0, 29, 0, 54,
- 0, 94, 94, 94, 0, 94, 0, 0, 0, 0,
- 29, 0, 29, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 28, 96, 0, 96, 96, 96, 96, 96,
+ 96, 0, 68, 66, 0, 67, 0, 69, 0, 54,
+ 0, 96, 96, 96, 86, 96, 29, 29, 0, 29,
+ 62, 29, 61, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 29, 0, 29, 0, 0, 0,
+ 0, 54, 0, 0, 96, 0, 0, 96, 0, 0,
+ 0, 0, 0, 150, 70, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 29, 0,
+ 0, 0, 0, 0, 0, 0, 96, 0, 96, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 54, 29, 0, 94, 0, 0, 94, 0, 0,
- 0, 0, 0, 0, 29, 0, 0, 0, 0, 0,
- 0, 53, 54, 0, 0, 0, 0, 0, 0, 0,
- 0, 72, 0, 0, 0, 0, 94, 0, 94, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 88, 0, 0, 0, 0, 0, 0, 0, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
- 111, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 170, 0, 0, 0, 0, 0,
- 0, 0, 0, 138, 0, 0, 0, 0, 0, 57,
- 58, 59, 60, 63, 64, 65, 0, 145, 146, 147,
- 0, 0, 0, 0, 152, 54, 54, 54, 54, 54,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 174, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 57,
+ 58, 59, 60, 63, 64, 65, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 54, 54, 54, 54, 54,
54, 54, 54, 54, 54, 54, 54, 0, 0, 0,
- 54, 54, 54, 0, 0, 0, 0, 0, 166, 0,
+ 54, 54, 54, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 29, 96, 96,
+ 96, 96, 96, 96, 96, 57, 58, 59, 60, 63,
+ 64, 65, 0, 0, 0, 0, 53, 54, 0, 29,
+ 29, 29, 29, 29, 29, 29, 72, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 88, 0, 0, 0, 0,
+ 0, 0, 0, 94, 95, 96, 97, 98, 99, 100,
+ 101, 102, 103, 104, 105, 112, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 94, 94,
- 94, 94, 94, 94, 94, 29, 29, 29, 29, 29,
- 29, 29,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 132, 0, 0, 0, 0, 0, 0, 0, 0,
+ 141, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 148, 149, 0, 0, 0, 0,
+ 0, 155, 0, 156, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 170,
};
-short luaY_check[] = { 2,
- 0, 40, 110, 40, 34, 40, 45, 41, 59, 2,
- 45, 42, 43, 2, 45, 8, 47, 44, 59, 8,
- 44, 44, 44, 0, 46, 57, 58, 44, 46, 91,
- 261, 262, 59, 44, 274, 266, 267, 61, 61, 61,
- 40, 41, 42, 43, 44, 45, 0, 47, 59, 59,
- 274, 44, 42, 6, 162, 44, 40, 47, 0, 59,
- 60, 59, 62, 94, 41, 42, 43, 44, 45, 91,
- 47, 24, 123, 91, 125, 137, 271, 261, 262, 274,
- 142, 113, 59, 60, 125, 62, 123, 0, 44, 123,
- 43, 40, 45, 93, 94, 127, 158, 123, 125, 41,
- 42, 43, 44, 45, 94, 47, 138, 274, 125, 171,
- 140, 0, 115, 123, 125, 125, 93, 59, 60, 274,
- 62, 153, 115, 123, 77, 125, 115, 43, 41, 42,
- 43, 44, 45, 94, 47, 266, 42, 43, 170, 45,
- 172, 47, 41, 41, 274, 0, 59, 60, 125, 62,
- 274, 93, 41, 42, 43, 44, 45, 61, 47, 42,
- 43, 77, 45, 116, 47, 125, 44, 44, 41, 40,
- 59, 60, 0, 62, 44, 46, 274, 60, 59, 62,
- 93, 267, 46, 125, 267, 46, 267, 58, 94, 40,
- 0, 123, 41, 44, 58, 46, 0, 58, 125, 259,
- 41, 125, 125, 263, 93, 265, 267, 58, 268, 269,
- 61, 94, 125, 125, 274, 45, 150, 143, 115, 258,
- 91, 115, 173, 258, 12, 132, -1, 91, -1, -1,
- 91, 59, -1, 272, 273, 274, 125, 272, 273, 274,
- 91, -1, -1, -1, 283, -1, -1, -1, 283, -1,
- 281, -1, -1, 42, 43, 59, 45, -1, 47, 259,
+short luaY_check[] = { 91,
+ 0, 40, 111, 40, 2, 40, 45, 2, 41, 2,
+ 45, 42, 43, 8, 45, 8, 47, 34, 59, 43,
+ 91, 42, 43, 0, 45, 44, 47, 261, 262, 42,
+ 46, 59, 59, 44, 47, 274, 271, 44, 44, 274,
+ 40, 41, 42, 43, 44, 45, 0, 47, 59, 44,
+ 274, 44, 91, 77, 61, 61, 44, 166, 0, 59,
+ 60, 40, 62, 94, 41, 42, 43, 44, 45, 140,
+ 47, 59, 59, 94, 145, 91, 123, 44, 40, 274,
+ 274, 94, 59, 60, 125, 62, 123, 0, 41, 94,
+ 123, 162, 266, 93, 94, 123, 123, 125, 125, 41,
+ 42, 43, 44, 45, 175, 47, 125, 261, 262, 57,
+ 58, 0, 266, 267, 125, 40, 93, 59, 60, 117,
+ 62, 46, 117, 123, 117, 125, 143, 274, 41, 42,
+ 43, 44, 45, 58, 47, 274, 41, 125, 44, 6,
+ 125, 44, 61, 41, 44, 0, 59, 60, 125, 62,
+ 59, 93, 41, 42, 43, 44, 45, 24, 47, 42,
+ 43, 267, 45, 267, 47, 267, 91, 115, 0, 41,
+ 59, 60, 0, 62, 123, 125, 43, 60, 45, 62,
+ 93, 129, 274, 125, 41, 44, 125, 46, 125, 267,
+ 125, 45, 153, 141, 146, 46, 0, 117, 12, 117,
+ 134, 46, 61, 177, 93, -1, -1, 58, -1, 157,
+ 77, 94, 125, 58, -1, -1, -1, -1, -1, 258,
+ -1, -1, -1, 258, -1, -1, 174, -1, 176, -1,
+ -1, 59, 91, 272, 273, 274, 125, 272, 273, 274,
+ 91, -1, -1, -1, 283, -1, 91, -1, 283, -1,
+ 281, 118, -1, 42, 43, 59, 45, -1, 47, 259,
260, 261, 262, 263, 264, 265, 266, 267, 268, 269,
- 270, 60, 123, 62, 274, 275, 276, 277, 278, 279,
+ 270, 60, -1, 62, 274, 275, 276, 277, 278, 279,
280, 281, 259, 260, 261, 262, 263, 264, 265, 266,
267, 268, 269, 270, -1, 123, -1, 274, 275, 276,
277, 278, 279, 280, 281, 94, -1, 261, 262, -1,
@@ -761,16 +775,16 @@ short luaY_check[] = { 2,
-1, -1, -1, -1, 41, 42, 43, 44, 45, 59,
47, -1, 42, 43, -1, 45, -1, 47, -1, 94,
-1, -1, 59, 60, 125, 62, -1, -1, -1, -1,
- 60, -1, 62, -1, -1, 41, -1, 259, 44, 261,
- 262, 263, -1, 265, 266, 267, 268, 269, -1, -1,
- -1, -1, 274, 59, 60, -1, 62, 94, -1, 259,
+ 60, -1, 62, -1, -1, 41, 259, 40, 44, -1,
+ 263, 44, 265, 46, -1, 268, 269, 270, -1, -1,
+ -1, 274, -1, 59, 60, 58, 62, 94, 61, 259,
-1, 261, 262, 263, 94, 265, 266, 267, 268, 269,
- 270, -1, -1, -1, 274, -1, -1, -1, 42, 43,
- 259, 45, -1, 47, 263, -1, 265, 93, -1, 268,
- 269, 270, -1, -1, -1, 274, 60, -1, 62, -1,
+ 270, -1, -1, -1, 274, -1, 259, -1, 42, 43,
+ 263, 45, 265, 47, -1, 268, 269, 93, 91, -1,
+ -1, 274, -1, -1, -1, -1, 60, -1, 62, -1,
-1, -1, -1, -1, -1, -1, -1, 259, 260, 261,
262, 263, 264, 265, 266, 267, 268, 269, 270, 125,
- -1, -1, 274, 275, 276, 277, 278, 279, 280, 281,
+ 123, -1, 274, 275, 276, 277, 278, 279, 280, 281,
94, 259, 260, 261, 262, 263, 264, 265, 266, 267,
268, 269, 270, -1, -1, -1, 274, 275, 276, 277,
278, 279, 280, 281, -1, -1, -1, -1, 259, 260,
@@ -801,8 +815,8 @@ short luaY_check[] = { 2,
-1, -1, -1, 93, -1, -1, -1, -1, -1, -1,
0, -1, -1, 125, 59, 60, -1, 62, -1, -1,
-1, -1, -1, -1, 41, -1, 93, 44, 0, -1,
- -1, -1, -1, -1, -1, 125, -1, -1, -1, -1,
- -1, -1, 59, -1, -1, -1, -1, -1, 93, -1,
+ 259, -1, 261, 262, 263, 125, 265, 266, 267, 268,
+ 269, -1, 59, -1, -1, 274, -1, -1, 93, -1,
-1, -1, -1, -1, -1, -1, -1, -1, 125, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, 59,
-1, -1, -1, -1, -1, -1, 93, -1, -1, -1,
@@ -830,30 +844,44 @@ short luaY_check[] = { 2,
262, 263, -1, 265, 266, 267, 268, 269, 270, -1,
-1, -1, 274, 40, -1, 42, 43, 44, 45, 46,
47, -1, 42, 43, -1, 45, -1, 47, -1, 93,
- -1, 58, 59, 60, -1, 62, -1, -1, -1, -1,
- 60, -1, 62, -1, -1, -1, -1, -1, -1, -1,
+ -1, 58, 59, 60, 61, 62, 42, 43, -1, 45,
+ 60, 47, 62, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 60, -1, 62, -1, -1, -1,
+ -1, 125, -1, -1, 91, -1, -1, 94, -1, -1,
+ -1, -1, -1, 93, 94, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 94, -1,
+ -1, -1, -1, -1, -1, -1, 123, -1, 125, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 125, 3, -1, 91, -1, -1, 94, -1, -1,
- -1, -1, -1, -1, 94, -1, -1, -1, -1, -1,
- -1, 22, 23, -1, -1, -1, -1, -1, -1, -1,
- -1, 32, -1, -1, -1, -1, 123, -1, 125, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 51, -1, -1, -1, -1, -1, -1, -1, 59, 60,
- 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
- 71, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, 260, -1, -1, -1, -1, -1,
- -1, -1, -1, 114, -1, -1, -1, -1, -1, 275,
- 276, 277, 278, 279, 280, 281, -1, 128, 129, 130,
- -1, -1, -1, -1, 135, 259, 260, 261, 262, 263,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 275,
+ 276, 277, 278, 279, 280, 281, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 259, 260, 261, 262, 263,
264, 265, 266, 267, 268, 269, 270, -1, -1, -1,
- 274, 275, 276, -1, -1, -1, -1, -1, 159, -1,
+ 274, 275, 276, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 275, 276,
+ -1, -1, -1, -1, -1, -1, -1, 3, 275, 276,
277, 278, 279, 280, 281, 275, 276, 277, 278, 279,
- 280, 281,
+ 280, 281, -1, -1, -1, -1, 22, 23, -1, 275,
+ 276, 277, 278, 279, 280, 281, 32, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 51, -1, -1, -1, -1,
+ -1, -1, -1, 59, 60, 61, 62, 63, 64, 65,
+ 66, 67, 68, 69, 70, 71, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 107, -1, -1, -1, -1, -1, -1, -1, -1,
+ 116, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 130, 131, -1, -1, -1, -1,
+ -1, 137, -1, 139, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 163,
};
#define YYFINAL 1
#ifndef YYDEBUG
@@ -958,7 +986,9 @@ char *luaY_rule[] = {
"ffieldlist : ffieldlist1 lastcomma",
"ffieldlist1 : ffield",
"ffieldlist1 : ffieldlist1 ',' ffield",
-"ffield : NAME '=' expr1",
+"ffield : ffieldkey '=' expr1",
+"ffieldkey : '[' expr1 ']'",
+"ffieldkey : NAME",
"lfieldlist :",
"lfieldlist : lfieldlist1 lastcomma",
"lfieldlist1 : expr1",
@@ -1139,7 +1169,7 @@ luaY_reduce:
switch (luaY_n)
{
case 5:
-#line 470 "lua.stx"
+#line 468 "lua.stx"
{
code_byte(PUSHFUNCTION);
code_code(luaY_vsp[0].pFunc);
@@ -1147,28 +1177,26 @@ case 5:
}
break;
case 6:
-#line 477 "lua.stx"
+#line 475 "lua.stx"
{ luaY_val.vLong =luaY_vsp[0].vLong; init_func(); }
break;
case 7:
-#line 479 "lua.stx"
+#line 477 "lua.stx"
{
- code_byte(PUSHSTRING);
- code_word(luaI_findconstant(luaY_vsp[0].pTStr));
+ code_constant(luaY_vsp[0].pTStr);
luaY_val.vLong = 0; /* indexed variable */
init_func();
add_localvar(luaI_createfixedstring("self"));
}
break;
case 8:
-#line 489 "lua.stx"
+#line 486 "lua.stx"
{
codereturn();
luaY_val.pFunc = new(TFunc);
luaI_initTFunc(luaY_val.pFunc);
luaY_val.pFunc->size = pc;
luaY_val.pFunc->code = newvector(pc, Byte);
- luaY_val.pFunc->fileName = lua_parsedfile;
luaY_val.pFunc->lineDefined = luaY_vsp[-3].vInt;
memcpy(luaY_val.pFunc->code, basepc, pc*sizeof(Byte));
if (lua_debug)
@@ -1182,15 +1210,15 @@ case 8:
}
break;
case 13:
-#line 516 "lua.stx"
+#line 512 "lua.stx"
{ codeIf(luaY_vsp[-4].vLong, luaY_vsp[-2].vLong); }
break;
case 14:
-#line 518 "lua.stx"
+#line 514 "lua.stx"
{luaY_val.vLong=pc;}
break;
case 15:
-#line 519 "lua.stx"
+#line 515 "lua.stx"
{
basepc[luaY_vsp[-3].vLong] = IFFJMP;
code_word_at(basepc+luaY_vsp[-3].vLong+1, pc - (luaY_vsp[-3].vLong + sizeof(Word)+1));
@@ -1199,18 +1227,18 @@ case 15:
}
break;
case 16:
-#line 526 "lua.stx"
+#line 522 "lua.stx"
{luaY_val.vLong=pc;}
break;
case 17:
-#line 527 "lua.stx"
+#line 523 "lua.stx"
{
basepc[luaY_vsp[0].vLong] = IFFUPJMP;
code_word_at(basepc+luaY_vsp[0].vLong+1, pc - (luaY_vsp[-4].vLong));
}
break;
case 18:
-#line 533 "lua.stx"
+#line 529 "lua.stx"
{
{
int i;
@@ -1222,22 +1250,26 @@ case 18:
}
}
break;
+case 19:
+#line 539 "lua.stx"
+{;}
+break;
case 20:
-#line 545 "lua.stx"
+#line 541 "lua.stx"
{ nlocalvar += luaY_vsp[-1].vInt;
adjust_mult_assign(luaY_vsp[-1].vInt, luaY_vsp[0].vInt, 0);
}
break;
case 23:
-#line 553 "lua.stx"
+#line 549 "lua.stx"
{ codeIf(luaY_vsp[-3].vLong, luaY_vsp[-1].vLong); }
break;
case 24:
-#line 556 "lua.stx"
+#line 552 "lua.stx"
{luaY_val.vInt = nlocalvar;}
break;
case 25:
-#line 557 "lua.stx"
+#line 553 "lua.stx"
{
if (nlocalvar != luaY_vsp[-2].vInt)
{
@@ -1251,14 +1283,14 @@ case 25:
}
break;
case 27:
-#line 572 "lua.stx"
+#line 568 "lua.stx"
{
adjust_functioncall(luaY_vsp[-1].vLong, MULT_RET);
codereturn();
}
break;
case 28:
-#line 579 "lua.stx"
+#line 575 "lua.stx"
{
luaY_val.vLong = pc;
code_byte(0); /* open space */
@@ -1266,103 +1298,102 @@ case 28:
}
break;
case 29:
-#line 586 "lua.stx"
+#line 582 "lua.stx"
{ adjust_functioncall(luaY_vsp[0].vLong, 1); }
break;
case 30:
-#line 589 "lua.stx"
+#line 585 "lua.stx"
{ luaY_val.vLong = luaY_vsp[-1].vLong; }
break;
case 31:
-#line 590 "lua.stx"
+#line 586 "lua.stx"
{ code_byte(EQOP); luaY_val.vLong = 0; }
break;
case 32:
-#line 591 "lua.stx"
+#line 587 "lua.stx"
{ code_byte(LTOP); luaY_val.vLong = 0; }
break;
case 33:
-#line 592 "lua.stx"
+#line 588 "lua.stx"
{ code_byte(GTOP); luaY_val.vLong = 0; }
break;
case 34:
-#line 593 "lua.stx"
+#line 589 "lua.stx"
{ code_byte(EQOP); code_byte(NOTOP); luaY_val.vLong = 0; }
break;
case 35:
-#line 594 "lua.stx"
+#line 590 "lua.stx"
{ code_byte(LEOP); luaY_val.vLong = 0; }
break;
case 36:
-#line 595 "lua.stx"
+#line 591 "lua.stx"
{ code_byte(GEOP); luaY_val.vLong = 0; }
break;
case 37:
-#line 596 "lua.stx"
+#line 592 "lua.stx"
{ code_byte(ADDOP); luaY_val.vLong = 0; }
break;
case 38:
-#line 597 "lua.stx"
+#line 593 "lua.stx"
{ code_byte(SUBOP); luaY_val.vLong = 0; }
break;
case 39:
-#line 598 "lua.stx"
+#line 594 "lua.stx"
{ code_byte(MULTOP); luaY_val.vLong = 0; }
break;
case 40:
-#line 599 "lua.stx"
+#line 595 "lua.stx"
{ code_byte(DIVOP); luaY_val.vLong = 0; }
break;
case 41:
-#line 600 "lua.stx"
+#line 596 "lua.stx"
{ code_byte(POWOP); luaY_val.vLong = 0; }
break;
case 42:
-#line 601 "lua.stx"
+#line 597 "lua.stx"
{ code_byte(CONCOP); luaY_val.vLong = 0; }
break;
case 43:
-#line 602 "lua.stx"
+#line 598 "lua.stx"
{ code_byte(MINUSOP); luaY_val.vLong = 0;}
break;
case 44:
-#line 603 "lua.stx"
+#line 599 "lua.stx"
{ luaY_val.vLong = 0; }
break;
case 45:
-#line 604 "lua.stx"
+#line 600 "lua.stx"
{ luaY_val.vLong = 0;}
break;
case 46:
-#line 605 "lua.stx"
+#line 601 "lua.stx"
{ code_number(luaY_vsp[0].vFloat); luaY_val.vLong = 0; }
break;
case 47:
-#line 607 "lua.stx"
+#line 603 "lua.stx"
{
- code_byte(PUSHSTRING);
- code_word(luaY_vsp[0].vWord);
- luaY_val.vLong = 0;
+ code_string(luaY_vsp[0].vWord);
+ luaY_val.vLong = 0;
}
break;
case 48:
-#line 612 "lua.stx"
+#line 607 "lua.stx"
{code_byte(PUSHNIL); luaY_val.vLong = 0; }
break;
case 49:
-#line 613 "lua.stx"
+#line 608 "lua.stx"
{ luaY_val.vLong = luaY_vsp[0].vLong; }
break;
case 50:
-#line 614 "lua.stx"
+#line 609 "lua.stx"
{ code_byte(NOTOP); luaY_val.vLong = 0;}
break;
case 51:
-#line 615 "lua.stx"
+#line 610 "lua.stx"
{code_byte(POP); }
break;
case 52:
-#line 616 "lua.stx"
+#line 611 "lua.stx"
{
basepc[luaY_vsp[-2].vLong] = ONFJMP;
code_word_at(basepc+luaY_vsp[-2].vLong+1, pc - (luaY_vsp[-2].vLong + sizeof(Word)+1));
@@ -1370,11 +1401,11 @@ case 52:
}
break;
case 53:
-#line 621 "lua.stx"
+#line 616 "lua.stx"
{code_byte(POP); }
break;
case 54:
-#line 622 "lua.stx"
+#line 617 "lua.stx"
{
basepc[luaY_vsp[-2].vLong] = ONTJMP;
code_word_at(basepc+luaY_vsp[-2].vLong+1, pc - (luaY_vsp[-2].vLong + sizeof(Word)+1));
@@ -1382,20 +1413,20 @@ case 54:
}
break;
case 55:
-#line 630 "lua.stx"
+#line 625 "lua.stx"
{
code_byte(CREATEARRAY);
luaY_val.vLong = pc; code_word(0);
}
break;
case 56:
-#line 635 "lua.stx"
+#line 630 "lua.stx"
{
code_word_at(basepc+luaY_vsp[-3].vLong, luaY_vsp[-1].vInt);
}
break;
case 57:
-#line 641 "lua.stx"
+#line 636 "lua.stx"
{
code_byte(CALLFUNC);
code_byte(luaY_vsp[-1].vInt+luaY_vsp[0].vInt);
@@ -1404,11 +1435,11 @@ case 57:
}
break;
case 58:
-#line 649 "lua.stx"
+#line 644 "lua.stx"
{ luaY_val.vInt = 0; }
break;
case 59:
-#line 651 "lua.stx"
+#line 646 "lua.stx"
{
code_byte(PUSHSELF);
code_word(luaI_findconstant(luaY_vsp[0].pTStr));
@@ -1416,31 +1447,31 @@ case 59:
}
break;
case 60:
-#line 659 "lua.stx"
+#line 654 "lua.stx"
{ luaY_val.vInt = adjust_functioncall(luaY_vsp[-1].vLong, 1); }
break;
case 61:
-#line 660 "lua.stx"
+#line 655 "lua.stx"
{ luaY_val.vInt = 1; }
break;
case 62:
-#line 663 "lua.stx"
+#line 658 "lua.stx"
{ luaY_val.vLong = 0; }
break;
case 63:
-#line 664 "lua.stx"
+#line 659 "lua.stx"
{ luaY_val.vLong = luaY_vsp[0].vLong; }
break;
case 64:
-#line 667 "lua.stx"
+#line 662 "lua.stx"
{ if (luaY_vsp[0].vLong != 0) luaY_val.vLong = luaY_vsp[0].vLong; else luaY_val.vLong = -1; }
break;
case 65:
-#line 668 "lua.stx"
+#line 663 "lua.stx"
{ luaY_val.vLong = adjust_functioncall(luaY_vsp[-1].vLong, 1); }
break;
case 66:
-#line 669 "lua.stx"
+#line 664 "lua.stx"
{
if (luaY_vsp[0].vLong == 0) luaY_val.vLong = -(luaY_vsp[-1].vLong + 1); /* -length */
else
@@ -1451,19 +1482,19 @@ case 66:
}
break;
case 67:
-#line 679 "lua.stx"
+#line 674 "lua.stx"
{ luaY_val.vInt = close_parlist(0); }
break;
case 68:
-#line 680 "lua.stx"
+#line 675 "lua.stx"
{ luaY_val.vInt = close_parlist(luaY_vsp[0].vInt); }
break;
case 69:
-#line 683 "lua.stx"
+#line 678 "lua.stx"
{ luaY_val.vInt = luaY_vsp[0].vInt; }
break;
case 70:
-#line 685 "lua.stx"
+#line 680 "lua.stx"
{
if (luaY_vsp[-2].vInt)
lua_error("invalid parameter list");
@@ -1471,113 +1502,110 @@ case 70:
}
break;
case 71:
-#line 692 "lua.stx"
+#line 687 "lua.stx"
{ add_localvar(luaY_vsp[0].pTStr); luaY_val.vInt = 0; }
break;
case 72:
-#line 693 "lua.stx"
+#line 688 "lua.stx"
{ luaY_val.vInt = 1; }
break;
case 73:
-#line 697 "lua.stx"
+#line 692 "lua.stx"
{ flush_list(luaY_vsp[0].vInt/FIELDS_PER_FLUSH, luaY_vsp[0].vInt%FIELDS_PER_FLUSH); }
break;
case 74:
-#line 699 "lua.stx"
+#line 694 "lua.stx"
{ luaY_val.vInt = luaY_vsp[-2].vInt+luaY_vsp[0].vInt; }
break;
case 75:
-#line 701 "lua.stx"
+#line 696 "lua.stx"
{ luaY_val.vInt = luaY_vsp[-1].vInt; flush_record(luaY_vsp[-1].vInt%FIELDS_PER_FLUSH); }
break;
case 76:
-#line 705 "lua.stx"
+#line 700 "lua.stx"
{ luaY_val.vInt = 0; }
break;
case 77:
-#line 707 "lua.stx"
+#line 702 "lua.stx"
{ luaY_val.vInt = luaY_vsp[0].vInt; flush_record(luaY_vsp[0].vInt%FIELDS_PER_FLUSH); }
break;
case 80:
-#line 714 "lua.stx"
+#line 709 "lua.stx"
{ luaY_val.vInt = 0; }
break;
case 81:
-#line 715 "lua.stx"
+#line 710 "lua.stx"
{ luaY_val.vInt = luaY_vsp[-1].vInt; }
break;
case 82:
-#line 718 "lua.stx"
+#line 713 "lua.stx"
{luaY_val.vInt=1;}
break;
case 83:
-#line 720 "lua.stx"
+#line 715 "lua.stx"
{
luaY_val.vInt=luaY_vsp[-2].vInt+1;
if (luaY_val.vInt%FIELDS_PER_FLUSH == 0) flush_record(FIELDS_PER_FLUSH);
}
break;
-case 84:
-#line 727 "lua.stx"
-{
- push_field(luaI_findconstant(luaY_vsp[-2].pTStr));
- }
+case 86:
+#line 725 "lua.stx"
+{ code_constant(luaY_vsp[0].pTStr); }
break;
-case 85:
-#line 732 "lua.stx"
+case 87:
+#line 728 "lua.stx"
{ luaY_val.vInt = 0; }
break;
-case 86:
-#line 733 "lua.stx"
+case 88:
+#line 729 "lua.stx"
{ luaY_val.vInt = luaY_vsp[-1].vInt; }
break;
-case 87:
-#line 736 "lua.stx"
+case 89:
+#line 732 "lua.stx"
{luaY_val.vInt=1;}
break;
-case 88:
-#line 738 "lua.stx"
+case 90:
+#line 734 "lua.stx"
{
luaY_val.vInt=luaY_vsp[-2].vInt+1;
if (luaY_val.vInt%FIELDS_PER_FLUSH == 0)
flush_list(luaY_val.vInt/FIELDS_PER_FLUSH - 1, FIELDS_PER_FLUSH);
}
break;
-case 89:
-#line 746 "lua.stx"
+case 91:
+#line 742 "lua.stx"
{
nvarbuffer = 0;
add_varbuffer(luaY_vsp[0].vLong);
luaY_val.vInt = (luaY_vsp[0].vLong == 0) ? 1 : 0;
}
break;
-case 90:
-#line 752 "lua.stx"
+case 92:
+#line 748 "lua.stx"
{
add_varbuffer(luaY_vsp[0].vLong);
luaY_val.vInt = (luaY_vsp[0].vLong == 0) ? luaY_vsp[-2].vInt + 1 : luaY_vsp[-2].vInt;
}
break;
-case 91:
-#line 758 "lua.stx"
+case 93:
+#line 754 "lua.stx"
{ luaY_val.vLong = luaY_vsp[0].vLong; }
break;
-case 92:
-#line 760 "lua.stx"
+case 94:
+#line 756 "lua.stx"
{
luaY_val.vLong = 0; /* indexed variable */
}
break;
-case 93:
-#line 764 "lua.stx"
+case 95:
+#line 760 "lua.stx"
{
- code_byte(PUSHSTRING);
- code_word(luaI_findconstant(luaY_vsp[0].pTStr));
- luaY_val.vLong = 0; /* indexed variable */
+ code_constant(luaY_vsp[0].pTStr);
+ luaY_val.vLong = 0; /* indexed variable */
}
break;
-case 94:
-#line 772 "lua.stx"
+case 96:
+#line 767 "lua.stx"
{
int local = lua_localname(luaY_vsp[0].pTStr);
if (local == -1) /* global var */
@@ -1586,30 +1614,30 @@ case 94:
luaY_val.vLong = -(local+1); /* return negative value */
}
break;
-case 95:
-#line 781 "lua.stx"
+case 97:
+#line 776 "lua.stx"
{ lua_pushvar(luaY_vsp[0].vLong); }
break;
-case 96:
-#line 784 "lua.stx"
+case 98:
+#line 779 "lua.stx"
{store_localvar(luaY_vsp[0].pTStr, 0); luaY_val.vInt = 1;}
break;
-case 97:
-#line 786 "lua.stx"
+case 99:
+#line 781 "lua.stx"
{
store_localvar(luaY_vsp[0].pTStr, luaY_vsp[-2].vInt);
luaY_val.vInt = luaY_vsp[-2].vInt+1;
}
break;
-case 98:
-#line 792 "lua.stx"
+case 100:
+#line 787 "lua.stx"
{ luaY_val.vInt = 0; }
break;
-case 99:
-#line 793 "lua.stx"
+case 101:
+#line 788 "lua.stx"
{ luaY_val.vInt = luaY_vsp[0].vLong; }
break;
-#line 1613 "y.tab.c"
+#line 1641 "y.tab.c"
}
luaY_ssp -= luaY_m;
luaY_state = *luaY_ssp;
diff --git a/src/table.c b/src/table.c
index b2e60a35..6f24ca9b 100644
--- a/src/table.c
+++ b/src/table.c
@@ -3,9 +3,11 @@
** Module to control static tables
*/
-char *rcs_table="$Id: table.c,v 2.58 1996/11/01 12:47:45 roberto Exp $";
+char *rcs_table="$Id: table.c,v 2.72 1997/06/17 18:09:31 roberto Exp $";
-#include "mem.h"
+#include "luamem.h"
+#include "auxlib.h"
+#include "func.h"
#include "opcode.h"
#include "tree.h"
#include "hash.h"
@@ -27,49 +29,14 @@ Word lua_nconstant = 0;
static Long lua_maxconstant = 0;
-#define GARBAGE_BLOCK 50
-
-static void lua_nextvar (void);
-
-/*
-** Internal functions
-*/
-static struct {
- char *name;
- lua_CFunction func;
-} int_funcs[] = {
- {"assert", luaI_assert},
- {"call", luaI_call},
- {"dofile", lua_internaldofile},
- {"dostring", lua_internaldostring},
- {"error", luaI_error},
- {"getglobal", luaI_getglobal},
- {"next", lua_next},
- {"nextvar", lua_nextvar},
- {"print", luaI_print},
- {"setfallback", luaI_setfallback},
- {"setglobal", luaI_setglobal},
- {"tonumber", lua_obj2number},
- {"tostring", luaI_tostring},
- {"type", luaI_type}
-};
-
-#define INTFUNCSIZE (sizeof(int_funcs)/sizeof(int_funcs[0]))
+#define GARBAGE_BLOCK 100
void luaI_initsymbol (void)
{
- int i;
- Word n;
lua_maxsymbol = BUFFER_BLOCK;
lua_table = newvector(lua_maxsymbol, Symbol);
- for (i=0; i<INTFUNCSIZE; i++)
- {
- n = luaI_findsymbolbyname(int_funcs[i].name);
- s_tag(n) = LUA_T_CFUNCTION; s_fvalue(n) = int_funcs[i].func;
- }
- n = luaI_findsymbolbyname("_VERSION_");
- s_tag(n) = LUA_T_STRING; s_tsvalue(n) = lua_createstring(LUA_VERSION);
+ luaI_predefine();
}
@@ -92,17 +59,17 @@ void luaI_initconstant (void)
*/
Word luaI_findsymbol (TaggedString *t)
{
- if (t->varindex == NOT_USED)
+ if (t->u.s.varindex == NOT_USED)
{
if (lua_ntable == lua_maxsymbol)
lua_maxsymbol = growvector(&lua_table, lua_maxsymbol, Symbol,
symbolEM, MAX_WORD);
- t->varindex = lua_ntable;
+ t->u.s.varindex = lua_ntable;
lua_table[lua_ntable].varname = t;
- s_tag(lua_ntable) = LUA_T_NIL;
+ s_ttype(lua_ntable) = LUA_T_NIL;
lua_ntable++;
}
- return t->varindex;
+ return t->u.s.varindex;
}
@@ -118,16 +85,16 @@ Word luaI_findsymbolbyname (char *name)
*/
Word luaI_findconstant (TaggedString *t)
{
- if (t->constindex == NOT_USED)
+ if (t->u.s.constindex == NOT_USED)
{
if (lua_nconstant == lua_maxconstant)
lua_maxconstant = growvector(&lua_constant, lua_maxconstant, TaggedString *,
constantEM, MAX_WORD);
- t->constindex = lua_nconstant;
+ t->u.s.constindex = lua_nconstant;
lua_constant[lua_nconstant] = t;
lua_nconstant++;
}
- return t->constindex;
+ return t->u.s.constindex;
}
@@ -145,10 +112,16 @@ TaggedString *luaI_createfixedstring (char *name)
}
+int luaI_globaldefined (char *name)
+{
+ return ttype(&lua_table[luaI_findsymbolbyname(name)].object) != LUA_T_NIL;
+}
+
+
/*
** Traverse symbol table objects
*/
-static char *lua_travsymbol (int (*fn)(Object *))
+static char *lua_travsymbol (int (*fn)(TObject *))
{
Word i;
for (i=0; i<lua_ntable; i++)
@@ -161,13 +134,14 @@ static char *lua_travsymbol (int (*fn)(Object *))
/*
** Mark an object if it is a string or a unmarked array.
*/
-int lua_markobject (Object *o)
+int lua_markobject (TObject *o)
{/* if already marked, does not change mark value */
- if (tag(o) == LUA_T_STRING && !tsvalue(o)->marked)
+ if (ttype(o) == LUA_T_USERDATA ||
+ (ttype(o) == LUA_T_STRING && !tsvalue(o)->marked))
tsvalue(o)->marked = 1;
- else if (tag(o) == LUA_T_ARRAY)
+ else if (ttype(o) == LUA_T_ARRAY)
lua_hashmark (avalue(o));
- else if ((o->tag == LUA_T_FUNCTION || o->tag == LUA_T_MARK)
+ else if ((o->ttype == LUA_T_FUNCTION || o->ttype == LUA_T_MARK)
&& !o->value.tf->marked)
o->value.tf->marked = 1;
return 0;
@@ -176,11 +150,11 @@ int lua_markobject (Object *o)
/*
* returns 0 if the object is going to be (garbage) collected
*/
-int luaI_ismarked (Object *o)
+int luaI_ismarked (TObject *o)
{
- switch (o->tag)
+ switch (o->ttype)
{
- case LUA_T_STRING:
+ case LUA_T_STRING: case LUA_T_USERDATA:
return o->value.ts->marked;
case LUA_T_FUNCTION:
return o->value.tf->marked;
@@ -192,76 +166,90 @@ int luaI_ismarked (Object *o)
}
+static void call_nilIM (void)
+{ /* signals end of garbage collection */
+ TObject t;
+ ttype(&t) = LUA_T_NIL;
+ luaI_gcIM(&t); /* end of list */
+}
+
/*
** Garbage collection.
** Delete all unused strings and arrays.
*/
-Long luaI_collectgarbage (void)
+static long gc_block = GARBAGE_BLOCK;
+static long gc_nentity = 0; /* total of strings, arrays, etc */
+
+static void markall (void)
{
- Long recovered = 0;
lua_travstack(lua_markobject); /* mark stack objects */
lua_travsymbol(lua_markobject); /* mark symbol table objects */
luaI_travlock(lua_markobject); /* mark locked objects */
luaI_travfallbacks(lua_markobject); /* mark fallbacks */
+}
+
+
+long lua_collectgarbage (long limit)
+{
+ long recovered = 0;
+ Hash *freetable;
+ TaggedString *freestr;
+ TFunc *freefunc;
+ markall();
luaI_invalidaterefs();
- recovered += lua_strcollector();
- recovered += lua_hashcollector();
- recovered += luaI_funccollector();
+ freetable = luaI_hashcollector(&recovered);
+ freestr = luaI_strcollector(&recovered);
+ freefunc = luaI_funccollector(&recovered);
+ gc_nentity -= recovered;
+ gc_block = (limit == 0) ? 2*(gc_block-recovered) : gc_nentity+limit;
+ luaI_hashcallIM(freetable);
+ luaI_strcallIM(freestr);
+ call_nilIM();
+ luaI_hashfree(freetable);
+ luaI_strfree(freestr);
+ luaI_funcfree(freefunc);
return recovered;
}
+
void lua_pack (void)
{
- static unsigned long block = GARBAGE_BLOCK;
- static unsigned long nentity = 0; /* total of strings, arrays, etc */
- unsigned long recovered = 0;
- if (nentity++ < block) return;
- recovered = luaI_collectgarbage();
- block = 2*(block-recovered);
- nentity -= recovered;
+ if (++gc_nentity >= gc_block)
+ lua_collectgarbage(0);
}
/*
** Internal function: return next global variable
*/
-static void lua_nextvar (void)
+void luaI_nextvar (void)
{
- Word next;
- lua_Object o = lua_getparam(1);
- if (o == LUA_NOOBJECT)
- lua_error("too few arguments to function `nextvar'");
- if (lua_getparam(2) != LUA_NOOBJECT)
- lua_error("too many arguments to function `nextvar'");
- if (lua_isnil(o))
- next = 0;
- else if (!lua_isstring(o))
- {
- lua_error("incorrect argument to function `nextvar'");
- return; /* to avoid warnings */
- }
- else
- next = luaI_findsymbolbyname(lua_getstring(o)) + 1;
- while (next < lua_ntable && s_tag(next) == LUA_T_NIL) next++;
- if (next < lua_ntable)
- {
- lua_pushstring(lua_table[next].varname->str);
- luaI_pushobject(&s_object(next));
- }
+ Word next;
+ if (lua_isnil(lua_getparam(1)))
+ next = 0;
+ else
+ next = luaI_findsymbolbyname(luaL_check_string(1)) + 1;
+ while (next < lua_ntable && s_ttype(next) == LUA_T_NIL)
+ next++;
+ if (next < lua_ntable) {
+ lua_pushstring(lua_table[next].varname->str);
+ luaI_pushobject(&s_object(next));
+ }
}
-static Object *functofind;
-static int checkfunc (Object *o)
+static TObject *functofind;
+static int checkfunc (TObject *o)
{
- if (o->tag == LUA_T_FUNCTION)
+ if (o->ttype == LUA_T_FUNCTION)
return
- ((functofind->tag == LUA_T_FUNCTION || functofind->tag == LUA_T_MARK)
+ ((functofind->ttype == LUA_T_FUNCTION || functofind->ttype == LUA_T_MARK)
&& (functofind->value.tf == o->value.tf));
- if (o->tag == LUA_T_CFUNCTION)
+ if (o->ttype == LUA_T_CFUNCTION)
return
- ((functofind->tag == LUA_T_CFUNCTION || functofind->tag == LUA_T_CMARK)
- && (functofind->value.f == o->value.f));
+ ((functofind->ttype == LUA_T_CFUNCTION ||
+ functofind->ttype == LUA_T_CMARK) &&
+ (functofind->value.f == o->value.f));
return 0;
}
@@ -270,7 +258,7 @@ char *lua_getobjname (lua_Object o, char **name)
{ /* try to find a name for given function */
functofind = luaI_Address(o);
if ((*name = luaI_travfallbacks(checkfunc)) != NULL)
- return "fallback";
+ return "tag-method";
else if ((*name = lua_travsymbol(checkfunc)) != NULL)
return "global";
else return "";
diff --git a/src/table.h b/src/table.h
index d7003c96..5a628526 100644
--- a/src/table.h
+++ b/src/table.h
@@ -1,7 +1,7 @@
/*
** Module to control static tables
** TeCGraf - PUC-Rio
-** $Id: table.h,v 2.21 1996/04/22 18:00:37 roberto Exp $
+** $Id: table.h,v 2.25 1997/05/26 14:42:36 roberto Exp $
*/
#ifndef table_h
@@ -12,7 +12,7 @@
typedef struct
{
- Object object;
+ TObject object;
TaggedString *varname;
} Symbol;
@@ -28,10 +28,11 @@ Word luaI_findsymbolbyname (char *name);
Word luaI_findsymbol (TaggedString *t);
Word luaI_findconstant (TaggedString *t);
Word luaI_findconstantbyname (char *name);
+int luaI_globaldefined (char *name);
+void luaI_nextvar (void);
TaggedString *luaI_createfixedstring (char *str);
-int lua_markobject (Object *o);
-int luaI_ismarked (Object *o);
-Long luaI_collectgarbage (void);
+int lua_markobject (TObject *o);
+int luaI_ismarked (TObject *o);
void lua_pack (void);
diff --git a/src/tree.c b/src/tree.c
index 8fbe4200..6f3f2d44 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -3,17 +3,18 @@
** TecCGraf - PUC-Rio
*/
-char *rcs_tree="$Id: tree.c,v 1.20 1996/03/14 15:56:26 roberto Exp $";
+char *rcs_tree="$Id: tree.c,v 1.28 1997/06/11 14:24:40 roberto Exp $";
#include <string.h>
-#include "mem.h"
+#include "luamem.h"
#include "lua.h"
#include "tree.h"
#include "lex.h"
#include "hash.h"
#include "table.h"
+#include "fallback.h"
#define NUM_HASHS 64
@@ -28,23 +29,43 @@ static int initialized = 0;
static stringtable string_root[NUM_HASHS];
-static TaggedString EMPTY = {NOT_USED, NOT_USED, 0, 2, {0}};
+static TaggedString EMPTY = {LUA_T_STRING, NULL, {{NOT_USED, NOT_USED}},
+ 0, 2, {0}};
-static unsigned long hash (char *str)
+static unsigned long hash (char *s, int tag)
{
- unsigned long h = 0;
- while (*str)
- h = ((h<<5)-h)^(unsigned char)*(str++);
+ unsigned long h;
+ if (tag != LUA_T_STRING)
+ h = (unsigned long)s;
+ else {
+ h = 0;
+ while (*s)
+ h = ((h<<5)-h)^(unsigned char)*(s++);
+ }
return h;
}
+
+static void luaI_inittree (void)
+{
+ int i;
+ for (i=0; i<NUM_HASHS; i++) {
+ string_root[i].size = 0;
+ string_root[i].nuse = 0;
+ string_root[i].hash = NULL;
+ }
+}
+
+
static void initialize (void)
{
initialized = 1;
+ luaI_inittree();
luaI_addReserved();
luaI_initsymbol();
luaI_initconstant();
+ luaI_initfallbacks();
}
@@ -58,8 +79,7 @@ static void grow (stringtable *tb)
/* rehash */
tb->nuse = 0;
for (i=0; i<tb->size; i++)
- if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY)
- {
+ if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY) {
int h = tb->hash[i]->hash%newsize;
while (newhash[h])
h = (h+1)%newsize;
@@ -71,10 +91,30 @@ static void grow (stringtable *tb)
tb->hash = newhash;
}
-static TaggedString *insert (char *str, stringtable *tb)
+
+static TaggedString *newone(char *buff, int tag, unsigned long h)
+{
+ TaggedString *ts;
+ if (tag == LUA_T_STRING) {
+ ts = (TaggedString *)luaI_malloc(sizeof(TaggedString)+strlen(buff));
+ strcpy(ts->str, buff);
+ ts->u.s.varindex = ts->u.s.constindex = NOT_USED;
+ ts->tag = LUA_T_STRING;
+ }
+ else {
+ ts = (TaggedString *)luaI_malloc(sizeof(TaggedString));
+ ts->u.v = buff;
+ ts->tag = tag == LUA_ANYTAG ? 0 : tag;
+ }
+ ts->marked = 0;
+ ts->hash = h;
+ return ts;
+}
+
+static TaggedString *insert (char *buff, int tag, stringtable *tb)
{
TaggedString *ts;
- unsigned long h = hash(str);
+ unsigned long h = hash(buff, tag);
int i;
int j = -1;
if ((Long)tb->nuse*3 >= (Long)tb->size*2)
@@ -84,12 +124,14 @@ static TaggedString *insert (char *str, stringtable *tb)
grow(tb);
}
i = h%tb->size;
- while (tb->hash[i])
+ while ((ts = tb->hash[i]) != NULL)
{
- if (tb->hash[i] == &EMPTY)
+ if (ts == &EMPTY)
j = i;
- else if (strcmp(str, tb->hash[i]->str) == 0)
- return tb->hash[i];
+ else if ((ts->tag == LUA_T_STRING) ?
+ (tag == LUA_T_STRING && (strcmp(buff, ts->str) == 0)) :
+ ((tag == ts->tag || tag == LUA_ANYTAG) && buff == ts->u.v))
+ return ts;
i = (i+1)%tb->size;
}
/* not found */
@@ -98,27 +140,49 @@ static TaggedString *insert (char *str, stringtable *tb)
i = j;
else
tb->nuse++;
- ts = tb->hash[i] = (TaggedString *)luaI_malloc(sizeof(TaggedString)+strlen(str));
- strcpy(ts->str, str);
- ts->marked = 0;
- ts->hash = h;
- ts->varindex = ts->constindex = NOT_USED;
+ ts = tb->hash[i] = newone(buff, tag, h);
return ts;
}
-TaggedString *lua_createstring (char *str)
+TaggedString *luaI_createudata (void *udata, int tag)
{
- return insert(str, &string_root[(unsigned)str[0]%NUM_HASHS]);
+ return insert(udata, tag, &string_root[(unsigned)udata%NUM_HASHS]);
+}
+
+TaggedString *lua_createstring (char *str)
+{
+ return insert(str, LUA_T_STRING, &string_root[(unsigned)str[0]%NUM_HASHS]);
+}
+
+
+void luaI_strcallIM (TaggedString *l)
+{
+ TObject o;
+ ttype(&o) = LUA_T_USERDATA;
+ for (; l; l=l->next) {
+ tsvalue(&o) = l;
+ luaI_gcIM(&o);
+ }
+}
+
+
+void luaI_strfree (TaggedString *l)
+{
+ while (l) {
+ TaggedString *next = l->next;
+ luaI_free(l);
+ l = next;
+ }
}
/*
** Garbage collection function.
-** This function traverse the string list freeing unindexed strings
*/
-Long lua_strcollector (void)
+TaggedString *luaI_strcollector (long *acum)
{
Long counter = 0;
+ TaggedString *frees = NULL;
int i;
for (i=0; i<NUM_HASHS; i++)
{
@@ -133,13 +197,15 @@ Long lua_strcollector (void)
t->marked = 0;
else
{
- luaI_free(t);
+ t->next = frees;
+ frees = t;
tb->hash[j] = &EMPTY;
counter++;
}
}
}
}
- return counter;
+ *acum += counter;
+ return frees;
}
diff --git a/src/tree.h b/src/tree.h
index f3af0a0a..22b81ae8 100644
--- a/src/tree.h
+++ b/src/tree.h
@@ -1,7 +1,7 @@
/*
** tree.h
** TecCGraf - PUC-Rio
-** $Id: tree.h,v 1.14 1996/02/26 17:07:49 roberto Exp $
+** $Id: tree.h,v 1.18 1997/06/09 17:28:14 roberto Exp $
*/
#ifndef tree_h
@@ -14,8 +14,15 @@
typedef struct TaggedString
{
- Word varindex; /* != NOT_USED if this is a symbol */
- Word constindex; /* != NOT_USED if this is a constant */
+ int tag; /* if != LUA_T_STRING, this is a userdata */
+ struct TaggedString *next;
+ union {
+ struct {
+ Word varindex; /* != NOT_USED if this is a symbol */
+ Word constindex; /* != NOT_USED if this is a constant */
+ } s;
+ void *v; /* if this is a userdata, here is its value */
+ } u;
unsigned long hash; /* 0 if not initialized */
int marked; /* for garbage collection; never collect (nor change) if > 1 */
char str[1]; /* \0 byte already reserved */
@@ -23,6 +30,9 @@ typedef struct TaggedString
TaggedString *lua_createstring (char *str);
-Long lua_strcollector (void);
+TaggedString *luaI_createudata (void *udata, int tag);
+TaggedString *luaI_strcollector (long *cont);
+void luaI_strfree (TaggedString *l);
+void luaI_strcallIM (TaggedString *l);
#endif
diff --git a/src/undump.c b/src/undump.c
index 2e6ee07f..1a00ef7f 100644
--- a/src/undump.c
+++ b/src/undump.c
@@ -3,33 +3,28 @@
** load bytecodes from files
*/
-char* rcs_undump="$Id: undump.c,v 1.21 1996/11/18 11:18:29 lhf Exp $";
+char* rcs_undump="$Id: undump.c,v 1.24 1997/06/17 18:19:17 roberto Exp $";
#include <stdio.h>
#include <string.h>
+#include "auxlib.h"
#include "opcode.h"
-#include "mem.h"
+#include "luamem.h"
#include "table.h"
#include "undump.h"
+#include "zio.h"
static int swapword=0;
static int swapfloat=0;
static TFunc* Main=NULL; /* functions in a chunk */
static TFunc* lastF=NULL;
-static void warn(char* s) /* TODO: remove */
-{
-#if 0
- fprintf(stderr,"undump: %s\n",s);
-#endif
-}
-
static void FixCode(Byte* code, Byte* end) /* swap words */
{
Byte* p;
for (p=code; p!=end;)
{
- OpCode op=(OpCode)*p;
+ int op=*p;
switch (op)
{
case PUSHNIL:
@@ -83,6 +78,8 @@ static void FixCode(Byte* code, Byte* end) /* swap words */
case STORELIST0:
case ADJUST:
case RETCODE:
+ case VARARGS:
+ case STOREMAP:
p+=2;
break;
case STORELIST:
@@ -132,7 +129,8 @@ static void FixCode(Byte* code, Byte* end) /* swap words */
break;
}
default:
- lua_error("corrupt binary file");
+ luaL_verror("corrupt binary file: bad opcode %d at %d\n",
+ op,(int)(p-code));
break;
}
}
@@ -150,149 +148,152 @@ static void Unthread(Byte* code, int i, int v)
}
}
-static int LoadWord(FILE* D)
+static int LoadWord(ZIO* Z)
{
Word w;
- fread(&w,sizeof(w),1,D);
+ zread(Z,&w,sizeof(w));
if (swapword)
{
- Byte* p=(Byte*)&w; /* TODO: need union? */
+ Byte* p=(Byte*)&w;
Byte t;
t=p[0]; p[0]=p[1]; p[1]=t;
}
return w;
}
-static int LoadSize(FILE* D)
+static int LoadSize(ZIO* Z)
{
- Word hi=LoadWord(D);
- Word lo=LoadWord(D);
+ Word hi=LoadWord(Z);
+ Word lo=LoadWord(Z);
int s=(hi<<16)|lo;
if ((Word)s != s) lua_error("code too long");
return s;
}
-static void* LoadBlock(int size, FILE* D)
+static void* LoadBlock(int size, ZIO* Z)
{
void* b=luaI_malloc(size);
- fread(b,size,1,D);
+ zread(Z,b,size);
return b;
}
-static char* LoadString(FILE* D)
+static char* LoadString(ZIO* Z)
{
- int size=LoadWord(D);
+ int size=LoadWord(Z);
char *b=luaI_buffer(size);
- fread(b,size,1,D);
+ zread(Z,b,size);
return b;
}
-static char* LoadNewString(FILE* D)
+static char* LoadNewString(ZIO* Z)
{
- return LoadBlock(LoadWord(D),D);
+ return LoadBlock(LoadWord(Z),Z);
}
-static void LoadFunction(FILE* D)
+static void LoadFunction(ZIO* Z)
{
TFunc* tf=new(TFunc);
tf->next=NULL;
tf->locvars=NULL;
- tf->size=LoadSize(D);
- tf->lineDefined=LoadWord(D);
+ tf->size=LoadSize(Z);
+ tf->lineDefined=LoadWord(Z);
if (IsMain(tf)) /* new main */
{
- tf->fileName=LoadNewString(D);
+ tf->fileName=LoadNewString(Z);
Main=lastF=tf;
}
else /* fix PUSHFUNCTION */
{
- tf->marked=LoadWord(D);
+ tf->marked=LoadWord(Z);
tf->fileName=Main->fileName;
memcpy(Main->code+tf->marked,&tf,sizeof(tf));
lastF=lastF->next=tf;
}
- tf->code=LoadBlock(tf->size,D);
+ tf->code=LoadBlock(tf->size,Z);
if (swapword || swapfloat) FixCode(tf->code,tf->code+tf->size);
while (1) /* unthread */
{
- int c=getc(D);
+ int c=zgetc(Z);
if (c==ID_VAR) /* global var */
{
- int i=LoadWord(D);
- char* s=LoadString(D);
+ int i=LoadWord(Z);
+ char* s=LoadString(Z);
int v=luaI_findsymbolbyname(s);
Unthread(tf->code,i,v);
}
else if (c==ID_STR) /* constant string */
{
- int i=LoadWord(D);
- char* s=LoadString(D);
+ int i=LoadWord(Z);
+ char* s=LoadString(Z);
int v=luaI_findconstantbyname(s);
Unthread(tf->code,i,v);
}
else
{
- ungetc(c,D);
+ zungetc(Z);
break;
}
}
}
-static void LoadSignature(FILE* D)
+static void LoadSignature(ZIO* Z)
{
char* s=SIGNATURE;
- while (*s!=0 && getc(D)==*s)
+ while (*s!=0 && zgetc(Z)==*s)
++s;
- if (*s!=0) lua_error("bad signature");
+ if (*s!=0) lua_error("cannot load binary file: bad signature");
}
-static void LoadHeader(FILE* D) /* TODO: error handling */
+static void LoadHeader(ZIO* Z)
{
Word w,tw=TEST_WORD;
float f,tf=TEST_FLOAT;
int version;
- LoadSignature(D);
- version=getc(D);
+ LoadSignature(Z);
+ version=zgetc(Z);
if (version>0x23) /* after 2.5 */
{
- int oldsizeofW=getc(D);
- int oldsizeofF=getc(D);
- int oldsizeofP=getc(D);
+ int oldsizeofW=zgetc(Z);
+ int oldsizeofF=zgetc(Z);
+ int oldsizeofP=zgetc(Z);
if (oldsizeofW!=2)
- lua_error("cannot load binary file created on machine with sizeof(Word)!=2");
+ luaL_verror(
+ "cannot load binary file created on machine with sizeof(Word)=%d; "
+ "expected 2",oldsizeofW);
if (oldsizeofF!=4)
- lua_error("cannot load binary file created on machine with sizeof(float)!=4. not an IEEE machine?");
- if (oldsizeofP!=sizeof(TFunc*)) /* TODO: pack */
- lua_error("cannot load binary file: different pointer sizes");
+ luaL_verror(
+ "cannot load binary file created on machine with sizeof(float)=%d; "
+ "expected 4\nnot an IEEE machine?",oldsizeofF);
+ if (oldsizeofP!=sizeof(TFunc*)) /* TODO: pack? */
+ luaL_verror(
+ "cannot load binary file created on machine with sizeof(TFunc*)=%d; "
+ "expected %d",oldsizeofP,(int)sizeof(TFunc*));
}
- fread(&w,sizeof(w),1,D); /* test word */
+ zread(Z,&w,sizeof(w)); /* test word */
if (w!=tw)
{
swapword=1;
- warn("different byte order");
}
- fread(&f,sizeof(f),1,D); /* test float */
+ zread(Z,&f,sizeof(f)); /* test float */
if (f!=tf)
{
- Byte* p=(Byte*)&f; /* TODO: need union? */
+ Byte* p=(Byte*)&f;
Byte t;
swapfloat=1;
t=p[0]; p[0]=p[3]; p[3]=t;
t=p[1]; p[1]=p[2]; p[2]=t;
if (f!=tf) /* TODO: try another perm? */
- lua_error("different float representation");
- else
- warn("different byte order in floats");
+ lua_error("cannot load binary file: unknown float representation");
}
}
-static void LoadChunk(FILE* D)
+static void LoadChunk(ZIO* Z)
{
- LoadHeader(D);
+ LoadHeader(Z);
while (1)
{
- int c=getc(D);
- if (c==ID_FUN) LoadFunction(D); else { ungetc(c,D); break; }
+ int c=zgetc(Z);
+ if (c==ID_FUN) LoadFunction(Z); else { zungetc(Z); break; }
}
}
@@ -300,30 +301,26 @@ static void LoadChunk(FILE* D)
** load one chunk from a file.
** return list of functions found, headed by main, or NULL at EOF.
*/
-TFunc* luaI_undump1(FILE* D)
+TFunc* luaI_undump1(ZIO* Z)
{
- while (1)
+ int c=zgetc(Z);
+ if (c==ID_CHUNK)
{
- int c=getc(D);
- if (c==ID_CHUNK)
- {
- LoadChunk(D);
- return Main;
- }
- else if (c==EOF)
- return NULL;
- else
- lua_error("not a lua binary file");
+ LoadChunk(Z);
+ return Main;
}
+ else if (c!=EOZ)
+ lua_error("not a lua binary file");
+ return NULL;
}
/*
** load and run all chunks in a file
*/
-int luaI_undump(FILE* D)
+int luaI_undump(ZIO* Z)
{
TFunc* m;
- while ((m=luaI_undump1(D)))
+ while ((m=luaI_undump1(Z)))
{
int status=luaI_dorun(m);
luaI_freefunc(m);
diff --git a/src/undump.h b/src/undump.h
index 8d757e36..39373583 100644
--- a/src/undump.h
+++ b/src/undump.h
@@ -1,10 +1,14 @@
/*
** undump.h
** definitions for lua decompiler
-** $Id: undump.h,v 1.3 1996/11/14 11:44:34 lhf Exp $
+** $Id: undump.h,v 1.6 1997/06/17 18:19:17 roberto Exp $
*/
+#ifndef undump_h
+#define undump_h
+
#include "func.h"
+#include "zio.h"
#define IsMain(f) (f->lineDefined==0)
@@ -15,9 +19,12 @@
#define ID_VAR 'V'
#define ID_STR 'S'
#define SIGNATURE "Lua"
-#define VERSION 0x25 /* 2.5 */
+#define VERSION 0x25 /* last format change was in 2.5 */
#define TEST_WORD 0x1234 /* a word for testing byte ordering */
#define TEST_FLOAT 0.123456789e-23 /* a float for testing representation */
-TFunc* luaI_undump1(FILE* D); /* load one chunk */
-int luaI_undump(FILE* D); /* load all chunks */
+
+TFunc* luaI_undump1(ZIO* Z);
+int luaI_undump(ZIO* Z); /* load all chunks */
+
+#endif
diff --git a/src/zio.c b/src/zio.c
new file mode 100644
index 00000000..2af49f42
--- /dev/null
+++ b/src/zio.c
@@ -0,0 +1,79 @@
+/*
+* zio.c
+* a generic input stream interface
+* $Id: zio.c,v 1.2 1997/06/20 19:25:54 roberto Exp $
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "zio.h"
+
+
+/* ----------------------------------------------------- memory buffers --- */
+
+static int zmfilbuf(ZIO* z)
+{
+ return EOZ;
+}
+
+ZIO* zmopen(ZIO* z, char* b, int size)
+{
+ if (b==NULL) return NULL;
+ z->n=size;
+ z->p= (unsigned char *)b;
+ z->filbuf=zmfilbuf;
+ z->u=NULL;
+ return z;
+}
+
+/* ------------------------------------------------------------ strings --- */
+
+ZIO* zsopen(ZIO* z, char* s)
+{
+ if (s==NULL) return NULL;
+ return zmopen(z,s,strlen(s));
+}
+
+/* -------------------------------------------------------------- FILEs --- */
+
+static int zffilbuf(ZIO* z)
+{
+ int n=fread(z->buffer,1,ZBSIZE,z->u);
+ if (n==0) return EOZ;
+ z->n=n-1;
+ z->p=z->buffer;
+ return *(z->p++);
+}
+
+
+ZIO* zFopen(ZIO* z, FILE* f)
+{
+ if (f==NULL) return NULL;
+ z->n=0;
+ z->p=z->buffer;
+ z->filbuf=zffilbuf;
+ z->u=f;
+ return z;
+}
+
+
+/* --------------------------------------------------------------- read --- */
+int zread(ZIO *z, void *b, int n)
+{
+ while (n) {
+ int m;
+ if (z->n == 0) {
+ if (z->filbuf(z) == EOZ)
+ return n; /* retorna quantos faltaram ler */
+ zungetc(z); /* poe o resultado de filbuf no buffer */
+ }
+ m = (n <= z->n) ? n : z->n; /* minimo de n e z->n */
+ memcpy(b, z->p, m);
+ z->n -= m;
+ z->p += m;
+ b = (char *)b + m;
+ n -= m;
+ }
+ return 0;
+}
diff --git a/src/zio.h b/src/zio.h
new file mode 100644
index 00000000..f0f36404
--- /dev/null
+++ b/src/zio.h
@@ -0,0 +1,48 @@
+/*
+* zio.h
+* a generic input stream interface
+* $Id: zio.h,v 1.5 1997/06/20 19:25:54 roberto Exp $
+*/
+
+#ifndef zio_h
+#define zio_h
+
+#include <stdio.h>
+
+
+
+/* For Lua only */
+#define zFopen luaZ_Fopen
+#define zsopen luaZ_sopen
+#define zmopen luaZ_mopen
+#define zread luaZ_read
+
+#define EOZ (-1) /* end of stream */
+
+typedef struct zio ZIO;
+
+ZIO* zFopen(ZIO* z, FILE* f); /* open FILEs */
+ZIO* zsopen(ZIO* z, char* s); /* string */
+ZIO* zmopen(ZIO* z, char* b, int size); /* memory */
+
+int zread(ZIO* z, void* b, int n); /* read next n bytes */
+
+#define zgetc(z) (--(z)->n>=0 ? ((int)*(z)->p++): (z)->filbuf(z))
+#define zungetc(z) (++(z)->n,--(z)->p)
+
+
+
+/* --------- Private Part ------------------ */
+
+#define ZBSIZE 256 /* buffer size */
+
+struct zio {
+ int n; /* bytes still unread */
+ unsigned char* p; /* current position in buffer */
+ int (*filbuf)(ZIO* z);
+ void* u; /* additional data */
+ unsigned char buffer[ZBSIZE]; /* buffer */
+};
+
+
+#endif