home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1997 March
/
VPR9703A.ISO
/
VPR_DATA
/
DOGA
/
SOURCES
/
POLYEDIT.LZH
/
ML
/
ML.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-06-21
|
12KB
|
450 lines
/*
* マクロ言語ライブラリ(公開関数)
*
* 1994.5.2 T.Koabayashi
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <sys\stat.h>
#include "parse.h"
#include "exec.h"
#include "strclass.h"
#include "lib.h"
#include "inlib.h"
extern int (**SystemFunc)();
static int ForceDumpMode = FALSE;
static int BreakNone(void);
int (*ErrorExec)();
int (*BreakCheck)(void) = BreakNone;
int __MLInit( func )
void *func ;
{
#ifdef DYNAMIC
if ( func != NULL )
SystemFunc = (int(**)())func ;
#endif
ErrorExec = MessageError ;
BreakCheck = BreakNone;
ParseDebug = FALSE ;
ExecDebug = FALSE ;
return 0 ;
}
/* デバッグモードの設定 */
void DebugMode( parse, exec )
int parse, exec ;
{
ParseDebug = parse ;
ExecDebug = exec ;
}
/* 中間コードバッファサイズ */
void SetMaxCodeSize( size )
int size ;
{
MaxCodeSize = size ;
}
/* 大域変数の最大数 */
void SetMaxGlobals( size )
int size ;
{
MaxGlobals = size ;
}
/* 関数の最大数 */
void SetMaxFunctions( size )
int size ;
{
MaxFunctions = size ;
}
/* スタックサイズの最大数 */
void SetMaxStacks( size )
int size ;
{
MaxStacks = size ;
}
/* 初期化 */
void ParseInit()
{
Parse3Init();
ScannerInit();
CodeInit( MaxCodeSize );
IdentGlobalVar = IdentAlloc( MaxGlobals, 0 );
IdentLocalVar = NULL ;
IdentFunction = IdentAlloc( MaxFunctions, FUNC_START );
ObjectInit();
ObjectSetClass( "", MaxFunctions, -1 );
SetStdFunction();
TopLevel = TRUE ;
StringInit();
FileioInit();
}
/* 終了処理 */
void ParseExit()
{
CodeExit();
IdentFree( IdentGlobalVar );
IdentFree( IdentFunction );
ObjectExit();
}
#if 0
/* 最後まで文を評価 */
void ParseSentenseAll( filename )
char *filename ;
{
TopLevel = TRUE ;
FileOpen( filename );
while( ParseSentense() );
}
#endif
#if defined(X68K)
#define MAGICSTR "X68k "
#elif defined(PC98)
#define MAGICSTR "PC98 "
#elif defined(PC)
#define MAGICSTR "IBMPC "
#elif defined(WINDOWS)
#define MAGICSTR "WINDOWS "
#else
#error "X68K or PC98 or PC or WINDOWS must be defined"
#endif
#define MAGICSIZE 16
typedef struct {
char Magic[MAGICSIZE];
int IdentGlobalSize;
int IdentFunctionSize;
int FuncSize;
int CodeSize;
char *CodeBeginPtr;
} PreCompileData;
void DumpMode( int flag )
{
ForceDumpMode = flag;
}
static void ParseSentenseAllOnly( char *filename )
{
TopLevel = TRUE ;
FileOpen( filename );
while( ParseSentense() );
FileClose();
IdentPrivate( IdentGlobalVar );
IdentPrivate( IdentFunction );
}
/* 最後まで文を評価 */
void ParseSentenseAll( filename )
char *filename ;
{
char fileprecomp[512];
FILE *fp;
PreCompileData *data;
struct stat mstat, mcstat ;
int size;
strcpy(fileprecomp, filename);
strcat(fileprecomp, "c");
if ((fp = fopen(fileprecomp, "rb")) == NULL) {
if (ForceDumpMode == FALSE) {
ParseSentenseAllOnly(filename);
return;
}
data = NULL;
} else {
stat( fileprecomp, &mcstat );
data = MemoryAlloc( mcstat.st_size + 1 );
size = fread( data, 1, mcstat.st_size, fp );
fclose(fp);
stat( filename, &mstat );
}
if (ForceDumpMode == FALSE
&& mstat.st_mtime <= mcstat.st_mtime && mcstat.st_size > sizeof(PreCompileData)
&& size == mcstat.st_size && strncmp(data->Magic, MAGICSTR, strlen(MAGICSTR)) == 0) {
int i, ident;
char *CodeBegin, *CodeEnd;
char *name;
IdentBuffer *pGlobalVar, *pFunction;
FuncBuffer *pFunctionBuffer;
CodeStruct *code;
Object *obj;
int *realGlobalIdent, *realFunctionIdent;
pGlobalVar = (IdentBuffer*)((char*)data + sizeof(PreCompileData));
pFunction = (IdentBuffer*)((char*)pGlobalVar + data->IdentGlobalSize);
pFunctionBuffer = (FuncBuffer*)((char*)pFunction + data->IdentFunctionSize);
code = (CodeStruct*)((char*)pFunctionBuffer + data->FuncSize);
obj = (Object*)((char*)code + data->CodeSize);
pGlobalVar->flag = (char*)( pGlobalVar + 1 );
pGlobalVar->name = (IdentName*)( pGlobalVar->flag + pGlobalVar->max );
realGlobalIdent = MemoryAlloc(sizeof(int) * pGlobalVar->max);
pFunction->flag = (char*)( pFunction + 1 );
pFunction->name = (IdentName*)( pFunction->flag + pFunction->max );
realFunctionIdent = MemoryAlloc(sizeof(int) * pFunction->max);
CodeBegin = (char*)CodeAlloc(data->CodeSize) ;
CodeEnd = (char*)CodeNextPtr();
/*
printf("Read PreCompile MacroFile\n");
printf("HeaderSize = %6d\n", sizeof(PreCompileData));
printf("IdentGlobalSize = %6d\n", data->IdentGlobalSize);
printf("IdentFunctionSize = %6d\n", data->IdentFunctionSize);
printf("CodeSize = %6d\n", data->CodeSize);
printf("CodeBegin = %8x\n", data->CodeBeginPtr);
printf("CodeBegin = %8x\n", CodeBegin);
*/
memcpy(CodeBegin, code, data->CodeSize);
InputFile = fileprecomp;
name = MemoryAlloc(strlen(filename)+1);
strcpy(name, filename);
code = (CodeStruct*)CodeBegin;
for (i = 0; i < pGlobalVar->count; i++) {
ident = -1;
if (pGlobalVar->flag[i] != IDENT_RESERVE) {
if ((ident = IdentSearch(IdentGlobalVar, pGlobalVar->name[i])) < 0) {
ident = IdentAppend(IdentGlobalVar, pGlobalVar->name[i], pGlobalVar->flag[i]);
/*printf("NewGlobalVar %16s : %5d ->%5d\n", pGlobalVar->name[i], i, ident);*/
}
}
realGlobalIdent[i] = ident;
}
for (i = FUNC_START; i < pFunction->count; i++) {
ident = -1;
if (pFunction->flag[i] != IDENT_RESERVE) {
if ((ident = IdentSearch(IdentFunction, pFunction->name[i])) < 0) {
ident = IdentAppend(IdentFunction, pFunction->name[i], pFunction->flag[i]);
}
if (data->CodeBeginPtr <= (char*)pFunctionBuffer[i].ptr
&& (char*)pFunctionBuffer[i].ptr < data->CodeBeginPtr + data->CodeSize) {
ClassList[0].func[ident].type = FUNC_USR;
ClassList[0].func[ident].name = IdentFunction->name[ident];
ClassList[0].func[ident].ptr = CodeBegin
+ ((char*)pFunctionBuffer[i].ptr - (char*)data->CodeBeginPtr);
}
}
realFunctionIdent[i] = ident;
}
while (code != NULL && (char*)code < CodeEnd) {
/*printf("Code = %08x\n", code);*/
if (code->type == CODE_CONST) {
if (code->c.data.type == TYPE_OBJECT) {
int osize = ((obj->size+3)/4)*4;
code->c.data.od.ptr = ObjectDup(obj);
obj = (Object*)((char*)obj + sizeof(Object) + osize);
/* obj = (Object*)((char*)obj + sizeof(Object) + obj->size);*/
/*
printf("Object(%3d) = %8x (%d)\n", code->c.data.od.ptr->type, code->c.data.od.ptr, osize);
*/
} else if (code->c.data.type == TYPE_FUNC
&& code->c.data.funcd.ident >= FUNC_START) {
code->c.data.funcd.ident = realFunctionIdent[code->c.data.funcd.ident];
}
} else if (code->type == CODE_SENTENSE) {
code->sent.file = name;
/*printf("Sentense : %8x ->", code->sent.next);*/
code->sent.next = CodeBegin
+ ((char*)code->sent.next - (char*)data->CodeBeginPtr);
/*printf(" %8x\n", code->sent.next);*/
if (code->sent.stype == SENT_DO
|| code->sent.stype == SENT_COMPLEX) {
code = CodeNext(code);
code->c.data.id.i = (int)CodeBegin
+ ((char*)code->c.data.id.i - (char*)data->CodeBeginPtr);
}
} else if (code->type == CODE_IDENT) {
if (code->ident.itype & IDENT_GLOBAL) {
code->ident.ident = realGlobalIdent[code->ident.ident];
} else if (code->ident.itype & IDENT_FUNC
&& code->ident.ident >= FUNC_START) {
code->ident.ident = realFunctionIdent[code->ident.ident];
}
}
code = CodeNext(code);
}
MemoryFree(realFunctionIdent);
MemoryFree(realGlobalIdent);
MemoryFree(data);
IdentPrivate( IdentGlobalVar );
IdentPrivate( IdentFunction );
} else {
char *CodeBegin, *CodeEnd;
int pCodeSize, IdentGlobalSize, IdentFunctionSize, FuncSize;
if (data != NULL) {
MemoryFree(data);
}
CodeBegin = (char*)CodeNextPtr();
TopLevel = TRUE ;
FileOpen( filename );
while( ParseSentense() );
FileClose();
CodeEnd = (char*)CodeNextPtr();
pCodeSize = (char*)CodeEnd - (char*)CodeBegin;
/* pCodeSize = ((pCodeSize +3)/4)*4;*/
if ((fp = fopen(fileprecomp, "wb")) == NULL) {
IdentPrivate( IdentGlobalVar );
IdentPrivate( IdentFunction );
return;
}
IdentGlobalSize = sizeof(IdentBuffer)
+ (sizeof(char) + sizeof(IdentName)) * IdentGlobalVar->max
- sizeof(IdentName) * (IdentGlobalVar->max - IdentGlobalVar->count-1);
/* IdentGlobalSize = ((IdentGlobalSize+3)/4)*4;*/
IdentFunctionSize = sizeof(IdentBuffer)
+ (sizeof(char) + sizeof(IdentName)) * IdentFunction->max
- sizeof(IdentName) * (IdentFunction->max - IdentFunction->count-1);
/* IdentFunctionSize = ((IdentFunctionSize+3)/4)*4;*/
FuncSize = sizeof(FuncBuffer) * IdentFunction->count;
data = MemoryAlloc( sizeof(PreCompileData) );
strcpy(data->Magic, MAGICSTR);
data->IdentGlobalSize = IdentGlobalSize;
data->IdentFunctionSize = IdentFunctionSize;
data->FuncSize = FuncSize;
data->CodeSize = pCodeSize;
data->CodeBeginPtr = CodeBegin;
/*
printf("Write PreCompile MacroFile\n");
printf("Write PreCompile MacroFile\n");
printf("HeaderSize = %6d\n", sizeof(PreCompileData));
printf("IdentGlobalSize = %6d\n", IdentGlobalSize);
printf("IdentFunctionSize = %6d\n", IdentFunctionSize);
printf("CodeSize = %6d\n", pCodeSize);
printf("CodeBegin = %8x\n", CodeBegin);
*/
if (fwrite(data, 1, sizeof(PreCompileData), fp) == sizeof(PreCompileData)
&& fwrite(IdentGlobalVar, 1, IdentGlobalSize, fp) == IdentGlobalSize
&& fwrite(IdentFunction, 1, IdentFunctionSize, fp) == IdentFunctionSize
&& fwrite(ClassList[0].func, 1, FuncSize, fp) == FuncSize
&& fwrite(CodeBegin, 1, pCodeSize, fp) == pCodeSize) {
CodeStruct *code;
code = (CodeStruct*)CodeBegin;
while (code != NULL && (char*)code < CodeEnd) {
if (code->type == CODE_CONST
&& code->c.data.type == TYPE_OBJECT) {
int osize = ((code->c.data.od.ptr->size+3)/4)*4;
fwrite(code->c.data.od.ptr, 1, sizeof(Object) + osize, fp);
/*
fwrite(code->c.data.od.ptr, 1, sizeof(Object) + code->c.data.od.ptr->size, fp);
printf("Object(%3d) = %8x (%d)\n", code->c.data.od.ptr->type, code->c.data.od.ptr, osize);
*/
}
code = CodeNext(code);
}
}
fclose(fp);
MemoryFree(data);
IdentPrivate( IdentGlobalVar );
IdentPrivate( IdentFunction );
}
}
/* 現在のコードサイズ */
int ReportCodeSize()
{
return (char*)CodeNextPtr() - (char*)CodeTop() ;
}
/* 識別子のレポート */
void ReportIdent( global, func )
int *global, *func ;
{
*global = IdentGlobalVar->count ;
*func = IdentFunction->count ;
}
/* 実行系の初期化 */
void ExecInit()
{
StackInit( MaxStacks );
if ( IdentGlobalVar->count > 0 )
DataGlobalVar = StackAlloc( IdentGlobalVar->count );
else
DataGlobalVar = NULL ;
DataLocalVar = NULL ;
ExecPtr = CodeTop();
}
/* 実行系の終了処理 */
void ExecExit()
{
StackExit();
}
/* 最後まで文を実行 */
void ExecSentenseAll()
{
while( ExecSentense() != RETURN_END );
}
/* 文字列オブジェクトの設定 */
void StringToObject( buf, str )
DataStruct *buf ;
char *str ;
{
if ( buf->type == TYPE_OBJECT )
ObjectFree( buf->od.ptr );
buf->type = TYPE_OBJECT ;
buf->od.ptr = (Object*)StringSet( str );
}
void SetBreakCheck(int (*func)(void))
{
if (func == NULL) {
BreakCheck = BreakNone;
} else {
BreakCheck = func;
}
}
static int BreakNone()
{
return FALSE;
}