using "zio" for parsing Lua code.

This commit is contained in:
Roberto Ierusalimschy 1997-06-16 13:50:22 -03:00
parent 9fe5be3acf
commit c9a2dfeb2c
9 changed files with 151 additions and 204 deletions

115
inout.c
View File

@ -5,22 +5,24 @@
** Also provides some predefined lua functions.
*/
char *rcs_inout="$Id: inout.c,v 2.59 1997/05/26 14:42:51 roberto Exp roberto $";
char *rcs_inout="$Id: inout.c,v 2.60 1997/06/09 17:28:14 roberto Exp roberto $";
#include <stdio.h>
#include <string.h>
#include "auxlib.h"
#include "lex.h"
#include "opcode.h"
#include "fallback.h"
#include "hash.h"
#include "inout.h"
#include "lex.h"
#include "lua.h"
#include "luamem.h"
#include "luamem.h"
#include "opcode.h"
#include "table.h"
#include "tree.h"
#include "lua.h"
#include "hash.h"
#include "luamem.h"
#include "fallback.h"
#include "luamem.h"
#include "undump.h"
#include "zio.h"
/* Exported variables */
@ -34,73 +36,58 @@ char *luaI_typenames[] = { /* ORDER LUA_T */
NULL
};
static FILE *fp;
static char *st;
/*
** Function to get the next character from the input file
*/
static int fileinput (void)
int lua_dofile (char *filename)
{
int c = fgetc(fp);
return (c == EOF) ? 0 : c;
}
int status;
int c;
FILE *f = (filename == NULL) ? stdin : fopen(filename, "r");
if (f == NULL)
return 2;
lua_parsedfile = luaI_createfixedstring(filename?filename:"(stdin)")->str;
c = fgetc(f);
ungetc(c, f);
if (c == ID_CHUNK) {
ZIO z;
f = freopen(filename, "rb", f); /* set binary mode */
zFopen(&z, f);
lua_setinput(&z);
status = luaI_undump(&z);
zclose(&z);
}
else {
ZIO z;
if (c == '#')
while ((c=fgetc(f)) != '\n') /* skip first line */;
zFopen(&z, f);
lua_setinput(&z);
status = lua_domain();
zclose(&z);
}
return status;
}
/*
** Function to get the next character from the input string
*/
static int stringinput (void)
{
return *st++;
}
/*
** Function to open a file to be input unit.
** Return the file.
*/
FILE *lua_openfile (char *fn)
{
lua_setinput (fileinput);
if (fn == NULL)
{
fp = stdin;
fn = "(stdin)";
}
else
fp = fopen (fn, "r");
lua_parsedfile = luaI_createfixedstring(fn)->str;
return fp;
}
/*
** Function to close an opened file
*/
void lua_closefile (void)
{
if (fp != stdin)
fclose(fp);
}
/*
** Function to open a string to be input unit
*/
#define SIZE_PREF 20 /* size of string prefix to appear in error messages */
void lua_openstring (char *s)
int lua_dostring (char *str)
{
int status;
char buff[SIZE_PREF+25];
lua_setinput(stringinput);
st = s;
sprintf(buff, "(dostring) >> %.20s%s", s,
(strlen(s) > SIZE_PREF) ? "..." : "");
ZIO z;
if (str == NULL) return 1;
sprintf(buff, "(dostring) >> %.20s%s", str,
(strlen(str) > SIZE_PREF) ? "..." : "");
lua_parsedfile = luaI_createfixedstring(buff)->str;
zsopen(&z, str);
lua_setinput(&z);
status = lua_domain();
zclose(&z);
return status;
}
/*
** Function to close an opened string
*/
void lua_closestring (void)
{
}

View File

@ -1,5 +1,5 @@
/*
** $Id: inout.h,v 1.16 1996/05/28 21:07:32 roberto Exp roberto $
** $Id: inout.h,v 1.17 1997/02/26 17:38:41 roberto Unstable roberto $
*/

30
lex.c
View File

