Compare commits

...

17 Commits

Author SHA1 Message Date
Roberto Ierusalimschy
a7ca46405d unused "#include". 1996-05-06 13:59:00 -03:00
Roberto Ierusalimschy
0e2297afaa update of dependencies from "#include"s. 1996-05-06 11:38:40 -03:00
Roberto Ierusalimschy
0a1891f6a0 new version. 1996-05-06 11:32:59 -03:00
Roberto Ierusalimschy
1936a9e53b tables may grow bigger than words. 1996-05-06 11:30:27 -03:00
Roberto Ierusalimschy
820ec63bdf as strings are no more duplicated, "nextvar" can use "pushstring". 1996-05-06 11:29:35 -03:00
Roberto Ierusalimschy
01ea523b80 small corrections. 1996-05-03 17:10:59 -03:00
Roberto Ierusalimschy
88cf0836fc "isatty" is POSIX, but not ANSI. 1996-05-03 14:27:03 -03:00
Roberto Ierusalimschy
3ec9ee0d0f new function "luaI_openlib" to help open libs. 1996-04-30 18:13:55 -03:00
Roberto Ierusalimschy
21c9ebf4a9 new algotithm to adjust garbage collection: it tries to adapt gc calls
so that it collects half of the total objects when it is called.
1996-04-29 15:53:53 -03:00
Roberto Ierusalimschy
4fb77c4308 no more "lua_Reference"; new return value for "append";
documentation of "exit" (it was not in the manual).
1996-04-29 15:50:08 -03:00
Roberto Ierusalimschy
bced00ab9e lua_Reference is int, so say so. 1996-04-25 11:10:00 -03:00
Roberto Ierusalimschy
25116a3065 "malloc.h" is not ansi. 1996-04-25 11:01:27 -03:00
Roberto Ierusalimschy
eadbb9cff4 "stat" is not ansi. 1996-04-23 09:43:07 -03:00
Roberto Ierusalimschy
42b947296b "fileno" is not ansi. 1996-04-23 09:43:07 -03:00
Roberto Ierusalimschy
f37e65d1cb "exit" has an optional parameter of status. 1996-04-22 16:28:37 -03:00
Roberto Ierusalimschy
0ef5cf2289 lock mechanism seperseded by the REFERENCE mechanism. 1996-04-22 15:00:37 -03:00
Roberto Ierusalimschy
fed9408ab5 page size "letter". 1996-04-01 11:36:35 -03:00
17 changed files with 311 additions and 229 deletions

View File

