Compare commits

..

85 Commits

Author SHA1 Message Date
Luiz Henrique de Figueiredo
e78c1c54aa mem.h is now luamem.h
removed warn
added support for new opcodes (VARARGS, STOREMAP)
better error messages with luaL_verror
1997-04-14 09:12:40 -03:00
Luiz Henrique de Figueiredo
42049b42f1 fix comment in VERSION 1997-04-14 09:12:40 -03:00
Roberto Ierusalimschy
a8cd072c76 nested "$if's", "$else", and "$if" constants (nil & 1). 1997-04-12 12:01:49 -03:00
Roberto Ierusalimschy
83e9897cf0 correction on comments about opcodes. 1997-04-11 18:34:53 -03:00
Roberto Ierusalimschy
f93704728f one cannot "create" a userdata. 1997-04-08 12:41:44 -03:00
Roberto Ierusalimschy
c9e3d32182 first implementation of "$if";
new function "findstring" (useful in good places)
1997-04-07 11:48:53 -03:00
Roberto Ierusalimschy
00050b8a6b detail: local names 1997-04-06 11:17:06 -03:00
Roberto Ierusalimschy
19a1e19ae1 detail: better way to put a "..." in message. 1997-04-06 11:14:27 -03:00
Roberto Ierusalimschy
3a9516ffc8 luaL check functions do not need the function name (it can be
accessed via luadebug interface).
1997-04-06 11:08:08 -03:00
Roberto Ierusalimschy
42fa305649 better error messages;
better names for some API functions.
1997-04-04 19:24:51 -03:00
Roberto Ierusalimschy
9319735744 using new lib auxlib. 1997-04-04 12:35:37 -03:00
Roberto Ierusalimschy
1ea6e8064c "setintmethod" returns old method (to be coerent with seterrormethod).
BUG: wrong pointer arithmetic (index out of range when comparing).
obs: version 4 is due to internal methods.
1997-04-03 15:27:06 -03:00
Roberto Ierusalimschy
c1746340c3 obs: version 4 is due to internal methods.
(some small details in comments)
1997-04-03 15:26:08 -03:00
Roberto Ierusalimschy
d0339e7b72 "setintmethod" returns old method (to be coerent with seterrormethod).
obs: version 2 is due to internal methods.
1997-04-03 15:24:23 -03:00
Roberto Ierusalimschy
075b7918c3 new function "getintmethod" 1997-04-02 20:04:12 -03:00
Roberto Ierusalimschy
7c99149a76 "tostring" gives an overview of a userdata. 1997-04-02 19:53:35 -03:00
Roberto Ierusalimschy
27d95f1880 "newtag" does not need a type name. 1997-04-02 19:52:42 -03:00
Roberto Ierusalimschy
f0d523887d lua_getuserdata must return NULL if object is not userdata 1997-04-02 14:44:18 -03:00
Roberto Ierusalimschy
f29fbf2bf6 lua_getuserdata must return NULL if object is not userdata;
small BUG: wrong error message for a=b[1] (b not a table)
1997-04-02 14:44:18 -03:00
Roberto Ierusalimschy
4355e1afcd "getbyte" returns userdata size when called without second parameter. 1997-04-02 14:44:18 -03:00
Roberto Ierusalimschy
cae1eff901 small "bugs" detected by Purify: cannot read "next" after 0. 1997-04-01 18:23:20 -03:00
Roberto Ierusalimschy
f83bc86e51 small "bugs" detected by Purify: some blocks may be smaller than
sizeof(int).
1997-04-01 18:23:20 -03:00
Roberto Ierusalimschy
59744f0311 "storeglobal" changed to "setglobal" 1997-04-01 16:02:43 -03:00
Roberto Ierusalimschy
bb2e2bec18 new lua function "tag" 1997-04-01 14:31:42 -03:00
Roberto Ierusalimschy
efaaf99c42 first version of "setglobal" and "getglobal" internal methods. 1997-03-31 17:59:09 -03:00
Roberto Ierusalimschy
f8a571ee35 some new options for warnings and optimizations. 1997-03-31 17:58:42 -03:00
Roberto Ierusalimschy
397e32399b update of ".h" dependencies 1997-03-31 11:23:49 -03:00
Roberto Ierusalimschy
373363cb69 new name for old "mem.h" (conflicts with some compiler libraries) 1997-03-31 11:19:01 -03:00
Roberto Ierusalimschy
ad5574c4c9 "Object" renamed to "TObject" (Tagged Object), to avoid conflicts with
pre-defined names in some C compilers.
1997-03-31 11:02:58 -03:00
Roberto Ierusalimschy
264f8c5e7b new (internal?) functions to manipulate userdata 1997-03-26 19:23:15 -03:00
Roberto Ierusalimschy
9e9e2ea287 BUG: must mark userdata in garbage collection. 1997-03-26 19:22:41 -03:00
Roberto Ierusalimschy
03d917f229 some corrections, improvements; 1997-03-24 14:13:22 -03:00
Roberto Ierusalimschy
c3488f5115 must call "gc" i.m. for nil after all others. 1997-03-21 18:39:57 -03:00
Roberto Ierusalimschy
6fef372fb8 mathlib now uses i.m. for "pow" operator. 1997-03-21 15:37:28 -03:00
Roberto Ierusalimschy
052a1cc46c files now have proper tags. 1997-03-20 17:36:58 -03:00
Roberto Ierusalimschy
ae067dcddd BUG: lua_newtag can be called before luaI_IMtable is initialized. 1997-03-20 17:36:19 -03:00
Roberto Ierusalimschy
5d60470508 i.m. "arith" and "order" splited for different operations 1997-03-20 16:20:43 -03:00
Roberto Ierusalimschy
88d7ffb0d0 luaI_type moved to fallback.c 1997-03-20 16:20:23 -03:00
Roberto Ierusalimschy
47527d2d3c setmethods should return old methods. 1997-03-19 18:12:34 -03:00
Roberto Ierusalimschy
1444d28476 first full implementation of internal methods 1997-03-19 16:41:10 -03:00
Roberto Ierusalimschy
2de803c250 new header 'auxlib.h' + new function luaL_verror 1997-03-18 12:30:50 -03:00
Roberto Ierusalimschy
fa08b42dd8 new header for auxiliar functions. 1997-03-18 12:30:50 -03:00
Roberto Ierusalimschy
eea734aa88 new module 'auxlib' centralizes functions to get/check parameters. 1997-03-17 14:02:29 -03:00
Roberto Ierusalimschy
b6d91e24e2 "tag" changed to "ttype" (since now tag has other meaning) 1997-03-11 15:44:28 -03:00
Roberto Ierusalimschy
a82ab0852e new explanation about communication between Lua and C. 1997-03-06 19:19:08 -03:00
Roberto Ierusalimschy
b8af9c56c9 new form for constructors: {[exp] = exp, ...} 1997-03-06 14:30:55 -03:00
Roberto Ierusalimschy
c3c0b52a1f atualization of #include dependencies. 1997-03-05 10:37:04 -03:00
Roberto Ierusalimschy
ec422ec7d0 skips can be nested (why not?). 1997-03-05 10:32:41 -03:00
Roberto Ierusalimschy
a8a15ff1bd "mem.c.debug" incorporated (with "#if"). 1997-03-03 16:55:38 -03:00
Roberto Ierusalimschy
131d66efd2 first step in implementing internal methods. 1997-02-26 14:38:41 -03:00
Roberto Ierusalimschy
bbf1b3060a small correction. 1997-02-26 14:07:57 -03:00
Roberto Ierusalimschy
8b7f271ea2 new pattern item ".-";
empty patterns may be used in gsub.
1997-02-21 12:21:34 -03:00
Roberto Ierusalimschy
bc323435ee new facilities for pattern matching (%b and .-);
explanations about  next-nextvar.
1997-02-21 12:19:37 -03:00
Roberto Ierusalimschy
6769f34817 lua_Type is private (preparation for tags) 1997-02-20 12:51:14 -03:00
Roberto Ierusalimschy
0b110f7922 small syntax error (yacc does not complain, but bison does). 1997-02-13 14:18:39 -02:00
Roberto Ierusalimschy
205ee1ec84 userdata can handle arbitrary binary data;
user tag is stored with data;
1997-02-11 09:40:01 -02:00
Roberto Ierusalimschy
b48847c5fa BUG: "inclinenumber" cannot use public buffer, since it could change
the buffer pointer (luaY_lex and read_long_string have local
pointers to it).
1997-02-07 11:49:46 -02:00
Roberto Ierusalimschy
1143bf9286 better check when converting from float to int, to avoid overflow
(on some machines it may result in run-time error)
1997-01-31 12:27:11 -02:00
Roberto Ierusalimschy
d9ecc13545 lhf revisions/sugestions 1997-01-23 14:17:53 -02:00
Roberto Ierusalimschy
f00d692445 small correction to avoid "wrong" default action 1997-01-15 14:11:37 -02:00
Roberto Ierusalimschy
d8b0bbb2ad BUG: pointer arithmetic does not have to work when pointing outside
an array.
1996-11-22 11:08:28 -02:00
Roberto Ierusalimschy
1f4ee4a4d2 ANSI ctype only works for unsigned chars (or EOF) 1996-11-22 11:08:02 -02:00
Roberto Ierusalimschy
6a9efa8b8e useless include. 1996-11-22 11:07:20 -02:00
Roberto Ierusalimschy
65459e7938 small BUG: pragma deletes 0 at end of yytext, so a syntax error just after
it may have a wrong token in message.
1996-11-21 12:44:04 -02:00
Roberto Ierusalimschy
42359b8b13 new version 1996-11-20 11:49:32 -02:00
Roberto Ierusalimschy
169870e37d BUG: ISO chars are negative, ISO ints are not. 1996-11-20 11:47:59 -02:00
Roberto Ierusalimschy
78e454d864 BUG: ISO chars are negative, ISO ints are not.
new "balanced" pattern.
1996-11-20 11:47:59 -02:00
Roberto Ierusalimschy
dbfe28e199 correction in inheritance code in C 1996-11-18 12:27:42 -02:00
Roberto Ierusalimschy
d59c52753f undump needs file in binary mode 1996-11-18 11:48:44 -02:00
Roberto Ierusalimschy
62e1a4c84d BUG: problems with negative indexes 1996-11-18 11:48:44 -02:00
Luiz Henrique de Figueiredo
81411e8913 headers includes sizeof(Word) not sizeof(int) 1996-11-18 09:18:29 -02:00
Luiz Henrique de Figueiredo
62aa717f7e stdlib.h for exit
blocks are void*
1996-11-16 18:14:23 -02:00
Roberto Ierusalimschy
a5614eae3c spelling corrections. 1996-11-14 15:45:37 -02:00
Luiz Henrique de Figueiredo
536bae5871 corrected version test (0x23 not 23) 1996-11-14 13:00:32 -02:00
Luiz Henrique de Figueiredo
679eddf296 1996-11-14 11:33:15 -02:00
Luiz Henrique de Figueiredo
d991def36c added 3 new bytes to header (sizeof's) 1996-11-14 09:44:34 -02:00
Luiz Henrique de Figueiredo
8b195533d2 new header version 1996-11-14 09:44:34 -02:00
Roberto Ierusalimschy
3ccdd57c26 new version 1996-11-12 14:00:16 -02:00
Roberto Ierusalimschy
a103455dda better format for error messages. 1996-11-08 17:08:30 -02:00
Roberto Ierusalimschy
60242e1930 error message for syntax "1..2";
syntax error function is in "lex.c" (it has the token)
1996-11-08 10:49:35 -02:00
Roberto Ierusalimschy
a0e9bfbb48 syntax error function is in "lex.c" (it has the token) 1996-11-08 10:49:35 -02:00
Roberto Ierusalimschy
2f19e0ba16 SunOS is not ANSI about the return value of "sprintf". 1996-11-07 18:26:19 -02:00
Roberto Ierusalimschy
ab7fdcbbed corrected copyright notice 1996-11-07 18:26:08 -02:00
Luiz Henrique de Figueiredo
48cf1de356 replaced unions by memcpy 1996-11-07 12:13:28 -02:00
Luiz Henrique de Figueiredo
8d50122af0 replaced unions by memcpy 1996-11-07 11:59:51 -02:00
30 changed files with 2441 additions and 1814 deletions

81
auxlib.c Normal file
View File

@@ -0,0 +1,81 @@
char *rcs_auxlib="$Id: auxlib.c,v 1.3 1997/04/06 14:08:08 roberto Exp roberto $";
#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)
{
char *funcname;
lua_getobjname(lua_stackedfunction(0), &funcname);
if (funcname == NULL)
funcname = "???";
if (!cond) {
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);
}

30
auxlib.h Normal file
View File

@@ -0,0 +1,30 @@
/*
** $Id: auxlib.h,v 1.2 1997/04/06 14:08:08 roberto Exp roberto $
*/
#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

View File

@@ -3,130 +3,37 @@
** TecCGraf - PUC-Rio
*/
char *rcs_fallback="$Id: fallback.c,v 1.24 1996/04/22 18:00:37 roberto Exp roberto $";
char *rcs_fallback="$Id: fallback.c,v 2.3 1997/04/06 14:08:08 roberto Exp roberto $";
#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,274 @@ 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;
}
static struct IM {
TObject int_method[IM_N];
} *luaI_IMtable = NULL;
static int IMtable_size = 0;
static int last_tag = LUA_T_NIL; /* ORDER LUA_T */
static char validevents[NUM_TYPES][IM_N] = { /* ORDER LUA_T, ORDER IM */
{1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* LUA_T_USERDATA */
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 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, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_CFUNCTION */
{1, 1, 1, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_STRING */
{1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1}, /* LUA_T_NUMBER */
{0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0} /* 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++)
luaI_IMtable[-tag].int_method[i].ttype = 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;
default:
luaL_verror("cannot change the tag of a %s", luaI_typenames[-ttype(o)]);
}
}
int luaI_tag (TObject *o)
{
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;
}
TObject *luaI_getim (int tag, IMS event)
{
if (tag > LUA_T_USERDATA)
tag = LUA_T_USERDATA; /* default for non-registered tags */
return &luaI_IMtable[-tag].int_method[event];
}
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_IMtable[-t].int_method[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_IMtable[-t].int_method[e]);
luaI_IMtable[-t].int_method[e] = *luaI_Address(func);
}
static TObject errorim = {LUA_T_NIL, {NULL}};
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_IMtable[-t].int_method[e]))
return luaI_eventname[e];
}
return NULL;
}
/*
* ===================================================================
* compatibility with old fallback system
*/
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_IMtable[-t].int_method[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_IMtable[-LUA_T_NIL].int_method[IM_GETGLOBAL];
luaI_IMtable[-LUA_T_NIL].int_method[IM_GETGLOBAL] = *luaI_Address(func);
replace = nilFB;
break;
case 2: { /* old arith fallback */
int i;
oldfunc = luaI_IMtable[-LUA_T_USERDATA].int_method[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_IMtable[-LUA_T_USERDATA].int_method[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_IMtable[-LUA_T_USERDATA].int_method[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);
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: fallback.h,v 1.12 1996/04/22 18:00:37 roberto Exp roberto $
** $Id: fallback.h,v 1.21 1997/04/02 23:04:12 roberto Exp roberto $
*/
#ifndef fallback_h
@@ -8,30 +8,53 @@
#include "lua.h"
#include "opcode.h"
extern struct FB {
char *kind;
Object function;
int nParams;
int nResults;
} luaI_fallBacks[];
/*
* 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 char *luaI_eventname[];
#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
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_getim (int tag, IMS event);
#define luaI_getimbyObj(o,e) (luaI_getim(luaI_tag(o),(e)))
TObject *luaI_geterrorim (void);
int luaI_tag (TObject *o);
void luaI_settagmethod (void);
void luaI_gettagmethod (void);
void luaI_seterrormethod (void);
void luaI_initfallbacks (void);
#endif

8
func.c
View File

@@ -2,7 +2,7 @@
#include "luadebug.h"
#include "table.h"
#include "mem.h"
#include "luamem.h"
#include "func.h"
#include "opcode.h"
@@ -83,13 +83,13 @@ Long luaI_funccollector (void)
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;

100
hash.c
View File

@@ -3,14 +3,15 @@
** hash manager for lua
*/
char *rcs_hash="$Id: hash.c,v 2.30 1996/05/06 14:30:27 roberto Exp roberto $";
char *rcs_hash="$Id: hash.c,v 2.40 1997/04/04 15:35:37 roberto Exp roberto $";
#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,6 +25,8 @@ char *rcs_hash="$Id: hash.c,v 2.30 1996/05/06 14:30:27 roberto Exp roberto $";
#define REHASH_LIMIT 0.70 /* avoid more than this % full */
#define TagDefault LUA_T_ARRAY;
static Hash *listhead = NULL;
@@ -46,47 +49,49 @@ int luaI_redimension (int nhash)
return 0; /* to avoid warnings */
}
static int hashindex (Hash *t, Object *ref) /* hash function */
static int hashindex (Hash *t, TObject *ref) /* hash function */
{
switch (tag(ref))
{
case LUA_T_NIL:
lua_error ("unexpected type to index table");
return -1; /* UNREACHEABLE */
case LUA_T_NUMBER:
return (((int)nvalue(ref))%nhash(t));
case LUA_T_STRING:
return (int)((tsvalue(ref)->hash)%nhash(t)); /* make it a valid index */
case LUA_T_FUNCTION:
return (((IntPoint)ref->value.tf)%nhash(t));
case LUA_T_CFUNCTION:
return (((IntPoint)fvalue(ref))%nhash(t));
case LUA_T_ARRAY:
return (((IntPoint)avalue(ref))%nhash(t));
default: /* user data */
return (((IntPoint)uvalue(ref))%nhash(t));
}
long int h;
switch (ttype(ref)) {
case LUA_T_NUMBER:
h = (long int)nvalue(ref); break;
case LUA_T_STRING: case LUA_T_USERDATA:
h = tsvalue(ref)->hash; break;
case LUA_T_FUNCTION:
h = (IntPoint)ref->value.tf; break;
case LUA_T_CFUNCTION:
h = (IntPoint)fvalue(ref); break;
case LUA_T_ARRAY:
h = (IntPoint)avalue(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 */
}
int lua_equalObj (Object *t1, Object *t2)
int lua_equalObj (TObject *t1, TObject *t2)
{
if (tag(t1) != tag(t2)) return 0;
switch (tag(t1))
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: return svalue(t1) == svalue(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: return uvalue(t1) == uvalue(t2);
default:
lua_error("internal error in `lua_equalObj'");
return 0; /* UNREACHEABLE */
}
}
static int present (Hash *t, Object *ref)
static int present (Hash *t, TObject *ref)
{
int h = hashindex(t, ref);
while (tag(ref(node(t, h))) != LUA_T_NIL)
while (ttype(ref(node(t, h))) != LUA_T_NIL)
{
if (lua_equalObj(ref, ref(node(t, h))))
return h;
@@ -104,7 +109,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;
}
@@ -119,6 +124,7 @@ static Hash *hashcreate (int nhash)
nhash(t) = nhash;
nuse(t) = 0;
markarray(t) = 0;
t->htag = TagDefault;
return t;
}
@@ -144,7 +150,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);
@@ -154,19 +160,17 @@ void lua_hashmark (Hash *h)
}
static void call_fallbacks (void)
void luaI_hashcallIM (void)
{
Hash *curr_array;
Object t;
tag(&t) = LUA_T_ARRAY;
TObject t;
ttype(&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);
luaI_gcIM(&t);
}
tag(&t) = LUA_T_NIL;
luaI_gcFB(&t); /* end of list */
}
@@ -178,7 +182,6 @@ Long lua_hashcollector (void)
{
Hash *curr_array = listhead, *prev = NULL;
Long counter = 0;
call_fallbacks();
while (curr_array != NULL)
{
Hash *next = curr_array->next;
@@ -230,7 +233,7 @@ static void rehash (Hash *t)
for (i=0; i<nold; i++)
{
Node *n = vold+i;
if (tag(ref(n)) != LUA_T_NIL && tag(val(n)) != LUA_T_NIL)
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 hahs */
}
luaI_free(vold);
@@ -240,10 +243,10 @@ static void rehash (Hash *t)
** 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;
}
@@ -252,13 +255,13 @@ 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)
if (ttype(ref(n)) == LUA_T_NIL)
{
nuse(t)++;
if ((float)nuse(t) > (float)nhash(t)*REHASH_LIMIT)
@@ -268,7 +271,7 @@ Object *lua_hashdefine (Hash *t, Object *ref)
n = node(t, h);
}
*ref(n) = *ref;
tag(val(n)) = LUA_T_NIL;
ttype(val(n)) = LUA_T_NIL;
}
return (val(n));
}
@@ -284,7 +287,8 @@ 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)
while (ttype(ref(node(t,i))) == LUA_T_NIL ||
ttype(val(node(t,i))) == LUA_T_NIL)
{
if (++i >= nhash(t))
return;
@@ -298,12 +302,8 @@ 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");
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))
{

30
hash.h
View File

@@ -1,7 +1,7 @@
/*
** hash.h
** hash manager for lua
** $Id: hash.h,v 2.11 1996/03/08 12:04:04 roberto Exp roberto $
** $Id: hash.h,v 2.14 1997/03/19 19:41:10 roberto Exp roberto $
*/
#ifndef hash_h
@@ -10,29 +10,29 @@
#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);
void luaI_hashcallIM (void);
TObject *lua_hashget (Hash *t, TObject *ref);
TObject *lua_hashdefine (Hash *t, TObject *ref);
void lua_next (void);
#endif

259
inout.c
View File

@@ -5,18 +5,22 @@
** Also provides some predefined lua functions.
*/
char *rcs_inout="$Id: inout.c,v 2.42 1996/09/24 21:46:44 roberto Exp roberto $";
char *rcs_inout="$Id: inout.c,v 2.56 1997/04/06 14:08:08 roberto Exp roberto $";
#include <stdio.h>
#include <string.h>
#include "auxlib.h"
#include "lex.h"
#include "opcode.h"
#include "inout.h"
#include "table.h"
#include "tree.h"
#include "lua.h"
#include "mem.h"
#include "hash.h"
#include "luamem.h"
#include "fallback.h"
#include "luamem.h"
/* Exported variables */
@@ -24,6 +28,12 @@ Word lua_linenumber;
char *lua_parsedfile;
char *luaI_typenames[] = { /* ORDER LUA_T */
"userdata", "line", "cmark", "mark", "function",
"function", "table", "string", "number", "nil",
NULL
};
static FILE *fp;
static char *st;
@@ -85,9 +95,8 @@ 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, "...");
sprintf(buff, "(dostring) >> %.20s%s", s,
(strlen(s) > SIZE_PREF) ? "..." : "");
lua_parsedfile = luaI_createfixedstring(buff)->str;
}
@@ -99,17 +108,6 @@ void lua_closestring (void)
}
static void check_arg (int cond, char *func)
{
if (!cond)
{
char buff[100];
sprintf(buff, "incorrect argument to function `%s'", func);
lua_error(buff);
}
}
static int passresults (void)
{
int arg = 0;
@@ -122,10 +120,9 @@ static int passresults (void)
/*
** 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)
if (lua_dostring(luaL_check_string(1)) == 0)
if (passresults() == 0)
lua_pushuserdata(NULL); /* at least one result to signal no errors */
}
@@ -133,15 +130,9 @@ void lua_internaldostring (void)
/*
** 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 +141,34 @@ 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(100);
int size = o->value.ts->size;
int i;
strcpy(buff, "userdata: ");
if (size > 10) size = 10;
for (i=0; i<size; i++)
sprintf(buff+strlen(buff), "%.2X",
(int)(unsigned char)o->value.ts->str[i]);
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 +176,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,46 +195,62 @@ 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 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_setglobal(luaL_check_string(1));
lua_pushobject(value); /* return given value */
}
void luaI_getglobal (void)
static void luaI_rawsetglobal (void)
{
lua_Object name = lua_getparam(1);
check_arg(lua_isstring(name), "getglobal");
lua_pushobject(lua_getglobal(lua_getstring(name)));
lua_Object value = lua_getparam(2);
luaL_arg_check(value != LUA_NOOBJECT, 2, NULL);
lua_pushobject(value);
lua_rawsetglobal(luaL_check_string(1));
lua_pushobject(value); /* return given value */
}
static void luaI_getglobal (void)
{
lua_pushobject(lua_getglobal(luaL_check_string(1)));
}
static void luaI_rawgetglobal (void)
{
lua_pushobject(lua_rawgetglobal(luaL_check_string(1)));
}
static void luatag (void)
{
lua_pushnumber(lua_tag(lua_getparam(1)));
}
#define MAXPARAMS 256
void luaI_call (void)
static void luaI_call (void)
{
lua_Object f = lua_getparam(1);
lua_Object arg = lua_getparam(2);
lua_Object temp, params[MAXPARAMS];
int narg, i;
check_arg(lua_istable(arg), "call");
check_arg(lua_isfunction(f), "call");
luaL_arg_check(lua_isfunction(f), 1, "function expected");
luaL_arg_check(lua_istable(arg), 2, "table expected");
/* narg = arg.n */
lua_pushobject(arg);
lua_pushstring("n");
@@ -298,3 +276,92 @@ void luaI_call (void)
else
passresults();
}
static void luaIl_settag (void)
{
lua_Object o = lua_getparam(1);
luaL_arg_check(o != LUA_NOOBJECT, 1, NULL);
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();
}
/*
** 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},
{"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},
{"setfallback", luaI_setfallback},
{"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);
}

14
inout.h
View File

@@ -1,5 +1,5 @@
/*
** $Id: inout.h,v 1.15 1996/03/15 18:21:58 roberto Exp roberto $
** $Id: inout.h,v 1.16 1996/05/28 21:07:32 roberto Exp roberto $
*/
@@ -19,16 +19,6 @@ 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_predefine (void);
#endif