@ -1,4 +1,4 @@
char *rcs_lex = "$Id: lex.c,v 3.4 1997/06/11 14:20:51 roberto Exp $";
char *rcs_lex = "$Id: lex.c,v 3.4 1997/06/11 18:56:02 roberto Exp roberto $";
#include <ctype.h>
@ -15,15 +15,15 @@ char *rcs_lex = "$Id: lex.c,v 3.4 1997/06/11 14:20:51 roberto Exp $";
#define MINBUFF 250
#define next() (current = input())
static int current; /* look ahead character */
static ZIO *lex_z;
#define next() (current = zgetc(lex_z))
#define save(x) (yytext[tokensize++] = (x))
#define save_and_next() (save(current), next())
static int current; /* look ahead character */
static Input input; /* input function */
#define MAX_IFS 5
/* "ifstate" keeps the state of each nested $if the lexical is dealing with. */
@ -37,14 +37,14 @@ static struct {
static int iflevel; /* level of nested $if's */
void lua_setinput (Input fn)
void lua_setinput (ZIO *z)
{
current = '\n';
lua_linenumber = 0;
iflevel = 0;
ifstate[0].skip = 0;
ifstate[0].elsepart = 1; /* to avoid a free $else */
input = fn;
lex_z = z;
}
@ -155,7 +155,7 @@ static void ifskip (void)
while (ifstate[iflevel].skip) {
if (current == '\n')
inclinenumber();
else if (current == 0)
else if (current == EOZ)
luaI_auxsyntaxerror("input ends inside a $if");
else next();
}
@ -183,7 +183,7 @@ static void inclinenumber (void)
break;
case 2: /* endinput */
if (!skip) {
current = 0;
current = EOZ;
iflevel = 0; /* to allow $endinput inside a $if */
}
break;
@ -216,7 +216,7 @@ static void inclinenumber (void)
skipspace();
if (current == '\n') /* pragma must end with a '\n' ... */
inclinenumber();
else if (current != 0) /* or eof */
else if (current != EOZ) /* or eof */
luaI_auxsyntaxerror("invalid pragma format");
ifskip();
}
@ -232,7 +232,7 @@ static int read_long_string (char *yytext, int buffsize)
yytext = luaI_buffer(buffsize *= 2);
switch (current)
{
case 0:
case EOZ:
save(0);
return WRONGTOKEN;
case '[':
@ -295,7 +295,7 @@ int luaY_lex (void)
case '-':
save_and_next();
if (current != '-') return '-';
do { next(); } while (current != '\n' && current != 0);
do { next(); } while (current != '\n' && current != EOZ);
continue;
case '[':
@ -338,7 +338,7 @@ int luaY_lex (void)
yytext = luaI_buffer(buffsize *= 2);
switch (current)
{
case 0:
case EOZ:
case '\n':
save(0);
return WRONGTOKEN;
@ -455,7 +455,7 @@ int luaY_lex (void)
return NUMBER;
}
case 0:
case EOZ:
save(0);
if (iflevel > 0)
luaI_syntaxerror("missing $endif");

7
lex.h
View File

@ -1,16 +1,15 @@
/*
** lex.h
** TecCGraf - PUC-Rio
** $Id: lex.h,v 1.2 1996/02/14 13:35:51 roberto Exp roberto $
** $Id: lex.h,v 1.3 1996/11/08 12:49:35 roberto Exp roberto $
*/
#ifndef lex_h
#define lex_h
#include "zio.h"
typedef int (*Input) (void);
void lua_setinput (Input fn);
void lua_setinput (ZIO *z);
void luaI_syntaxerror (char *s);
int luaY_lex (void);
void luaI_addReserved (void);

View File

@ -1,4 +1,4 @@
# $Id: makefile,v 1.33 1997/04/06 14:08:08 roberto Exp roberto $
# $Id: makefile,v 1.34 1997/06/11 18:57:00 roberto Exp roberto $
#configuration
@ -32,7 +32,8 @@ LUAOBJS = \
luamem.o \
func.o \
undump.o \
auxlib.o
auxlib.o \
zio.o
LIBOBJS = \
iolib.o \
@ -77,29 +78,32 @@ clear :
co $@
auxlib.o: auxlib.c lua.h auxlib.h
auxlib.o: auxlib.c lua.h auxlib.h luadebug.h
fallback.o: fallback.c auxlib.h lua.h luamem.h fallback.h opcode.h \
types.h tree.h func.h table.h hash.h
func.o: func.c luadebug.h lua.h table.h tree.h types.h opcode.h func.h \
luamem.h
hash.o: hash.c luamem.h opcode.h lua.h types.h tree.h func.h hash.h \
table.h auxlib.h
inout.o: inout.c auxlib.h lua.h lex.h opcode.h types.h tree.h func.h \
inout.h table.h hash.h luamem.h fallback.h
inout.o: inout.c auxlib.h lua.h fallback.h opcode.h types.h tree.h \
func.h hash.h inout.h lex.h zio.h luamem.h table.h undump.h
iolib.o: iolib.c lua.h auxlib.h luadebug.h lualib.h
lex.o: lex.c auxlib.h lua.h luamem.h tree.h types.h table.h opcode.h \
func.h lex.h inout.h luadebug.h parser.h
func.h lex.h zio.h inout.h luadebug.h parser.h
lua.o: lua.c lua.h auxlib.h lualib.h
luamem.o: luamem.c luamem.h lua.h
mathlib.o: mathlib.c lualib.h lua.h auxlib.h
opcode.o: opcode.c luadebug.h lua.h luamem.h opcode.h types.h tree.h \
func.h hash.h inout.h table.h fallback.h undump.h auxlib.h
parser.o: parser.c luadebug.h lua.h luamem.h lex.h opcode.h types.h \
tree.h func.h hash.h inout.h table.h
func.h hash.h inout.h table.h fallback.h auxlib.h lex.h zio.h
parser.o: parser.c luadebug.h lua.h luamem.h lex.h zio.h opcode.h \
types.h tree.h func.h hash.h inout.h table.h
strlib.o: strlib.c lua.h auxlib.h lualib.h
table.o: table.c luamem.h auxlib.h lua.h opcode.h types.h tree.h \
func.h hash.h table.h inout.h fallback.h luadebug.h
tree.o: tree.c luamem.h lua.h tree.h types.h lex.h hash.h opcode.h \
func.h table.h fallback.h
undump.o: undump.c opcode.h lua.h types.h tree.h func.h luamem.h \
table.h undump.h
table.o: table.c luamem.h auxlib.h lua.h func.h types.h tree.h \
opcode.h hash.h table.h inout.h fallback.h luadebug.h
tree.o: tree.c luamem.h lua.h tree.h types.h lex.h zio.h hash.h \
opcode.h func.h table.h fallback.h
undump.o: undump.c auxlib.h lua.h opcode.h types.h tree.h func.h \
luamem.h table.h undump.h zio.h
y.tab.o: y.tab.c luadebug.h lua.h luamem.h lex.h zio.h opcode.h \
types.h tree.h func.h hash.h inout.h table.h
zio.o: zio.c zio.h

View File

@ -3,7 +3,7 @@
** TecCGraf - PUC-Rio
*/
char *rcs_opcode="$Id: opcode.c,v 4.7 1997/06/09 17:28:14 roberto Exp roberto $";
char *rcs_opcode="$Id: opcode.c,v 4.8 1997/06/12 18:27:29 roberto Exp roberto $";
#include <setjmp.h>
#include <stdio.h>
@ -18,8 +18,8 @@ char *rcs_opcode="$Id: opcode.c,v 4.7 1997/06/09 17:28:14 roberto Exp roberto $"
#include "table.h"
#include "lua.h"
#include "fallback.h"
#include "undump.h"
#include "auxlib.h"
#include "lex.h"
#define tonumber(o) ((ttype(o) != LUA_T_NUMBER) && (lua_tonumber(o) != 0))
#define tostring(o) ((ttype(o) != LUA_T_STRING) && (lua_tostring(o) != 0))
@ -597,7 +597,8 @@ int luaI_dorun (TFunc *tf)
return status;
}
static int do_protectedmain (lua_CFunction closef)
int lua_domain (void)
{
TFunc tf;
int status;
@ -614,7 +615,6 @@ static int do_protectedmain (lua_CFunction closef)
adjustC(0); /* erase extra slot */
status = 1;
}
closef();
if (status == 0)
status = luaI_dorun(&tf);
errorJmp = oldErr;
@ -622,7 +622,6 @@ static int do_protectedmain (lua_CFunction closef)
return status;
}
/*
** Execute the given lua function. Return 0 on success or 1 on error.
*/
@ -639,47 +638,6 @@ int lua_callfunction (lua_Object function)
}
/*
** Open file, generate opcode and execute global statement. Return 0 on
** success or non 0 on error.
*/
int lua_dofile (char *filename)
{
int status;
int c;
FILE *f = lua_openfile(filename);
if (f == NULL)
return 2;
c = fgetc(f);
ungetc(c, f);
if (c == ID_CHUNK) {
f = freopen(filename, "rb", f); /* set binary mode */
status = luaI_undump(f);
lua_closefile();
}
else {
if (c == '#')
while ((c=fgetc(f)) != '\n') /* skip first line */;
status = do_protectedmain(lua_closefile);
}
return status;
}
/*
** Generate opcode stored on string and execute global statement. Return 0 on
** success or non 0 on error.
*/
int lua_dostring (char *str)
{
int status;
if (str == NULL)
return 1;
lua_openstring(str);
status = do_protectedmain(lua_closestring);
return status;
}
/*
** API: set a function as a fallback
*/
@ -1058,7 +1016,7 @@ static void call_arith (IMS event)
if (ttype(im) == LUA_T_NIL) {
im = luaI_getim(0, event); /* try a 'global' i.m. */
if (ttype(im) == LUA_T_NIL)
lua_error("unexpected type at conversion to number");
lua_error("unexpected type at arithmetic operation");
}
}
lua_pushstring(luaI_eventname[event]);

