Compare commits

...

55 Commits

Author SHA1 Message Date
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
27 changed files with 775 additions and 671 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.22 1996/03/19 22:28:37 roberto Exp roberto $";
#include <stdio.h>
#include <string.h>
@@ -49,7 +49,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++)
{
@@ -116,12 +116,12 @@ static void funcFB (void)
*/
static Object *lockArray = NULL;
static Word lockSize = 0;
static int lockSize = 0;
int luaI_lock (Object *object)
{
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++)
@@ -132,16 +132,7 @@ int luaI_lock (Object *object)
}
/* 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);
}
lockSize = growvector(&lockArray, lockSize, Object, lockEM, MAX_WORD);
for (i=oldSize; i<lockSize; i++)
tag(&lockArray[i]) = LUA_T_NIL;
lockArray[oldSize] = *object;
@@ -168,7 +159,7 @@ Object *luaI_getlocked (int ref)
void luaI_travlock (int (*fn)(Object *))
{
Word i;
int i;
for (i=0; i<lockSize; i++)
fn(&lockArray[i]);
}
@@ -176,7 +167,7 @@ void luaI_travlock (int (*fn)(Object *))
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;

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);

3
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.10 1996/02/12 18:32:40 roberto Exp roberto $
*/
#ifndef hash_h

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);

84
iolib.c
View File

@@ -3,7 +3,7 @@
** 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.39 1996/03/14 15:55:18 roberto Exp roberto $";
#include <stdio.h>
#include <ctype.h>
@@ -30,6 +30,14 @@ int pclose();
#endif
static void pushresult (int i)
{
if (i)
lua_pushnumber (1);
else
lua_pushnil();
}
static void closeread (void)
{
if (in != stdin)
@@ -373,25 +381,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 +422,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 +473,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 +500,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 */
}
/*
@@ -544,7 +544,7 @@ 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);
}
@@ -567,7 +567,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 +583,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");
}
}
@@ -611,6 +611,8 @@ void iolib_open (void)
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);
@@ -620,25 +622,3 @@ void iolib_open (void)
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();

4
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.7 1995/10/31 17:05:35 roberto Exp roberto $";
#include <stdio.h>
#include <string.h>
@@ -44,7 +44,7 @@ static void manual_input (void)
if (isatty(fileno(stdin)))
{
char buffer[250];
while (gets(buffer) != 0)
while (fgets(buffer, sizeof(buffer), stdin) != 0)
lua_dostring(buffer);
}
else

20
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.24 1996/03/19 22:28:37 roberto Exp roberto $
*/
#ifndef lua_h
#define lua_h
#define LUA_VERSION "Lua 2.3 (beta)"
#define LUA_VERSION "Lua 2.4 (beta)"
#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);
@@ -88,14 +96,6 @@ lua_Object lua_createtable (void);
#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 */

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,7 +2,7 @@
** 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.6 1996/02/09 19:00:23 roberto Exp roberto $
*/
#ifndef lualib_h
@@ -18,6 +18,7 @@ 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,7 +3,7 @@
** 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.10 1996/03/21 16:31:32 roberto Exp roberto $";
#include <stdlib.h>
#include <string.h>
@@ -13,22 +13,17 @@ char *rcs_mem = "$Id: mem.c,v 1.6 1996/01/22 14:15:13 roberto Exp roberto $";
#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 +38,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.5 1996/03/21 16:31:32 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 lockEM "lock 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,4 +1,4 @@
# $Id: makefile,v 1.19 1996/02/07 18:14:38 roberto Exp roberto $
# $Id: makefile,v 1.21 1996/03/05 15:57:53 roberto Exp roberto $
#configuration
@@ -25,7 +25,8 @@ LUAOBJS = \
tree.o \
fallback.o \
mem.o \
func.o
func.o \
undump.o
LIBOBJS = \
iolib.o \
@@ -36,7 +37,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
@@ -62,25 +63,29 @@ clear :
rm -f parser.c parser.h y.tab.c y.tab.h
co lua.h lualib.h luadebug.h
% : RCS/%,v
co $@
fallback.o : fallback.c mem.h fallback.h opcode.h lua.h types.h tree.h func.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,4 +1,4 @@
% $Id: manual.tex,v 1.10 1996/02/12 18:32:09 roberto Exp roberto $
% $Id: manual.tex,v 1.13 1996/03/19 22:39:07 roberto Exp roberto $
\documentstyle[A4,11pt,bnf]{article}
@@ -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/03/19 22:39:07 $}
\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
< > <= >= ~= =
< > <= >= ~= ==
..
+ -
* /
@@ -740,7 +744,7 @@ The API functions can be classified in the following categories:
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.
@@ -1113,7 +1125,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 +1282,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}
@@ -1360,6 +1380,15 @@ This function returns 2 if the file already exists,
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.
@@ -1558,7 +1587,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 +1609,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 +1726,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.
@@ -1829,7 +1879,7 @@ void Index (void)
\end{figure}
This code must be registered with:
\begin{verbatim}
lua_pushliteral("parent");
lua_pushstring("parent");
lockedParentName = lua_lock();
lua_pushobject(lua_setfallback("index", Index));
lockedOldIndex = lua_lock();

159
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.65 1996/03/21 18:55:02 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.
*/
@@ -786,10 +786,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.
@@ -881,7 +888,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 +1250,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 +1266,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.21 1996/03/21 22:18:08 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");

70
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.50 1996/03/21 16:31:32 roberto Exp roberto $";
#include "mem.h"
#include "opcode.h"
@@ -19,11 +19,11 @@ 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;
@@ -33,29 +33,30 @@ static Long lua_maxconstant = 0;
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 +77,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 +92,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 +105,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 +118,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 +130,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;
}

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.19 1996/02/26 21:00:27 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,7 +28,7 @@ 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);
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 */