Compare commits

..

72 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
Roberto Ierusalimschy
ce23901f04 smaller limit to stack size (otherwise C stack can finish first) 1996-03-22 16:12:15 -03:00
Roberto Ierusalimschy
df1ee1fb1c small "abstraction" 1996-03-22 14:57:24 -03:00
Roberto Ierusalimschy
f1d0276684 small bug in strfind. 1996-03-21 19:18:08 -03:00
Roberto Ierusalimschy
7ecc2ea597 new version 1996-03-21 18:30:29 -03:00
Roberto Ierusalimschy
7a35f23c16 a simplification about memory error messages. 1996-03-21 15:55:02 -03:00
Roberto Ierusalimschy
9284742a11 better control when growing arrays. 1996-03-21 13:33:47 -03:00
Roberto Ierusalimschy
9704ff4cb1 hook variables are global, no more "lua_set...hook" functions. 1996-03-20 15:44:02 -03:00
Roberto Ierusalimschy
e3c0ce9a69 dofile accepts pre-compiled chunks.
lua_is... do coercion.
small correction: = versus ==.
1996-03-19 19:39:07 -03:00
Roberto Ierusalimschy
85b76bcc01 functions "lua_is..." consider coercions.
small change when calling call hook.
1996-03-19 19:28:37 -03:00
Roberto Ierusalimschy
a275d9a25b functions "lua_is..." consider coercions. 1996-03-19 19:28:37 -03:00
Roberto Ierusalimschy
7e0be1fbde unused "#include" 1996-03-19 13:50:24 -03:00
Roberto Ierusalimschy
54ba642cc3 new module "undump.o" 1996-03-15 15:22:09 -03:00
Roberto Ierusalimschy
8826eb7918 small correction 1996-03-15 15:21:58 -03:00
Roberto Ierusalimschy
e701a86385 "openfile" now returns the file 1996-03-15 10:13:13 -03:00
Roberto Ierusalimschy
3e1f731826 integration with undump (execution of pre-compiled chuncks) 1996-03-15 10:13:13 -03:00
Roberto Ierusalimschy
f86c1367db new functions "rename" and "tmpname".
new option 'q' for function "format".
new example, about vararg.
1996-03-14 14:45:01 -03:00
Luiz Henrique de Figueiredo
58fd8aa851 added cast instead of union [lazy?] 1996-03-14 14:31:15 -03:00
Roberto Ierusalimschy
3226ac2da8 "lua_ntable" and "lua_nconstant" are public (undump.c uses them). 1996-03-14 12:57:19 -03:00
Roberto Ierusalimschy
3e9daa7416 creation of strings must call garbage collector. 1996-03-14 12:56:26 -03:00
Roberto Ierusalimschy
7236df875a new function "luaI_buffer". 1996-03-14 12:55:49 -03:00
Roberto Ierusalimschy
675e608325 new functions "rename" and "tmpname". 1996-03-14 12:55:18 -03:00
Roberto Ierusalimschy
1dc0e82aeb "freefunc" now is public. 1996-03-14 12:54:20 -03:00
Roberto Ierusalimschy
c2eb02aaf6 both "write" and "format" need "addquoted". 1996-03-14 12:53:09 -03:00
Roberto Ierusalimschy
2fee7e42c9 new option 'q' in function "format". 1996-03-14 12:52:35 -03:00
Roberto Ierusalimschy
281db390e8 no more "ugly" programs.
no more comments with '#'.
1996-03-14 12:17:28 -03:00
Luiz Henrique de Figueiredo
df8cf53cc9 removed tf->marked=0; 1996-03-12 17:00:40 -03:00
Roberto Ierusalimschy
40306b10db small corrections. 1996-03-12 12:56:03 -03:00
Luiz Henrique de Figueiredo
5eff5d3eac moved some includes from undump.h
LoadString now uses luaI_buffer
added LoadNewString
needs tf->marked=0
luaI_undump now returns int and aborts if luaI_dorun fails
1996-03-11 19:01:46 -03:00
Luiz Henrique de Figueiredo
8ad8426c43 moved some includes to undump.c
luaI_undump now returns int
1996-03-11 18:59:41 -03:00
Luiz Henrique de Figueiredo
3cab7cd025 undump.c is now a module
panic is now lua_error
 included swap.c
 tries float permutation earlier
 new functions: luaI_undump1 and luaI_undump
1996-03-08 18:44:12 -03:00
Luiz Henrique de Figueiredo
bb26efbbec definitions for lua decompiler
undump is now a module
1996-03-08 18:43:21 -03:00
Roberto Ierusalimschy
5c0e5fd36d details. 1996-03-08 09:04:04 -03:00
Roberto Ierusalimschy
621322a305 "PrintCode" now is defined in luac. 1996-03-08 09:02:37 -03:00
Luiz Henrique de Figueiredo
e33a3b8e0d now loads size as two words 1996-03-06 18:40:10 -03:00
Luiz Henrique de Figueiredo
9a6cccb08c removed support for local vars 1996-03-06 13:01:08 -03:00
Roberto Ierusalimschy
b58225e93b unused declaration removed. 1996-03-06 10:11:23 -03:00
Luiz Henrique de Figueiredo
852b919465 now swaps bytes (but need to make it more robust) 1996-03-05 22:41:18 -03:00
Roberto Ierusalimschy
ef94999647 parse.o was included twice in lua.a 1996-03-05 12:57:53 -03:00
Roberto Ierusalimschy
6f30fa98d8 small change to avoid error on "lua_pushstring(NULL)". 1996-03-04 11:46:35 -03:00
Roberto Ierusalimschy
74102bd716 small corrections. 1996-03-04 10:29:10 -03:00
Roberto Ierusalimschy
8d82aa821a small correction (about types) 1996-03-01 13:54:00 -03:00
Luiz Henrique de Figueiredo
cec1ffb80b uses ID_* constants
simplified signature checking
loads local vars
1996-03-01 00:43:50 -03:00
Luiz Henrique de Figueiredo
870967ca77 headers for Main and others are different 1996-02-28 20:10:46 -03:00
Roberto Ierusalimschy
66fc0f554a using double to read numbers. 1996-02-26 19:35:51 -03:00
Roberto Ierusalimschy
d6e4c29733 fixed strings (not collectable) don't need to be inserted in the constant table. 1996-02-26 18:00:27 -03:00
Luiz Henrique de Figueiredo
3e42969979 main always reads "luac.out" 1996-02-26 16:44:17 -03:00
Roberto Ierusalimschy
712ac505e0 small correction 1996-02-26 14:07:49 -03:00
Roberto Ierusalimschy
f935d3397e check if jump is bigger than 2^16. 1996-02-26 14:07:20 -03:00
Roberto Ierusalimschy
30dd3a2dbc small changes (preparing for new module of pre-compilation) 1996-02-26 14:06:39 -03:00
Luiz Henrique de Figueiredo
b04f88d581 functions now linked into a list headed by main 1996-02-24 13:44:28 -03:00
Luiz Henrique de Figueiredo
b3c10c8c41 fix to PUSHFUNCTION now correctly at tf->marked 1996-02-24 00:46:57 -03:00
Luiz Henrique de Figueiredo
5c1bd89a1c added fix to PUSHFUNCTION and support for main function 1996-02-23 19:00:26 -03:00
Luiz Henrique de Figueiredo
15f3ab09eb load bytecodes from files 1996-02-23 16:04:38 -03:00
Roberto Ierusalimschy
c7e834f424 function "write_quoted" rewritten more clearly. 1996-02-22 17:56:33 -03:00
Roberto Ierusalimschy
8c1a9899d4 functions "luaI_free" and "luaI_realloc" (or macro "growvector") may be
called with NULL.
1996-02-22 17:34:33 -03:00
30 changed files with 1064 additions and 878 deletions

View File

@@ -3,7 +3,7 @@
** TecCGraf - PUC-Rio
*/
char *rcs_fallback="$Id: fallback.c,v 1.18 1996/01/30 15:25:23 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 <string.h>
@@ -12,6 +12,7 @@ char *rcs_fallback="$Id: fallback.c,v 1.18 1996/01/30 15:25:23 roberto Exp rober
#include "fallback.h"
#include "opcode.h"
#include "lua.h"
#include "table.h"
static void errorFB (void);
@@ -49,7 +50,7 @@ void luaI_setfallback (void)
int i;
char *name = lua_getstring(lua_getparam(1));
lua_Object func = lua_getparam(2);
if (name == NULL || !(lua_isfunction(func) || lua_iscfunction(func)))
if (name == NULL || !lua_isfunction(func))
lua_error("incorrect argument to function `setfallback'");
for (i=0; i<N_FB; i++)
{
@@ -112,71 +113,77 @@ static void funcFB (void)
/*
** Lock routines
** Reference routines
*/
static Object *lockArray = NULL;
static Word lockSize = 0;
static struct ref {
Object o;
enum {LOCK, HOLD, FREE, COLLECTED} status;
} *refArray = NULL;
static int refSize = 0;
int luaI_lock (Object *object)
int luaI_ref (Object *object, int lock)
{
Word i;
Word oldSize;
int i;
int oldSize;
if (tag(object) == LUA_T_NIL)
return -1; /* special lock ref for nil */
for (i=0; i<lockSize; i++)
if (tag(&lockArray[i]) == LUA_T_NIL)
{
lockArray[i] = *object;
return i;
}
return -1; /* special ref for nil */
for (i=0; i<refSize; i++)
if (refArray[i].status == FREE)
goto found;
/* no more empty spaces */
oldSize = lockSize;
if (lockArray == NULL)
{
lockSize = 10;
lockArray = newvector(lockSize, Object);
}
else
{
lockSize = 3*oldSize/2 + 5;
lockArray = growvector(lockArray, lockSize, Object);
}
for (i=oldSize; i<lockSize; i++)
tag(&lockArray[i]) = LUA_T_NIL;
lockArray[oldSize] = *object;
return oldSize;
oldSize = refSize;
refSize = growvector(&refArray, refSize, struct ref, refEM, MAX_WORD);
for (i=oldSize; i<refSize; i++)
refArray[i].status = FREE;
i = oldSize;
found:
refArray[i].o = *object;
refArray[i].status = lock ? LOCK : HOLD;
return i;
}
void lua_unlock (int ref)
void lua_unref (int ref)
{
if (ref >= 0 && ref < lockSize)
tag(&lockArray[ref]) = LUA_T_NIL;
if (ref >= 0 && ref < refSize)
refArray[ref].status = FREE;
}
Object *luaI_getlocked (int ref)
Object *luaI_getref (int ref)
{
static Object nul = {LUA_T_NIL, {0}};
if (ref >= 0 && ref < lockSize)
return &lockArray[ref];
else
if (ref == -1)
return &nul;
if (ref >= 0 && ref < refSize &&
(refArray[ref].status == LOCK || refArray[ref].status == HOLD))
return &refArray[ref].o;
else
return NULL;
}
void luaI_travlock (int (*fn)(Object *))
{
Word i;
for (i=0; i<lockSize; i++)
fn(&lockArray[i]);
int i;
for (i=0; i<refSize; i++)
if (refArray[i].status == LOCK)
fn(&refArray[i].o);
}
void luaI_invalidaterefs (void)
{
int i;
for (i=0; i<refSize; i++)
if (refArray[i].status == HOLD && !luaI_ismarked(&refArray[i].o))
refArray[i].status = COLLECTED;
}
char *luaI_travfallbacks (int (*fn)(Object *))
{
Word i;
int i;
for (i=0; i<N_FB; i++)
if (fn(&luaI_fallBacks[i].function))
return luaI_fallBacks[i].kind;

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
#define fallback_h
#include "lua.h"
#include "opcode.h"
extern struct FB {
@@ -26,9 +27,10 @@ extern struct FB {
#define FB_GETGLOBAL 9
void luaI_setfallback (void);
int luaI_lock (Object *object);
Object *luaI_getlocked (int ref);
int luaI_ref (Object *object, int lock);
Object *luaI_getref (int ref);
void luaI_travlock (int (*fn)(Object *));
void luaI_invalidaterefs (void);
char *luaI_travfallbacks (int (*fn)(Object *));
#endif

25
func.c
View File

@@ -1,4 +1,4 @@
#include <stdio.h>
#include <stdlib.h>
#include "luadebug.h"
#include "table.h"
@@ -6,7 +6,6 @@
#include "func.h"
#include "opcode.h"
#define LOCALVARINITSIZE 10
static TFunc *function_root = NULL;
static LocVar *currvars = NULL;
@@ -19,8 +18,12 @@ static int maxcurrvars = 0;
*/
void luaI_initTFunc (TFunc *f)
{
f->next = NULL;
f->marked = 0;
f->size = 0;
f->code = NULL;
f->lineDefined = 0;
f->fileName = NULL;
f->locvars = NULL;
}
@@ -39,11 +42,10 @@ void luaI_insertfunction (TFunc *f)
/*
** Free function
*/
static void freefunc (TFunc *f)
void luaI_freefunc (TFunc *f)
{
luaI_free (f->code);
if (f->locvars)
luaI_free (f->locvars);
luaI_free (f->locvars);
luaI_free (f);
}
@@ -65,7 +67,7 @@ Long luaI_funccollector (void)
function_root = next;
else
prev->next = next;
freefunc (curr);
luaI_freefunc (curr);
++counter;
}
else
@@ -100,16 +102,7 @@ void lua_funcinfo (lua_Object func, char **filename, int *linedefined)
void luaI_registerlocalvar (TaggedString *varname, int line)
{
if (numcurrvars >= maxcurrvars)
if (currvars == NULL)
{
maxcurrvars = LOCALVARINITSIZE;
currvars = newvector (maxcurrvars, LocVar);
}
else
{
maxcurrvars *= 2;
currvars = growvector (currvars, maxcurrvars, LocVar);
}
maxcurrvars = growvector(&currvars, maxcurrvars, LocVar, "", MAX_WORD);
currvars[numcurrvars].varname = varname;
currvars[numcurrvars].line = line;
numcurrvars++;

8
func.h
View File

@@ -1,8 +1,13 @@
/*
** $Id: func.h,v 1.7 1996/03/08 12:04:04 roberto Exp roberto $
*/
#ifndef func_h
#define func_h
#include "types.h"
#include "lua.h"
#include "tree.h"
typedef struct LocVar
{
@@ -17,7 +22,7 @@ typedef struct LocVar
typedef struct TFunc
{
struct TFunc *next;
char marked;
int marked;
int size;
Byte *code;
int lineDefined;
@@ -29,6 +34,7 @@ Long luaI_funccollector (void);
void luaI_insertfunction (TFunc *f);
void luaI_initTFunc (TFunc *f);
void luaI_freefunc (TFunc *f);
void luaI_registerlocalvar (TaggedString *varname, int line);
void luaI_unregisterlocalvar (int line);

49
hash.c
View File

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

13
hash.h
View File

@@ -1,8 +1,7 @@
/*
** hash.h
** hash manager for lua
** Luiz Henrique de Figueiredo - 17 Aug 90
** $Id: hash.h,v 2.9 1996/02/07 14:13:17 roberto Exp roberto $
** $Id: hash.h,v 2.11 1996/03/08 12:04:04 roberto Exp roberto $
*/
#ifndef hash_h
@@ -20,16 +19,16 @@ typedef struct node
typedef struct Hash
{
struct Hash *next;
char mark;
Word nhash;
Word nuse;
Node *node;
int nhash;
int nuse;
char mark;
} Hash;
int lua_equalObj (Object *t1, Object *t2);
Word luaI_redimension (Word nhash);
Hash *lua_createarray (Word nhash);
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);

69
inout.c
View File

@@ -5,10 +5,9 @@
** Also provides some predefined lua functions.
*/
char *rcs_inout="$Id: inout.c,v 2.31 1996/02/13 17:30:39 roberto Exp roberto $";
char *rcs_inout="$Id: inout.c,v 2.35 1996/03/19 16:50:24 roberto Exp roberto $";
#include <stdio.h>
#include <stdlib.h>
#include "lex.h"
#include "opcode.h"
@@ -16,13 +15,7 @@ char *rcs_inout="$Id: inout.c,v 2.31 1996/02/13 17:30:39 roberto Exp roberto $";
#include "table.h"
#include "tree.h"
#include "lua.h"
#ifndef MAXFUNCSTACK
#define MAXFUNCSTACK 100
#endif
#define MAXMESSAGE MAXFUNCSTACK*80
#include "mem.h"
/* Exported variables */
@@ -51,9 +44,9 @@ static int stringinput (void)
/*
** Function to open a file to be input unit.
** Return 0 on success or 1 error.
** Return the file.
*/
int lua_openfile (char *fn)
FILE *lua_openfile (char *fn)
{
lua_setinput (fileinput);
if (fn == NULL)
@@ -64,10 +57,10 @@ int lua_openfile (char *fn)
else
fp = fopen (fn, "r");
if (fp == NULL)
return 1;
return NULL;
lua_linenumber = 1;
lua_parsedfile = lua_constcreate(fn)->str;
return 0;
lua_parsedfile = luaI_createfixedstring(fn)->str;
return fp;
}
/*
@@ -90,7 +83,7 @@ void lua_openstring (char *s)
lua_setinput (stringinput);
st = s;
lua_linenumber = 1;
lua_parsedfile = lua_constcreate("(string)")->str;
lua_parsedfile = luaI_createfixedstring("(string)")->str;
}
/*
@@ -134,22 +127,27 @@ void lua_internaldofile (void)
static char *tostring (lua_Object obj)
{
static char buff[20];
if (lua_isstring(obj))
char *buff = luaI_buffer(20);
if (lua_isstring(obj)) /* get strings and numbers */
return lua_getstring(obj);
if (lua_isnumber(obj))
sprintf(buff, "%g", lua_getnumber(obj));
else if (lua_isfunction(obj))
sprintf(buff, "function: %p", (luaI_Address(obj))->value.tf);
else if (lua_iscfunction(obj))
sprintf(buff, "cfunction: %p", lua_getcfunction(obj));
else if (lua_isuserdata(obj))
sprintf(buff, "userdata: %p", lua_getuserdata(obj));
else if (lua_istable(obj))
sprintf(buff, "table: %p", avalue(luaI_Address(obj)));
else if (lua_isnil(obj))
sprintf(buff, "nil");
else buff[0] = 0;
else switch(lua_type(obj))
{
case LUA_T_FUNCTION:
sprintf(buff, "function: %p", (luaI_Address(obj))->value.tf);
break;
case LUA_T_CFUNCTION:
sprintf(buff, "cfunction: %p", lua_getcfunction(obj));
break;
case LUA_T_ARRAY:
sprintf(buff, "table: %p", avalue(luaI_Address(obj)));
break;
case LUA_T_NIL:
sprintf(buff, "nil");
break;
default:
sprintf(buff, "userdata: %p", lua_getuserdata(obj));
break;
}
return buff;
}
@@ -208,16 +206,7 @@ void lua_obj2number (void)
{
lua_Object o = lua_getparam(1);
if (lua_isnumber(o))
lua_pushobject(o);
else if (lua_isstring(o))
{
char c;
float f;
if (sscanf(lua_getstring(o),"%f %c",&f,&c) == 1)
lua_pushnumber(f);
else
lua_pushnil();
}
lua_pushnumber(lua_getnumber(o));
else
lua_pushnil();
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: inout.h,v 1.12 1996/01/26 14:05:28 roberto Exp roberto $
** $Id: inout.h,v 1.14 1996/03/15 13:13:13 roberto Exp roberto $
*/
@@ -7,13 +7,14 @@
#define inout_h
#include "types.h"
#include <stdio.h>
extern Word lua_linenumber;
extern Word lua_debugline;
extern char *lua_parsedfile;
int lua_openfile (char *fn);
FILE *lua_openfile (char *fn);
void lua_closefile (void);
void lua_openstring (char *s);
void lua_closestring (void);

138
iolib.c
View File

@@ -3,12 +3,10 @@
** Input/output library to LUA
*/
char *rcs_iolib="$Id: iolib.c,v 1.35 1996/02/09 19:35:23 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 <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
@@ -30,6 +28,14 @@ int pclose();
#endif
static void pushresult (int i)
{
if (i)
lua_pushnumber (1);
else
lua_pushnil();
}
static void closeread (void)
{
if (in != stdin)
@@ -117,15 +123,12 @@ static void io_writeto (void)
** LUA interface:
** status = appendto (filename)
** where:
** status = 2 -> success (already exist)
** status = 1 -> success (new file)
** status = 1 -> success
** status = nil -> error
*/
static void io_appendto (void)
{
char *s = lua_check_string(1, "appendto");
struct stat st;
int r = (stat(s, &st) == -1) ? 1 : 2;
FILE *fp = fopen (s, "a");
if (fp == NULL)
lua_pushnil();
@@ -133,7 +136,7 @@ static void io_appendto (void)
{
if (out != stdout) fclose (out);
out = fp;
lua_pushnumber (r);
lua_pushnumber(1);
}
}
@@ -373,25 +376,8 @@ static int write_string (char *s, int just, int m)
static int write_quoted (int just, int m)
{
char *s = lua_check_string(1, "write");
luaI_addchar(0);
luaI_addchar('"');
while (1)
{
switch (*s)
{
case '"': case '\\': case '\n':
luaI_addchar('\\');
luaI_addchar(*s);
break;
case 0:
goto END_WHILE;
default:
luaI_addchar(*s);
}
s++;
} END_WHILE:
luaI_addchar('"');
luaI_addquoted(lua_check_string(1, "write"));
return write_string(luaI_addchar(0), just, m);
}
@@ -431,9 +417,10 @@ static void io_write (void)
if (lua_getparam (2) == LUA_NOOBJECT) /* free format */
{
lua_Object o1 = lua_getparam(1);
if (lua_isnumber(o1))
int t = lua_type(o1);
if (t == LUA_T_NUMBER)
status = fprintf (out, "%g", lua_getnumber(o1)) >= 0;
else if (lua_isstring(o1))
else if (t == LUA_T_STRING)
status = fprintf (out, "%s", lua_getstring(o1)) >= 0;
}
else /* formated */
@@ -481,10 +468,19 @@ static void io_execute (void)
*/
static void io_remove (void)
{
if (remove(lua_check_string(1, "remove")) == 0)
lua_pushnumber (1);
else
lua_pushnil();
pushresult(remove(lua_check_string(1, "remove")) == 0);
}
static void io_rename (void)
{
char *f1 = lua_check_string(1, "rename");
char *f2 = lua_check_string(2, "rename");
pushresult(rename(f1, f2) == 0);
}
static void io_tmpname (void)
{
lua_pushstring(tmpnam(NULL));
}
static void io_errorno (void)
@@ -499,8 +495,7 @@ static void io_errorno (void)
static void io_getenv (void)
{
char *env = getenv(lua_check_string(1, "getenv"));
if (env == NULL) lua_pushnil();
else lua_pushstring(env);
lua_pushstring(env); /* if NULL push nil */
}
/*
@@ -529,9 +524,8 @@ static void io_date (void)
static void io_exit (void)
{
lua_Object o = lua_getparam(1);
if (lua_isstring(o))
fprintf(stderr, "%s\n", lua_getstring(o));
exit(1);
int code = lua_isnumber(o) ? (int)lua_getnumber(o) : 1;
exit(code);
}
/*
@@ -544,14 +538,14 @@ static void io_debug (void)
{
char buffer[250];
fprintf(stderr, "lua_debug> ");
if (gets(buffer) == 0) return;
if (fgets(buffer, sizeof(buffer), stdin) == 0) return;
if (strcmp(buffer, "cont") == 0) return;
lua_dostring(buffer);
}
}
void lua_printstack (FILE *f)
static void lua_printstack (FILE *f)
{
int level = 0;
lua_Object func;
@@ -567,7 +561,7 @@ void lua_printstack (FILE *f)
fprintf(f, "function %s", name);
break;
case 'f':
fprintf(f, "fallback %s", name);
fprintf(f, "`%s' fallback", name);
break;
default:
{
@@ -583,7 +577,7 @@ void lua_printstack (FILE *f)
}
}
if ((currentline = lua_currentline(func)) > 0)
fprintf(f, " at line %d", currentline);
fprintf(f, " at line %d", currentline);
fprintf(f, "\n");
}
}
@@ -598,47 +592,27 @@ static void errorfb (void)
}
/*
** Open io library
*/
static struct lua_reg iolib[] = {
{"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)
{
lua_register ("readfrom", io_readfrom);
lua_register ("writeto", io_writeto);
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 ("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);
luaI_openlib(iolib, (sizeof(iolib)/sizeof(iolib[0])));
lua_setfallback("error", errorfb);
}
/*
** Return user formatted time stamp
*
static void sys_localtime (void)
{
time_t t;
struct tm *tm;
lua_Object o = lua_getparam(1);
time(&t); tm = localtime(&t);
if (lua_isstring(o))
{
char b[BUFSIZ];
if (strftime(b,sizeof(b),lua_getstring(o),tm)==0)
lua_pushstring(ctime(&t));
else
lua_pushstring(b);
}
else
lua_pushstring(ctime(&t));
}
*/

39
lex.c
View File

@@ -1,9 +1,8 @@
char *rcs_lex = "$Id: lex.c,v 2.27 1996/02/14 13:35:51 roberto Exp roberto $";
char *rcs_lex = "$Id: lex.c,v 2.31 1996/03/19 16:50:24 roberto Exp roberto $";
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include "mem.h"
#include "tree.h"
@@ -12,7 +11,6 @@ char *rcs_lex = "$Id: lex.c,v 2.27 1996/02/14 13:35:51 roberto Exp roberto $";
#include "inout.h"
#include "luadebug.h"
#include "parser.h"
#include "ugly.h"
#define MINBUFF 260
@@ -85,8 +83,7 @@ void luaI_addReserved (void)
static void growtext (void)
{
int size = yytextLast - yytext;
textsize *= 2;
yytext = growvector(yytext, textsize, char);
textsize = growvector(&yytext, textsize, char, lexEM, MAX_WORD);
yytextLast = yytext + size;
}
@@ -135,7 +132,7 @@ static int read_long_string (void)
int luaY_lex (void)
{
float a;
double a;
static int linelasttoken = 0;
if (lua_debug)
luaI_codedebugline(linelasttoken);
@@ -143,9 +140,6 @@ int luaY_lex (void)
while (1)
{
yytextLast = yytext;
#if 0
fprintf(stderr,"'%c' %d\n",current,current);
#endif
switch (current)
{
case EOF:
@@ -177,8 +171,7 @@ int luaY_lex (void)
case '-':
save_and_next();
if (current != '-') return '-'; /* else goes through */
case '#':
if (current != '-') return '-';
do { next(); } while (current != '\n' && current != 0);
continue;
@@ -297,22 +290,22 @@ int luaY_lex (void)
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
a=0.0;
do { a=10*a+current-'0'; save_and_next(); } while (isdigit(current));
do { a=10.0*a+(current-'0'); save_and_next(); } while (isdigit(current));
if (current == '.') save_and_next();
fraction:
{ float da=0.1;
{ double da=0.1;
while (isdigit(current))
{a+=(current-'0')*da; da/=10.0; save_and_next()};
if (current == 'e' || current == 'E')
{
int e=0;
int neg;
float ea;
double ea;
save_and_next();
neg=(current=='-');
if (current == '+' || current == '-') save_and_next();
if (!isdigit(current)) return WRONGTOKEN;
do { e=10*e+current-'0'; save_and_next(); } while (isdigit(current));
do { e=10.0*e+(current-'0'); save_and_next(); } while (isdigit(current));
for (ea=neg?0.1:10.0; e>0; e>>=1)
{
if (e & 1) a*=ea;
@@ -323,22 +316,6 @@ fraction:
return NUMBER;
}
case U_and: case U_do: case U_else: case U_elseif: case U_end:
case U_function: case U_if: case U_local: case U_nil: case U_not:
case U_or: case U_repeat: case U_return: case U_then:
case U_until: case U_while:
{
int old = current;
next();
return reserved[old-U_and].token;
}
case U_eq: next(); return EQ;
case U_le: next(); return LE;
case U_ge: next(); return GE;
case U_ne: next(); return NE;
case U_sc: next(); return CONC;
default: /* also end of file */
{
save_and_next();

14
lua.c
View File

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

37
lua.h
View File

@@ -2,14 +2,14 @@
** LUA - Linguagem para Usuarios de Aplicacao
** Grupo de Tecnologia em Computacao Grafica
** TeCGraf - PUC-Rio
** $Id: lua.h,v 3.22 1996/02/12 18:32:09 roberto Exp roberto $
** $Id: lua.h,v 3.27 1996/04/25 14:10:00 roberto Exp roberto $
*/
#ifndef lua_h
#define lua_h
#define LUA_VERSION "Lua 2.3 (beta)"
#define LUA_VERSION "Lua 2.4"
#define LUA_COPYRIGHT "Copyright (C) 1994, 1995 TeCGraf"
#define LUA_AUTHORS "W. Celes, R. Ierusalimschy & L. H. de Figueiredo"
@@ -52,6 +52,14 @@ void lua_endblock (void);
lua_Object lua_getparam (int number);
#define lua_getresult(_) lua_getparam(_)
#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_isnumber (lua_Object object);
int lua_isstring (lua_Object object);
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);
@@ -72,33 +80,32 @@ lua_Object lua_getsubscript (void);
int lua_type (lua_Object object);
int lua_lock (void);
lua_Object lua_getlocked (int ref);
void lua_pushlocked (int ref);
void lua_unlock (int ref);
int lua_ref (int lock);
lua_Object lua_getref (int ref);
void lua_pushref (int ref);
void lua_unref (int ref);
lua_Object lua_createtable (void);
/* 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_pushuserdata(u) lua_pushusertag(u, LUA_T_USERDATA)
#define lua_isnil(_) (lua_type(_)==LUA_T_NIL)
#define lua_isnumber(_) (lua_type(_)==LUA_T_NUMBER)
#define lua_isstring(_) (lua_type(_)==LUA_T_STRING)
#define lua_istable(_) (lua_type(_)==LUA_T_ARRAY)
#define lua_isfunction(_) (lua_type(_)==LUA_T_FUNCTION)
#define lua_iscfunction(_) (lua_type(_)==LUA_T_CFUNCTION)
#define lua_isuserdata(_) (lua_type(_)>=LUA_T_USERDATA)
/* 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_getindexed(o,n) (lua_pushobject(o), lua_pushnumber(n), lua_getsubscript())

248
lua.stx
View File

@@ -1,6 +1,6 @@
%{
char *rcs_luastx = "$Id: lua.stx,v 3.31 1996/02/13 17:30:39 roberto Exp roberto $";
char *rcs_luastx = "$Id: lua.stx,v 3.35 1996/03/08 12:02:37 roberto Exp roberto $";
#include <stdio.h>
#include <stdlib.h>
@@ -31,7 +31,7 @@ int yyparse (void);
#endif
static int maxcode;
static int maxmain;
static Long maxcurr; /* to allow maxcurr *= 2 without overflow */
static int maxcurr;
static Byte *funcCode = NULL;
static Byte **initcode;
static Byte *basepc;
@@ -70,14 +70,7 @@ static void yyerror (char *s)
static void code_byte (Byte c)
{
if (pc>maxcurr-2) /* 1 byte free to code HALT of main code */
{
if (maxcurr >= MAX_INT)
yyerror("code size overflow");
maxcurr *= 2;
if (maxcurr >= MAX_INT)
maxcurr = MAX_INT;
basepc = growvector(basepc, maxcurr, Byte);
}
maxcurr = growvector(&basepc, maxcurr, Byte, codeEM, MAX_INT);
basepc[pc++] = c;
}
@@ -109,10 +102,12 @@ static void code_code (TFunc *tf)
code_byte(code.m.c4);
}
static void code_word_at (Byte *p, Word n)
static void code_word_at (Byte *p, int n)
{
CodeWord code;
code.w = n;
if ((Word)n != n)
yyerror("block too big");
code.w = (Word)n;
*p++ = code.m.c1;
*p++ = code.m.c2;
}
@@ -485,7 +480,7 @@ funcname : var { $$ =$1; init_func(); }
code_word(luaI_findconstant($3));
$$ = 0; /* indexed variable */
init_func();
add_localvar(lua_constcreate("self"));
add_localvar(luaI_createfixedstring("self"));
}
;
@@ -791,230 +786,3 @@ setdebug : DEBUG { lua_debug = $1; }
;
%%
#if LISTING
static void PrintCode (Byte *code, Byte *end)
{
Byte *p = code;
printf ("\n\nCODE\n");
while (p != end)
{
switch ((OpCode)*p)
{
case PUSHNIL: printf ("%d PUSHNIL\n", (p++)-code); break;
case PUSH0: case PUSH1: case PUSH2:
printf ("%d PUSH%c\n", p-code, *p-PUSH0+'0');
p++;
break;
case PUSHBYTE:
printf ("%d PUSHBYTE %d\n", p-code, *(p+1));
p+=2;
break;
case PUSHWORD:
{
CodeWord c;
int n = p-code;
p++;
get_word(c,p);
printf ("%d PUSHWORD %d\n", n, c.w);
}
break;
case PUSHFLOAT:
{
CodeFloat c;
int n = p-code;
p++;
get_float(c,p);
printf ("%d PUSHFLOAT %f\n", n, c.f);
}
break;
case PUSHSTRING:
{
CodeWord c;
int n = p-code;
p++;
get_word(c,p);
printf ("%d PUSHSTRING %d\n", n, c.w);
}
break;
case PUSHFUNCTION:
{
CodeCode c;
int n = p-code;
p++;
get_code(c,p);
printf ("%d PUSHFUNCTION %p\n", n, c.tf);
}
break;
case PUSHLOCAL0: case PUSHLOCAL1: case PUSHLOCAL2: case PUSHLOCAL3:
case PUSHLOCAL4: case PUSHLOCAL5: case PUSHLOCAL6: case PUSHLOCAL7:
case PUSHLOCAL8: case PUSHLOCAL9:
printf ("%d PUSHLOCAL%c\n", p-code, *p-PUSHLOCAL0+'0');
p++;
break;
case PUSHLOCAL: printf ("%d PUSHLOCAL %d\n", p-code, *(p+1));
p+=2;
break;
case PUSHGLOBAL:
{
CodeWord c;
int n = p-code;
p++;
get_word(c,p);
printf ("%d PUSHGLOBAL %d\n", n, c.w);
}
break;
case PUSHINDEXED: printf ("%d PUSHINDEXED\n", (p++)-code); break;
case STORELOCAL0: case STORELOCAL1: case STORELOCAL2: case STORELOCAL3:
case STORELOCAL4: case STORELOCAL5: case STORELOCAL6: case STORELOCAL7:
case STORELOCAL8: case STORELOCAL9:
printf ("%d STORELOCAL%c\n", p-code, *p-STORELOCAL0+'0');
p++;
break;
case STORELOCAL:
printf ("%d STORELOCAL %d\n", p-code, *(p+1));
p+=2;
break;
case STOREGLOBAL:
{
CodeWord c;
int n = p-code;
p++;
get_word(c,p);
printf ("%d STOREGLOBAL %d\n", n, c.w);
}
break;
case PUSHSELF:
{
CodeWord c;
int n = p-code;
p++;
get_word(c,p);
printf ("%d PUSHSELF %d\n", n, c.w);
}
break;
case STOREINDEXED0: printf ("%d STOREINDEXED0\n", (p++)-code); break;
case STOREINDEXED: printf ("%d STOREINDEXED %d\n", p-code, *(p+1));
p+=2;
break;
case STORELIST0:
printf("%d STORELIST0 %d\n", p-code, *(p+1));
p+=2+;
break;
case STORELIST:
printf("%d STORELIST %d %d\n", p-code, *(p+1), *(p+2));
p+=3;
break;
case STORERECORD:
printf("%d STORERECORD %d\n", p-code, *(p+1));
p += *p*sizeof(Word) + 2;
break;
case ADJUST0: printf ("%d ADJUST0\n", (p++)-code); break;
case ADJUST:
printf ("%d ADJUST %d\n", p-code, *(p+1));
p+=2;
break;
case CREATEARRAY:
{
CodeWord c;
int n = p-code;
p++;
get_word(c,p);
printf ("%d CREATEARRAY %d\n", n, c.w);
break;
}
case EQOP: printf ("%d EQOP\n", (p++)-code); break;
case LTOP: printf ("%d LTOP\n", (p++)-code); break;
case LEOP: printf ("%d LEOP\n", (p++)-code); break;
case ADDOP: printf ("%d ADDOP\n", (p++)-code); break;
case SUBOP: printf ("%d SUBOP\n", (p++)-code); break;
case MULTOP: printf ("%d MULTOP\n", (p++)-code); break;
case DIVOP: printf ("%d DIVOP\n", (p++)-code); break;
case POWOP: printf ("%d POWOP\n", (p++)-code); break;
case CONCOP: printf ("%d CONCOP\n", (p++)-code); break;
case MINUSOP: printf ("%d MINUSOP\n", (p++)-code); break;
case NOTOP: printf ("%d NOTOP\n", (p++)-code); break;
case ONTJMP:
{
CodeWord c;
int n = p-code;
p++;
get_word(c,p);
printf ("%d ONTJMP %d\n", n, c.w);
}
break;
case ONFJMP:
{
CodeWord c;
int n = p-code;
p++;
get_word(c,p);
printf ("%d ONFJMP %d\n", n, c.w);
}
break;
case JMP:
{
CodeWord c;
int n = p-code;
p++;
get_word(c,p);
printf ("%d JMP %d\n", n, c.w);
}
break;
case UPJMP:
{
CodeWord c;
int n = p-code;
p++;
get_word(c,p);
printf ("%d UPJMP %d\n", n, c.w);
}
break;
case IFFJMP:
{
CodeWord c;
int n = p-code;
p++;
get_word(c,p);
printf ("%d IFFJMP %d\n", n, c.w);
}
break;
case IFFUPJMP:
{
CodeWord c;
int n = p-code;
p++;
get_word(c,p);
printf ("%d IFFUPJMP %d\n", n, c.w);
}
break;
case POP: printf ("%d POP\n", (p++)-code); break;
case CALLFUNC:
printf ("%d CALLFUNC %d %d\n", p-code, *(p+1), *(p+2));
p+=3;
break;
case RETCODE0: printf ("%d RETCODE0\n", (p++)-code); break;
case RETCODE:
printf ("%d RETCODE %d\n", p-code, *(p+1));
p+=2;
break;
case SETLINE:
{
CodeWord c;
int n = p-code;
p++;
get_word(c,p);
printf ("%d SETLINE %d\n", n, c.w);
}
break;
default: printf ("%d Cannot happen: code %d\n", p-code, *p));
p+=1;
break;
}
}
}
#endif

View File

@@ -2,7 +2,7 @@
** LUA - Linguagem para Usuarios de Aplicacao
** Grupo de Tecnologia em Computacao Grafica
** TeCGraf - PUC-Rio
** $Id: luadebug.h,v 1.4 1996/02/07 18:10:27 roberto Exp roberto $
** $Id: luadebug.h,v 1.5 1996/02/08 17:03:20 roberto Exp roberto $
*/
@@ -20,12 +20,12 @@ lua_Function lua_stackedfunction (int level);
void lua_funcinfo (lua_Object func, char **filename, int *linedefined);
int lua_currentline (lua_Function func);
char *lua_getobjname (lua_Object o, char **name);
lua_LHFunction lua_setlinehook (lua_LHFunction hook);
lua_CHFunction lua_setcallhook (lua_CHFunction hook);
lua_Object lua_getlocal (lua_Function func, int local_number, char **name);
int lua_setlocal (lua_Function func, int local_number);
extern lua_LHFunction lua_linehook;
extern lua_CHFunction lua_callhook;
extern int lua_debug;
#endif

View File

@@ -2,22 +2,32 @@
** Libraries to be used in LUA programs
** Grupo de Tecnologia em Computacao Grafica
** TeCGraf - PUC-Rio
** $Id: lualib.h,v 1.5 1996/01/22 17:38:57 roberto Exp roberto $
** $Id: lualib.h,v 1.7 1996/03/14 15:53:09 roberto Exp roberto $
*/
#ifndef lualib_h
#define lualib_h
#include "lua.h"
void iolib_open (void);
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_error(char *funcname);
char *lua_check_string (int numArg, char *funcname);
double lua_check_number (int numArg, char *funcname);
char *luaI_addchar (int c);
void luaI_addquoted (char *s);
#endif

View File

@@ -3,32 +3,24 @@
** TecCGraf - PUC-Rio
*/
char *rcs_mem = "$Id: mem.c,v 1.6 1996/01/22 14:15:13 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 <string.h>
#include <stdio.h>
#include "mem.h"
#include "lua.h"
#include "table.h"
static void mem_error (void)
{
Long recovered = luaI_collectgarbage(); /* try to collect garbage */
if (recovered)
lua_error("not enough memory");
else
{ /* if there is no garbage then must exit */
fprintf(stderr, "lua error: memory overflow - unable to recover\n");
exit(1);
}
}
#define mem_error() lua_error(memEM)
void luaI_free (void *block)
{
*((int *)block) = -1; /* to catch errors */
free(block);
if (block)
{
*((int *)block) = -1; /* to catch errors */
free(block);
}
}
@@ -43,16 +35,33 @@ void *luaI_malloc (unsigned long size)
void *luaI_realloc (void *oldblock, unsigned long size)
{
void *block = realloc(oldblock, (size_t)size);
void *block = oldblock ? realloc(oldblock, (size_t)size) :
malloc((size_t)size);
if (block == NULL)
mem_error();
return block;
}
char *luaI_strdup (char *str)
int luaI_growvector (void **block, unsigned long nelems, int size,
char *errormsg, unsigned long limit)
{
char *newstr = luaI_malloc(strlen(str)+1);
strcpy(newstr, str);
return newstr;
if (nelems >= limit)
lua_error(errormsg);
nelems = (nelems == 0) ? 20 : nelems*2;
if (nelems > limit)
nelems = limit;
*block = luaI_realloc(*block, nelems*size);
return (int) nelems;
}
void* luaI_buffer (unsigned long size)
{
static unsigned long buffsize = 0;
static char* buffer = NULL;
if (size > buffsize)
buffer = luaI_realloc(buffer, buffsize=size);
return buffer;
}

View File

@@ -1,7 +1,7 @@
/*
** mem.c
** memory manager for lua
** $Id: mem.h,v 1.1 1994/11/16 17:38:08 roberto Stab roberto $
** $Id: mem.h,v 1.6 1996/03/21 18:54:29 roberto Exp roberto $
*/
#ifndef mem_h
@@ -11,15 +11,29 @@
#define NULL 0
#endif
/* memory error messages */
#define codeEM "code size overflow"
#define symbolEM "symbol table overflow"
#define constantEM "constant table overflow"
#define stackEM "stack size overflow"
#define lexEM "lex buffer overflow"
#define refEM "reference table overflow"
#define tableEM "table overflow"
#define memEM "not enough memory"
void luaI_free (void *block);
void *luaI_malloc (unsigned long size);
void *luaI_realloc (void *oldblock, unsigned long size);
char *luaI_strdup (char *str);
void *luaI_buffer (unsigned long size);
int luaI_growvector (void **block, unsigned long nelems, int size,
char *errormsg, unsigned long limit);
#define new(s) ((s *)luaI_malloc(sizeof(s)))
#define newvector(n,s) ((s *)luaI_malloc((n)*sizeof(s)))
#define growvector(old,n,s) ((s *)luaI_realloc(old,(n)*sizeof(s)))
#define growvector(old,n,s,e,l) \
(luaI_growvector((void**)old,n,sizeof(s),e,l))
#endif

View File

@@ -1,9 +1,10 @@
# $Id: makefile,v 1.19 1996/02/07 18:14:38 roberto Exp roberto $
# $Id: makefile,v 1.25 1996/05/06 14:38:40 roberto Exp $
#configuration
# 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
CC = gcc
CFLAGS = $(CONFIG) -I/usr/5include -Wall -Wmissing-prototypes -Wshadow -ansi -O2
@@ -25,7 +26,8 @@ LUAOBJS = \
tree.o \
fallback.o \
mem.o \
func.o
func.o \
undump.o
LIBOBJS = \
iolib.o \
@@ -36,7 +38,7 @@ LIBOBJS = \
lua : lua.o lua.a lualib.a
$(CC) $(CFLAGS) -o $@ lua.o lua.a lualib.a -lm
lua.a : parser.o $(LUAOBJS)
lua.a : $(LUAOBJS)
$(AR) $(ARFLAGS) $@ $?
ranlib lua.a
@@ -47,14 +49,14 @@ lualib.a : $(LIBOBJS)
liblua.so.1.0 : lua.o
ld -o liblua.so.1.0 $(LUAOBJS)
y.tab.c y.tab.h : lua.stx
yacc++ -d lua.stx
#y.tab.c y.tab.h : lua.stx
# yacc++ -d lua.stx
parser.c : y.tab.c
sed -e 's/yy/luaY_/g' y.tab.c > parser.c
#parser.c : y.tab.c
# sed -e 's/yy/luaY_/g' -e 's/malloc\.h/stdlib\.h/g' y.tab.c > parser.c
parser.h : y.tab.h
sed -e 's/yy/luaY_/g' y.tab.h > parser.h
#parser.h : y.tab.h
# sed -e 's/yy/luaY_/g' y.tab.h > parser.h
clear :
rcsclean
@@ -62,25 +64,29 @@ clear :
rm -f parser.c parser.h y.tab.c y.tab.h
co lua.h lualib.h luadebug.h
% : RCS/%,v
co $@
#% : RCS/%,v
# co $@
fallback.o : fallback.c mem.h fallback.h opcode.h lua.h types.h tree.h func.h
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
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 ugly.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 table.h tree.h types.h opcode.h func.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
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 hash.h opcode.h func.h table.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

View File

@@ -1,6 +1,6 @@
% $Id: manual.tex,v 1.10 1996/02/12 18:32:09 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{\see}[1]{see Section~\ref{#1}}
@@ -13,7 +13,7 @@
\newcommand{\Def}[1]{{\em #1}\index{#1}}
\newcommand{\Deffunc}[1]{\index{#1}}
\newcommand{\Version}{2.3}
\newcommand{\Version}{2.4}
\makeindex
@@ -34,7 +34,7 @@ Waldemar Celes Filho
\tecgraf\ --- Departamento de Inform\'atica --- PUC-Rio
}
\date{\small \verb$Date: 1996/02/12 18:32:09 $}
\date{\small \verb$Date: 1996/04/22 18:00:37 $}
\maketitle
@@ -137,7 +137,11 @@ of new functions%
\footnote{Actually, a function definition is an
assignment to a global variable; \see{TypesSec}.}.
Chunks may be pre-compiled; see program \IndexVerb{luac} for details.
Ascii files with chunk code and their binary pre-compiled forms
are interchangeable.
Lua automatically detects the file type and acts accordingly.
\index{pre-compilation}
\section{\Index{Types}} \label{TypesSec}
@@ -412,7 +416,7 @@ Otherwise, their values are compared.
Numbers and strings are compared in the usual way.
Tables, CFunctions, and functions are compared by reference,
that is, two tables are considered equal only if they are the same table.
The operator \verb'~=' is exactly the negation of equality (\verb'=').
The operator \verb'~=' is exactly the negation of equality (\verb'==').
The other operators work as follows.
If both arguments are numbers, they are compared as such.
@@ -444,7 +448,7 @@ Otherwise, the fallback ``concat'' is called; \see{fallback}.
from the lower to the higher priority:
\begin{verbatim}
and or
< > <= >= ~= =
< > <= >= ~= ==
..
+ -
* /
@@ -735,12 +739,12 @@ The API functions can be classified in the following categories:
\item manipulating (reading and writing) Lua objects;
\item calling Lua functions;
\item C functions to be called by Lua;
\item locking Lua Objects.
\item references to Lua Objects.
\end{enumerate}
All API functions are declared in the file \verb'lua.h'.
\subsection{Executing Lua Code}
A host program can execute Lua programs written in a file or in a string,
A host program can execute Lua chunks written in a file or in a string,
using the following functions:
\Deffunc{lua_dofile}\Deffunc{lua_dostring}
\begin{verbatim}
@@ -751,6 +755,9 @@ Both functions return an error code:
0, in case of success; non zero, in case of errors.
The function \verb'lua_dofile', if called with argument NULL (0),
executes the ``file'' {\tt stdin}.
Function \verb'lua_dofile' is also able to execute pre-compiled chunks.
It detects whether the file is text or not,
and loads it accordingly (see program \IndexVerb{luac}).
\subsection{Converting Values between C and Lua} \label{valuesCLua}
Because Lua has no static type system,
@@ -788,19 +795,24 @@ the following function is available:
\begin{verbatim}
int lua_type (lua_Object object);
\end{verbatim}
plus the following macros:
plus the following macros and functions:
\Deffunc{lua_isnil}\Deffunc{lua_isnumber}\Deffunc{lua_isstring}
\Deffunc{lua_istable}\Deffunc{lua_iscfunction}\Deffunc{lua_isuserdata}
\Deffunc{lua_isfunction}
\begin{verbatim}
int lua_isnil (lua_Object object);
int lua_isnumber (lua_Object object);
int lua_isstring (lua_Object object);
int lua_istable (lua_Object object);
int lua_isfunction (lua_Object object);
int lua_iscfunction (lua_Object object);
int lua_isuserdata (lua_Object object);
\end{verbatim}
All macros return 1 if the object has the given type,
All macros return 1 if the object is compatible with the given type,
and 0 otherwise.
The function \verb'lua_isnumber' accepts numbers and numerical strings,
\verb'lua_isstring' accepts strings and numbers (\see{coercion}),
and \verb'lua_isfunction' accepts Lua and C functions.
The function \verb'lua_type' can be used to distinguish between
different kinds of user data; see below.
@@ -1057,30 +1069,37 @@ many results.
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.
If the C code needs to keep a \verb'lua_Object'
outside block boundaries,
it has to {\em lock} the object.
The routines to manipulate locking are the following:
\Deffunc{lua_lock}\Deffunc{lua_getlocked}
\Deffunc{lua_pushlocked}\Deffunc{lua_unlock}
it must create a \Def{reference} to the object.
The routines to manipulate references are the following:
\Deffunc{lua_ref}\Deffunc{lua_getref}
\Deffunc{lua_pushref}\Deffunc{lua_unref}
\begin{verbatim}
int lua_lock (void);
lua_Object lua_getlocked (int ref);
void lua_pushlocked (int ref);
void lua_unlock (int ref);
int lua_ref (int lock);
lua_Object lua_getref (int ref);
void lua_pushref (int ref);
void lua_unref (int ref);
\end{verbatim}
The function \verb'lua_lock' locks the object
which is on the top of the stack,
and returns a reference to it.
Whenever the locked object is needed,
a call to \verb'lua_getlocked'
The function \verb'lua_ref' creates a reference
to the object which is on the top of the stack,
and returns this reference.
If \verb'lock' is true, the object is {\em locked}:
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,
while \verb'lua_pushlocked' pushes the handle on the stack.
When a locked object is no longer needed,
it can be unlocked with a call to \verb'lua_unlock'.
while \verb'lua_pushref' pushes the object on the stack.
If the object has been collected,
\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'.
@@ -1101,7 +1120,7 @@ Currently there are three standard libraries:
\begin{itemize}
\item string manipulation;
\item mathematical functions (sin, cos, etc);
\item input and output.
\item input and output (plus some system facilities).
\end{itemize}
In order to have access to these libraries,
the host program must call the functions
@@ -1113,7 +1132,8 @@ declared in \verb-lualib.h-.
\subsubsection*{{\tt dofile (filename)}}\Deffunc{dofile}
This function receives a file name,
opens it and executes its contents as a Lua chunk.
opens it and executes its contents as a Lua chunk,
or as pre-compiled chunks.
When called without arguments,
it executes the contents of the standard input.
It returns 1 if there are no errors, \nil\ otherwise.
@@ -1269,12 +1289,19 @@ following the description given in its first argument (which must be a string).
The format string follows the same rules as the \verb'printf' family of
standard C functions.
The only differencies are that the options/modifiers
\verb'*', \verb'l', \verb'L', \verb'n', \verb'p',
and \verb'h' are not supported.
The options \verb'c', \verb'd', \verb'i', \verb'o', \verb'u',
\verb'x', \verb'X', \verb'e', \verb'E', \verb'f', and \verb'g' all
\verb'*', \verb'l', \verb'L', \verb'n', \verb'p',
and \verb'h' are not supported,
and there is an extra option, \verb'q'.
This option formats a string in a form suitable to be safely read
back by the Lua interpreter.
The string is written between double quotes,
and all double quotes, returns and backslashes in the string
are correctly escaped when written.
The options \verb'c', \verb'd', \verb'E', \verb'e', \verb'f',
\verb'g' \verb'i', \verb'o', \verb'u', \verb'X', and \verb'x' all
expect a number argument,
while \verb's' expects a string.
while \verb'q' and \verb's' expects a string.
\subsection{Mathematical Functions} \label{mathlib}
@@ -1353,13 +1380,20 @@ This function opens a file named \verb'filename' and sets it as the
{\em current} output file.
Unlike the \verb'writeto' operation,
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}
This function deletes the file with the given name.
\subsubsection*{{\tt rename (name1, name2)}}\Deffunc{rename}
This function renames file \verb'name1' to \verb'name2'.
\subsubsection*{{\tt tmpname ()}}\Deffunc{tmpname}
This function returns a string with a file name that can safely
be used for a temporary file.
\subsubsection*{{\tt read ([format])}}\Deffunc{read}
This function returns a value read from the current input.
@@ -1446,15 +1480,11 @@ it returns a reasonable date and time representation.
This function replaces functions \verb'date' and \verb'time' from
previous Lua versions.
\subsubsection*{{\tt exit ([code])}}\Deffunc{exit}
% \subsubsection*{{\tt debug ()}}
% This function, when called, repeatedly presents a prompt \verb'lua_debug> '
% in the error output stream (\verb'stderr'),
% 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.
This function calls the C function \verb-exit-,
with an optional \verb-code-,
to terminate the program.
\section{The Debuger Interface} \label{debugI}
@@ -1558,7 +1588,10 @@ this function fails and returns 0.
The Lua interpreter offers two hooks for debug purposes:
\begin{verbatim}
typedef void (*lua_CHFunction) (lua_Function func, char *file, int line);
extern lua_CHFunction lua_callhook;
typedef void (*lua_LHFunction) (int line);
extern lua_LHFunction lua_linehook;
\end{verbatim}
The first one is called whenever the interpreter enters or leaves a
function.
@@ -1577,12 +1610,8 @@ Its only parameter is the line number
This second hook is only called if the active function
has been pre-compiled with debug information (\see{pragma}).
To set these hooks, there are the functions:
\begin{verbatim}
lua_LHFunction lua_setlinehook (lua_LHFunction hook);
lua_CHFunction lua_setcallhook (lua_CHFunction hook);
\end{verbatim}
Both return the previous hook.
A hook is disabled when its value is NULL (0),
which is the initial value of both hooks.
\section{Some Examples}
@@ -1698,6 +1727,28 @@ end
\end{verbatim}
\subsection{\Index{Variable number of arguments}}
Lua does not provide any explicit mechanism to deal with
variable number of arguments.
However, one can use table constructors to simulate this mechanism.
As an example, suppose a function to concatenate all its arguments.
It could be written like
\begin{verbatim}
function concat (o)
local i = 1
local s = ''
while o[i] do
s = s .. o[i]
i = i+1
end
return s
end
\end{verbatim}
To call it, one uses a table constructor to join all arguments:
\begin{verbatim}
x = concat{"hello ", "john", " and ", "mary"}
\end{verbatim}
\subsection{\Index{Persistence}}
Because of its reflexive facilities,
persistence in Lua can be achieved within the language.
@@ -1789,12 +1840,14 @@ as illustrated in Figure~\ref{Cinher}.
\begin{figure}
\Line
\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 */
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(index);
lua_callfunction(oldIndex);
@@ -1811,7 +1864,7 @@ void Index (void)
return;
}
lua_pushobject(table);
lua_pushlocked(lockedParentName);
lua_pushref(lockedParentName);
parent = lua_getsubscript();
if (lua_istable(parent))
{
@@ -1829,10 +1882,10 @@ void Index (void)
\end{figure}
This code must be registered with:
\begin{verbatim}
lua_pushliteral("parent");
lockedParentName = lua_lock();
lua_pushstring("parent");
lockedParentName = lua_ref(1);
lua_pushobject(lua_setfallback("index", Index));
lockedOldIndex = lua_lock();
lockedOldIndex = lua_ref(1);
\end{verbatim}
Notice how the string \verb'"parent"' is kept
locked in Lua for optimal performance.
@@ -1842,6 +1895,9 @@ There are many different ways to do object-oriented programming in Lua.
This section presents one possible way to
implement classes,
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 a table.
@@ -2026,12 +2082,18 @@ Here is a list of all these differences.
Functions \verb'date' and \verb'time' (from \verb'iolib')
have been superseded by the new version of function \verb'date'.
\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'format', with parameter \verb'"%c"'.
\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
\verb'lua_pushstring'.
Programmers are encouraged not to use this macro.
\end{itemize}
\subsection*{Incompatibilities with \Index{version 2.1}}

View File

@@ -3,7 +3,7 @@
** 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 <math.h>
@@ -113,7 +113,7 @@ static void math_pow (void)
lua_Object op = lua_getparam(3);
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(o2);
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
*/
void mathlib_open (void)
{
lua_register ("abs", math_abs);
lua_register ("sin", math_sin);
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));
luaI_openlib(mathlib, (sizeof(mathlib)/sizeof(mathlib[0])));
old_pow = lua_refobject(lua_setfallback("arith", math_pow), 1);
}

207
opcode.c
View File

@@ -3,10 +3,9 @@
** TecCGraf - PUC-Rio
*/
char *rcs_opcode="$Id: opcode.c,v 3.56 1996/02/08 17:03:20 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 <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -18,6 +17,7 @@ char *rcs_opcode="$Id: opcode.c,v 3.56 1996/02/08 17:03:20 roberto Exp roberto $
#include "table.h"
#include "lua.h"
#include "fallback.h"
#include "undump.h"
#define tonumber(o) ((tag(o) != LUA_T_NUMBER) && (lua_tonumber(o) != 0))
#define tostring(o) ((tag(o) != LUA_T_STRING) && (lua_tostring(o) != 0))
@@ -25,6 +25,10 @@ char *rcs_opcode="$Id: opcode.c,v 3.56 1996/02/08 17:03:20 roberto Exp roberto $
#define STACK_SIZE 128
#ifndef STACK_LIMIT
#define STACK_LIMIT 6000
#endif
typedef int StkId; /* index to stack elements */
static Object initial_stack;
@@ -54,8 +58,8 @@ static jmp_buf *errorJmp = NULL; /* current error recover point */
/* Hooks */
static lua_LHFunction line_hook = NULL;
static lua_CHFunction call_hook = NULL;
lua_LHFunction lua_linehook = NULL;
lua_CHFunction lua_callhook = NULL;
static StkId lua_execute (Byte *pc, StkId base);
@@ -69,24 +73,6 @@ Object *luaI_Address (lua_Object o)
}
/*
** Functions to change hook functions.
*/
lua_LHFunction lua_setlinehook (lua_LHFunction hook)
{
lua_LHFunction temp = line_hook;
line_hook = hook;
return temp;
}
lua_CHFunction lua_setcallhook (lua_CHFunction hook)
{
lua_CHFunction temp = call_hook;
call_hook = hook;
return temp;
}
/*
** Init stack
*/
@@ -111,14 +97,17 @@ static void growstack (void)
lua_initstack();
else
{
static int limit = STACK_LIMIT;
StkId t = top-stack;
Long maxstack = stackLimit - stack;
maxstack *= 2;
stack = growvector(stack, maxstack, Object);
stackLimit = stack+maxstack;
Long stacksize = stackLimit - stack;
stacksize = growvector(&stack, stacksize, Object, stackEM, limit+100);
stackLimit = stack+stacksize;
top = stack + t;
if (maxstack >= MAX_WORD/2)
lua_error("stack size overflow");
if (stacksize >= limit)
{
limit = stacksize;
lua_error(stackEM);
}
}
}
@@ -128,18 +117,9 @@ static void growstack (void)
*/
static char *lua_strconc (char *l, char *r)
{
static char *buffer = NULL;
static int buffer_size = 0;
int nl = strlen(l);
int n = nl+strlen(r)+1;
if (n > buffer_size)
{
buffer_size = n;
if (buffer != NULL)
luaI_free(buffer);
buffer = newvector(buffer_size, char);
}
strcpy(buffer,l);
int nl = strlen(l);
char *buffer = luaI_buffer(nl+strlen(r)+1);
strcpy(buffer, l);
strcpy(buffer+nl, r);
return buffer;
}
@@ -172,7 +152,7 @@ static int lua_tonumber (Object *obj)
*/
static int lua_tostring (Object *obj)
{
static char s[256];
char s[256];
if (tag(obj) != LUA_T_NUMBER)
return 1;
if ((int) nvalue(obj) == nvalue(obj))
@@ -180,8 +160,6 @@ static int lua_tostring (Object *obj)
else
sprintf (s, "%g", nvalue(obj));
tsvalue(obj) = lua_createstring(s);
if (tsvalue(obj) == NULL)
return 1;
tag(obj) = LUA_T_STRING;
return 0;
}
@@ -223,7 +201,7 @@ static void lineHook (int line)
int oldCnResults = CnResults;
StkId old_top = CBase = top-stack;
CnResults = 0;
(*line_hook)(line);
(*lua_linehook)(line);
top = stack+old_top;
CnResults = oldCnResults;
CBase = oldBase;
@@ -241,14 +219,14 @@ static void callHook (StkId base, lua_Type type, int isreturn)
StkId old_top = CBase = top-stack;
CnResults = 0;
if (isreturn)
(*call_hook)(LUA_NOOBJECT, "(return)", 0);
(*lua_callhook)(LUA_NOOBJECT, "(return)", 0);
else
{
Object *f = stack+base-1;
if (type == LUA_T_MARK)
(*call_hook)(Ref(f), f->value.tf->fileName, f->value.tf->lineDefined);
(*lua_callhook)(Ref(f), f->value.tf->fileName, f->value.tf->lineDefined);
else
(*call_hook)(Ref(f), "(C)", -1);
(*lua_callhook)(Ref(f), "(C)", -1);
}
top = stack+old_top;
CnResults = oldCnResults;
@@ -269,14 +247,11 @@ static StkId callC (lua_CFunction func, StkId base)
CnResults = (top-stack) - base;
/* incorporate parameters on the stack */
CBase = base+CnResults; /* == top-stack */
if (call_hook)
{
callHook (base, LUA_T_CMARK, 0);
(*func)();
callHook (base, LUA_T_CMARK, 1);
}
else
(*func)();
if (lua_callhook)
callHook(base, LUA_T_CMARK, 0);
(*func)();
if (lua_callhook) /* func may have changed lua_callhook */
callHook(base, LUA_T_CMARK, 1);
firstResult = CBase;
CBase = oldBase;
CnResults = oldCnResults;
@@ -501,6 +476,16 @@ static int do_protectedrun (int nResults)
return status;
}
int luaI_dorun (TFunc *tf)
{
int status;
adjustC(1); /* one slot for the pseudo-function */
stack[CBase].tag = LUA_T_FUNCTION;
stack[CBase].value.tf = tf;
status = do_protectedrun(0);
adjustC(0);
return status;
}
static int do_protectedmain (void)
{
@@ -509,15 +494,12 @@ static int do_protectedmain (void)
jmp_buf myErrorJmp;
jmp_buf *oldErr = errorJmp;
errorJmp = &myErrorJmp;
adjustC(1); /* one slot for the pseudo-function */
stack[CBase].tag = LUA_T_FUNCTION;
stack[CBase].value.tf = &tf;
luaI_initTFunc(&tf);
tf.fileName = lua_parsedfile;
if (setjmp(myErrorJmp) == 0)
{
lua_parse(&tf);
status = do_protectedrun(0);
status = luaI_dorun(&tf);
}
else
{
@@ -525,8 +507,7 @@ static int do_protectedmain (void)
adjustC(0); /* erase extra slot */
}
errorJmp = oldErr;
if (tf.code)
luaI_free(tf.code);
luaI_free(tf.code);
return status;
}
@@ -563,9 +544,13 @@ int lua_call (char *funcname)
int lua_dofile (char *filename)
{
int status;
if (lua_openfile(filename))
int c;
FILE *f = lua_openfile(filename);
if (f == NULL)
return 1;
status = do_protectedmain();
c = fgetc(f);
ungetc(c, f);
status = (c == ID_CHUNK) ? luaI_undump(f) : do_protectedmain();
lua_closefile();
return status;
}
@@ -624,8 +609,9 @@ static StkId Cblocks[MAX_C_BLOCKS];
*/
void lua_beginblock (void)
{
if (numCblocks < MAX_C_BLOCKS)
Cblocks[numCblocks] = CBase;
if (numCblocks >= MAX_C_BLOCKS)
lua_error("`lua_beginblock': too many nested blocks");
Cblocks[numCblocks] = CBase;
numCblocks++;
}
@@ -635,11 +621,8 @@ void lua_beginblock (void)
void lua_endblock (void)
{
--numCblocks;
if (numCblocks < MAX_C_BLOCKS)
{
CBase = Cblocks[numCblocks];
adjustC(0);
}
CBase = Cblocks[numCblocks];
adjustC(0);
}
/*
@@ -676,6 +659,23 @@ lua_Object lua_getparam (int number)
return CBase-CnResults+number;
}
int lua_isnumber (lua_Object object)
{
return (object != LUA_NOOBJECT) && (tonumber(Address(object)) == 0);
}
int lua_isstring (lua_Object object)
{
int t = lua_type(object);
return (t == LUA_T_STRING) || (t == LUA_T_NUMBER);
}
int lua_isfunction (lua_Object object)
{
int t = lua_type(object);
return (t == LUA_T_FUNCTION) || (t == LUA_T_CFUNCTION);
}
/*
** Given an object handle, return its number value. On error, return 0.0.
*/
@@ -717,27 +717,31 @@ void *lua_getuserdata (lua_Object object)
}
lua_Object lua_getlocked (int ref)
lua_Object lua_getref (int ref)
{
adjustC(0);
*top = *luaI_getlocked(ref);
incr_top;
CBase++; /* incorporate object in the stack */
return Ref(top-1);
Object *o = luaI_getref(ref);
if (o == NULL)
return LUA_NOOBJECT;
adjustC(0);
luaI_pushobject(o);
CBase++; /* incorporate object in the stack */
return Ref(top-1);
}
void lua_pushlocked (int ref)
void lua_pushref (int ref)
{
*top = *luaI_getlocked(ref);
incr_top;
Object *o = luaI_getref(ref);
if (o == NULL)
lua_error("access to invalid (possibly garbage collected) reference");
luaI_pushobject(o);
}
int lua_lock (void)
int lua_ref (int lock)
{
adjustC(1);
return luaI_lock(--top);
return luaI_ref(--top, lock);
}
@@ -786,10 +790,17 @@ void lua_pushnumber (real n)
*/
void lua_pushstring (char *s)
{
tsvalue(top) = lua_createstring(s);
tag(top) = LUA_T_STRING;
incr_top;
if (s == NULL)
tag(top) = LUA_T_NIL;
else
{
tsvalue(top) = lua_createstring(s);
tag(top) = LUA_T_STRING;
}
incr_top;
}
/*>>>>>>>>>#undef lua_pushliteral
void lua_pushliteral(char *s) { lua_pushstring(s); }*/
/*
** Push an object (tag=cfunction) to stack.
@@ -805,20 +816,12 @@ void lua_pushcfunction (lua_CFunction fn)
*/
void lua_pushusertag (void *u, int tag)
{
if (tag < LUA_T_USERDATA) return;
if (tag < LUA_T_USERDATA)
lua_error("invalid tag in `lua_pushusertag'");
tag(top) = tag; uvalue(top) = u;
incr_top;
}
/*
** Push a lua_Object to stack.
*/
void lua_pushobject (lua_Object o)
{
*top = *Address(o);
incr_top;
}
/*
** Push an object on the stack.
*/
@@ -828,6 +831,16 @@ void luaI_pushobject (Object *o)
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)
{
if (o == LUA_NOOBJECT)
@@ -881,7 +894,7 @@ static void comparison (lua_Type tag_less, lua_Type tag_equal,
*/
static StkId lua_execute (Byte *pc, StkId base)
{
if (call_hook)
if (lua_callhook)
callHook (base, LUA_T_MARK, 0);
while (1)
{
@@ -1243,7 +1256,7 @@ static StkId lua_execute (Byte *pc, StkId base)
case RETCODE0:
case RETCODE:
if (call_hook)
if (lua_callhook)
callHook (base, LUA_T_MARK, 1);
return (base + ((opcode==RETCODE0) ? 0 : *pc));
@@ -1259,7 +1272,7 @@ static StkId lua_execute (Byte *pc, StkId base)
(stack+base-1)->tag = LUA_T_LINE;
}
(stack+base-1)->value.i = code.w;
if (line_hook)
if (lua_linehook)
lineHook (code.w);
break;
}

View File

@@ -1,6 +1,6 @@
/*
** TeCGraf - PUC-Rio
** $Id: opcode.h,v 3.16 1996/01/26 18:03:19 roberto Exp roberto $
** $Id: opcode.h,v 3.19 1996/03/06 13:11:23 roberto Exp $
*/
#ifndef opcode_h
@@ -109,14 +109,14 @@ typedef struct Object
typedef union
{
struct {char c1; char c2;} m;
struct {Byte c1; Byte c2;} m;
Word w;
} CodeWord;
#define get_word(code,pc) {code.m.c1 = *pc++; code.m.c2 = *pc++;}
typedef union
{
struct {char c1; char c2; char c3; char c4;} m;
struct {Byte c1; Byte c2; Byte c3; Byte c4;} m;
float f;
} CodeFloat;
#define get_float(code,pc) {code.m.c1 = *pc++; code.m.c2 = *pc++;\
@@ -124,7 +124,7 @@ typedef union
typedef union
{
struct {char c1; char c2; char c3; char c4;} m;
struct {Byte c1; Byte c2; Byte c3; Byte c4;} m;
TFunc *tf;
} CodeCode;
#define get_code(code,pc) {code.m.c1 = *pc++; code.m.c2 = *pc++;\
@@ -132,13 +132,12 @@ typedef union
/* Exported functions */
char *lua_strdup (char *l);
void lua_parse (TFunc *tf); /* from "lua.stx" module */
void luaI_codedebugline (int line); /* from "lua.stx" module */
void lua_travstack (int (*fn)(Object *));
Object *luaI_Address (lua_Object o);
void luaI_pushobject (Object *o);
void luaI_gcFB (Object *o);
int luaI_dorun (TFunc *tf);
#endif

View File

@@ -3,12 +3,13 @@
** String library to LUA
*/
char *rcs_strlib="$Id: strlib.c,v 1.18 1996/02/12 18:32:40 roberto Exp $";
char *rcs_strlib="$Id: strlib.c,v 1.22 1996/03/22 17:57:24 roberto Exp roberto $";
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <limits.h>
#include "lua.h"
#include "lualib.h"
@@ -24,7 +25,7 @@ void lua_arg_error(char *funcname)
char *lua_check_string (int numArg, char *funcname)
{
lua_Object o = lua_getparam(numArg);
if (!(lua_isstring(o) || lua_isnumber(o)))
if (!lua_isstring(o))
lua_arg_error(funcname);
return lua_getstring(o);
}
@@ -32,17 +33,15 @@ char *lua_check_string (int numArg, char *funcname)
double lua_check_number (int numArg, char *funcname)
{
lua_Object o = lua_getparam(numArg);
if (lua_isnumber(o))
return lua_getnumber(o);
else if (lua_isstring(o))
{
float t;
char c;
if (sscanf(lua_getstring(o), "%f %c",&t, &c) == 1)
return t;
}
lua_arg_error(funcname);
return 0; /* to avoid warnings */
if (!lua_isnumber(o))
lua_arg_error(funcname);
return lua_getnumber(o);
}
static int lua_opt_number (int numArg, int def, char *funcname)
{
return (lua_getparam(numArg) == LUA_NOOBJECT) ? def :
(int)lua_check_number(numArg, funcname);
}
char *luaI_addchar (int c)
@@ -81,15 +80,12 @@ static void str_find (void)
{
char *s1 = lua_check_string(1, "strfind");
char *s2 = lua_check_string(2, "strfind");
int init = (lua_getparam(3) == LUA_NOOBJECT) ? 0 :
(int)lua_check_number(3, "strfind")-1;
char *f = strstr(s1+init,s2);
int init = lua_opt_number(3, 1, "strfind") - 1;
char *f = (init>=0 && init<=strlen(s1)) ? strstr(s1+init,s2) : NULL;
if (f != NULL)
{
int pos = f-s1+1;
if (lua_getparam (4) == LUA_NOOBJECT)
lua_pushnumber (pos);
else if ((int)lua_check_number(4, "strfind") >= pos+strlen(s2)-1)
if (lua_opt_number(4, INT_MAX, "strfind") >= pos+strlen(s2)-1)
lua_pushnumber (pos);
else
lua_pushnil();
@@ -119,8 +115,7 @@ static void str_sub (void)
{
char *s = lua_check_string(1, "strsub");
int start = (int)lua_check_number(2, "strsub");
int end = (lua_getparam(3) == LUA_NOOBJECT) ? strlen(s) :
(int)lua_check_number(3, "strsub");
int end = lua_opt_number(3, strlen(s), "strsub");
if (end < start || start < 1 || end > strlen(s))
lua_pushliteral("");
else
@@ -167,14 +162,23 @@ static void str_upper (void)
static void str_ascii (void)
{
char *s = lua_check_string(1, "ascii");
lua_Object o2 = lua_getparam(2);
int pos;
pos = (o2 == LUA_NOOBJECT) ? 0 : (int)lua_check_number(2, "ascii")-1;
int pos = lua_opt_number(2, 1, "ascii") - 1;
if (pos<0 || pos>=strlen(s))
lua_arg_error("ascii");
lua_pushnumber(s[pos]);
}
void luaI_addquoted (char *s)
{
luaI_addchar('"');
for (; *s; s++)
{
if (*s == '"' || *s == '\\' || *s == '\n')
luaI_addchar('\\');
luaI_addchar(*s);
}
luaI_addchar('"');
}
#define MAX_CONVERTION 2000
#define MAX_FORMAT 50
@@ -215,6 +219,10 @@ static void str_format (void)
form[i+1] = 0; /* ends string */
switch (form[i])
{
case 'q':
luaI_addquoted(lua_check_string(arg++, "format"));
buff[0] = '\0'; /* addchar already done */
break;
case 's':
{
char *s = lua_check_string(arg++, "format");
@@ -241,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
*/
void strlib_open (void)
{
lua_register ("strfind", str_find);
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);
luaI_openlib(strlib, (sizeof(strlib)/sizeof(strlib[0])));
}

109
table.c
View File

@@ -3,7 +3,7 @@
** Module to control static tables
*/
char *rcs_table="$Id: table.c,v 2.46 1996/02/14 13:35:51 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 "opcode.h"
@@ -19,43 +19,43 @@ char *rcs_table="$Id: table.c,v 2.46 1996/02/14 13:35:51 roberto Exp roberto $";
#define BUFFER_BLOCK 256
Symbol *lua_table = NULL;
static Word lua_ntable = 0;
Word lua_ntable = 0;
static Long lua_maxsymbol = 0;
TaggedString **lua_constant = NULL;
static Word lua_nconstant = 0;
Word lua_nconstant = 0;
static Long lua_maxconstant = 0;
#define GARBAGE_BLOCK 1024
#define MIN_GARBAGE_BLOCK (GARBAGE_BLOCK/2)
#define GARBAGE_BLOCK 50
static void lua_nextvar (void);
/*
** Initialise symbol table with internal functions
** Internal functions
*/
static struct {
char *name;
lua_CFunction func;
} int_funcs[] = {
{"nextvar", lua_nextvar},
{"error", luaI_error},
{"tonumber", lua_obj2number},
{"setfallback", luaI_setfallback},
{"next", lua_next},
{"assert", luaI_assert},
{"dofile", lua_internaldofile},
{"setglobal", luaI_setglobal},
{"getglobal", luaI_getglobal},
{"type", luaI_type},
{"tostring", luaI_tostring},
{"print", luaI_print},
{"dostring", lua_internaldostring},
{"assert", luaI_assert}
{"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;
@@ -76,6 +76,9 @@ void luaI_initconstant (void)
{
lua_maxconstant = BUFFER_BLOCK;
lua_constant = newvector(lua_maxconstant, TaggedString *);
/* pre-register mem error messages, to avoid loop when error arises */
luaI_findconstantbyname(tableEM);
luaI_findconstantbyname(memEM);
}
@@ -88,20 +91,12 @@ Word luaI_findsymbol (TaggedString *t)
if (t->varindex == NOT_USED)
{
if (lua_ntable == lua_maxsymbol)
{
if (lua_maxsymbol >= MAX_WORD)
lua_error("symbol table overflow");
lua_maxsymbol *= 2;
if (lua_maxsymbol >= MAX_WORD)
lua_maxsymbol = MAX_WORD;
lua_table = growvector(lua_table, lua_maxsymbol, Symbol);
}
lua_maxsymbol = growvector(&lua_table, lua_maxsymbol, Symbol,
symbolEM, MAX_WORD);
t->varindex = lua_ntable;
lua_table[lua_ntable].varname = t;
s_tag(lua_ntable) = LUA_T_NIL;
lua_ntable++;
if (!t->marked)
t->marked = 2; /* avoid GC */
}
return t->varindex;
}
@@ -109,7 +104,7 @@ Word luaI_findsymbol (TaggedString *t)
Word luaI_findsymbolbyname (char *name)
{
return luaI_findsymbol(lua_createstring(name));
return luaI_findsymbol(luaI_createfixedstring(name));
}
@@ -122,19 +117,11 @@ Word luaI_findconstant (TaggedString *t)
if (t->constindex == NOT_USED)
{
if (lua_nconstant == lua_maxconstant)
{
if (lua_maxconstant >= MAX_WORD)
lua_error("constant table overflow");
lua_maxconstant *= 2;
if (lua_maxconstant >= MAX_WORD)
lua_maxconstant = MAX_WORD;
lua_constant = growvector(lua_constant, lua_maxconstant, TaggedString *);
}
lua_maxconstant = growvector(&lua_constant, lua_maxconstant, TaggedString *,
constantEM, MAX_WORD);
t->constindex = lua_nconstant;
lua_constant[lua_nconstant] = t;
lua_nconstant++;
if (!t->marked)
t->marked = 2; /* avoid GC */
}
return t->constindex;
}
@@ -142,13 +129,15 @@ Word luaI_findconstant (TaggedString *t)
Word luaI_findconstantbyname (char *name)
{
return luaI_findconstant(lua_createstring(name));
return luaI_findconstant(luaI_createfixedstring(name));
}
TaggedString *lua_constcreate(char *name)
TaggedString *luaI_createfixedstring (char *name)
{
int i = luaI_findconstantbyname(name);
return lua_constant[i];
TaggedString *ts = lua_createstring(name);
if (!ts->marked)
ts->marked = 2; /* avoid GC */
return ts;
}
@@ -180,6 +169,24 @@ int lua_markobject (Object *o)
return 0;
}
/*
* returns 0 if the object is going to be (garbage) collected
*/
int luaI_ismarked (Object *o)
{
switch (o->tag)
{
case LUA_T_STRING:
return o->value.ts->marked;
case LUA_T_FUNCTION:
return o->value.tf->marked;
case LUA_T_ARRAY:
return o->value.a->mark;
default: /* nil, number, cfunction, or user data */
return 1;
}
}
/*
** Garbage collection.
@@ -192,6 +199,7 @@ 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_invalidaterefs();
recovered += lua_strcollector();
recovered += lua_hashcollector();
recovered += luaI_funccollector();
@@ -200,14 +208,13 @@ Long luaI_collectgarbage (void)
void lua_pack (void)
{
static Long block = GARBAGE_BLOCK; /* when garbage collector will be called */
static Long nentity = 0; /* counter of new entities (strings and arrays) */
Long recovered = 0;
static unsigned long block = GARBAGE_BLOCK;
static unsigned long nentity = 0; /* total of strings, arrays, etc */
unsigned long recovered = 0;
if (nentity++ < block) return;
recovered = luaI_collectgarbage();
nentity = 0; /* reset counter */
block=(16*block-7*recovered)/12; /* adapt block size */
if (block < MIN_GARBAGE_BLOCK) block = MIN_GARBAGE_BLOCK;
block = block*2*(1.0 - (float)recovered/nentity);
nentity -= recovered;
}
@@ -239,11 +246,7 @@ static void lua_nextvar (void)
}
else
{
TaggedString *t = lua_table[next].varname;
Object name;
tag(&name) = LUA_T_STRING;
tsvalue(&name) = t;
luaI_pushobject(&name);
lua_pushstring(lua_table[next].varname->str);
luaI_pushobject(&s_object(next));
}
}

View File

@@ -1,7 +1,7 @@
/*
** Module to control static tables
** TeCGraf - PUC-Rio
** $Id: table.h,v 2.17 1996/02/12 18:32:40 roberto Exp roberto $
** $Id: table.h,v 2.20 1996/03/14 15:57:19 roberto Exp roberto $
*/
#ifndef table_h
@@ -18,7 +18,9 @@ typedef struct
extern Symbol *lua_table;
extern Word lua_ntable;
extern TaggedString **lua_constant;
extern Word lua_nconstant;
void luaI_initsymbol (void);
void luaI_initconstant (void);
@@ -26,8 +28,9 @@ Word luaI_findsymbolbyname (char *name);
Word luaI_findsymbol (TaggedString *t);
Word luaI_findconstant (TaggedString *t);
Word luaI_findconstantbyname (char *name);
TaggedString *lua_constcreate (char *str);
TaggedString *luaI_createfixedstring (char *str);
int lua_markobject (Object *o);
int luaI_ismarked (Object *o);
Long luaI_collectgarbage (void);
void lua_pack (void);

29
tree.c
View File

@@ -3,7 +3,7 @@
** TecCGraf - PUC-Rio
*/
char *rcs_tree="$Id: tree.c,v 1.17 1996/02/14 13:35:51 roberto Exp roberto $";
char *rcs_tree="$Id: tree.c,v 1.19 1996/02/22 20:34:33 roberto Exp $";
#include <string.h>
@@ -55,20 +55,18 @@ static void grow (stringtable *tb)
int i;
for (i=0; i<newsize; i++)
newhash[i] = NULL;
if (tb->size > 0)
{ /* rehash */
tb->nuse = 0;
for (i=0; i<tb->size; i++)
if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY)
{
int h = tb->hash[i]->hash%newsize;
while (newhash[h])
h = (h+1)%newsize;
newhash[h] = tb->hash[i];
tb->nuse++;
}
luaI_free(tb->hash);
}
/* rehash */
tb->nuse = 0;
for (i=0; i<tb->size; i++)
if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY)
{
int h = tb->hash[i]->hash%newsize;
while (newhash[h])
h = (h+1)%newsize;
newhash[h] = tb->hash[i];
tb->nuse++;
}
luaI_free(tb->hash);
tb->size = newsize;
tb->hash = newhash;
}
@@ -95,6 +93,7 @@ static TaggedString *insert (char *str, stringtable *tb)
i = (i+1)%tb->size;
}
/* not found */
lua_pack();
if (j != -1) /* is there an EMPTY space? */
i = j;
else

6
tree.h
View File

@@ -1,7 +1,7 @@
/*
** tree.h
** TecCGraf - PUC-Rio
** $Id: tree.h,v 1.12 1996/02/12 18:32:40 roberto Exp roberto $
** $Id: tree.h,v 1.13 1996/02/14 13:35:51 roberto Exp roberto $
*/
#ifndef tree_h
@@ -14,8 +14,8 @@
typedef struct TaggedString
{
unsigned short varindex; /* != NOT_USED if this is a symbol */
unsigned short constindex; /* != NOT_USED if this is a constant */
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 */

36
ugly.h
View File

@@ -1,36 +0,0 @@
/*
** ugly.h
** TecCGraf - PUC-Rio
** $Id: $
*/
#ifndef ugly_h
#define ugly_h
/* This enum must have the same order of the array 'reserved' in lex.c */
enum {
U_and=128,
U_do,
U_else,
U_elseif,
U_end,
U_function,
U_if,
U_local,
U_nil,
U_not,
U_or,
U_repeat,
U_return,
U_then,
U_until,
U_while,
U_eq = '='+128,
U_le = '<'+128,
U_ge = '>'+128,
U_ne = '~'+128,
U_sc = '.'+128
};
#endif

326
undump.c Normal file
View File

@@ -0,0 +1,326 @@
/*
** undump.c
** load bytecodes from files
*/
char* rcs_undump="$Id: undump.c,v 1.13 1996/03/12 20:00:40 lhf Exp lhf $";
#include <stdio.h>
#include <string.h>
#include "opcode.h"
#include "mem.h"
#include "table.h"
#include "undump.h"
static int swapword=0;
static int swapfloat=0;
static TFunc* Main=NULL; /* functions in a chunk */
static TFunc* lastF=NULL;
static void warn(char* s) /* TODO: remove */
{
#if 0
fprintf(stderr,"undump: %s\n",s);
#endif
}
static void FixCode(Byte* code, Byte* end) /* swap words */
{
Byte* p;
for (p=code; p!=end;)
{
OpCode op=(OpCode)*p;
switch (op)
{
case PUSHNIL:
case PUSH0:
case PUSH1:
case PUSH2:
case PUSHLOCAL0:
case PUSHLOCAL1:
case PUSHLOCAL2:
case PUSHLOCAL3:
case PUSHLOCAL4:
case PUSHLOCAL5:
case PUSHLOCAL6:
case PUSHLOCAL7:
case PUSHLOCAL8:
case PUSHLOCAL9:
case PUSHINDEXED:
case STORELOCAL0:
case STORELOCAL1:
case STORELOCAL2:
case STORELOCAL3:
case STORELOCAL4:
case STORELOCAL5:
case STORELOCAL6:
case STORELOCAL7:
case STORELOCAL8:
case STORELOCAL9:
case STOREINDEXED0:
case ADJUST0:
case EQOP:
case LTOP:
case LEOP:
case GTOP:
case GEOP:
case ADDOP:
case SUBOP:
case MULTOP:
case DIVOP:
case POWOP:
case CONCOP:
case MINUSOP:
case NOTOP:
case POP:
case RETCODE0:
p++;
break;
case PUSHBYTE:
case PUSHLOCAL:
case STORELOCAL:
case STOREINDEXED:
case STORELIST0:
case ADJUST:
case RETCODE:
p+=2;
break;
case STORELIST:
case CALLFUNC:
p+=3;
break;
case PUSHFUNCTION:
p+=5;
break;
case PUSHWORD:
case PUSHSELF:
case CREATEARRAY:
case ONTJMP:
case ONFJMP:
case JMP:
case UPJMP:
case IFFJMP:
case IFFUPJMP:
case SETLINE:
case PUSHSTRING:
case PUSHGLOBAL:
case STOREGLOBAL:
{
Byte t;
t=p[1]; p[1]=p[2]; p[2]=t;
p+=3;
break;
}
case PUSHFLOAT:
{
Byte t;
t=p[1]; p[1]=p[4]; p[4]=t;
t=p[2]; p[2]=p[3]; p[3]=t;
p+=5;
break;
}
case STORERECORD:
{
int n=*++p;
p++;
while (n--)
{
Byte t;
t=p[0]; p[0]=p[1]; p[1]=t;
p+=2;
}
break;
}
default:
lua_error("corrupt binary file");
break;
}
}
}
static void Unthread(Byte* code, int i, int v)
{
while (i!=0)
{
CodeWord c;
Byte* p=code+i;
get_word(c,p);
i=c.w;
c.w=v;
p[-2]=c.m.c1;
p[-1]=c.m.c2;
}
}
static int LoadWord(FILE* D)
{
Word w;
fread(&w,sizeof(w),1,D);
if (swapword)
{
Byte* p=(Byte*)&w; /* TODO: need union? */
Byte t;
t=p[0]; p[0]=p[1]; p[1]=t;
}
return w;
}
static int LoadSize(FILE* D)
{
Word hi=LoadWord(D);
Word lo=LoadWord(D);
int s=(hi<<16)|lo;
if ((Word)s != s) lua_error("code too long");
return s;
}
static char* LoadBlock(int size, FILE* D)
{
char* b=luaI_malloc(size);
fread(b,size,1,D);
return b;
}
static char* LoadString(FILE* D)
{
int size=LoadWord(D);
char *b=luaI_buffer(size);
fread(b,size,1,D);
return b;
}
static char* LoadNewString(FILE* D)
{
return LoadBlock(LoadWord(D),D);
}
static void LoadFunction(FILE* D)
{
TFunc* tf=new(TFunc);
tf->next=NULL;
tf->locvars=NULL;
tf->size=LoadSize(D);
tf->lineDefined=LoadWord(D);
if (IsMain(tf)) /* new main */
{
tf->fileName=LoadNewString(D);
Main=lastF=tf;
}
else /* fix PUSHFUNCTION */
{
CodeCode c;
Byte* p;
tf->marked=LoadWord(D);
tf->fileName=Main->fileName;
p=Main->code+tf->marked;
c.tf=tf;
*p++=c.m.c1; *p++=c.m.c2; *p++=c.m.c3; *p++=c.m.c4;
lastF=lastF->next=tf;
}
tf->code=LoadBlock(tf->size,D);
if (swapword || swapfloat) FixCode(tf->code,tf->code+tf->size);
while (1) /* unthread */
{
int c=getc(D);
if (c==ID_VAR) /* global var */
{
int i=LoadWord(D);
char* s=LoadString(D);
int v=luaI_findsymbolbyname(s);
Unthread(tf->code,i,v);
}
else if (c==ID_STR) /* constant string */
{
int i=LoadWord(D);
char* s=LoadString(D);
int v=luaI_findconstantbyname(s);
Unthread(tf->code,i,v);
}
else
{
ungetc(c,D);
break;
}
}
}
static void LoadSignature(FILE* D)
{
char* s=SIGNATURE;
while (*s!=0 && getc(D)==*s)
++s;
if (*s!=0) lua_error("bad signature");
}
static void LoadHeader(FILE* D) /* TODO: error handling */
{
Word w,tw=TEST_WORD;
float f,tf=TEST_FLOAT;
LoadSignature(D);
getc(D); /* skip version */
fread(&w,sizeof(w),1,D); /* test word */
if (w!=tw)
{
swapword=1;
warn("different byte order");
}
fread(&f,sizeof(f),1,D); /* test float */
if (f!=tf)
{
Byte* p=(Byte*)&f; /* TODO: need union? */
Byte t;
swapfloat=1;
t=p[0]; p[0]=p[3]; p[3]=t;
t=p[1]; p[1]=p[2]; p[2]=t;
if (f!=tf) /* TODO: try another perm? */
lua_error("different float representation");
else
warn("different byte order in floats");
}
}
static void LoadChunk(FILE* D)
{
LoadHeader(D);
while (1)
{
int c=getc(D);
if (c==ID_FUN) LoadFunction(D); else { ungetc(c,D); break; }
}
}
/*
** load one chunk from a file.
** return list of functions found, headed by main, or NULL at EOF.
*/
TFunc* luaI_undump1(FILE* D)
{
while (1)
{
int c=getc(D);
if (c==ID_CHUNK)
{
LoadChunk(D);
return Main;
}
else if (c==EOF)
return NULL;
else
lua_error("not a lua binary file");
}
}
/*
** load and run all chunks in a file
*/
int luaI_undump(FILE* D)
{
TFunc* m;
while ((m=luaI_undump1(D)))
{
int status=luaI_dorun(m);
luaI_freefunc(m);
if (status!=0) return status;
}
return 0;
}

23
undump.h Normal file
View File

@@ -0,0 +1,23 @@
/*
** undump.h
** definitions for lua decompiler
** $Id: undump.h,v 1.1 1996/03/08 21:43:21 lhf Exp lhf $
*/
#include "func.h"
#define IsMain(f) (f->lineDefined==0)
/* definitions for chunk headers */
#define ID_CHUNK 27 /* ESC */
#define ID_FUN 'F'
#define ID_VAR 'V'
#define ID_STR 'S'
#define SIGNATURE "Lua"
#define VERSION 0x23 /* 2.3 */
#define TEST_WORD 0x1234 /* a word for testing byte ordering */
#define TEST_FLOAT 0.123456789e-23 /* a float for testing representation */
TFunc* luaI_undump1(FILE* D); /* load one chunk */
int luaI_undump(FILE* D); /* load all chunks */