View File

@ -1,6 +1,6 @@
/*
** TeCGraf - PUC-Rio
** $Id: opcode.h,v 3.32 1997/04/04 22:24:51 roberto Exp roberto $
** $Id: opcode.h,v 3.33 1997/04/11 21:34:53 roberto Exp roberto $
*/
#ifndef opcode_h
@ -166,5 +166,6 @@ TObject *luaI_Address (lua_Object o);
void luaI_pushobject (TObject *o);
void luaI_gcIM (TObject *o);
int luaI_dorun (TFunc *tf);
int lua_domain (void);
#endif

105
undump.c
View File

@ -3,7 +3,7 @@
** load bytecodes from files
*/
char* rcs_undump="$Id: undump.c,v 1.21 1996/11/18 11:18:29 lhf Exp lhf $";
char* rcs_undump="$Id: undump.c,v 1.24 1997/06/13 11:08:47 lhf Exp $";
#include <stdio.h>
#include <string.h>
@ -12,6 +12,7 @@ char* rcs_undump="$Id: undump.c,v 1.21 1996/11/18 11:18:29 lhf Exp lhf $";
#include "luamem.h"
#include "table.h"
#include "undump.h"
#include "zio.h"
static int swapword=0;
static int swapfloat=0;
@ -147,10 +148,10 @@ static void Unthread(Byte* code, int i, int v)
}
}
static int LoadWord(FILE* D)
static int LoadWord(ZIO* Z)
{
Word w;
fread(&w,sizeof(w),1,D);
zread(Z,&w,sizeof(w));
if (swapword)
{
Byte* p=(Byte*)&w;
@ -160,101 +161,101 @@ static int LoadWord(FILE* D)
return w;
}
static int LoadSize(FILE* D)
static int LoadSize(ZIO* Z)
{
Word hi=LoadWord(D);
Word lo=LoadWord(D);
Word hi=LoadWord(Z);
Word lo=LoadWord(Z);
int s=(hi<<16)|lo;
if ((Word)s != s) lua_error("code too long");
return s;
}
static void* LoadBlock(int size, FILE* D)
static void* LoadBlock(int size, ZIO* Z)
{
void* b=luaI_malloc(size);
fread(b,size,1,D);
zread(Z,b,size);
return b;
}
static char* LoadString(FILE* D)
static char* LoadString(ZIO* Z)
{
int size=LoadWord(D);
int size=LoadWord(Z);
char *b=luaI_buffer(size);
fread(b,size,1,D);
zread(Z,b,size);
return b;
}
static char* LoadNewString(FILE* D)
static char* LoadNewString(ZIO* Z)
{
return LoadBlock(LoadWord(D),D);
return LoadBlock(LoadWord(Z),Z);
}
static void LoadFunction(FILE* D)
static void LoadFunction(ZIO* Z)
{
TFunc* tf=new(TFunc);
tf->next=NULL;
tf->locvars=NULL;
tf->size=LoadSize(D);
tf->lineDefined=LoadWord(D);
tf->size=LoadSize(Z);
tf->lineDefined=LoadWord(Z);
if (IsMain(tf)) /* new main */
{
tf->fileName=LoadNewString(D);
tf->fileName=LoadNewString(Z);
Main=lastF=tf;
}
else /* fix PUSHFUNCTION */
{
tf->marked=LoadWord(D);
tf->marked=LoadWord(Z);
tf->fileName=Main->fileName;
memcpy(Main->code+tf->marked,&tf,sizeof(tf));
lastF=lastF->next=tf;
}
tf->code=LoadBlock(tf->size,D);
tf->code=LoadBlock(tf->size,Z);
if (swapword || swapfloat) FixCode(tf->code,tf->code+tf->size);
while (1) /* unthread */
{
int c=getc(D);
int c=zgetc(Z);
if (c==ID_VAR) /* global var */
{
int i=LoadWord(D);
char* s=LoadString(D);
int i=LoadWord(Z);
char* s=LoadString(Z);
int v=luaI_findsymbolbyname(s);
Unthread(tf->code,i,v);
}
else if (c==ID_STR) /* constant string */
{
int i=LoadWord(D);
char* s=LoadString(D);
int i=LoadWord(Z);
char* s=LoadString(Z);
int v=luaI_findconstantbyname(s);
Unthread(tf->code,i,v);
}
else
{
ungetc(c,D);
zungetc(Z);
break;
}
}
}
static void LoadSignature(FILE* D)
static void LoadSignature(ZIO* Z)
{
char* s=SIGNATURE;
while (*s!=0 && getc(D)==*s)
while (*s!=0 && zgetc(Z)==*s)
++s;
if (*s!=0) lua_error("cannot load binary file: bad signature");
}
static void LoadHeader(FILE* D)
static void LoadHeader(ZIO* Z)
{
Word w,tw=TEST_WORD;
float f,tf=TEST_FLOAT;
int version;
LoadSignature(D);
version=getc(D);
LoadSignature(Z);
version=zgetc(Z);
if (version>0x23) /* after 2.5 */
{
int oldsizeofW=getc(D);
int oldsizeofF=getc(D);
int oldsizeofP=getc(D);
int oldsizeofW=zgetc(Z);
int oldsizeofF=zgetc(Z);
int oldsizeofP=zgetc(Z);
if (oldsizeofW!=2)
luaL_verror(
"cannot load binary file created on machine with sizeof(Word)=%d; "
@ -266,14 +267,14 @@ static void LoadHeader(FILE* D)
if (oldsizeofP!=sizeof(TFunc*)) /* TODO: pack? */
luaL_verror(
"cannot load binary file created on machine with sizeof(TFunc*)=%d; "
"expected %d",oldsizeofP,sizeof(TFunc*));
"expected %d",oldsizeofP,(int)sizeof(TFunc*));
}
fread(&w,sizeof(w),1,D); /* test word */
zread(Z,&w,sizeof(w)); /* test word */
if (w!=tw)
{
swapword=1;
}
fread(&f,sizeof(f),1,D); /* test float */
zread(Z,&f,sizeof(f)); /* test float */
if (f!=tf)
{
Byte* p=(Byte*)&f;
@ -286,13 +287,13 @@ static void LoadHeader(FILE* D)
}
}
static void LoadChunk(FILE* D)
static void LoadChunk(ZIO* Z)
{
LoadHeader(D);
LoadHeader(Z);
while (1)
{
int c=getc(D);
if (c==ID_FUN) LoadFunction(D); else { ungetc(c,D); break; }
int c=zgetc(Z);
if (c==ID_FUN) LoadFunction(Z); else { zungetc(Z); break; }
}
}
@ -300,30 +301,26 @@ static void LoadChunk(FILE* D)
** load one chunk from a file.
** return list of functions found, headed by main, or NULL at EOF.
*/
TFunc* luaI_undump1(FILE* D)
static TFunc* luaI_undump1(ZIO* Z)
{
while (1)
int c=zgetc(Z);
if (c==ID_CHUNK)
{
int c=getc(D);
if (c==ID_CHUNK)
{
LoadChunk(D);
return Main;
}
else if (c==EOF)
return NULL;
else
lua_error("not a lua binary file");
LoadChunk(Z);
return Main;
}
else if (c!=EOZ)
lua_error("not a lua binary file");
return NULL;
}
/*
** load and run all chunks in a file
*/
int luaI_undump(FILE* D)
int luaI_undump(ZIO* Z)
{
TFunc* m;
while ((m=luaI_undump1(D)))
while ((m=luaI_undump1(Z)))
{
int status=luaI_dorun(m);
luaI_freefunc(m);

View File

@ -1,10 +1,11 @@
/*
** undump.h
** definitions for lua decompiler
** $Id: undump.h,v 1.3 1996/11/14 11:44:34 lhf Exp lhf $
** $Id: undump.h,v 1.4 1997/04/14 12:12:40 lhf Exp roberto $
*/
#include "func.h"
#include "zio.h"
#define IsMain(f) (f->lineDefined==0)
@ -19,5 +20,5 @@
#define TEST_WORD 0x1234 /* a word for testing byte ordering */
#define TEST_FLOAT 0.123456789e-23 /* a float for testing representation */
TFunc* luaI_undump1(FILE* D); /* load one chunk */
int luaI_undump(FILE* D); /* load all chunks */
int luaI_undump(ZIO* Z); /* load all chunks */