122
iolib.c
View File

@@ -1,17 +1,19 @@
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <errno.h>
#include "lua.h"
#include "auxlib.h"
#include "luadebug.h"
#include "lualib.h"
FILE *lua_infile, *lua_outfile;
int lua_tagio;
#ifdef POPEN
FILE *popen();
@@ -31,7 +33,7 @@ static void pushresult (int i)
#ifndef NOSTRERROR
lua_pushstring(strerror(errno));
#else
lua_pushstring("system unable to define the error");
lua_pushstring("O.S. unable to define the error");
#endif
}
}
@@ -56,10 +58,10 @@ static void io_readfrom (void)
lua_Object f = lua_getparam(1);
if (f == LUA_NOOBJECT)
closefile(lua_infile); /* restore standart input */
else if (lua_isuserdata(f))
else if (lua_tag(f) == lua_tagio)
lua_infile = lua_getuserdata(f);
else {
char *s = lua_check_string(1, "readfrom");
char *s = luaL_check_string(1);
FILE *fp = (*s == '|') ? popen(s+1, "r") : fopen(s, "r");
if (fp)
lua_infile = fp;
@@ -68,7 +70,7 @@ static void io_readfrom (void)
return;
}
}
lua_pushuserdata(lua_infile);
lua_pushusertag(lua_infile, lua_tagio);
}
@@ -77,10 +79,10 @@ static void io_writeto (void)
lua_Object f = lua_getparam(1);
if (f == LUA_NOOBJECT)
closefile(lua_outfile); /* restore standart output */
else if (lua_isuserdata(f))
else if (lua_tag(f) == lua_tagio)
lua_outfile = lua_getuserdata(f);
else {
char *s = lua_check_string(1, "writeto");
char *s = luaL_check_string(1);
FILE *fp = (*s == '|') ? popen(s+1,"w") : fopen(s,"w");
if (fp)
lua_outfile = fp;
@@ -89,17 +91,17 @@ static void io_writeto (void)
return;
}
}
lua_pushuserdata(lua_outfile);
lua_pushusertag(lua_outfile, lua_tagio);
}
static void io_appendto (void)
{
char *s = lua_check_string(1, "appendto");
char *s = luaL_check_string(1);
FILE *fp = fopen (s, "a");
if (fp != NULL) {
lua_outfile = fp;
lua_pushuserdata(lua_outfile);
lua_pushusertag(lua_outfile, lua_tagio);
}
else
pushresult(0);
@@ -111,21 +113,28 @@ static void io_appendto (void)
static void io_read (void)
{
char *buff;
char *p = lua_opt_string(1, "[^\n]*{\n}", "read");
char *p = luaL_opt_string(1, "[^\n]*{\n}");
int inskip = 0; /* to control {skips} */
int c = NEED_OTHER;
luaI_addchar(0);
luaI_emptybuff();
while (*p) {
if (*p == '{' || *p == '}') {
inskip = (*p == '{');
if (*p == '{') {
inskip++;
p++;
}
else if (*p == '}') {
if (inskip == 0)
lua_error("unbalanced braces in read pattern");
inskip--;
p++;
}
else {
char *ep = item_end(p); /* get what is next */
int m;
char *ep = luaL_item_end(p); /* get what is next */
int m; /* match result */
if (c == NEED_OTHER) c = getc(lua_infile);
if ((m = singlematch(c, p)) != 0) {
if (!inskip) luaI_addchar(c);
m = (c == EOF) ? 0 : luaL_singlematch((char)c, p);
if (m) {
if (inskip == 0) luaI_addchar(c);
c = NEED_OTHER;
}
switch (*ep) {
@@ -155,7 +164,7 @@ static void io_write (void)
int arg = 1;
int status = 1;
char *s;
while ((s = lua_opt_string(arg++, NULL, "write")) != NULL)
while ((s = luaL_opt_string(arg++, NULL)) != NULL)
status = status && (fputs(s, lua_outfile) != EOF);
pushresult(status);
}
@@ -163,20 +172,20 @@ static void io_write (void)
static void io_execute (void)
{
lua_pushnumber(system(lua_check_string(1, "execute")));
lua_pushnumber(system(luaL_check_string(1)));
}
static void io_remove (void)
{
pushresult(remove(lua_check_string(1, "remove")) == 0);
pushresult(remove(luaL_check_string(1)) == 0);
}
static void io_rename (void)
{
pushresult(rename(lua_check_string(1, "rename"),
lua_check_string(2, "rename")) == 0);
pushresult(rename(luaL_check_string(1),
luaL_check_string(2)) == 0);
}
@@ -189,7 +198,7 @@ static void io_tmpname (void)
static void io_getenv (void)
{
lua_pushstring(getenv(lua_check_string(1, "getenv"))); /* if NULL push nil */
lua_pushstring(getenv(luaL_check_string(1))); /* if NULL push nil */
}
@@ -197,7 +206,7 @@ static void io_date (void)
{
time_t t;
struct tm *tm;
char *s = lua_opt_string(1, "%c", "date");
char *s = luaL_opt_string(1, "%c");
char b[BUFSIZ];
time(&t); tm = localtime(&t);
if (strftime(b,sizeof(b),s,tm))
@@ -228,19 +237,18 @@ static void io_debug (void)
static void lua_printstack (FILE *f)
{
int level = 0;
int level = 1; /* skip level 0 (it's this function) */
lua_Object func;
fprintf(f, "Active Stack:\n");
while ((func = lua_stackedfunction(level++)) != LUA_NOOBJECT) {
char *name;
int currentline;
fprintf(f, "\t");
fprintf(f, (level==2) ? "Active Stack:\n\t" : "\t");
switch (*lua_getobjname(func, &name)) {
case 'g':
fprintf(f, "function %s", name);
break;
case 'f':
fprintf(f, "`%s' fallback", name);
fprintf(f, "`%s' iternal method", name);
break;
default: {
char *filename;
@@ -263,13 +271,56 @@ static void lua_printstack (FILE *f)
static void errorfb (void)
{
char *s = lua_opt_string(1, "(no messsage)", NULL);
fprintf(stderr, "lua: %s\n", s);
fprintf(stderr, "lua: %s\n", lua_getstring(lua_getparam(1)));
lua_printstack(stderr);
}
static struct lua_reg iolib[] = {
/* --------------------------------------------
* functions to manipulate userdata
*/
static void getbyte (void)
{
lua_Object ud = lua_getparam(1);
int i = luaL_opt_number(2, -1);
luaL_arg_check(lua_isuserdata(ud), 1, "userdata expected");
if (i == -1)
lua_pushnumber(lua_getbindatasize(ud));
else {
i--;
if (0 <= i && i < lua_getbindatasize(ud))
lua_pushnumber(*(((char *)lua_getbindata(ud))+i));
else
lua_pushnil();
}
}
static void newuserdata (void)
{
lua_Object t = lua_getparam(1);
int tag = luaL_opt_number(2, 0);
int i;
luaI_emptybuff();
luaL_arg_check(lua_istable(t), 1, "table expected");
for (i=0; ; i++) {
lua_Object o;
lua_beginblock();
lua_pushobject(t);
lua_pushnumber(i+1);
o = lua_rawgettable();
if (lua_isnil(o)) {
lua_endblock();
break;
}
luaL_arg_check(lua_isnumber(o), 1, "table values must be numbers");
luaI_addchar(lua_getnumber(o));
lua_endblock();
}
lua_pushbindata(luaI_addchar(0), i, tag);
}
static struct luaL_reg iolib[] = {
{"readfrom", io_readfrom},
{"writeto", io_writeto},
{"appendto", io_appendto},
@@ -283,12 +334,15 @@ static struct lua_reg iolib[] = {
{"date", io_date},
{"exit", io_exit},
{"debug", io_debug},
{"getbyte", getbyte},
{"userdata", newuserdata},
{"print_stack", errorfb}
};
void iolib_open (void)
{
lua_tagio = lua_newtag();
lua_infile=stdin; lua_outfile=stdout;
luaI_openlib(iolib, (sizeof(iolib)/sizeof(iolib[0])));
lua_setfallback("error", errorfb);
luaL_openlib(iolib, (sizeof(iolib)/sizeof(iolib[0])));
lua_seterrormethod(errorfb);
}

204
lex.c
View File

@@ -1,10 +1,11 @@
char *rcs_lex = "$Id: lex.c,v 2.36 1996/09/25 21:52:00 roberto Exp roberto $";
char *rcs_lex = "$Id: lex.c,v 2.46 1997/04/07 14:48:53 roberto Exp roberto $";
#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,7 +13,7 @@ char *rcs_lex = "$Id: lex.c,v 2.36 1996/09/25 21:52:00 roberto Exp roberto $";
#include "luadebug.h"
#include "parser.h"
#define MINBUFF 260
#define MINBUFF 250
#define next() (current = input())
#define save(x) (yytext[tokensize++] = (x))
@@ -22,17 +23,46 @@ char *rcs_lex = "$Id: lex.c,v 2.36 1996/09/25 21:52:00 roberto Exp roberto $";
static int current; /* look ahead character */
static Input input; /* input function */
#define MAX_IFS 10
/* "ifstate" keeps the state of each nested $if the lexical is
** dealing with. The first bit indicates whether the $if condition
** is false or true. The second bit indicates whether the lexical is
** inside the "then" part (0) or the "else" part (2)
*/
static int ifstate[MAX_IFS]; /* 0 => then part - condition false */
/* 1 => then part - condition true */
/* 2 => else part - condition false */
/* 3 => else part - condition true */
static int iflevel; /* level of nested $if's */
void lua_setinput (Input fn)
{
current = '\n';
lua_linenumber = 0;
iflevel = 0;
input = fn;
}
char *lua_lasttext (void)
static void luaI_auxsyntaxerror (char *s)
{
return luaI_buffer(1);
luaL_verror("%s;\n> at line %d in file %s",
s, lua_linenumber, lua_parsedfile);
}
static void luaI_auxsynterrbf (char *s, char *token)
{
if (token[0] == 0)
token = "<eof>";
luaL_verror("%s;\n> last token read: \"%s\" at line %d in file %s",
s, token, lua_linenumber, lua_parsedfile);
}
void luaI_syntaxerror (char *s)
{
luaI_auxsynterrbf(s, luaI_buffer(1));
}
@@ -72,25 +102,113 @@ void luaI_addReserved (void)
}
}
static int inclinenumber (int pragma_allowed)
/*
** Pragma handling
*/
#define PRAGMASIZE 20
static void skipspace (void)
{
if (pragma_allowed && current == '$') { /* is a pragma? */
char buff[MINBUFF];
int i = 0;
next(); /* skip $ */
while (isalnum(current)) {
if (i >= MINBUFF) lua_error("pragma too long");
buff[i++] = current;
next();
}
buff[i] = 0;
if (strcmp(buff, "debug") == 0)
lua_debug = 1;
else if (strcmp(buff, "nodebug") == 0)
lua_debug = 0;
else lua_error("invalid pragma");
while (current == ' ' || current == '\t') next();
}
static int checkcond (char *buff)
{
if (strcmp(buff, "nil") == 0)
return 0;
else if (strcmp(buff, "1") == 0)
return 1;
else if (isalpha((unsigned char)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)) {
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 (int thisiflevel)
{
while (iflevel > thisiflevel &&
(ifstate[thisiflevel] == 0 || ifstate[thisiflevel] == 3)) {
if (current == '\n')
inclinenumber();
else if (current == 0)
luaI_auxsyntaxerror("input ends inside a $if");
else next();
}
}
static void inclinenumber (void)
{
static char *pragmas [] =
{"debug", "nodebug", "end", "ifnot", "if", "else", NULL};
next(); /* skip '\n' */
++lua_linenumber;
if (current == '$') { /* is a pragma? */
char buff[PRAGMASIZE+1];
int ifnot = 0;
next(); /* skip $ */
readname(buff);
switch (luaI_findstring(buff, pragmas)) {
case 0: /* debug */
lua_debug = 1;
break;
case 1: /* nodebug */
lua_debug = 0;
break;
case 2: /* end */
if (--iflevel < 0)
luaI_auxsyntaxerror("unmatched $endif");
break;
case 3: /* ifnot */
ifnot = 1;
/* go through */
case 4: /* if */
if (iflevel == MAX_IFS)
luaI_auxsyntaxerror("too many nested `$ifs'");
readname(buff);
ifstate[iflevel++] = checkcond(buff) ? !ifnot : ifnot;
break;
case 5: /* else */
if (iflevel <= 0 || (ifstate[iflevel-1] & 2))
luaI_auxsyntaxerror("unmatched $else");
ifstate[iflevel-1] = ifstate[iflevel-1] | 2;
break;
default:
luaI_auxsynterrbf("invalid pragma", buff);
}
skipspace();
if (current == '\n') /* pragma must end with a '\n' */
inclinenumber();
else if (current != 0) /* or eof */
luaI_auxsyntaxerror("invalid pragma format");
if (iflevel > 0)
ifskip(iflevel-1);
}
return ++lua_linenumber;
}
static int read_long_string (char *yytext, int buffsize)
@@ -124,8 +242,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();
@@ -155,8 +273,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 */
@@ -220,7 +338,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;
@@ -251,7 +369,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)
@@ -273,7 +393,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;
@@ -284,11 +404,16 @@ int luaY_lex (void)
do {
a=10.0*a+(current-'0');
save_and_next();
} while (isdigit(current));
if (current == '.') save_and_next();
} while (isdigit((unsigned char)current));
if (current == '.') {
save_and_next();
if (current == '.')
luaI_syntaxerror(
"ambiguous syntax (decimal point x string concatenation)");
}
fraction:
{ double da=0.1;
while (isdigit(current))
while (isdigit((unsigned char)current))
{
a+=(current-'0')*da;
da/=10.0;
@@ -302,11 +427,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;
@@ -318,11 +444,15 @@ int luaY_lex (void)
return NUMBER;
}
default: /* also end of program (0) */
{
case 0:
save(0);
if (iflevel > 0)
luaI_syntaxerror("missing $endif");
return 0;
default:
save_and_next();
return yytext[0];
}
}
}
}

4
lex.h
View File

@@ -1,7 +1,7 @@
/*
** lex.h
** TecCGraf - PUC-Rio
** $Id: lex.h,v 1.1 1996/02/13 17:30:39 roberto Exp roberto $
** $Id: lex.h,v 1.2 1996/02/14 13:35:51 roberto Exp roberto $
*/
#ifndef lex_h
@@ -11,7 +11,7 @@
typedef int (*Input) (void);
void lua_setinput (Input fn);
char *lua_lasttext (void);
void luaI_syntaxerror (char *s);
int luaY_lex (void);
void luaI_addReserved (void);

6
lua.c
View File

@@ -3,7 +3,7 @@
** Linguagem para Usuarios de Aplicacao
*/
char *rcs_lua="$Id: lua.c,v 1.13 1996/07/06 20:20:35 roberto Exp roberto $";
char *rcs_lua="$Id: lua.c,v 1.14 1996/09/24 17:30:28 roberto Exp roberto $";
#include <stdio.h>
#include <string.h>
@@ -59,8 +59,8 @@ int main (int argc, char *argv[])
result = lua_dofile (argv[i]);
if (result) {
if (result == 2) {
fprintf(stderr, "lua: cannot execute file `%s' - ", argv[i]);
perror(NULL);
fprintf(stderr, "lua: cannot execute file ");
perror(argv[i]);
}
return 1;
}

97
lua.h
View File

@@ -1,61 +1,50 @@
/*
** LUA - Linguagem para Usuarios de Aplicacao
** Grupo de Tecnologia em Computacao Grafica
** TeCGraf - PUC-Rio
** $Id: lua.h,v 3.28 1996/05/06 14:32:59 roberto Exp roberto $
** LUA - An Extensible Extension Language
** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil
** e-mail: lua@tecgraf.puc-rio.br
** $Id: lua.h,v 4.1 1997/04/03 18:26:08 roberto Exp roberto $
*/
#ifndef lua_h
#define lua_h
#define LUA_VERSION "Lua 2.5 (beta)"
#define LUA_COPYRIGHT "Copyright (C) 1994, 1995 TeCGraf"
#define LUA_VERSION "Lua 3.0 (alpha)"
#define LUA_COPYRIGHT "Copyright (C) 1994-1997 TeCGraf"
#define LUA_AUTHORS "W. Celes, R. Ierusalimschy & L. H. de Figueiredo"
/* Private Part */
typedef enum
{
LUA_T_NIL = -1,
LUA_T_NUMBER = -2,
LUA_T_STRING = -3,
LUA_T_ARRAY = -4,
LUA_T_FUNCTION = -5,
LUA_T_CFUNCTION= -6,
LUA_T_MARK = -7,
LUA_T_CMARK = -8,
LUA_T_LINE = -9,
LUA_T_USERDATA = 0
} lua_Type;
/* Public Part */
#define LUA_NOOBJECT 0
typedef void (*lua_CFunction) (void);
typedef unsigned int lua_Object;
lua_Object lua_setfallback (char *name, lua_CFunction fallback);
void lua_settagmethod (int tag, char *event, lua_CFunction method);
void lua_gettagmethod (int tag, char *event); /* out: method */
void lua_seterrormethod (lua_CFunction method);
int lua_newtag (void);
void lua_settag (int tag); /* In: object */
void lua_error (char *s);
int lua_dofile (char *filename);
int lua_dostring (char *string);
int lua_callfunction (lua_Object function);
int lua_dofile (char *filename); /* Out: returns */
int lua_dostring (char *string); /* Out: returns */
int lua_callfunction (lua_Object f);
/* In: parameters; Out: returns */
int lua_call (char *funcname);
/* In: parameters; Out: returns */
void lua_beginblock (void);
void lua_endblock (void);
lua_Object lua_getparam (int number);
#define lua_getresult(_) lua_getparam(_)
lua_Object lua_lua2C (int number);
#define lua_getparam(_) lua_lua2C(_)
#define lua_getresult(_) lua_lua2C(_)
#define lua_isnil(_) (lua_type(_)==LUA_T_NIL)
#define lua_istable(_) (lua_type(_)==LUA_T_ARRAY)
#define lua_isuserdata(_) (lua_type(_)>=LUA_T_USERDATA)
#define lua_iscfunction(_) (lua_type(_)==LUA_T_CFUNCTION)
int lua_isnil (lua_Object object);
int lua_istable (lua_Object object);
int lua_isuserdata (lua_Object object);
int lua_iscfunction (lua_Object object);
int lua_isnumber (lua_Object object);
int lua_isstring (lua_Object object);
int lua_isfunction (lua_Object object);
@@ -63,25 +52,31 @@ int lua_isfunction (lua_Object object);
float lua_getnumber (lua_Object object);
char *lua_getstring (lua_Object object);
lua_CFunction lua_getcfunction (lua_Object object);
void *lua_getuserdata (lua_Object object);
void *lua_getbindata (lua_Object object);
int lua_getbindatasize (lua_Object object);
void lua_pushnil (void);
void lua_pushnumber (float n);
void lua_pushstring (char *s);
void lua_pushcfunction (lua_CFunction fn);
void lua_pushbindata (void *buff, int size, int tag);
void lua_pushusertag (void *u, int tag);
void lua_pushobject (lua_Object object);
lua_Object lua_getglobal (char *name);
void lua_storeglobal (char *name);
lua_Object lua_rawgetglobal (char *name);
void lua_setglobal (char *name); /* In: value */
void lua_rawsetglobal (char *name); /* In: value */
void lua_storesubscript (void);
lua_Object lua_getsubscript (void);
void lua_settable (void); /* In: table, index, value */
void lua_rawsettable (void); /* In: table, index, value */
lua_Object lua_gettable (void); /* In: table, index */
lua_Object lua_rawgettable (void); /* In: table, index */
int lua_type (lua_Object object);
int lua_tag (lua_Object object);
int lua_ref (int lock);
int lua_ref (int lock); /* In: value */
lua_Object lua_getref (int ref);
void lua_pushref (int ref);
void lua_unref (int ref);
@@ -89,16 +84,25 @@ void lua_unref (int ref);
lua_Object lua_createtable (void);
/* =============================================================== */
/* some useful macros */
#define lua_refobject(o,l) (lua_pushobject(o), lua_ref(l))
#define lua_register(n,f) (lua_pushcfunction(f), lua_storeglobal(n))
#define lua_register(n,f) (lua_pushcfunction(f), lua_setglobal(n))
#define lua_pushuserdata(u) lua_pushusertag(u, LUA_T_USERDATA)
#define lua_pushuserdata(u) lua_pushusertag(u, 0)
/* for compatibility with old versions. Avoid using these macros */
/* =============================================================== */
/* for compatibility with old versions. Avoid using these macros/functions */
lua_Object lua_setfallback (char *event, lua_CFunction fallback);
#define lua_storeglobal(n) lua_setglobal(n)
#define lua_type(o) (lua_tag(o))
void *lua_getuserdata (lua_Object object);
#define lua_lockobject(o) lua_refobject(o,1)
#define lua_lock() lua_ref(1)
@@ -108,9 +112,10 @@ lua_Object lua_createtable (void);
#define lua_pushliteral(o) lua_pushstring(o)
#define lua_getindexed(o,n) (lua_pushobject(o), lua_pushnumber(n), lua_getsubscript())
#define lua_getfield(o,f) (lua_pushobject(o), lua_pushliteral(f), lua_getsubscript())
#define lua_getindexed(o,n) (lua_pushobject(o), lua_pushnumber(n), lua_gettable())
#define lua_getfield(o,f) (lua_pushobject(o), lua_pushliteral(f), lua_gettable())
#define lua_copystring(o) (strdup(lua_getstring(o)))
#define lua_getsubscript lua_gettable
#endif

70
lua.stx
View File

@@ -1,13 +1,13 @@
%{
char *rcs_luastx = "$Id: lua.stx,v 3.39 1996/09/24 17:29:50 roberto Exp roberto $";
char *rcs_luastx = "$Id: lua.stx,v 3.45 1997/03/06 17:30:55 roberto Exp roberto $";
#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;
@@ -59,13 +57,7 @@ int lua_debug = 0;
static void yyerror (char *s)
{
char msg[256];
char *token = lua_lasttext();
if (token[0] == 0)
token = "<eof>";
sprintf (msg,"%s; last token read: \"%s\" at line %d in file `%s'",
s, token, lua_linenumber, lua_parsedfile);
lua_error (msg);
luaI_syntaxerror(s);
}
static void check_space (int i)
@@ -109,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)
@@ -167,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)
{
@@ -465,7 +457,7 @@ void lua_parse (TFunc *tf)
%% /* beginning of rules section */
chunk : chunklist ret
chunk : chunklist ret ;
chunklist : /* empty */
| chunklist stat sc
@@ -483,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"));
@@ -546,7 +537,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);
@@ -611,9 +602,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; }
@@ -729,12 +719,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; }
;
@@ -768,9 +759,8 @@ var : singlevar { $$ = $1; }
}
| varexp '.' NAME
{
code_byte(PUSHSTRING);
code_word(luaI_findconstant($3));
$$ = 0; /* indexed variable */
code_constant($3);
$$ = 0; /* indexed variable */
}
;

View File

@@ -2,7 +2,7 @@
** Libraries to be used in LUA programs
** Grupo de Tecnologia em Computacao Grafica
** TeCGraf - PUC-Rio
** $Id: lualib.h,v 1.9 1996/08/01 14:55:33 roberto Exp roberto $
** $Id: lualib.h,v 1.12 1997/03/18 15:30:50 roberto Exp roberto $
*/
#ifndef lualib_h
@@ -15,24 +15,15 @@ void strlib_open (void);
void mathlib_open (void);
/* auxiliar functions (private) */
struct lua_reg {
char *name;
lua_CFunction func;
};
void luaI_openlib (struct lua_reg *l, int n);
void lua_arg_check(int cond, char *funcname);
char *lua_check_string (int numArg, char *funcname);
char *lua_opt_string (int numArg, char *def, char *funcname);
double lua_check_number (int numArg, char *funcname);
long lua_opt_number (int numArg, long def, char *funcname);
char *luaI_addchar (int c);
void luaI_emptybuff (void);
void luaI_addquoted (char *s);
char *item_end (char *p);
int singlematch (int c, char *p);
char *luaL_item_end (char *p);
int luaL_singlematch (int c, char *p);
#endif

107
luamem.c
View File

@@ -3,19 +3,23 @@
** TecCGraf - PUC-Rio
*/
char *rcs_mem = "$Id: mem.c,v 1.12 1996/05/06 16:59:00 roberto Exp roberto $";
char *rcs_luamem = "$Id: luamem.c,v 1.15 1997/03/31 14:17:09 roberto Exp roberto $";
#include <stdlib.h>
#include "mem.h"
#include "luamem.h"
#include "lua.h"
#define DEBUG 0
#if !DEBUG
void luaI_free (void *block)
{
if (block)
{
*((int *)block) = -1; /* to catch errors */
*((char *)block) = -1; /* to catch errors */
free(block);
}
}
@@ -56,3 +60,100 @@ void* luaI_buffer (unsigned long 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

View File

@@ -1,11 +1,11 @@
/*
** mem.c
** memory manager for lua
** $Id: mem.h,v 1.7 1996/04/22 18:00:37 roberto Exp roberto $
** $Id: luamem.h,v 1.8 1996/05/24 14:31:10 roberto Exp roberto $
*/
#ifndef mem_h
#define mem_h
#ifndef luamem_h
#define luamem_h
#ifndef NULL
#define NULL 0

View File

@@ -1,4 +1,4 @@
# $Id: makefile,v 1.27 1996/08/28 20:45:48 roberto Exp roberto $
# $Id: makefile,v 1.32 1997/03/31 20:58:42 roberto Exp roberto $
#configuration
@@ -9,7 +9,8 @@
CONFIG = -DPOPEN -D_POSIX_SOURCE
# Compilation parameters
CC = gcc
CFLAGS = $(CONFIG) -Wall -Wmissing-prototypes -Wshadow -ansi -O2 -pedantic
CWARNS = -Wall -Wmissing-prototypes -Wshadow -pedantic -Wpointer-arith -Wcast-align -Waggregate-return
CFLAGS = $(CONFIG) $(CWARNS) -ansi -O2 -fomit-frame-pointer
#CC = acc
#CFLAGS = -fast -I/usr/5include
@@ -28,9 +29,10 @@ LUAOBJS = \
inout.o \
tree.o \
fallback.o \
mem.o \
luamem.o \
func.o \
undump.o
undump.o \
auxlib.o
LIBOBJS = \
iolib.o \
@@ -75,24 +77,29 @@ clear :
co $@
fallback.o : fallback.c mem.h fallback.h lua.h opcode.h types.h tree.h func.h \
table.h
func.o : func.c luadebug.h lua.h table.h tree.h types.h opcode.h func.h mem.h
hash.o : hash.c mem.h opcode.h lua.h types.h tree.h func.h hash.h table.h
inout.o : inout.c lex.h opcode.h lua.h types.h tree.h func.h inout.h table.h \
mem.h
iolib.o : iolib.c lua.h luadebug.h lualib.h
lex.o : lex.c mem.h tree.h types.h table.h opcode.h lua.h func.h lex.h inout.h \
luadebug.h parser.h
lua.o : lua.c lua.h lualib.h
mathlib.o : mathlib.c lualib.h lua.h
mem.o : mem.c mem.h lua.h
opcode.o : opcode.c luadebug.h lua.h mem.h opcode.h types.h tree.h func.h hash.h \
inout.h table.h fallback.h undump.h
parser.o : parser.c luadebug.h lua.h mem.h lex.h opcode.h types.h tree.h func.h \
hash.h inout.h table.h
strlib.o : strlib.c lua.h lualib.h
table.o : table.c mem.h opcode.h lua.h types.h tree.h func.h hash.h table.h \
inout.h fallback.h luadebug.h
tree.o : tree.c mem.h lua.h tree.h types.h lex.h hash.h opcode.h func.h table.h
undump.o : undump.c opcode.h lua.h types.h tree.h func.h mem.h table.h undump.h
auxlib.o: auxlib.c lua.h auxlib.h
fallback.o: fallback.c auxlib.h lua.h luamem.h fallback.h opcode.h \
types.h tree.h func.h table.h hash.h
func.o: func.c luadebug.h lua.h table.h tree.h types.h opcode.h func.h \
luamem.h
hash.o: hash.c luamem.h opcode.h lua.h types.h tree.h func.h hash.h \
table.h auxlib.h
inout.o: inout.c auxlib.h lua.h lex.h opcode.h types.h tree.h func.h \
inout.h table.h hash.h luamem.h fallback.h
iolib.o: iolib.c lua.h auxlib.h luadebug.h lualib.h
lex.o: lex.c auxlib.h lua.h luamem.h tree.h types.h table.h opcode.h \
func.h lex.h inout.h luadebug.h parser.h
lua.o: lua.c lua.h lualib.h
luamem.o: luamem.c luamem.h lua.h
mathlib.o: mathlib.c lualib.h lua.h auxlib.h
opcode.o: opcode.c luadebug.h lua.h luamem.h opcode.h types.h tree.h \
func.h hash.h inout.h table.h fallback.h undump.h auxlib.h
parser.o: parser.c luadebug.h lua.h luamem.h lex.h opcode.h types.h \
tree.h func.h hash.h inout.h table.h
strlib.o: strlib.c lua.h auxlib.h lualib.h
table.o: table.c luamem.h auxlib.h lua.h opcode.h types.h tree.h \
func.h hash.h table.h inout.h fallback.h luadebug.h
tree.o: tree.c luamem.h lua.h tree.h types.h lex.h hash.h opcode.h \
func.h table.h fallback.h
undump.o: undump.c opcode.h lua.h types.h tree.h func.h luamem.h \
table.h undump.h

1191
manual.tex

File diff suppressed because it is too large Load Diff

View File

@@ -3,12 +3,13 @@
** Mathematics library to LUA
*/
char *rcs_mathlib="$Id: mathlib.c,v 1.17 1996/04/30 21:13:55 roberto Exp roberto $";
char *rcs_mathlib="$Id: mathlib.c,v 1.22 1997/04/04 22:24:51 roberto Exp roberto $";
#include <stdlib.h>
#include <math.h>
#include "lualib.h"
#include "auxlib.h"
#include "lua.h"
#ifndef PI
@@ -19,7 +20,7 @@ char *rcs_mathlib="$Id: mathlib.c,v 1.17 1996/04/30 21:13:55 roberto Exp roberto
static void math_abs (void)
{
double d = lua_check_number(1, "abs");
double d = luaL_check_number(1);
if (d < 0) d = -d;
lua_pushnumber (d);
}
@@ -27,7 +28,7 @@ static void math_abs (void)
static void math_sin (void)
{
double d = lua_check_number(1, "sin");
double d = luaL_check_number(1);
lua_pushnumber (sin(TORAD(d)));
}
@@ -35,7 +36,7 @@ static void math_sin (void)
static void math_cos (void)
{
double d = lua_check_number(1, "cos");
double d = luaL_check_number(1);
lua_pushnumber (cos(TORAD(d)));
}
@@ -43,98 +44,82 @@ static void math_cos (void)
static void math_tan (void)
{
double d = lua_check_number(1, "tan");
double d = luaL_check_number(1);
lua_pushnumber (tan(TORAD(d)));
}
static void math_asin (void)
{
double d = lua_check_number(1, "asin");
double d = luaL_check_number(1);
lua_pushnumber (TODEGREE(asin(d)));
}
static void math_acos (void)
{
double d = lua_check_number(1, "acos");
double d = luaL_check_number(1);
lua_pushnumber (TODEGREE(acos(d)));
}
static void math_atan (void)
{
double d = lua_check_number(1, "atan");
double d = luaL_check_number(1);
lua_pushnumber (TODEGREE(atan(d)));
}
static void math_atan2 (void)
{
double d1 = lua_check_number(1, "atan2");
double d2 = lua_check_number(2, "atan2");
double d1 = luaL_check_number(1);
double d2 = luaL_check_number(2);
lua_pushnumber (TODEGREE(atan2(d1, d2)));
}
static void math_ceil (void)
{
double d = lua_check_number(1, "ceil");
double d = luaL_check_number(1);
lua_pushnumber (ceil(d));
}
static void math_floor (void)
{
double d = lua_check_number(1, "floor");
double d = luaL_check_number(1);
lua_pushnumber (floor(d));
}
static void math_mod (void)
{
float x = lua_check_number(1, "mod");
float y = lua_check_number(2, "mod");
float x = luaL_check_number(1);
float y = luaL_check_number(2);
lua_pushnumber(fmod(x, y));
}
static void math_sqrt (void)
{
double d = lua_check_number(1, "sqrt");
double d = luaL_check_number(1);
lua_pushnumber (sqrt(d));
}
static int old_pow;
static void math_pow (void)
{
lua_Object o1 = lua_getparam (1);
lua_Object o2 = lua_getparam (2);
lua_Object op = lua_getparam(3);
if (!lua_isnumber(o1) || !lua_isnumber(o2) || *(lua_getstring(op)) != 'p')
{
lua_Object old = lua_getref(old_pow);
lua_pushobject(o1);
lua_pushobject(o2);
lua_pushobject(op);
if (lua_callfunction(old) != 0)
lua_error(NULL);
}
else
{
double d1 = lua_getnumber(o1);
double d2 = lua_getnumber(o2);
lua_pushnumber (pow(d1,d2));
}
double d1 = luaL_check_number(1);
double d2 = luaL_check_number(2);
lua_pushnumber(pow(d1,d2));
}
static void math_min (void)
{
int i=1;
double dmin = lua_check_number(i, "min");
double dmin = luaL_check_number(i);
while (lua_getparam(++i) != LUA_NOOBJECT)
{
double d = lua_check_number(i, "min");
double d = luaL_check_number(i);
if (d < dmin) dmin = d;
}
lua_pushnumber (dmin);
@@ -143,10 +128,10 @@ static void math_min (void)
static void math_max (void)
{
int i=1;
double dmax = lua_check_number(i, "max");
double dmax = luaL_check_number(i);
while (lua_getparam(++i) != LUA_NOOBJECT)
{
double d = lua_check_number(i, "max");
double d = luaL_check_number(i);
if (d > dmax) dmax = d;
}
lua_pushnumber (dmax);
@@ -154,33 +139,33 @@ static void math_max (void)
static void math_log (void)
{
double d = lua_check_number(1, "log");
double d = luaL_check_number(1);
lua_pushnumber (log(d));
}
static void math_log10 (void)
{
double d = lua_check_number(1, "log10");
double d = luaL_check_number(1);
lua_pushnumber (log10(d));
}
static void math_exp (void)
{
double d = lua_check_number(1, "exp");
double d = luaL_check_number(1);
lua_pushnumber (exp(d));
}
static void math_deg (void)
{
float d = lua_check_number(1, "deg");
float d = luaL_check_number(1);
lua_pushnumber (d*180./PI);
}
static void math_rad (void)
{
float d = lua_check_number(1, "rad");
float d = luaL_check_number(1);
lua_pushnumber (d/180.*PI);
}
@@ -191,11 +176,11 @@ static void math_random (void)
static void math_randomseed (void)
{
srand(lua_check_number(1, "randomseed"));
srand(luaL_check_number(1));
}
static struct lua_reg mathlib[] = {
static struct luaL_reg mathlib[] = {
{"abs", math_abs},
{"sin", math_sin},
{"cos", math_cos},
@@ -224,7 +209,7 @@ static struct lua_reg mathlib[] = {
*/
void mathlib_open (void)
{
luaI_openlib(mathlib, (sizeof(mathlib)/sizeof(mathlib[0])));
old_pow = lua_refobject(lua_setfallback("arith", math_pow), 1);
luaL_openlib(mathlib, (sizeof(mathlib)/sizeof(mathlib[0])));
lua_settagmethod(0, "pow", math_pow);
}

711
opcode.c

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/*
** TeCGraf - PUC-Rio
** $Id: opcode.h,v 3.23 1996/09/26 21:08:41 roberto Exp roberto $
** $Id: opcode.h,v 3.32 1997/04/04 22:24:51 roberto Exp roberto $
*/
#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,10 @@ 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);
#endif

253
strlib.c
View File

@@ -3,7 +3,7 @@
** String library to LUA
*/
char *rcs_strlib="$Id: strlib.c,v 1.30 1996/10/31 17:26:04 roberto Exp roberto $";
char *rcs_strlib="$Id: strlib.c,v 1.40 1997/04/06 14:08:08 roberto Exp roberto $";
#include <string.h>
#include <stdio.h>
@@ -11,6 +11,7 @@ char *rcs_strlib="$Id: strlib.c,v 1.30 1996/10/31 17:26:04 roberto Exp roberto $
#include <ctype.h>
#include "lua.h"
#include "auxlib.h"
#include "lualib.h"
@@ -23,7 +24,7 @@ struct lbuff {
static struct lbuff lbuffer = {NULL, 0, 0};
static char *lua_strbuffer (unsigned long size)
static char *strbuffer (unsigned long size)
{
if (size > lbuffer.max) {
/* ANSI "realloc" doesn't need this test, but some machines (Sun!)
@@ -38,55 +39,24 @@ static char *lua_strbuffer (unsigned long size)
static char *openspace (unsigned long size)
{
char *buff = lua_strbuffer(lbuffer.size+size);
char *buff = strbuffer(lbuffer.size+size);
return buff+lbuffer.size;
}
void lua_arg_check(int cond, char *funcname)
{
if (!cond) {
char buff[100];
sprintf(buff, "incorrect argument to function `%s'", funcname);
lua_error(buff);
}
}
char *lua_check_string (int numArg, char *funcname)
{
lua_Object o = lua_getparam(numArg);
lua_arg_check(lua_isstring(o), funcname);
return lua_getstring(o);
}
char *lua_opt_string (int numArg, char *def, char *funcname)
{
return (lua_getparam(numArg) == LUA_NOOBJECT) ? def :
lua_check_string(numArg, funcname);
}
double lua_check_number (int numArg, char *funcname)
{
lua_Object o = lua_getparam(numArg);
lua_arg_check(lua_isnumber(o), funcname);
return lua_getnumber(o);
}
long lua_opt_number (int numArg, long def, char *funcname)
{
return (lua_getparam(numArg) == LUA_NOOBJECT) ? def :
(long)lua_check_number(numArg, funcname);
}
char *luaI_addchar (int c)
{
if (lbuffer.size >= lbuffer.max)
lua_strbuffer(lbuffer.max == 0 ? 100 : lbuffer.max*2);
strbuffer(lbuffer.max == 0 ? 100 : lbuffer.max*2);
lbuffer.b[lbuffer.size++] = c;
if (c == 0)
lbuffer.size = 0; /* prepare for next string */
return lbuffer.b;
}
void luaI_emptybuff (void)
{
lbuffer.size = 0; /* prepare for next string */
}
static void addnchar (char *s, int n)
{
char *b = openspace(n);
@@ -104,17 +74,17 @@ static void addstr (char *s)
*/
static void str_tok (void)
{
char *s1 = lua_check_string(1, "strtok");
char *del = lua_check_string(2, "strtok");
char *s1 = luaL_check_string(1);
char *del = luaL_check_string(2);
lua_Object t = lua_createtable();
int i = 1;
/* As strtok changes s1, and s1 is "constant", make a copy of it */
s1 = strcpy(lua_strbuffer(strlen(s1+1)), s1);
s1 = strcpy(strbuffer(strlen(s1+1)), s1);
while ((s1 = strtok(s1, del)) != NULL) {
lua_pushobject(t);
lua_pushnumber(i++);
lua_pushstring(s1);
lua_storesubscript();
lua_settable();
s1 = NULL; /* prepare for next strtok */
}
lua_pushobject(t);
@@ -127,7 +97,7 @@ static void str_tok (void)
*/
static void str_len (void)
{
lua_pushnumber(strlen(lua_check_string(1, "strlen")));
lua_pushnumber(strlen(luaL_check_string(1)));
}
/*
@@ -135,11 +105,11 @@ static void str_len (void)
*/
static void str_sub (void)
{
char *s = lua_check_string(1, "strsub");
long start = (long)lua_check_number(2, "strsub");
long end = lua_opt_number(3, strlen(s), "strsub");
char *s = luaL_check_string(1);
long start = (long)luaL_check_number(2);
long end = (long)luaL_opt_number(3, strlen(s));
if (1 <= start && start <= end && end <= strlen(s)) {
luaI_addchar(0);
luaI_emptybuff();
addnchar(s+start-1, end-start+1);
lua_pushstring(luaI_addchar(0));
}
@@ -151,10 +121,10 @@ static void str_sub (void)
*/
static void str_lower (void)
{
char *s = lua_check_string(1, "strlower");
luaI_addchar(0);
while (*s)
luaI_addchar(tolower(*s++));
char *s;
luaI_emptybuff();
for (s = luaL_check_string(1); *s; s++)
luaI_addchar(tolower((unsigned char)*s));
lua_pushstring(luaI_addchar(0));
}
@@ -163,18 +133,18 @@ static void str_lower (void)
*/
static void str_upper (void)
{
char *s = lua_check_string(1, "strupper");
luaI_addchar(0);
while (*s)
luaI_addchar(toupper(*s++));
char *s;
luaI_emptybuff();
for (s = luaL_check_string(1); *s; s++)
luaI_addchar(toupper((unsigned char)*s));
lua_pushstring(luaI_addchar(0));
}
static void str_rep (void)
{
char *s = lua_check_string(1, "strrep");
int n = (int)lua_check_number(2, "strrep");
luaI_addchar(0);
char *s = luaL_check_string(1);
int n = (int)luaL_check_number(2);
luaI_emptybuff();
while (n-- > 0)
addstr(s);
lua_pushstring(luaI_addchar(0));
@@ -185,9 +155,9 @@ static void str_rep (void)
*/
static void str_ascii (void)
{
char *s = lua_check_string(1, "ascii");
long pos = lua_opt_number(2, 1, "ascii") - 1;
lua_arg_check(0<=pos && pos<strlen(s), "ascii");
char *s = luaL_check_string(1);
long pos = (long)luaL_opt_number(2, 1) - 1;
luaL_arg_check(0<=pos && pos<strlen(s), 2, "out of range");
lua_pushnumber((unsigned char)s[pos]);
}
@@ -195,23 +165,23 @@ static void str_ascii (void)
/* pattern matching */
#define ESC '%'
#define SPECIALS "^$*?.([%"
#define SPECIALS "^$*?.([%-"
static char *bracket_end (char *p)
{
return (*p == 0) ? NULL : strchr((*p=='^') ? p+2 : p+1, ']');
}
char *item_end (char *p)
char *luaL_item_end (char *p)
{
switch (*p++) {
case '\0': return p-1;
case ESC:
if (*p == 0) lua_error("incorrect pattern");
if (*p == 0) luaL_verror("incorrect pattern (ends with `%c')", ESC);
return p+1;
case '[': {
char *end = bracket_end(p);
if (end == NULL) lua_error("incorrect pattern");
if (end == NULL) lua_error("incorrect pattern (missing `]')");
return end+1;
}
default:
@@ -222,23 +192,23 @@ char *item_end (char *p)
static int matchclass (int c, int cl)
{
int res;
switch (tolower(cl)) {
case 'a' : res = isalpha(c); break;
case 'c' : res = iscntrl(c); break;
case 'd' : res = isdigit(c); break;
case 'l' : res = islower(c); break;
case 'p' : res = ispunct(c); break;
case 's' : res = isspace(c); break;
case 'u' : res = isupper(c); break;
case 'w' : res = isalnum(c); break;
switch (tolower((unsigned char)cl)) {
case 'a' : res = isalpha((unsigned char)c); break;
case 'c' : res = iscntrl((unsigned char)c); break;
case 'd' : res = isdigit((unsigned char)c); break;
case 'l' : res = islower((unsigned char)c); break;
case 'p' : res = ispunct((unsigned char)c); break;
case 's' : res = isspace((unsigned char)c); break;
case 'u' : res = isupper((unsigned char)c); break;
case 'w' : res = isalnum((unsigned char)c); break;
default: return (cl == c);
}
return (islower(cl) ? res : !res);
return (islower((unsigned char)cl) ? res : !res);
}
int singlematch (int c, char *p)
int luaL_singlematch (int c, char *p)
{
if (c <= 0) return 0; /* \0, EOF or other strange flags */
if (c == 0) return 0;
switch (*p) {
case '.': return 1;
case ESC: return matchclass(c, *(p+1));
@@ -300,6 +270,21 @@ static int capture_to_close (int level)
return 0; /* to avoid warnings */
}
static char *matchbalance (char *s, int b, int e)
{
if (*s != b) return NULL;
else {
int cont = 1;
while (*(++s)) {
if (*s == e) {
if (--cont == 0) return s+1;
}
else if (*s == b) cont++;
}
}
return NULL; /* string ends out of balance */
}
static char *match (char *s, char *p, int level)
{
init: /* using goto's to optimize tail recursion */
@@ -317,16 +302,25 @@ static char *match (char *s, char *p, int level)
capture[l].len = -1; /* undo capture */
return res;
}
case ESC: /* possibly a capture (if followed by a digit) */
if (!isdigit(*(p+1))) goto dflt;
else {
case ESC:
if (isdigit((unsigned char)*(p+1))) { /* capture */
int l = check_cap(*(p+1), level);
if (strncmp(capture[l].init, s, capture[l].len) == 0) {
/* return match(p+2, s+capture[l].len, level); */
p+=2; s+=capture[l].len; goto init;
}
else return NULL;
}
}
else if (*(p+1) == 'b') { /* balanced string */
if (*(p+2) == 0 || *(p+3) == 0)
lua_error("bad balanced pattern specification");
s = matchbalance(s, *(p+2), *(p+3));
if (s == NULL) return NULL;
else { /* return match(p+4, s, level); */
p+=4; goto init;
}
}
else goto dflt;
case '\0': case '$': /* (possibly) end of pattern */
if (*p == 0 || (*(p+1) == 0 && *s == 0)) {
num_captures = level;
@@ -334,8 +328,8 @@ static char *match (char *s, char *p, int level)
}
else goto dflt;
default: dflt: { /* it is a pattern item */
int m = singlematch(*s, p);
char *ep = item_end(p); /* get what is next */
int m = luaL_singlematch(*s, p);
char *ep = luaL_item_end(p); /* get what is next */
switch (*ep) {
case '*': { /* repetition */
char *res;
@@ -343,6 +337,17 @@ static char *match (char *s, char *p, int level)
return res;
p=ep+1; goto init; /* else return match(s, ep+1, level); */
}
case '-': { /* repetition */
char *res;
if ((res = match(s, ep+1, level)) != 0)
return res;
else if (m) {
s++;
goto init; /* return match(s+1, p, level); */
}
else
return NULL;
}
case '?': { /* optional */
char *res;
if (m && (res = match(s+1, ep+1, level)))
@@ -359,10 +364,10 @@ static char *match (char *s, char *p, int level)
static void str_find (void)
{
char *s = lua_check_string(1, "strfind");
char *p = lua_check_string(2, "strfind");
long init = lua_opt_number(3, 1, "strfind") - 1;
lua_arg_check(0 <= init && init <= strlen(s), "strfind");
char *s = luaL_check_string(1);
char *p = luaL_check_string(2);
long init = (long)luaL_opt_number(3, 1) - 1;
luaL_arg_check(0 <= init && init <= strlen(s), 3, "out of range");
if (lua_getparam(4) != LUA_NOOBJECT ||
strpbrk(p, SPECIALS) == NULL) { /* no special caracters? */
char *s2 = strstr(s+init, p);
@@ -391,7 +396,7 @@ static void add_s (lua_Object newp)
if (lua_isstring(newp)) {
char *news = lua_getstring(newp);
while (*news) {
if (*news != ESC || !isdigit(*++news))
if (*news != ESC || !isdigit((unsigned char)*++news))
luaI_addchar(*news++);
else {
int l = check_cap(*news++, num_captures);
@@ -415,28 +420,29 @@ static void add_s (lua_Object newp)
addstr(lua_isstring(res) ? lua_getstring(res) : "");
lua_endblock();
}
else lua_arg_check(0, "gsub");
else luaL_arg_check(0, 3, NULL);
}
static void str_gsub (void)
{
char *src = lua_check_string(1, "gsub");
char *p = lua_check_string(2, "gsub");
char *src = luaL_check_string(1);
char *p = luaL_check_string(2);
lua_Object newp = lua_getparam(3);
int max_s = lua_opt_number(4, strlen(src), "gsub");
int max_s = (int)luaL_opt_number(4, strlen(src)+1);
int anchor = (*p == '^') ? (p++, 1) : 0;
int n = 0;
luaI_addchar(0);
while (*src && n < max_s) {
char *e;
if ((e=match(src, p, 0)) == NULL)
luaI_addchar(*src++);
else {
if (e == src) lua_error("empty pattern in substitution");
luaI_emptybuff();
while (n < max_s) {
char *e = match(src, p, 0);
if (e) {
add_s(newp);
src = e;
n++;
}
if (e && e>src) /* non empty match? */
src = e; /* skip it */
else if (*src)
luaI_addchar(*src++);
else break;
if (anchor) break;
}
addstr(src);
@@ -446,12 +452,12 @@ static void str_gsub (void)
static void str_set (void)
{
char *item = lua_check_string(1, "strset");
char *item = luaL_check_string(1);
int i;
lua_arg_check(*item_end(item) == 0, "strset");
luaI_addchar(0);
luaL_arg_check(*luaL_item_end(item) == 0, 1, "wrong format");
luaI_emptybuff();
for (i=1; i<256; i++) /* 0 cannot be part of a set */
if (singlematch(i, item))
if (luaL_singlematch(i, item))
luaI_addchar(i);
lua_pushstring(luaI_addchar(0));
}
@@ -473,8 +479,8 @@ void luaI_addquoted (char *s)
static void str_format (void)
{
int arg = 1;
char *strfrmt = lua_check_string(arg++, "format");
luaI_addchar(0); /* initialize */
char *strfrmt = luaL_check_string(arg++);
luaI_emptybuff(); /* initialize */
while (*strfrmt) {
if (*strfrmt != '%')
luaI_addchar(*strfrmt++);
@@ -486,47 +492,38 @@ static void str_format (void)
char *initf = strfrmt-1; /* -1 to include % */
strfrmt = match(strfrmt, "[-+ #]*(%d*)%.?(%d*)", 0);
if (capture[0].len > 3 || capture[1].len > 3) /* < 1000? */
lua_error("invalid format (width/precision too long)");
lua_error("invalid format (width or precision too long)");
strncpy(form, initf, strfrmt-initf+1); /* +1 to include convertion */
form[strfrmt-initf+1] = 0;
buff = openspace(1000); /* to store the formated value */
switch (*strfrmt++) {
case 'q':
luaI_addquoted(lua_check_string(arg++, "format"));
break;
luaI_addquoted(luaL_check_string(arg++));
continue;
case 's': {
char *s = lua_check_string(arg++, "format");
char *s = luaL_check_string(arg++);
buff = openspace(strlen(s));
lbuffer.size += sprintf(buff, form, s);
sprintf(buff, form, s);
break;
}
case 'c': case 'd': case 'i': case 'o':
case 'u': case 'x': case 'X':
lbuffer.size += sprintf(buff, form,
(int)lua_check_number(arg++, "format"));
sprintf(buff, form, (int)luaL_check_number(arg++));
break;
case 'e': case 'E': case 'f': case 'g':
lbuffer.size += sprintf(buff, form,
lua_check_number(arg++, "format"));
sprintf(buff, form, luaL_check_number(arg++));
break;
default: /* also treat cases 'pnLlh' */
lua_error("invalid format option in function `format'");
}
lbuffer.size += strlen(buff);
}
}
lua_pushstring(luaI_addchar(0)); /* push the result */
}
void luaI_openlib (struct lua_reg *l, int n)
{
int i;
for (i=0; i<n; i++)
lua_register(l[i].name, l[i].func);
}
static struct lua_reg strlib[] = {
static struct luaL_reg strlib[] = {
{"strtok", str_tok},
{"strlen", str_len},
{"strsub", str_sub},
@@ -546,5 +543,5 @@ static struct lua_reg strlib[] = {
*/
void strlib_open (void)
{
luaI_openlib(strlib, (sizeof(strlib)/sizeof(strlib[0])));
luaL_openlib(strlib, (sizeof(strlib)/sizeof(strlib[0])));
}

124
table.c
View File

@@ -3,9 +3,10 @@
** Module to control static tables
*/
char *rcs_table="$Id: table.c,v 2.57 1996/07/12 20:00:26 roberto Exp roberto $";
char *rcs_table="$Id: table.c,v 2.67 1997/04/06 14:08:08 roberto Exp roberto $";
#include "mem.h"
#include "luamem.h"
#include "auxlib.h"
#include "opcode.h"
#include "tree.h"
#include "hash.h"
@@ -29,47 +30,12 @@ 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]))
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();
}
@@ -99,7 +65,7 @@ Word luaI_findsymbol (TaggedString *t)
symbolEM, MAX_WORD);
t->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;
@@ -145,10 +111,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 +133,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,9 +149,9 @@ 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:
return o->value.ts->marked;
@@ -192,6 +165,13 @@ 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.
@@ -203,6 +183,9 @@ Long luaI_collectgarbage (void)
lua_travsymbol(lua_markobject); /* mark symbol table objects */
luaI_travlock(lua_markobject); /* mark locked objects */
luaI_travfallbacks(lua_markobject); /* mark fallbacks */
luaI_hashcallIM();
luaI_strcallIM();
call_nilIM();
luaI_invalidaterefs();
recovered += lua_strcollector();
recovered += lua_hashcollector();
@@ -225,43 +208,34 @@ void lua_pack (void)
/*
** 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;
}

10
table.h
View File

@@ -1,7 +1,7 @@
/*
** Module to control static tables
** TeCGraf - PUC-Rio
** $Id: table.h,v 2.20 1996/03/14 15:57:19 roberto Exp roberto $
** $Id: table.h,v 2.23 1997/03/31 14:02:58 roberto Exp roberto $
*/
#ifndef table_h
@@ -12,7 +12,7 @@
typedef struct
{
Object object;
TObject object;
TaggedString *varname;
} Symbol;
@@ -28,9 +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);
int lua_markobject (TObject *o);
int luaI_ismarked (TObject *o);
Long luaI_collectgarbage (void);
void lua_pack (void);

61
tree.c
View File

@@ -3,17 +3,18 @@
** TecCGraf - PUC-Rio
*/
char *rcs_tree="$Id: tree.c,v 1.19 1996/02/22 20:34:33 roberto Exp $";
char *rcs_tree="$Id: tree.c,v 1.23 1997/03/31 14:02:58 roberto Exp roberto $";
#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,14 +29,14 @@ 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, 0, NOT_USED, NOT_USED, 0, 2, {0}};
static unsigned long hash (char *str)
static unsigned long hash (char *buff, long size)
{
unsigned long h = 0;
while (*str)
h = ((h<<5)-h)^(unsigned char)*(str++);
while (size--)
h = ((h<<5)-h)^(unsigned char)*(buff++);
return h;
}
@@ -45,6 +46,7 @@ static void initialize (void)
luaI_addReserved();
luaI_initsymbol();
luaI_initconstant();
luaI_initfallbacks();
}
@@ -71,10 +73,10 @@ static void grow (stringtable *tb)
tb->hash = newhash;
}
static TaggedString *insert (char *str, stringtable *tb)
static TaggedString *insert (char *buff, long size, int tag, stringtable *tb)
{
TaggedString *ts;
unsigned long h = hash(str);
unsigned long h = hash(buff, size);
int i;
int j = -1;
if ((Long)tb->nuse*3 >= (Long)tb->size*2)
@@ -84,12 +86,13 @@ 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->size == size && ts->tag == tag &&
memcmp(buff, ts->str, size) == 0)
return ts;
i = (i+1)%tb->size;
}
/* not found */
@@ -98,17 +101,43 @@ 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 = tb->hash[i] = (TaggedString *)luaI_malloc(sizeof(TaggedString)+size-1);
memcpy(ts->str, buff, size);
ts->tag = tag;
ts->size = size;
ts->marked = 0;
ts->hash = h;
ts->varindex = ts->constindex = NOT_USED;
return ts;
}
TaggedString *lua_createstring (char *str)
TaggedString *luaI_createuserdata (char *buff, long size, int tag)
{
return insert(str, &string_root[(unsigned)str[0]%NUM_HASHS]);
return insert(buff, size, tag, &string_root[(unsigned)buff[0]%NUM_HASHS]);
}
TaggedString *lua_createstring (char *str)
{
return luaI_createuserdata(str, strlen(str)+1, LUA_T_STRING);
}
void luaI_strcallIM (void)
{
int i;
TObject o;
ttype(&o) = LUA_T_USERDATA;
for (i=0; i<NUM_HASHS; i++) {
stringtable *tb = &string_root[i];
int j;
for (j=0; j<tb->size; j++) {
TaggedString *t = tb->hash[j];
if (t != NULL && t->tag != LUA_T_STRING && t->marked == 0) {
tsvalue(&o) = t;
luaI_gcIM(&o);
}
}
}
}

8
tree.h
View File

@@ -1,7 +1,7 @@
/*
** tree.h
** TecCGraf - PUC-Rio
** $Id: tree.h,v 1.13 1996/02/14 13:35:51 roberto Exp roberto $
** $Id: tree.h,v 1.15 1997/02/11 11:35:05 roberto Exp roberto $
*/
#ifndef tree_h
@@ -14,15 +14,19 @@
typedef struct TaggedString
{
int tag; /* if != LUA_T_STRING, this is a userdata */
long size;
Word varindex; /* != NOT_USED if this is a symbol */
Word constindex; /* != NOT_USED if this is a constant */
unsigned long hash; /* 0 if not initialized */
int marked; /* for garbage collection; never collect (nor change) if > 1 */
char str[1]; /* \0 byte already reserved */
char str[1]; /* \0 byte already reserved; MAY BE NOT 0 TERMINATED!! */
} TaggedString;
TaggedString *lua_createstring (char *str);
TaggedString *luaI_createuserdata (char *buff, long size, int tag);
Long lua_strcollector (void);
void luaI_strcallIM (void);
#endif

View File

@@ -3,12 +3,13 @@
** load bytecodes from files
*/
char* rcs_undump="$Id: undump.c,v 1.13 1996/03/12 20:00:40 lhf Exp lhf $";
char* rcs_undump="$Id: undump.c,v 1.21 1996/11/18 11:18:29 lhf Exp lhf $";
#include <stdio.h>
#include <string.h>
#include "auxlib.h"
#include "opcode.h"
#include "mem.h"
#include "luamem.h"
#include "table.h"
#include "undump.h"
@@ -17,19 +18,12 @@ 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 +77,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:
@@ -90,7 +86,7 @@ static void FixCode(Byte* code, Byte* end) /* swap words */
p+=3;
break;
case PUSHFUNCTION:
p+=5;
p+=5; /* TODO: use sizeof(TFunc*) or old? */
break;
case PUSHWORD:
case PUSHSELF:
@@ -111,7 +107,7 @@ static void FixCode(Byte* code, Byte* end) /* swap words */
p+=3;
break;
}
case PUSHFLOAT:
case PUSHFLOAT: /* assumes sizeof(float)==4 */
{
Byte t;
t=p[1]; p[1]=p[4]; p[4]=t;
@@ -132,7 +128,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;
}
}
@@ -142,13 +139,11 @@ static void Unthread(Byte* code, int i, int v)
{
while (i!=0)
{
CodeWord c;
Word w;
Byte* p=code+i;
get_word(c,p);
i=c.w;
c.w=v;
p[-2]=c.m.c1;
p[-1]=c.m.c2;
memcpy(&w,p,sizeof(w));
i=w; w=v;
memcpy(p,&w,sizeof(w));
}
}
@@ -158,7 +153,7 @@ static int LoadWord(FILE* D)
fread(&w,sizeof(w),1,D);
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;
}
@@ -174,9 +169,9 @@ static int LoadSize(FILE* D)
return s;
}
static char* LoadBlock(int size, FILE* D)
static void* LoadBlock(int size, FILE* D)
{
char* b=luaI_malloc(size);
void* b=luaI_malloc(size);
fread(b,size,1,D);
return b;
}
@@ -208,13 +203,9 @@ static void LoadFunction(FILE* D)
}
else /* fix PUSHFUNCTION */
{
CodeCode c;
Byte* p;
tf->marked=LoadWord(D);
tf->fileName=Main->fileName;
p=Main->code+tf->marked;
c.tf=tf;
*p++=c.m.c1; *p++=c.m.c2; *p++=c.m.c3; *p++=c.m.c4;
memcpy(Main->code+tf->marked,&tf,sizeof(tf));
lastF=lastF->next=tf;
}
tf->code=LoadBlock(tf->size,D);
@@ -249,33 +240,49 @@ static void LoadSignature(FILE* D)
char* s=SIGNATURE;
while (*s!=0 && getc(D)==*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(FILE* D)
{
Word w,tw=TEST_WORD;
float f,tf=TEST_FLOAT;
int version;
LoadSignature(D);
getc(D); /* skip version */
version=getc(D);
if (version>0x23) /* after 2.5 */
{
int oldsizeofW=getc(D);
int oldsizeofF=getc(D);
int oldsizeofP=getc(D);
if (oldsizeofW!=2)
luaL_verror(
"cannot load binary file created on machine with sizeof(Word)=%d; "
"expected 2",oldsizeofW);
if (oldsizeofF!=4)
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,sizeof(TFunc*));
}
fread(&w,sizeof(w),1,D); /* test word */
if (w!=tw)
{
swapword=1;
warn("different byte order");
}
fread(&f,sizeof(f),1,D); /* test float */
if (f!=tf)
{
Byte* p=(Byte*)&f; /* TODO: need union? */
Byte* 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");
}
}

View File

@@ -1,7 +1,7 @@
/*
** undump.h
** definitions for lua decompiler
** $Id: undump.h,v 1.1 1996/03/08 21:43:21 lhf Exp lhf $
** $Id: undump.h,v 1.3 1996/11/14 11:44:34 lhf Exp lhf $
*/
#include "func.h"
@@ -15,7 +15,7 @@
#define ID_VAR 'V'
#define ID_STR 'S'
#define SIGNATURE "Lua"
#define VERSION 0x23 /* 2.3 */
#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 */