@@ -3,7 +3,7 @@
** TecCGraf - PUC-Rio ** TecCGraf - PUC-Rio
*/ */
char *rcs_fallback="$Id: fallback.c,v 1.22 1996/03/19 22:28:37 roberto Exp roberto $"; char *rcs_fallback="$Id: fallback.c,v 1.24 1996/04/22 18:00:37 roberto Exp roberto $";
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@@ -12,6 +12,7 @@ char *rcs_fallback="$Id: fallback.c,v 1.22 1996/03/19 22:28:37 roberto Exp rober
#include "fallback.h" #include "fallback.h"
#include "opcode.h" #include "opcode.h"
#include "lua.h" #include "lua.h"
#include "table.h"
static void errorFB (void); static void errorFB (void);
@@ -112,59 +113,74 @@ static void funcFB (void)
/* /*
** Lock routines ** Reference routines
*/ */
static Object *lockArray = NULL; static struct ref {
static int lockSize = 0; Object o;
enum {LOCK, HOLD, FREE, COLLECTED} status;
} *refArray = NULL;
static int refSize = 0;
int luaI_lock (Object *object) int luaI_ref (Object *object, int lock)
{ {
int i; int i;
int oldSize; int oldSize;
if (tag(object) == LUA_T_NIL) if (tag(object) == LUA_T_NIL)
return -1; /* special lock ref for nil */ return -1; /* special ref for nil */
for (i=0; i<lockSize; i++) for (i=0; i<refSize; i++)
if (tag(&lockArray[i]) == LUA_T_NIL) if (refArray[i].status == FREE)
{ goto found;
lockArray[i] = *object;
return i;
}
/* no more empty spaces */ /* no more empty spaces */
oldSize = lockSize; oldSize = refSize;
lockSize = growvector(&lockArray, lockSize, Object, lockEM, MAX_WORD); refSize = growvector(&refArray, refSize, struct ref, refEM, MAX_WORD);
for (i=oldSize; i<lockSize; i++) for (i=oldSize; i<refSize; i++)
tag(&lockArray[i]) = LUA_T_NIL; refArray[i].status = FREE;
lockArray[oldSize] = *object; i = oldSize;
return oldSize; found:
refArray[i].o = *object;
refArray[i].status = lock ? LOCK : HOLD;
return i;
} }
void lua_unlock (int ref) void lua_unref (int ref)
{ {
if (ref >= 0 && ref < lockSize) if (ref >= 0 && ref < refSize)
tag(&lockArray[ref]) = LUA_T_NIL; refArray[ref].status = FREE;
} }
Object *luaI_getlocked (int ref) Object *luaI_getref (int ref)
{ {
static Object nul = {LUA_T_NIL, {0}}; static Object nul = {LUA_T_NIL, {0}};
if (ref >= 0 && ref < lockSize) if (ref == -1)
return &lockArray[ref];
else
return &nul; return &nul;
if (ref >= 0 && ref < refSize &&
(refArray[ref].status == LOCK || refArray[ref].status == HOLD))
return &refArray[ref].o;
else
return NULL;
} }
void luaI_travlock (int (*fn)(Object *)) void luaI_travlock (int (*fn)(Object *))
{ {
int i; int i;
for (i=0; i<lockSize; i++) for (i=0; i<refSize; i++)
fn(&lockArray[i]); if (refArray[i].status == LOCK)
fn(&refArray[i].o);
} }
void luaI_invalidaterefs (void)
{
int i;
for (i=0; i<refSize; i++)
if (refArray[i].status == HOLD && !luaI_ismarked(&refArray[i].o))
refArray[i].status = COLLECTED;
}
char *luaI_travfallbacks (int (*fn)(Object *)) char *luaI_travfallbacks (int (*fn)(Object *))
{ {
int i; int i;

View File

@@ -1,10 +1,11 @@
/* /*
** $Id: fallback.h,v 1.10 1995/10/17 11:52:38 roberto Exp roberto $ ** $Id: fallback.h,v 1.12 1996/04/22 18:00:37 roberto Exp roberto $
*/ */
#ifndef fallback_h #ifndef fallback_h
#define fallback_h #define fallback_h
#include "lua.h"
#include "opcode.h" #include "opcode.h"
extern struct FB { extern struct FB {
@@ -26,9 +27,10 @@ extern struct FB {
#define FB_GETGLOBAL 9 #define FB_GETGLOBAL 9
void luaI_setfallback (void); void luaI_setfallback (void);
int luaI_lock (Object *object); int luaI_ref (Object *object, int lock);
Object *luaI_getlocked (int ref); Object *luaI_getref (int ref);
void luaI_travlock (int (*fn)(Object *)); void luaI_travlock (int (*fn)(Object *));
void luaI_invalidaterefs (void);
char *luaI_travfallbacks (int (*fn)(Object *)); char *luaI_travfallbacks (int (*fn)(Object *));
#endif #endif

49
hash.c
View File

@@ -3,7 +3,7 @@
** hash manager for lua ** hash manager for lua
*/ */
char *rcs_hash="$Id: hash.c,v 2.28 1996/02/12 18:32:40 roberto Exp roberto $"; char *rcs_hash="$Id: hash.c,v 2.29 1996/02/14 18:25:04 roberto Exp roberto $";
#include "mem.h" #include "mem.h"
@@ -29,14 +29,15 @@ static Hash *listhead = NULL;
/* hash dimensions values */ /* hash dimensions values */
static Word dimensions[] = static Long dimensions[] =
{3, 5, 7, 11, 23, 47, 97, 197, 397, 797, 1597, 3203, 6421, {3L, 5L, 7L, 11L, 23L, 47L, 97L, 197L, 397L, 797L, 1597L, 3203L, 6421L,
12853, 25717, 51437, 65521, 0}; /* 65521 == last prime < MAX_WORD */ 12853L, 25717L, 51437L, 102811L, 205619L, 411233L, 822433L,
1644817L, 3289613L, 6579211L, 13158023L, MAX_INT};
Word luaI_redimension (Word nhash) int luaI_redimension (int nhash)
{ {
Word i; int i;
for (i=0; dimensions[i]!=0; i++) for (i=0; dimensions[i]<MAX_INT; i++)
{ {
if (dimensions[i] > nhash) if (dimensions[i] > nhash)
return dimensions[i]; return dimensions[i];
@@ -45,7 +46,7 @@ Word luaI_redimension (Word nhash)
return 0; /* to avoid warnings */ return 0; /* to avoid warnings */
} }
static Word hashindex (Hash *t, Object *ref) /* hash function */ static int hashindex (Hash *t, Object *ref) /* hash function */
{ {
switch (tag(ref)) switch (tag(ref))
{ {
@@ -53,9 +54,9 @@ static Word hashindex (Hash *t, Object *ref) /* hash function */
lua_error ("unexpected type to index table"); lua_error ("unexpected type to index table");
return -1; /* UNREACHEABLE */ return -1; /* UNREACHEABLE */
case LUA_T_NUMBER: case LUA_T_NUMBER:
return (((Word)nvalue(ref))%nhash(t)); return (((int)nvalue(ref))%nhash(t));
case LUA_T_STRING: case LUA_T_STRING:
return (Word)((tsvalue(ref)->hash)%nhash(t)); /* make it a valid index */ return (int)((tsvalue(ref)->hash)%nhash(t)); /* make it a valid index */
case LUA_T_FUNCTION: case LUA_T_FUNCTION:
return (((IntPoint)ref->value.tf)%nhash(t)); return (((IntPoint)ref->value.tf)%nhash(t));
case LUA_T_CFUNCTION: case LUA_T_CFUNCTION:
@@ -82,9 +83,9 @@ int lua_equalObj (Object *t1, Object *t2)
} }
} }
static Word present (Hash *t, Object *ref) static int present (Hash *t, Object *ref)
{ {
Word h = hashindex(t, ref); int h = hashindex(t, ref);
while (tag(ref(node(t, h))) != LUA_T_NIL) while (tag(ref(node(t, h))) != LUA_T_NIL)
{ {
if (lua_equalObj(ref, ref(node(t, h)))) if (lua_equalObj(ref, ref(node(t, h))))
@@ -98,9 +99,9 @@ static Word present (Hash *t, Object *ref)
/* /*
** Alloc a vector node ** Alloc a vector node
*/ */
static Node *hashnodecreate (Word nhash) static Node *hashnodecreate (int nhash)
{ {
Word i; int i;
Node *v = newvector (nhash, Node); Node *v = newvector (nhash, Node);
for (i=0; i<nhash; i++) for (i=0; i<nhash; i++)
tag(ref(&v[i])) = LUA_T_NIL; tag(ref(&v[i])) = LUA_T_NIL;
@@ -110,10 +111,10 @@ static Node *hashnodecreate (Word nhash)
/* /*
** Create a new hash. Return the hash pointer or NULL on error. ** Create a new hash. Return the hash pointer or NULL on error.
*/ */
static Hash *hashcreate (Word nhash) static Hash *hashcreate (int nhash)
{ {
Hash *t = new(Hash); Hash *t = new(Hash);
nhash = luaI_redimension((Word)((float)nhash/REHASH_LIMIT)); nhash = luaI_redimension((int)((float)nhash/REHASH_LIMIT));
nodevector(t) = hashnodecreate(nhash); nodevector(t) = hashnodecreate(nhash);
nhash(t) = nhash; nhash(t) = nhash;
nuse(t) = 0; nuse(t) = 0;
@@ -138,7 +139,7 @@ void lua_hashmark (Hash *h)
{ {
if (markarray(h) == 0) if (markarray(h) == 0)
{ {
Word i; int i;
markarray(h) = 1; markarray(h) = 1;
for (i=0; i<nhash(h); i++) for (i=0; i<nhash(h); i++)
{ {
@@ -205,7 +206,7 @@ Long lua_hashcollector (void)
** executes garbage collection if the number of arrays created ** executes garbage collection if the number of arrays created
** exceed a pre-defined range. ** exceed a pre-defined range.
*/ */
Hash *lua_createarray (Word nhash) Hash *lua_createarray (int nhash)
{ {
Hash *array; Hash *array;
lua_pack(); lua_pack();
@@ -221,8 +222,8 @@ Hash *lua_createarray (Word nhash)
*/ */
static void rehash (Hash *t) static void rehash (Hash *t)
{ {
Word i; int i;
Word nold = nhash(t); int nold = nhash(t);
Node *vold = nodevector(t); Node *vold = nodevector(t);
nhash(t) = luaI_redimension(nhash(t)); nhash(t) = luaI_redimension(nhash(t));
nodevector(t) = hashnodecreate(nhash(t)); nodevector(t) = hashnodecreate(nhash(t));
@@ -241,7 +242,7 @@ static void rehash (Hash *t)
*/ */
Object *lua_hashget (Hash *t, Object *ref) Object *lua_hashget (Hash *t, Object *ref)
{ {
Word h = present(t, ref); int h = present(t, ref);
if (tag(ref(node(t, h))) != LUA_T_NIL) return val(node(t, h)); if (tag(ref(node(t, h))) != LUA_T_NIL) return val(node(t, h));
else return NULL; else return NULL;
} }
@@ -253,7 +254,7 @@ Object *lua_hashget (Hash *t, Object *ref)
*/ */
Object *lua_hashdefine (Hash *t, Object *ref) Object *lua_hashdefine (Hash *t, Object *ref)
{ {
Word h; int h;
Node *n; Node *n;
h = present(t, ref); h = present(t, ref);
n = node(t, h); n = node(t, h);
@@ -279,7 +280,7 @@ Object *lua_hashdefine (Hash *t, Object *ref)
** in the hash. ** in the hash.
** This function pushs the element value and its reference to the stack. ** This function pushs the element value and its reference to the stack.
*/ */
static void hashnext (Hash *t, Word i) static void hashnext (Hash *t, int i)
{ {
if (i >= nhash(t)) if (i >= nhash(t))
{ {
@@ -316,7 +317,7 @@ void lua_next (void)
} }
else else
{ {
Word h = present (t, luaI_Address(r)); int h = present (t, luaI_Address(r));
hashnext(t, h+1); hashnext(t, h+1);
} }
} }

12
hash.h
View File

@@ -1,7 +1,7 @@
/* /*
** hash.h ** hash.h
** hash manager for lua ** hash manager for lua
** $Id: hash.h,v 2.10 1996/02/12 18:32:40 roberto Exp roberto $ ** $Id: hash.h,v 2.11 1996/03/08 12:04:04 roberto Exp roberto $
*/ */
#ifndef hash_h #ifndef hash_h
@@ -19,16 +19,16 @@ typedef struct node
typedef struct Hash typedef struct Hash
{ {
struct Hash *next; struct Hash *next;
char mark;
Word nhash;
Word nuse;
Node *node; Node *node;
int nhash;
int nuse;
char mark;
} Hash; } Hash;
int lua_equalObj (Object *t1, Object *t2); int lua_equalObj (Object *t1, Object *t2);
Word luaI_redimension (Word nhash); int luaI_redimension (int nhash);
Hash *lua_createarray (Word nhash); Hash *lua_createarray (int nhash);
void lua_hashmark (Hash *h); void lua_hashmark (Hash *h);
Long lua_hashcollector (void); Long lua_hashcollector (void);
Object *lua_hashget (Hash *t, Object *ref); Object *lua_hashget (Hash *t, Object *ref);

60
iolib.c
View File

@@ -3,12 +3,10 @@
** Input/output library to LUA ** Input/output library to LUA
*/ */
char *rcs_iolib="$Id: iolib.c,v 1.39 1996/03/14 15:55:18 roberto Exp roberto $"; char *rcs_iolib="$Id: iolib.c,v 1.43 1996/04/30 21:13:55 roberto Exp roberto $";
#include <stdio.h> #include <stdio.h>
#include <ctype.h> #include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <stdlib.h> #include <stdlib.h>
@@ -125,15 +123,12 @@ static void io_writeto (void)
** LUA interface: ** LUA interface:
** status = appendto (filename) ** status = appendto (filename)
** where: ** where:
** status = 2 -> success (already exist) ** status = 1 -> success
** status = 1 -> success (new file)
** status = nil -> error ** status = nil -> error
*/ */
static void io_appendto (void) static void io_appendto (void)
{ {
char *s = lua_check_string(1, "appendto"); char *s = lua_check_string(1, "appendto");
struct stat st;
int r = (stat(s, &st) == -1) ? 1 : 2;
FILE *fp = fopen (s, "a"); FILE *fp = fopen (s, "a");
if (fp == NULL) if (fp == NULL)
lua_pushnil(); lua_pushnil();
@@ -141,7 +136,7 @@ static void io_appendto (void)
{ {
if (out != stdout) fclose (out); if (out != stdout) fclose (out);
out = fp; out = fp;
lua_pushnumber (r); lua_pushnumber(1);
} }
} }
@@ -529,9 +524,8 @@ static void io_date (void)
static void io_exit (void) static void io_exit (void)
{ {
lua_Object o = lua_getparam(1); lua_Object o = lua_getparam(1);
if (lua_isstring(o)) int code = lua_isnumber(o) ? (int)lua_getnumber(o) : 1;
fprintf(stderr, "%s\n", lua_getstring(o)); exit(code);
exit(1);
} }
/* /*
@@ -551,7 +545,7 @@ static void io_debug (void)
} }
void lua_printstack (FILE *f) static void lua_printstack (FILE *f)
{ {
int level = 0; int level = 0;
lua_Object func; lua_Object func;
@@ -598,27 +592,27 @@ static void errorfb (void)
} }
/* static struct lua_reg iolib[] = {
** Open io library {"readfrom", io_readfrom},
*/ {"writeto", io_writeto},
{"appendto", io_appendto},
{"read", io_read},
{"readuntil",io_readuntil},
{"write", io_write},
{"execute", io_execute},
{"remove", io_remove},
{"rename", io_rename},
{"tmpname", io_tmpname},
{"ioerror", io_errorno},
{"getenv", io_getenv},
{"date", io_date},
{"exit", io_exit},
{"debug", io_debug},
{"print_stack", errorfb}
};
void iolib_open (void) void iolib_open (void)
{ {
lua_register ("readfrom", io_readfrom); luaI_openlib(iolib, (sizeof(iolib)/sizeof(iolib[0])));
lua_register ("writeto", io_writeto); lua_setfallback("error", errorfb);
lua_register ("appendto", io_appendto);
lua_register ("read", io_read);
lua_register ("readuntil",io_readuntil);
lua_register ("write", io_write);
lua_register ("execute", io_execute);
lua_register ("remove", io_remove);
lua_register ("rename", io_rename);
lua_register ("tmpname", io_tmpname);
lua_register ("ioerror", io_errorno);
lua_register ("getenv", io_getenv);
lua_register ("date", io_date);
lua_register ("exit", io_exit);
lua_register ("debug", io_debug);
lua_register ("print_stack", errorfb);
lua_setfallback("error", errorfb);
} }

12
lua.c
View File

@@ -3,7 +3,7 @@
** Linguagem para Usuarios de Aplicacao ** Linguagem para Usuarios de Aplicacao
*/ */
char *rcs_lua="$Id: lua.c,v 1.7 1995/10/31 17:05:35 roberto Exp roberto $"; char *rcs_lua="$Id: lua.c,v 1.9 1996/04/23 12:43:07 roberto Exp roberto $";
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@@ -14,11 +14,15 @@ char *rcs_lua="$Id: lua.c,v 1.7 1995/10/31 17:05:35 roberto Exp roberto $";
static int lua_argc; static int lua_argc;
static char **lua_argv; static char **lua_argv;
#ifdef POSIX
/* /*
** although this function is POSIX, there is no standard header file that ** although this function is POSIX, there is no standard header file that
** defines it ** defines it
*/ */
int isatty (int fd); int isatty (int fd);
#else
#define isatty(x) (x==0) /* assume stdin is a tty */
#endif
/* /*
%F Allow Lua code to access argv strings. %F Allow Lua code to access argv strings.
@@ -41,7 +45,7 @@ static void lua_getargv (void)
static void manual_input (void) static void manual_input (void)
{ {
if (isatty(fileno(stdin))) if (isatty(0))
{ {
char buffer[250]; char buffer[250];
while (fgets(buffer, sizeof(buffer), stdin) != 0) while (fgets(buffer, sizeof(buffer), stdin) != 0)
@@ -83,7 +87,11 @@ int main (int argc, char *argv[])
printf("%s %s\n(written by %s)\n\n", printf("%s %s\n(written by %s)\n\n",
LUA_VERSION, LUA_COPYRIGHT, LUA_AUTHORS); LUA_VERSION, LUA_COPYRIGHT, LUA_AUTHORS);
else else
{
result = lua_dofile (argv[i]); result = lua_dofile (argv[i]);
if (result)
fprintf(stderr, "lua: error trying to run file %s\n", argv[i]);
}
} }
} }
return result; return result;

21
lua.h
View File

@@ -2,14 +2,14 @@
** LUA - Linguagem para Usuarios de Aplicacao ** LUA - Linguagem para Usuarios de Aplicacao
** Grupo de Tecnologia em Computacao Grafica ** Grupo de Tecnologia em Computacao Grafica
** TeCGraf - PUC-Rio ** TeCGraf - PUC-Rio
** $Id: lua.h,v 3.24 1996/03/19 22:28:37 roberto Exp roberto $ ** $Id: lua.h,v 3.27 1996/04/25 14:10:00 roberto Exp roberto $
*/ */
#ifndef lua_h #ifndef lua_h
#define lua_h #define lua_h
#define LUA_VERSION "Lua 2.4 (beta)" #define LUA_VERSION "Lua 2.4"
#define LUA_COPYRIGHT "Copyright (C) 1994, 1995 TeCGraf" #define LUA_COPYRIGHT "Copyright (C) 1994, 1995 TeCGraf"
#define LUA_AUTHORS "W. Celes, R. Ierusalimschy & L. H. de Figueiredo" #define LUA_AUTHORS "W. Celes, R. Ierusalimschy & L. H. de Figueiredo"
@@ -80,17 +80,18 @@ lua_Object lua_getsubscript (void);
int lua_type (lua_Object object); int lua_type (lua_Object object);
int lua_lock (void);
lua_Object lua_getlocked (int ref); int lua_ref (int lock);
void lua_pushlocked (int ref); lua_Object lua_getref (int ref);
void lua_unlock (int ref); void lua_pushref (int ref);
void lua_unref (int ref);
lua_Object lua_createtable (void); lua_Object lua_createtable (void);
/* some useful macros */ /* some useful macros */
#define lua_lockobject(o) (lua_pushobject(o), lua_lock()) #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_storeglobal(n))
@@ -99,6 +100,12 @@ lua_Object lua_createtable (void);
/* for compatibility with old versions. Avoid using these macros */ /* for compatibility with old versions. Avoid using these macros */
#define lua_lockobject(o) lua_refobject(o,1)
#define lua_lock() lua_ref(1)
#define lua_getlocked lua_getref
#define lua_pushlocked lua_pushref
#define lua_unlock lua_unref
#define lua_pushliteral(o) lua_pushstring(o) #define lua_pushliteral(o) lua_pushstring(o)
#define lua_getindexed(o,n) (lua_pushobject(o), lua_pushnumber(n), lua_getsubscript()) #define lua_getindexed(o,n) (lua_pushobject(o), lua_pushnumber(n), lua_getsubscript())

View File

@@ -2,18 +2,27 @@
** Libraries to be used in LUA programs ** Libraries to be used in LUA programs
** Grupo de Tecnologia em Computacao Grafica ** Grupo de Tecnologia em Computacao Grafica
** TeCGraf - PUC-Rio ** TeCGraf - PUC-Rio
** $Id: lualib.h,v 1.6 1996/02/09 19:00:23 roberto Exp roberto $ ** $Id: lualib.h,v 1.7 1996/03/14 15:53:09 roberto Exp roberto $
*/ */
#ifndef lualib_h #ifndef lualib_h
#define lualib_h #define lualib_h
#include "lua.h"
void iolib_open (void); void iolib_open (void);
void strlib_open (void); void strlib_open (void);
void mathlib_open (void); void mathlib_open (void);
/* auxiliar functions (private) */ /* auxiliar functions (private) */
struct lua_reg {
char *name;
lua_CFunction func;
};
void luaI_openlib (struct lua_reg *l, int n);
void lua_arg_error(char *funcname); void lua_arg_error(char *funcname);
char *lua_check_string (int numArg, char *funcname); char *lua_check_string (int numArg, char *funcname);
double lua_check_number (int numArg, char *funcname); double lua_check_number (int numArg, char *funcname);

View File

@@ -3,15 +3,12 @@
** TecCGraf - PUC-Rio ** TecCGraf - PUC-Rio
*/ */
char *rcs_mem = "$Id: mem.c,v 1.10 1996/03/21 16:31:32 roberto Exp roberto $"; char *rcs_mem = "$Id: mem.c,v 1.11 1996/03/21 18:54:29 roberto Exp roberto $";
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "mem.h" #include "mem.h"
#include "lua.h" #include "lua.h"
#include "table.h"
#define mem_error() lua_error(memEM) #define mem_error() lua_error(memEM)

View File

@@ -1,7 +1,7 @@
/* /*
** mem.c ** mem.c
** memory manager for lua ** memory manager for lua
** $Id: mem.h,v 1.5 1996/03/21 16:31:32 roberto Exp roberto $ ** $Id: mem.h,v 1.6 1996/03/21 18:54:29 roberto Exp roberto $
*/ */
#ifndef mem_h #ifndef mem_h
@@ -18,7 +18,7 @@
#define constantEM "constant table overflow" #define constantEM "constant table overflow"
#define stackEM "stack size overflow" #define stackEM "stack size overflow"
#define lexEM "lex buffer overflow" #define lexEM "lex buffer overflow"
#define lockEM "lock table overflow" #define refEM "reference table overflow"
#define tableEM "table overflow" #define tableEM "table overflow"
#define memEM "not enough memory" #define memEM "not enough memory"

View File

@@ -1,9 +1,10 @@
# $Id: makefile,v 1.21 1996/03/05 15:57:53 roberto Exp roberto $ # $Id: makefile,v 1.25 1996/05/06 14:38:40 roberto Exp $
#configuration #configuration
# define (undefine) POPEN if your system (does not) support piped I/O # define (undefine) POPEN if your system (does not) support piped I/O
CONFIG = -DPOPEN # define (undefine) POSIX if your system is (not) POSIX compliant
CONFIG = -DPOPEN -DPOSIX
# Compilation parameters # Compilation parameters
CC = gcc CC = gcc
CFLAGS = $(CONFIG) -I/usr/5include -Wall -Wmissing-prototypes -Wshadow -ansi -O2 CFLAGS = $(CONFIG) -I/usr/5include -Wall -Wmissing-prototypes -Wshadow -ansi -O2
@@ -48,14 +49,14 @@ lualib.a : $(LIBOBJS)
liblua.so.1.0 : lua.o liblua.so.1.0 : lua.o
ld -o liblua.so.1.0 $(LUAOBJS) ld -o liblua.so.1.0 $(LUAOBJS)
y.tab.c y.tab.h : lua.stx #y.tab.c y.tab.h : lua.stx
yacc++ -d lua.stx # yacc++ -d lua.stx
parser.c : y.tab.c #parser.c : y.tab.c
sed -e 's/yy/luaY_/g' y.tab.c > parser.c # sed -e 's/yy/luaY_/g' -e 's/malloc\.h/stdlib\.h/g' y.tab.c > parser.c
parser.h : y.tab.h #parser.h : y.tab.h
sed -e 's/yy/luaY_/g' y.tab.h > parser.h # sed -e 's/yy/luaY_/g' y.tab.h > parser.h
clear : clear :
rcsclean rcsclean
@@ -64,12 +65,12 @@ clear :
co lua.h lualib.h luadebug.h co lua.h lualib.h luadebug.h
% : RCS/%,v #% : RCS/%,v
co $@ # co $@
fallback.o : fallback.c mem.h fallback.h lua.h opcode.h types.h tree.h func.h \
fallback.o : fallback.c mem.h fallback.h opcode.h lua.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 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 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 \ inout.o : inout.c lex.h opcode.h lua.h types.h tree.h func.h inout.h table.h \

View File

@@ -1,6 +1,6 @@
% $Id: manual.tex,v 1.13 1996/03/19 22:39:07 roberto Exp roberto $ % $Id: manual.tex,v 1.16 1996/04/22 18:00:37 roberto Exp roberto $
\documentstyle[A4,11pt,bnf]{article} \documentstyle[fullpage,11pt,bnf]{article}
\newcommand{\rw}[1]{{\bf #1}} \newcommand{\rw}[1]{{\bf #1}}
\newcommand{\see}[1]{see Section~\ref{#1}} \newcommand{\see}[1]{see Section~\ref{#1}}
@@ -34,7 +34,7 @@ Waldemar Celes Filho
\tecgraf\ --- Departamento de Inform\'atica --- PUC-Rio \tecgraf\ --- Departamento de Inform\'atica --- PUC-Rio
} }
\date{\small \verb$Date: 1996/03/19 22:39:07 $} \date{\small \verb$Date: 1996/04/22 18:00:37 $}
\maketitle \maketitle
@@ -739,7 +739,7 @@ The API functions can be classified in the following categories:
\item manipulating (reading and writing) Lua objects; \item manipulating (reading and writing) Lua objects;
\item calling Lua functions; \item calling Lua functions;
\item C functions to be called by Lua; \item C functions to be called by Lua;
\item locking Lua Objects. \item references to Lua Objects.
\end{enumerate} \end{enumerate}
All API functions are declared in the file \verb'lua.h'. All API functions are declared in the file \verb'lua.h'.
@@ -1069,30 +1069,37 @@ many results.
Section~\ref{exCFunction} presents an example of a CFunction. Section~\ref{exCFunction} presents an example of a CFunction.
\subsection{Locking Lua Objects} \subsection{References to Lua Objects}
As already noted, \verb'lua_Object's are volatile. As already noted, \verb'lua_Object's are volatile.
If the C code needs to keep a \verb'lua_Object' If the C code needs to keep a \verb'lua_Object'
outside block boundaries, outside block boundaries,
it has to {\em lock} the object. it must create a \Def{reference} to the object.
The routines to manipulate locking are the following: The routines to manipulate references are the following:
\Deffunc{lua_lock}\Deffunc{lua_getlocked} \Deffunc{lua_ref}\Deffunc{lua_getref}
\Deffunc{lua_pushlocked}\Deffunc{lua_unlock} \Deffunc{lua_pushref}\Deffunc{lua_unref}
\begin{verbatim} \begin{verbatim}
int lua_lock (void); int lua_ref (int lock);
lua_Object lua_getlocked (int ref); lua_Object lua_getref (int ref);
void lua_pushlocked (int ref); void lua_pushref (int ref);
void lua_unlock (int ref); void lua_unref (int ref);
\end{verbatim} \end{verbatim}
The function \verb'lua_lock' locks the object The function \verb'lua_ref' creates a reference
which is on the top of the stack, to the object which is on the top of the stack,
and returns a reference to it. and returns this reference.
Whenever the locked object is needed, If \verb'lock' is true, the object is {\em locked}:
a call to \verb'lua_getlocked' that means the object will not be garbage collected.
Notice that an unlocked reference may be garbage collected.
Whenever the referenced object is needed,
a call to \verb'lua_getref'
returns a handle to it, returns a handle to it,
while \verb'lua_pushlocked' pushes the handle on the stack. while \verb'lua_pushref' pushes the object on the stack.
When a locked object is no longer needed, If the object has been collected,
it can be unlocked with a call to \verb'lua_unlock'. \verb'lua_getref' returns \verb'LUA_NOOBJECT',
and \verb'lua_pushobject' issues an error.
When a reference is no longer needed,
it can be freed with a call to \verb'lua_unref'.
@@ -1113,7 +1120,7 @@ Currently there are three standard libraries:
\begin{itemize} \begin{itemize}
\item string manipulation; \item string manipulation;
\item mathematical functions (sin, cos, etc); \item mathematical functions (sin, cos, etc);
\item input and output. \item input and output (plus some system facilities).
\end{itemize} \end{itemize}
In order to have access to these libraries, In order to have access to these libraries,
the host program must call the functions the host program must call the functions
@@ -1373,8 +1380,6 @@ This function opens a file named \verb'filename' and sets it as the
{\em current} output file. {\em current} output file.
Unlike the \verb'writeto' operation, Unlike the \verb'writeto' operation,
this function does not erase any previous content of the file. this function does not erase any previous content of the file.
This function returns 2 if the file already exists,
1 if it creates a new file, and \nil\ on failure.
\subsubsection*{{\tt remove (filename)}}\Deffunc{remove} \subsubsection*{{\tt remove (filename)}}\Deffunc{remove}
@@ -1475,15 +1480,11 @@ it returns a reasonable date and time representation.
This function replaces functions \verb'date' and \verb'time' from This function replaces functions \verb'date' and \verb'time' from
previous Lua versions. previous Lua versions.
\subsubsection*{{\tt exit ([code])}}\Deffunc{exit}
% \subsubsection*{{\tt debug ()}} This function calls the C function \verb-exit-,
% This function, when called, repeatedly presents a prompt \verb'lua_debug> ' with an optional \verb-code-,
% in the error output stream (\verb'stderr'), to terminate the program.
% reads a line from the standard input,
% and executes (``dostring'') the line.
% The loop ends when the user types \verb'cont' to the prompt.
% This function then returns and the execution of the program continues.
\section{The Debuger Interface} \label{debugI} \section{The Debuger Interface} \label{debugI}
@@ -1839,12 +1840,14 @@ as illustrated in Figure~\ref{Cinher}.
\begin{figure} \begin{figure}
\Line \Line
\begin{verbatim} \begin{verbatim}
int lockedParentName; /* stores the lock index for the string "parent" */ #include "lua.h"
int lockedParentName; /* lock index for the string "parent" */
int lockedOldIndex; /* previous fallback function */ int lockedOldIndex; /* previous fallback function */
void callOldFallback (lua_Object table, lua_Object index) void callOldFallback (lua_Object table, lua_Object index)
{ {
lua_Object oldIndex = lua_getlocked(lockedOldIndex); lua_Object oldIndex = lua_getref(lockedOldIndex);
lua_pushobject(table); lua_pushobject(table);
lua_pushobject(index); lua_pushobject(index);
lua_callfunction(oldIndex); lua_callfunction(oldIndex);
@@ -1861,7 +1864,7 @@ void Index (void)
return; return;
} }
lua_pushobject(table); lua_pushobject(table);
lua_pushlocked(lockedParentName); lua_pushref(lockedParentName);
parent = lua_getsubscript(); parent = lua_getsubscript();
if (lua_istable(parent)) if (lua_istable(parent))
{ {
@@ -1880,9 +1883,9 @@ void Index (void)
This code must be registered with: This code must be registered with:
\begin{verbatim} \begin{verbatim}
lua_pushstring("parent"); lua_pushstring("parent");
lockedParentName = lua_lock(); lockedParentName = lua_ref(1);
lua_pushobject(lua_setfallback("index", Index)); lua_pushobject(lua_setfallback("index", Index));
lockedOldIndex = lua_lock(); lockedOldIndex = lua_ref(1);
\end{verbatim} \end{verbatim}
Notice how the string \verb'"parent"' is kept Notice how the string \verb'"parent"' is kept
locked in Lua for optimal performance. locked in Lua for optimal performance.
@@ -1892,6 +1895,9 @@ There are many different ways to do object-oriented programming in Lua.
This section presents one possible way to This section presents one possible way to
implement classes, implement classes,
using the inheritance mechanism presented above. using the inheritance mechanism presented above.
{\em Please notice: the following examples only work
with the index fallback redefined according to
Section~\ref{exfallback}}.
As one could expect, a good way to represent a class is As one could expect, a good way to represent a class is
as a table. as a table.
@@ -2076,12 +2082,18 @@ Here is a list of all these differences.
Functions \verb'date' and \verb'time' (from \verb'iolib') Functions \verb'date' and \verb'time' (from \verb'iolib')
have been superseded by the new version of function \verb'date'. have been superseded by the new version of function \verb'date'.
\item \item
Function \verb'append' (from \verb'iolib') now returns 1 whenever it succeeds,
whether the file is new or not.
\item
Function \verb'int2str' (from \verb'strlib') has been superseded by new Function \verb'int2str' (from \verb'strlib') has been superseded by new
function \verb'format', with parameter \verb'"%c"'. function \verb'format', with parameter \verb'"%c"'.
\item \item
The API lock mechanism has been superseded by the reference mechanism.
However, \verb-lua.h- provides compatibility macros,
so there is no need to change programs.
\item
API function \verb'lua_pushliteral' now is just a macro to API function \verb'lua_pushliteral' now is just a macro to
\verb'lua_pushstring'. \verb'lua_pushstring'.
Programmers are encouraged not to use this macro.
\end{itemize} \end{itemize}
\subsection*{Incompatibilities with \Index{version 2.1}} \subsection*{Incompatibilities with \Index{version 2.1}}

View File

@@ -3,7 +3,7 @@
** Mathematics library to LUA ** Mathematics library to LUA
*/ */
char *rcs_mathlib="$Id: mathlib.c,v 1.13 1995/11/10 17:54:31 roberto Exp roberto $"; char *rcs_mathlib="$Id: mathlib.c,v 1.16 1996/04/25 14:10:00 roberto Exp roberto $";
#include <stdlib.h> #include <stdlib.h>
#include <math.h> #include <math.h>
@@ -113,7 +113,7 @@ static void math_pow (void)
lua_Object op = lua_getparam(3); lua_Object op = lua_getparam(3);
if (!lua_isnumber(o1) || !lua_isnumber(o2) || *(lua_getstring(op)) != 'p') if (!lua_isnumber(o1) || !lua_isnumber(o2) || *(lua_getstring(op)) != 'p')
{ {
lua_Object old = lua_getlocked(old_pow); lua_Object old = lua_getref(old_pow);
lua_pushobject(o1); lua_pushobject(o1);
lua_pushobject(o2); lua_pushobject(o2);
lua_pushobject(op); lua_pushobject(op);
@@ -195,33 +195,36 @@ static void math_randomseed (void)
} }
static struct lua_reg mathlib[] = {
{"abs", math_abs},
{"sin", math_sin},
{"cos", math_cos},
{"tan", math_tan},
{"asin", math_asin},
{"acos", math_acos},
{"atan", math_atan},
{"atan2", math_atan2},
{"ceil", math_ceil},
{"floor", math_floor},
{"mod", math_mod},
{"sqrt", math_sqrt},
{"min", math_min},
{"max", math_max},
{"log", math_log},
{"log10", math_log10},
{"exp", math_exp},
{"deg", math_deg},
{"rad", math_rad},
{"random", math_random},
{"randomseed", math_randomseed}
};
/* /*
** Open math library ** Open math library
*/ */
void mathlib_open (void) void mathlib_open (void)
{ {
lua_register ("abs", math_abs); luaI_openlib(mathlib, (sizeof(mathlib)/sizeof(mathlib[0])));
lua_register ("sin", math_sin); old_pow = lua_refobject(lua_setfallback("arith", math_pow), 1);
lua_register ("cos", math_cos);
lua_register ("tan", math_tan);
lua_register ("asin", math_asin);
lua_register ("acos", math_acos);
lua_register ("atan", math_atan);
lua_register ("atan2", math_atan2);
lua_register ("ceil", math_ceil);
lua_register ("floor", math_floor);
lua_register ("mod", math_mod);
lua_register ("sqrt", math_sqrt);
lua_register ("min", math_min);
lua_register ("max", math_max);
lua_register ("log", math_log);
lua_register ("log10", math_log10);
lua_register ("exp", math_exp);
lua_register ("deg", math_deg);
lua_register ("rad", math_rad);
lua_register ("random", math_random);
lua_register ("randomseed", math_randomseed);
old_pow = lua_lockobject(lua_setfallback("arith", math_pow));
} }

View File

@@ -3,7 +3,7 @@
** TecCGraf - PUC-Rio ** TecCGraf - PUC-Rio
*/ */
char *rcs_opcode="$Id: opcode.c,v 3.65 1996/03/21 18:55:02 roberto Exp roberto $"; char *rcs_opcode="$Id: opcode.c,v 3.67 1996/04/22 18:00:37 roberto Exp roberto $";
#include <setjmp.h> #include <setjmp.h>
#include <stdio.h> #include <stdio.h>
@@ -717,27 +717,31 @@ void *lua_getuserdata (lua_Object object)
} }
lua_Object lua_getlocked (int ref) lua_Object lua_getref (int ref)
{ {
adjustC(0); Object *o = luaI_getref(ref);
*top = *luaI_getlocked(ref); if (o == NULL)
incr_top; return LUA_NOOBJECT;
CBase++; /* incorporate object in the stack */ adjustC(0);
return Ref(top-1); luaI_pushobject(o);
CBase++; /* incorporate object in the stack */
return Ref(top-1);
} }
void lua_pushlocked (int ref) void lua_pushref (int ref)
{ {
*top = *luaI_getlocked(ref); Object *o = luaI_getref(ref);
incr_top; if (o == NULL)
lua_error("access to invalid (possibly garbage collected) reference");
luaI_pushobject(o);
} }
int lua_lock (void) int lua_ref (int lock)
{ {
adjustC(1); adjustC(1);
return luaI_lock(--top); return luaI_ref(--top, lock);
} }
@@ -812,20 +816,12 @@ void lua_pushcfunction (lua_CFunction fn)
*/ */
void lua_pushusertag (void *u, int tag) void lua_pushusertag (void *u, int tag)
{ {
if (tag < LUA_T_USERDATA) return; if (tag < LUA_T_USERDATA)
lua_error("invalid tag in `lua_pushusertag'");
tag(top) = tag; uvalue(top) = u; tag(top) = tag; uvalue(top) = u;
incr_top; incr_top;
} }
/*
** Push a lua_Object to stack.
*/
void lua_pushobject (lua_Object o)
{
*top = *Address(o);
incr_top;
}
/* /*
** Push an object on the stack. ** Push an object on the stack.
*/ */
@@ -835,6 +831,16 @@ void luaI_pushobject (Object *o)
incr_top; incr_top;
} }
/*
** Push a lua_Object on stack.
*/
void lua_pushobject (lua_Object o)
{
if (o == LUA_NOOBJECT)
lua_error("attempt to push a NOOBJECT");
luaI_pushobject(Address(o));
}
int lua_type (lua_Object o) int lua_type (lua_Object o)
{ {
if (o == LUA_NOOBJECT) if (o == LUA_NOOBJECT)

View File

@@ -3,7 +3,7 @@
** String library to LUA ** String library to LUA
*/ */
char *rcs_strlib="$Id: strlib.c,v 1.21 1996/03/21 22:18:08 roberto Exp roberto $"; char *rcs_strlib="$Id: strlib.c,v 1.22 1996/03/22 17:57:24 roberto Exp roberto $";
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
@@ -249,16 +249,28 @@ static void str_format (void)
} }
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[] = {
{"strfind", str_find},
{"strlen", str_len},
{"strsub", str_sub},
{"strlower", str_lower},
{"strupper", str_upper},
{"ascii", str_ascii},
{"format", str_format}
};
/* /*
** Open string library ** Open string library
*/ */
void strlib_open (void) void strlib_open (void)
{ {
lua_register ("strfind", str_find); luaI_openlib(strlib, (sizeof(strlib)/sizeof(strlib[0])));
lua_register ("strlen", str_len);
lua_register ("strsub", str_sub);
lua_register ("strlower", str_lower);
lua_register ("strupper", str_upper);
lua_register ("ascii", str_ascii);
lua_register ("format", str_format);
} }

41
table.c
View File

@@ -3,7 +3,7 @@
** Module to control static tables ** Module to control static tables
*/ */
char *rcs_table="$Id: table.c,v 2.50 1996/03/21 16:31:32 roberto Exp roberto $"; char *rcs_table="$Id: table.c,v 2.53 1996/04/29 18:53:53 roberto Exp roberto $";
#include "mem.h" #include "mem.h"
#include "opcode.h" #include "opcode.h"
@@ -27,8 +27,7 @@ Word lua_nconstant = 0;
static Long lua_maxconstant = 0; static Long lua_maxconstant = 0;
#define GARBAGE_BLOCK 1024 #define GARBAGE_BLOCK 50
#define MIN_GARBAGE_BLOCK (GARBAGE_BLOCK/2)
static void lua_nextvar (void); static void lua_nextvar (void);
@@ -170,6 +169,24 @@ int lua_markobject (Object *o)
return 0; return 0;
} }
/*
* returns 0 if the object is going to be (garbage) collected
*/
int luaI_ismarked (Object *o)
{
switch (o->tag)
{
case LUA_T_STRING:
return o->value.ts->marked;
case LUA_T_FUNCTION:
return o->value.tf->marked;
case LUA_T_ARRAY:
return o->value.a->mark;
default: /* nil, number, cfunction, or user data */
return 1;
}
}
/* /*
** Garbage collection. ** Garbage collection.
@@ -182,6 +199,7 @@ Long luaI_collectgarbage (void)
lua_travsymbol(lua_markobject); /* mark symbol table objects */ lua_travsymbol(lua_markobject); /* mark symbol table objects */
luaI_travlock(lua_markobject); /* mark locked objects */ luaI_travlock(lua_markobject); /* mark locked objects */
luaI_travfallbacks(lua_markobject); /* mark fallbacks */ luaI_travfallbacks(lua_markobject); /* mark fallbacks */
luaI_invalidaterefs();
recovered += lua_strcollector(); recovered += lua_strcollector();
recovered += lua_hashcollector(); recovered += lua_hashcollector();
recovered += luaI_funccollector(); recovered += luaI_funccollector();
@@ -190,14 +208,13 @@ Long luaI_collectgarbage (void)
void lua_pack (void) void lua_pack (void)
{ {
static Long block = GARBAGE_BLOCK; /* when garbage collector will be called */ static unsigned long block = GARBAGE_BLOCK;
static Long nentity = 0; /* counter of new entities (strings and arrays) */ static unsigned long nentity = 0; /* total of strings, arrays, etc */
Long recovered = 0; unsigned long recovered = 0;
if (nentity++ < block) return; if (nentity++ < block) return;
recovered = luaI_collectgarbage(); recovered = luaI_collectgarbage();
nentity = 0; /* reset counter */ block = block*2*(1.0 - (float)recovered/nentity);
block=(16*block-7*recovered)/12; /* adapt block size */ nentity -= recovered;
if (block < MIN_GARBAGE_BLOCK) block = MIN_GARBAGE_BLOCK;
} }
@@ -229,11 +246,7 @@ static void lua_nextvar (void)
} }
else else
{ {
TaggedString *t = lua_table[next].varname; lua_pushstring(lua_table[next].varname->str);
Object name;
tag(&name) = LUA_T_STRING;
tsvalue(&name) = t;
luaI_pushobject(&name);
luaI_pushobject(&s_object(next)); luaI_pushobject(&s_object(next));
} }
} }

View File

@@ -1,7 +1,7 @@
/* /*
** Module to control static tables ** Module to control static tables
** TeCGraf - PUC-Rio ** TeCGraf - PUC-Rio
** $Id: table.h,v 2.19 1996/02/26 21:00:27 roberto Exp roberto $ ** $Id: table.h,v 2.20 1996/03/14 15:57:19 roberto Exp roberto $
*/ */
#ifndef table_h #ifndef table_h
@@ -30,6 +30,7 @@ Word luaI_findconstant (TaggedString *t);
Word luaI_findconstantbyname (char *name); Word luaI_findconstantbyname (char *name);
TaggedString *luaI_createfixedstring (char *str); TaggedString *luaI_createfixedstring (char *str);
int lua_markobject (Object *o); int lua_markobject (Object *o);
int luaI_ismarked (Object *o);
Long luaI_collectgarbage (void); Long luaI_collectgarbage (void);
void lua_pack (void); void lua_pack (void);