📄 bldfile.cpp
字号:
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ +
+ bldfile.cpp - construct header and output file +
+ append bytecode from pass2 on to end +
+ +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ macros +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*#define PASS3_DEBUG 1*/
#ifdef PASS3_DEBUG
#define PASS3_DEBUG0(arg); printf(arg);
#define PASS3_DEBUG1(arg1,arg2); printf(arg1,arg2);
#define PASS3_DEBUG2(arg1,arg2,arg3); printf(arg1,arg2,arg3);
#else
#define PASS3_DEBUG0(arg);
#define PASS3_DEBUG1(arg1,arg2);
#define PASS3_DEBUG2(arg1,arg2,arg3);
#endif
/*byte sizes of records in debug DB*/
#define SIZE_GLOBREC 37
#define SIZE_PROCREC 25
#define SIZE_RETREC 16
#define SIZE_ARGREC 16
#define SIZE_LOCREC 16
#define SIZE_LBLREC 20
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ declaration +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
class BuildFile
{
CommandLine *cmdLine;
SymbolTable *symTbl;
StringTable *strTbl;
FILE *ofptr; /*pointer to output file*/
FILE *afptr; /*pointer to temporary bytecode file*/
char *ofile; /*pointer to output file name*/
char *afile; /*pointer to temporary file name*/
char ofBuffer[BUFFER_SIZE]; /*buffer for output file*/
int iOFChar; /*index into ofBuffer*/
U1 output[8]; /*holds bytes to write to output file*/
/*manage output buffer*/
void putByteOutBuff(U1 byte);
void flushOutBuff();
/*these functions convert a number to big endian and write to output*/
void commit2Bytes(U2 val);
void commit4Bytes(U4 val);
void commit8Bytes(U8 val);
public:
BuildFile(CommandLine *cptr, StringTable *st, SymbolTable *syt);
~BuildFile();
void buildFileFormat();
};
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ definitions +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
BuildFile::BuildFile(CommandLine *cptr, StringTable *st, SymbolTable *syt)
{
cmdLine = cptr;
strTbl = st;
symTbl = syt;
ofile = (*cptr).outputFile;
afile = (*cptr).tempFile;
if(ofile==NULL)
{
ERROR0("BuildFile::BuildFile(): output file name has not been specified\n");
FATAL_ERROR();
}
if(afile==NULL)
{
ERROR0("BuildFile::BuildFile(): temporary file's name has not been specified\n");
FATAL_ERROR();
}
ofptr = fopen(ofile,"wb");
afptr = fopen(afile,"rb");
if(ofptr==NULL)
{
ERROR1("BuildFile::BuildFile(): could not open output file->%s\n",ofile);
FATAL_ERROR();
}
if(afptr==NULL)
{
ERROR1("BuildFile::BuildFile(): could not open temporary file->%s\n",afile);
FATAL_ERROR();
}
iOFChar = 0;
return;
}/*end constructor*/
/*-----------------------------------------------------------------*/
BuildFile::~BuildFile()
{
flushOutBuff();
if(fclose(ofptr)){ ERROR1("BuildFile::BuildFile(): problem closing output file ->%s\n",ofile); }
if(fclose(afptr)){ ERROR1("BuildFile::BuildFile(): problem closing temp file ->%s\n",afile); }
return;
}/*end finalizePass3*/
/*-----------------------------------------------------------------*/
void BuildFile::putByteOutBuff(U1 byte)
{
int nbytes;
nbytes = 0;
ofBuffer[iOFChar] = byte;
iOFChar++;
if(iOFChar==BUFFER_SIZE)
{
nbytes = fwrite(ofBuffer,sizeof(U1),BUFFER_SIZE,ofptr);
if(nbytes!=BUFFER_SIZE)
{
ERROR1("BuildFile::putByteOutBuff(): error during fwrite to %s\n",ofile);
FATAL_ERROR();
}
iOFChar = 0;
}
return;
}/*end putByteOutBuff*/
/*-----------------------------------------------------------------*/
void BuildFile::flushOutBuff()
{
int nbytes;
nbytes = 0;
if(iOFChar>0)
{
PASS3_DEBUG1("BuildFile::flushOutBuff(): trying to flush %lu bytes\n",iOFChar);
nbytes = fwrite(ofBuffer,sizeof(U1),iOFChar,ofptr);
if(nbytes!=iOFChar)
{
ERROR1("BuildFile::flushOutBuff(): only flushed %lu bytes\n",nbytes);
ERROR1("BuildFile::flushOutBuff(): error during fwrite to %s\n",ofile);
FATAL_ERROR();
}
iOFChar = 0;
}
return;
}/*end flushOutBuff*/
/*-----------------------------------------------------------------*/
void BuildFile::commit2Bytes(U2 val)
{
wordToBytecode(val,output);
putByteOutBuff(output[0]);
putByteOutBuff(output[1]);
return;
}/*end commit2Bytes*/
/*-----------------------------------------------------------------*/
void BuildFile::commit4Bytes(U4 val)
{
dwordToBytecode(val,output);
putByteOutBuff(output[0]);
putByteOutBuff(output[1]);
putByteOutBuff(output[2]);
putByteOutBuff(output[3]);
return;
}/*end commit4Bytes*/
/*-----------------------------------------------------------------*/
void BuildFile::commit8Bytes(U8 val)
{
qwordToBytecode(val,output);
putByteOutBuff(output[0]);
putByteOutBuff(output[1]);
putByteOutBuff(output[2]);
putByteOutBuff(output[3]);
putByteOutBuff(output[4]);
putByteOutBuff(output[5]);
putByteOutBuff(output[6]);
putByteOutBuff(output[7]);
return;
}/*end commit8Bytes*/
/*-----------------------------------------------------------------*/
void BuildFile::buildFileFormat()
{
U8 size_symtbl;
U8 size_strtbl;
U8 size_bc;
U8 i;
U8 j;
int ch;
size_symtbl = 0;
size_strtbl = 0;
size_bc = 0;
/* 1) determine size of symbol table*/
size_symtbl = size_symtbl + 8; /*table of contents */
size_symtbl = size_symtbl + SIZE_GLOBREC*((*symTbl).iGlobVar);
size_symtbl = size_symtbl + SIZE_PROCREC*((*symTbl).iProc);
for(i=0;i<(*symTbl).iProc;i++)
{
size_symtbl = size_symtbl + SIZE_RETREC*(((*symTbl).proc[i]).nRet);
size_symtbl = size_symtbl + SIZE_ARGREC*(((*symTbl).proc[i]).iArg);
size_symtbl = size_symtbl + SIZE_LOCREC*(((*symTbl).proc[i]).iLocal);
size_symtbl = size_symtbl + SIZE_LBLREC*(((*symTbl).proc[i]).iLabel);
}
/* 2) determine size of string table*/
size_strtbl = (*strTbl).iStr;
/* 3) determine size of bytecode */
size_bc = getFileSize(afile);
/* 4) commit header to output file */
putByteOutBuff(0xDE); /*magic word to output file */
putByteOutBuff(0xED);
if((*cmdLine).omitDebugData==TRUE)
{
commit8Bytes((U8)0);
commit8Bytes((U8)0);
commit8Bytes(size_bc);
ch = fgetc(afptr);
while(ch!=EOF)
{
putByteOutBuff((U1)ch);
ch = fgetc(afptr);
}
return;
}
commit8Bytes(size_symtbl);
commit8Bytes(size_strtbl);
commit8Bytes(size_bc);
/* 5) commit tables of contents (# globals and # procs) */
commit4Bytes((*symTbl).iGlobVar);
commit4Bytes((*symTbl).iProc);
/* 6) commit global vars to output file */
for(i=0;i<(*symTbl).iGlobVar;i++)
{
commit8Bytes(((*symTbl).globVar[i]).text);
putByteOutBuff(((*symTbl).globVar[i]).dType);
commit8Bytes(((*symTbl).globVar[i]).len);
commit8Bytes(((*symTbl).globVar[i]).size);
commit8Bytes(-((S8)((*symTbl).globVar[i]).offset));
commit4Bytes(((*symTbl).globVar[i]).line);
}
/* 7) commit procedures to output file */
for(i=0;i<(*symTbl).iProc;i++)
{
commit8Bytes(((*symTbl).proc[i]).text);
commit8Bytes(((*symTbl).proc[i]).address);
commit4Bytes(((*symTbl).proc[i]).line);
putByteOutBuff(((*symTbl).proc[i]).nRet);
putByteOutBuff(((*symTbl).proc[i]).iArg);
putByteOutBuff(((*symTbl).proc[i]).iLocal);
commit2Bytes(((*symTbl).proc[i]).iLabel);
for(j=0;j<((*symTbl).proc[i]).nRet;j++)
{
commit8Bytes((((*symTbl).proc[i]).ret).text);
commit4Bytes((((*symTbl).proc[i]).ret).fpOffset);
commit4Bytes((((*symTbl).proc[i]).ret).line);
}
for(j=0;j<((*symTbl).proc[i]).iArg;j++)
{
commit8Bytes((((*symTbl).proc[i]).arg[j]).text);
commit4Bytes((((*symTbl).proc[i]).arg[j]).fpOffset);
commit4Bytes((((*symTbl).proc[i]).arg[j]).line);
}
for(j=0;j<((*symTbl).proc[i]).iLocal;j++)
{
commit8Bytes((((*symTbl).proc[i]).local[j]).text);
commit4Bytes((((*symTbl).proc[i]).local[j]).fpOffset);
commit4Bytes((((*symTbl).proc[i]).local[j]).line);
}
for(j=0;j<((*symTbl).proc[i]).iLabel;j++)
{
commit8Bytes((((*symTbl).proc[i]).label[j]).text);
commit8Bytes((((*symTbl).proc[i]).label[j]).address);
commit4Bytes((((*symTbl).proc[i]).label[j]).line);
}
}
/* 8) commit string table to output file */
for(i=0;i<(*strTbl).iStr;i++){ putByteOutBuff((*strTbl).text[i]); }
/* 9) append bytecode in temp to output file */
ch = fgetc(afptr);
while(ch!=EOF)
{
putByteOutBuff((U1)ch);
ch = fgetc(afptr);
}
return;
}/*end buildFileFormat*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -