forked from KolibriOS/kolibrios
02b76505a6
git-svn-id: svn://kolibrios.org@1846 a494cfbc-eb01-0410-851d-a64ba20cac60
1442 lines
30 KiB
Plaintext
1442 lines
30 KiB
Plaintext
//===== ”« £¨ ª®¬¯¨«ï樨
|
||
#pragma option w32c
|
||
#stack 0x8000
|
||
#argc TRUE
|
||
|
||
//===== <20>®¤ª«îç ¥¬ë¥ ¬®¤ã«¨
|
||
#include "wapi.h--"
|
||
#include "enums.h--"
|
||
#include "data.h--"
|
||
#include "opcodesc.h--"
|
||
#include "tree.h--"
|
||
#include "directiv.h--"
|
||
#include "tokscan.h--"
|
||
#include "exe.h--"
|
||
#include "generate.h--"
|
||
#include "parser.h--"
|
||
|
||
//===== ƒ« ¢ ï äãªæ¨ï ¯à®£à ¬¬ë
|
||
main()
|
||
dword count,pari,cmdline;
|
||
{
|
||
stdout=GetStdHandle(STD_OUTPUT_HANDLE);
|
||
WRITESTR("\n32-Compiler Version 0.01\tXAC (C) 1999.");
|
||
WRITESTR("\nBased on SPHINX C-- Compiler Peter Cellik (C) 1995.\n");
|
||
// <20> §¡®à ª®¬¬ ¤®© áâப¨: 32.exe <SourceFileName> [/map] [/debug]
|
||
pari=@PARAMCOUNT();
|
||
for(count=1;count<pari;count++){ //®¡à ¡®âª ª®¬ ¤®© áâப¨
|
||
cmdline=@PARAMSTR(count);
|
||
CharUpperA(EAX);
|
||
CharToOemA(cmdline,cmdline); // <20>८¡à §ã¥¬ ¢ ‡€ƒ‹ ¢ OEM ª®¤à®¢ª¥
|
||
ESI=cmdline;
|
||
IF(DSBYTE[ESI]=='/'){
|
||
ESI++;
|
||
IF(lstrcmpA("MAP",ESI)==0)makemapfile = 1;
|
||
ELSE IF(lstrcmpA("DEBUG",ESI)==0)dbg=1;
|
||
ELSE{
|
||
WRITESTR("ERROR > Unknown command line option: '");
|
||
WRITESTR(cmdline);
|
||
WRITESTR("'\n");
|
||
ExitProcess(e_unknowncommandline);
|
||
}
|
||
}
|
||
ELSE{ // Š®¯¨à㥬 ¨¬ï ¨á室®£® ä ©« ¡¥§ à áè¨à¥¨ï
|
||
EDI=#rawfilename;
|
||
for(;;){
|
||
$LODSB
|
||
IF(AL=='.')||(AL==0)BREAK; // …áâì à áè¨à¥¨¥?
|
||
$STOSB;
|
||
}
|
||
AL=0;
|
||
$STOSB;
|
||
lstrcpyA(#inputfile,cmdline); // Š®¯¨à㥬 ¨¬ï ¢å®¤®£® ä ©« á à áè¨à¥¨¥¬
|
||
}
|
||
}
|
||
IF(rawfilename[0]==0){
|
||
errmsg();
|
||
WRITESTR("No input file specified");
|
||
pari=1;
|
||
}
|
||
IF(pari < 2){
|
||
WRITESTR("\nUsage: 32.exe [/MAP] [/DEBUG] <Source file>");
|
||
WRITESTR("\n\t/MAP\t<< generate map file");
|
||
WRITESTR("\n\t/DEBUG\t<< generate .TDS - debug info file\n");
|
||
ExitProcess(e_noinputspecified);
|
||
}
|
||
GetMem(); // ¢ë¤¥«¥¨¥ ¯ ¬ï⨠¤«ï ª®¬¯¨«ï樨
|
||
TokInit(); // ¨¨æ¨ «¨§ æ¨ï ᯨ᪮¢
|
||
Compile();
|
||
IF( error == 0 )EAX=e_ok;
|
||
ELSE EAX=e_someerrors;
|
||
ExitProcess(EAX);
|
||
}
|
||
|
||
//===== Š®¬¯¨«ïâ®à
|
||
Compile()
|
||
{
|
||
IF(makemapfile)StartMapfile();
|
||
WRITESTR("Compiling ...\n");
|
||
Preview(#inputfile);
|
||
CompileAll();
|
||
/*if( endifcount > 0 )
|
||
preerror("#endif expected before end of file");
|
||
if( outptr%16 != 0 ) // paragraph align the end of the code seg
|
||
outptr += 16 - outptr%16;*/
|
||
DoLink(); // ”®à¬¨à®¢ ¨¥ link
|
||
IF(posts > 0)DoPosts(); // Ž¡®¢«¥¨¥ ¢á¥å post ¤à¥á®¢
|
||
SeekUndefined(treestart);
|
||
if(error==0){
|
||
wsprintfA(#mapstr,"\nCOMPILING FINISHED.\tErrors: %d\tLines: %u\n",error,totallines);
|
||
WRITESTR(#mapstr);
|
||
runfilesize = outptr-output;
|
||
postsize += postsize%2;
|
||
PrintMemsizes(GetStdHandle(STD_OUTPUT_HANDLE));
|
||
IF(WriteEXE()==0) {
|
||
wsprintfA(#mapstr,"\nRun File Saved (%ld bytes).\n",runfilesize);
|
||
WRITESTR(#mapstr);
|
||
wsprintfA(#mapstr,"DLL: %d\tAPI: %d \n",DLLcount,APIcount);
|
||
WRITESTR(#mapstr);
|
||
}
|
||
// if(dbg)
|
||
// dotds(); // do turbo debugger line info
|
||
}
|
||
IF(makemapfile)FinishMapfile();
|
||
}
|
||
|
||
// ---- <20>।¢ à¨â¥«ì ï ®¡à ¡®âª ä ©«
|
||
Preview(dword filename)
|
||
long hold;
|
||
char trialfilename[FILENAMESIZE];
|
||
{
|
||
lstrcpyA(#trialfilename,filename);
|
||
hold = LoadInputfile(#trialfilename);
|
||
IF(EAX==-2)unabletoopen(#trialfilename);
|
||
IF(hold!=0)ExitProcess(e_cannotopeninput);
|
||
lstrcpyA(#currentfilename,#trialfilename);
|
||
module++;
|
||
IF(module<MAXMDL) {
|
||
lstrcpyA(FILENAMESIZE*module+#modules,#currentfilename);
|
||
currmod = module;
|
||
}
|
||
IF(makemapfile){
|
||
EBX=inptr;
|
||
cha=DSBYTE[EBX];
|
||
wsprintfA(#mapstr,"File %s included.\n\n%c",#currentfilename,cha);
|
||
fprint(mapfile,#mapstr);
|
||
}
|
||
ShowSrcLine();
|
||
NextChar();
|
||
cha2 = cha;
|
||
inptr2=inptr;
|
||
linenum2 = 1;
|
||
NextTok();
|
||
WHILE(tok!=tk_eof){ // <20>®ª ¥ ª®ç¨âáï ¢å®¤®© ¡ãä¥à
|
||
IF(tok==tk_directive){
|
||
GetDirAddr(#Jmp_Directives,number);
|
||
EAX();
|
||
}
|
||
ELSE IF(tok==tk_command){
|
||
GetDirAddr(#Jmp_Commands,number);
|
||
EAX();
|
||
}
|
||
ELSE IF(tok==tk_id)GetProc(tk_void);
|
||
ELSE IF(tok==tk_void){
|
||
NextTok();
|
||
GetProc(tk_void);
|
||
}
|
||
ELSE{
|
||
preerror("unuseable input");
|
||
NextTok();
|
||
}
|
||
}
|
||
LocalFree(input);
|
||
}
|
||
|
||
// ---- Š®¬¯¨«ïæ¨ï ®¤®© ¯à®æ¥¤ãàë ¨«¨ ®¡ê¥¨ï ¤ ëå
|
||
CompileSrc(dword ptr)
|
||
{
|
||
EAX=src;
|
||
if(EAX){
|
||
inptr = EAX;
|
||
inptr2 = EAX;
|
||
endoffile = 0; // <20> ç «® ¡ãä¥à
|
||
linenum2 = modline&0xFFFF;
|
||
currmod=modline>>16;
|
||
lstrcpyA(#currentfilename,FILENAMESIZE*currmod+#modules);
|
||
NextChar();
|
||
cha2 = cha;
|
||
inptr2=inptr;
|
||
IF(tok==tk_proc){
|
||
Proc(cpt_near);
|
||
DoPoststrings();
|
||
}
|
||
ELSE IF(tok==tk_var)GlobalVar(type);
|
||
ELSE preerror("Bad input format\n");
|
||
}
|
||
ELSE{ // post-¯¥à¥¬¥ ï ¡¥§ à §¬¥à®áâ¨
|
||
ESI=ptr;
|
||
DSDWORD[ESI+recnumber] = postsize;
|
||
DSDWORD[ESI+recpost] = 1;
|
||
postsize+=TypeSize(type);
|
||
}
|
||
}
|
||
|
||
// ---- Š®¬¯¨«ïæ¨ï ¢á¥å ¯à®æ¥¤ãà ¨ ®¡ê¥¨© ¤ ëå
|
||
CompileAll()
|
||
{
|
||
IF(SearchTree(#tok,#type,#src,#post,"main",#number))AX=3; // Console
|
||
ELSE IF(SearchTree(#tok,#type,#src,#post,"WinMain",#number))AX=2; // GUI
|
||
ELSE{
|
||
preerror("Main not found");
|
||
return;
|
||
}
|
||
OptSubSystem=AX;
|
||
OptEntryPointRVA=OptBaseOfCode+outptr-output;
|
||
CompileSrc(treeptr); // Š®¬¯¨«ïæ¨ï main
|
||
WHILE(SeekToDo(treestart)){
|
||
ESI=treeptr;
|
||
wsprintfA(#mapstr,"==>%3d %8lXh %8lXh %6Xh\t%s\n",DSDWORD[ESI+rectok],
|
||
DSDWORD[ESI+rectype],DSDWORD[ESI+recnumber],DSDWORD[ESI+recpost],
|
||
DSDWORD[ESI+recid]);
|
||
fprint(mapfile,#mapstr);
|
||
CompileSrc(treeptr); // Š®¬¯¨«ïæ¨ï ¨á室¨ª®¢
|
||
}
|
||
IF(makemapfile)
|
||
fprint(mapfile,"Compile all sources\n");
|
||
}
|
||
|
||
// ---- Ž¡à ¡®âª ¯ à ¬¥â஢ ¯à¨ ®¡ê¥¨¨ ¯à®æ¥¤ãàë
|
||
DeclareParams()
|
||
dword paramtok,paramtype;
|
||
{
|
||
LL:
|
||
IF(tok==tk_command)GetDirAddr(#Jmp_Commands,number);
|
||
ELSE EAX=-1;
|
||
IF(EAX==#CmdShort){
|
||
paramtok = tk_param;
|
||
paramtype=tk_short;
|
||
}
|
||
ELSE IF(EAX==#CmdWord){
|
||
paramtok = tk_param;
|
||
paramtype=tk_word;
|
||
}
|
||
ELSE IF(EAX==#CmdChar){
|
||
paramtok = tk_param;
|
||
paramtype=tk_char;
|
||
}
|
||
ELSE IF(EAX==#CmdByte){
|
||
paramtok = tk_param;
|
||
paramtype=tk_byte;
|
||
}
|
||
ELSE IF(EAX==#CmdInt){
|
||
paramtok = tk_param;
|
||
paramtype=tk_int;
|
||
}
|
||
ELSE IF(EAX==#CmdDword){
|
||
paramtok = tk_param;
|
||
paramtype=tk_dword;
|
||
}
|
||
ELSE{
|
||
datatype_expected();
|
||
NextTok();
|
||
}
|
||
for(;;){
|
||
NextTok();
|
||
IF(tok==tk_id ){
|
||
paramsize += 4;
|
||
AddLocalvar(#string,paramtok,paramtype,paramsize);
|
||
}
|
||
ELSE IF(tok==tk_semicolon){
|
||
NextTok();
|
||
$JMP LL
|
||
}
|
||
ELSE IF(tok==tk_closebracket)BREAK;
|
||
ELSE IF(tok!=tk_comma)idexpected();
|
||
}
|
||
}
|
||
|
||
// ---- Ž¡à ¡®âª «®ª «ìëå ¯¥à¥¬¥ëå ¯à¨ ®¡ê¥¨¨ ¯à®æ¥¤ãàë
|
||
DeclareLocals()
|
||
dword size;
|
||
dword loctok,loctype;
|
||
{
|
||
LL:
|
||
IF(tok==tk_command)GetDirAddr(#Jmp_Commands,number);
|
||
IF(EAX==#CmdShort){
|
||
loctok = tk_local;
|
||
loctype=tk_short;
|
||
size = 2;
|
||
}
|
||
else IF(EAX==#CmdWord){
|
||
loctok = tk_local;
|
||
loctype=tk_word;
|
||
size = 2;
|
||
}
|
||
else IF(EAX==#CmdChar){
|
||
loctok = tk_local;
|
||
loctype=tk_char;
|
||
size = 1;
|
||
}
|
||
ELSE IF(EAX==#CmdByte){
|
||
loctok = tk_local;
|
||
loctype=tk_byte;
|
||
size = 1;
|
||
}
|
||
ELSE IF(EAX==#CmdInt){
|
||
loctok = tk_local;
|
||
loctype=tk_int;
|
||
size = 4;
|
||
}
|
||
ELSE IF(EAX==#CmdDword){
|
||
loctok = tk_local;
|
||
loctype=tk_dword;
|
||
size = 4;
|
||
}
|
||
ELSE IF(tok==tk_eof)||(tok==tk_openbrace)$JMP L1
|
||
ELSE{
|
||
datatype_expected();
|
||
NextTok();
|
||
goto LL;
|
||
}
|
||
for(;;){
|
||
NextTok();
|
||
IF(tok==tk_id){
|
||
AddLocalvar(#string,loctok,loctype,localsize);
|
||
IF(tok2==tk_openblock){
|
||
NextTok();
|
||
NextTok();
|
||
localsize += DoConstLongMath()*size;
|
||
EAX=localsize;
|
||
$TEST EAX,3;
|
||
IF(NOTZEROFLAG){
|
||
EAX=EAX>>2+1<<2;
|
||
localsize=EAX; // ‚ëà ¢¨¢ ¨¥ dword
|
||
}
|
||
expecting(tk_closeblock);
|
||
}
|
||
ELSE localsize+=4;
|
||
}
|
||
ELSE IF(tok==tk_semicolon){
|
||
NextTok();
|
||
$JMP LL
|
||
}
|
||
ELSE IF(tok==tk_openbrace)||(tok==tk_eof)BREAK;
|
||
ELSE IF(tok!=tk_comma)idexpected();
|
||
}
|
||
L1:
|
||
IF(paramsize==0)Asm("push ebp; mov ebp,esp;");
|
||
wsprintfA(#mapstr,"sub esp,%d;",localsize);
|
||
Asm(#mapstr);
|
||
}
|
||
|
||
// ---- Ž¡à ¡®âª ®¡à é¥¨ï ª 㦥 ®¯¨á ®© ¯à®æ¥¤ãà¥
|
||
DoAnyProc()
|
||
byte s[80];
|
||
{
|
||
wsprintfA(#s,"call %s;",#string);
|
||
NextTok();
|
||
DoParams();
|
||
Asm(#s);
|
||
}
|
||
|
||
// ---- Ž¡à ¡®âª à ¥¥ ®¡ê¢«¥®©, ® ¯®ª ¥ ¨§¢¥á⮩ ¬¥âª¨
|
||
dword DoAnyUndefproc(dword expectedreturn)
|
||
byte s[80];
|
||
{
|
||
IF( tok2 == tk_colon ){ // ¬¥âª
|
||
number = outptr-output+OptImageBase+OptBaseOfCode;
|
||
tok = tk_proc;
|
||
ESI=treeptr;
|
||
DSDWORD[ESI+rectok] = tok;
|
||
DSDWORD[ESI+recnumber] = number;
|
||
DSDWORD[ESI+recpost] = 0;
|
||
NextTok(); // move past id
|
||
NextTok(); // move past :
|
||
RETURN(tokens);
|
||
}
|
||
IF( tok2 == tk_openbracket ){
|
||
wsprintfA(#s,"call %s;",#string);
|
||
NextTok();
|
||
DoParams();
|
||
Asm(#s);
|
||
RETURN(tk_dword);
|
||
}
|
||
undefinederror();
|
||
NextTok();
|
||
return(tk_int);
|
||
}
|
||
|
||
// ---- Ž¡à ¡®âª ®¡à é¥¨ï ª API äãªæ¨¨
|
||
dword doAPI()
|
||
dword hold;
|
||
byte s[IDLENGTH];
|
||
{
|
||
if( tok2 == tk_openbracket ){
|
||
hold = treeptr;
|
||
GetVarname(#s);
|
||
NextTok();
|
||
DoParams();
|
||
IF(posts>=MAXPOSTS){
|
||
preerror("maximum number of API procedure calls exceeded");
|
||
return(tokens);
|
||
}
|
||
EBX=hold;
|
||
IF(DSDWORD[EBX+recpost]==0) { // <20>¥à¢ë© ¢ë§®¢ API?
|
||
DSDWORD[EBX+recpost]=1; // ®â¬¥â¨¬ ¢ë§®¢ ¤ ®© API
|
||
APIcount++;
|
||
EAX=DSDWORD[EBX+rectype]; // “ª § ⥫ì DLL, ¢ ª®â®à®¬ 室¨âáï API
|
||
DSDWORD[EAX+recmodline]++; // “¢¥«¨ç¨¬ áç¥â稪 API, ¢ë§¢ ëå ¨§ DLL
|
||
}
|
||
OUTWORD(0x15FF); // call [dword]
|
||
SetPost(hold,POST_API);
|
||
OUTDWORD(0);
|
||
IF(list){
|
||
fprint(mapfile,"\t//\tcall ");
|
||
fprint(mapfile,#s);
|
||
fprint(mapfile,"\n");
|
||
}
|
||
return(tk_int);
|
||
}
|
||
undefinederror();
|
||
NextTok();
|
||
return(tokens);
|
||
}
|
||
|
||
// ---- Ž¡à ¡®âª ¯à®£à ¬¬®£® ¡«®ª {...}
|
||
void DoBlock()
|
||
{
|
||
expecting(tk_openbrace);
|
||
for(;;){
|
||
IF(tok==tk_eof){
|
||
unexpectedeof();
|
||
BREAK;
|
||
}
|
||
IF(tok == tk_closebrace){
|
||
NextTok();
|
||
BREAK;
|
||
}
|
||
DoCommand();
|
||
}
|
||
}
|
||
|
||
// ---- Ž¡à ¡®âª ®¤®© ª®¬ ¤ë ¢ãâਠ¡«®ª
|
||
DoCommand()
|
||
{
|
||
LL:
|
||
FastSearch(#string,#St_Sizes);// <20>â® à §¬¥à ®¯¥à ¤ ?
|
||
IF(CARRYFLAG){ // „ : byte,word ¨«¨ dword
|
||
type=EAX<<1+tk_byte;
|
||
string[0]=0;
|
||
tok=tk_var;
|
||
GOTO LL;
|
||
}
|
||
IF(tok==tk_mnemonics){
|
||
DoMnemonics();
|
||
NextTok();
|
||
}
|
||
else IF(tok==tk_directive){
|
||
GetDirAddr(#Jmp_Directives,number);
|
||
EAX();
|
||
}
|
||
else IF(tok==tk_command){
|
||
GetDirAddr(#Jmp_Commands,number);
|
||
EAX();
|
||
}
|
||
else IF(tok==tk_id){
|
||
DoId(tk_void);
|
||
IF(EAX!=tokens)NextSemiNext();
|
||
}
|
||
else IF(tok==tk_undefproc){
|
||
DoAnyUndefproc(tk_void);
|
||
IF(EAX!=tokens)NextSemiNext();
|
||
}
|
||
else IF(tok==tk_proc){
|
||
DoAnyProc();
|
||
NextSemiNext();
|
||
}
|
||
else IF(tok==tk_API){
|
||
IF(doAPI()!=tokens)NextSemiNext();
|
||
}
|
||
else IF(tok==tk_var)||(tok==tk_local)||(tok==tk_param)||(tok==tk_reg)DoVar(type);
|
||
ELSE IF(tok==tk_openblock)DoVar(tk_dword);
|
||
ELSE IF(tok==tk_string){
|
||
Macros();
|
||
NextSemiNext();
|
||
}
|
||
ELSE IF(tok==tk_locallabel)DoLocalPost();
|
||
ELSE IF(tok==tk_openbrace)DoBlock();
|
||
ELSE IF(tok==tk_comma)||(tok==tk_semicolon)NextTok();
|
||
ELSE IF(tok==tk_eof)unexpectedeof();
|
||
/* case tk_from:
|
||
NextTok(); DoFrom(0); NextSemiNext(); break;
|
||
case tk_extract:
|
||
NextTok(); DoExtract(0); SemiNext(); break;
|
||
*/
|
||
}
|
||
|
||
// ---- Ž¡à ¡®âª ®¢ëå ¨¤¥â¨ä¨ª â®à®¢
|
||
dword DoId(dword expectedreturn)
|
||
byte s[80];
|
||
{
|
||
IF(tok2 == tk_colon){ // ¬¥âª ?
|
||
number = outptr-output+OptImageBase+OptBaseOfCode;
|
||
tok = tk_proc;
|
||
post = 0;
|
||
AddToTree(#string);
|
||
NextTok(); NextTok(); // ¯à®¯ãá⨬ ¨¤¥â¨ä¨ª â®à ¨ :
|
||
EAX=tokens;
|
||
}
|
||
ELSE IF(tok2 == tk_openbracket){ // ¢ë§®¢ ¯à®æ¥¤ãàë
|
||
wsprintfA(#s,"call %s;",#string);
|
||
tok = tk_undefproc;
|
||
number=0;
|
||
post=1;
|
||
AddToTree(#string);
|
||
NextTok();
|
||
DoParams();
|
||
Asm(#s);
|
||
EAX=expectedreturn;
|
||
}
|
||
ELSE{
|
||
undefinederror();
|
||
NextTok();
|
||
EAX=tk_int;
|
||
}
|
||
}
|
||
|
||
// ---- Ž¡à ¡®âª ¯ à ¬¥â஢ ¯à¨ ¢ë§®¢¥ ¯à®æ¥¤ãàë
|
||
DoParams()
|
||
{
|
||
IF(tok==tk_openbracket){
|
||
inptr2--;
|
||
DoParam();
|
||
NextTok();
|
||
}
|
||
ELSE expecting(tk_openbracket);
|
||
}
|
||
|
||
// ---- Ž¡à ¡®âª <Var> ...
|
||
DoVar(dword vartype)
|
||
dword next,vtok;
|
||
byte varName[2*IDLENGTH];
|
||
byte varName2[2*IDLENGTH];
|
||
{
|
||
next=1;
|
||
vtok=GetVarname(#varName);
|
||
NextTok();
|
||
IF(tok==tk_assign){
|
||
NextTok();
|
||
IF(tok2notstopper()){
|
||
DoExpr(#varName,vtok,vartype,"mov");
|
||
next=0;
|
||
}
|
||
ELSE GetIntoVar(#varName,vtok,vartype);
|
||
}
|
||
else IF(tok==tk_minusminus){ // Var--;
|
||
wsprintfA(#mapstr,"dec %s",#varName);
|
||
Asm(#mapstr);
|
||
}
|
||
else IF(tok==tk_plusplus){ // Var++;
|
||
wsprintfA(#mapstr,"inc %s",#varName);
|
||
Asm(#mapstr);
|
||
}
|
||
else IF(tok==tk_plusequals){ // Var+=Expr;
|
||
NextTok();
|
||
DoExpr(#varName,tk_var,vartype,"add");
|
||
next=1;
|
||
}
|
||
else IF(tok==tk_minusequals){ // Var-=Expr;
|
||
NextTok();
|
||
DoExpr(#varName,tk_var,vartype,"sub");
|
||
next=1;
|
||
}
|
||
else IF(tok==tk_andequals){ // Var&=Expr;
|
||
NextTok();
|
||
DoExpr(#varName,tk_var,vartype,"and");
|
||
next=1;
|
||
}
|
||
else IF(tok==tk_xorequals){ // Var^=Expr;
|
||
NextTok();
|
||
DoExpr(#varName,tk_var,vartype,"xor");
|
||
next=1;
|
||
}
|
||
else IF(tok==tk_orequals){ // Var|=Expr;
|
||
NextTok();
|
||
DoExpr(#varName,tk_var,vartype,"or");
|
||
next=1;
|
||
}
|
||
else if(tok==tk_swap){ // Var><Var;
|
||
NextTok();
|
||
GetVarname(#varName2);
|
||
IF(tok==tk_reg){
|
||
wsprintfA(#mapstr,"xchg %s,%s",#string,#varName);
|
||
Asm(#mapstr);
|
||
}
|
||
else if(tok==tk_var)&&(tok2notstopper()==0){
|
||
IF(vartype==tk_dword)||(vartype==tk_int){
|
||
wsprintfA(#mapstr,"xchg %s,eax",#varName);
|
||
Asm(#mapstr);
|
||
wsprintfA(#mapstr,"xchg %s,eax",#varName2);
|
||
Asm(#mapstr);
|
||
wsprintfA(#mapstr,"xchg %s,eax",#varName);
|
||
}
|
||
else IF(vartype==tk_word)||(vartype==tk_short){
|
||
wsprintfA(#mapstr,"xchg %s,ax",#varName);
|
||
Asm(#mapstr);
|
||
wsprintfA(#mapstr,"xchg %s,ax",#varName2);
|
||
Asm(#mapstr);
|
||
wsprintfA(#mapstr,"xchg %s,ax",#varName);
|
||
}
|
||
ELSE IF(vartype==tk_byte)||(vartype==tk_char){
|
||
wsprintfA(#mapstr,"xchg %s,al",#varName);
|
||
Asm(#mapstr);
|
||
wsprintfA(#mapstr,"xchg %s,al",#varName2);
|
||
Asm(#mapstr);
|
||
wsprintfA(#mapstr,"xchg %s,al",#varName);
|
||
}
|
||
Asm(#mapstr);
|
||
}
|
||
ELSE swaperror();
|
||
}
|
||
else IF(tok==tk_llequals){ // Var<<=Expr;
|
||
NextTok();
|
||
IF(tok == tk_number) wsprintfA(#mapstr,"shl %s,%d",#varName,DoConstMath());
|
||
ELSE{
|
||
Expression("cl",tk_reg,tk_byte);
|
||
wsprintfA(#mapstr,"shl %s,cl",#varName);
|
||
next=0;
|
||
}
|
||
Asm(#mapstr);
|
||
}
|
||
ELSE IF(tok==tk_rrequals){ // Var>>=Expr;
|
||
NextTok();
|
||
IF(tok == tk_number)wsprintfA(#mapstr,"shr %s,%d",#varName,DoConstMath());
|
||
ELSE{
|
||
Expression("cl",tk_reg,tk_byte);
|
||
wsprintfA(#mapstr,"shr %s,cl",#varName);
|
||
next=0;
|
||
}
|
||
Asm(#mapstr);
|
||
}
|
||
ELSE operatorexpected();
|
||
IF(next)NextSemiNext();
|
||
ELSE SemiNext();
|
||
}
|
||
|
||
// ---- Ž¡à ¡®âª ááë«®ª ¢¯¥à¥¤
|
||
DoPosts()
|
||
dword addhold,i;
|
||
{
|
||
i=0;
|
||
while(i<posts){
|
||
ECX=i<<2;
|
||
ESI=posttype+ECX;
|
||
EAX=DSDWORD[ESI];
|
||
ESI=postloc+ECX;
|
||
EBX=DSDWORD[ESI];
|
||
ESI=postnum+ECX;
|
||
ECX=DSDWORD[ESI];
|
||
IF(EAX==POST_DATA){
|
||
IF(DSDWORD[ECX+recpost]){
|
||
GetDword(EBX);
|
||
EAX=EAX+DSDWORD[ECX+recnumber]+OptImageBase+OptBaseOfCode+outptr-output;
|
||
}
|
||
ELSE{
|
||
GetDword(EBX);
|
||
EAX+=DSDWORD[ECX+recnumber];
|
||
}
|
||
SetDword(EBX,EAX);
|
||
}
|
||
ELSE IF(EAX==POST_CALL){
|
||
EAX=DSDWORD[ECX+recnumber]-OptImageBase-OptBaseOfCode-EBX; // <20> áç¥â ®â®á¨â¥«ì®£® ᬥ饨ï EAX-=addvalue;
|
||
EAX+=output;
|
||
SetDword(EBX,EAX-4);
|
||
}
|
||
ELSE IF(EAX==POST_LOC){
|
||
EAX=ECX; EAX-=OptImageBase;
|
||
EAX-=OptBaseOfCode; EAX-=EBX; // <20> áç¥â ®â®á¨â¥«ì®£® ᬥ饨ï EAX-=addvalue;
|
||
EAX+=output; SetDword(EBX,EAX-4);
|
||
}
|
||
ELSE IF(EAX==POST_API){
|
||
addhold = OptImageBase + DSDWORD[ECX+recmodline];
|
||
SetDword(EBX,addhold);
|
||
}
|
||
ELSE preerror("Bad post type\n");
|
||
i++;
|
||
}
|
||
}
|
||
|
||
// ---- <20>ëáâàë© ¯®¨áª ¯® â ¡«¨æ¥
|
||
// OUTPUT: EAX=No.& CARRYFLAG - success
|
||
dword FastSearch(dword probe,table)
|
||
byte ident[IDLENGTH];
|
||
{
|
||
$PUSH ECX,ESI,EDI,EDX
|
||
lstrcpyA(#ident,probe);
|
||
CharUpperA(#ident);
|
||
lstrlenA(#ident);
|
||
EDX=EAX-1;
|
||
$JZ HET // ident ¨§ ®¤®£® ᨬ¢®«
|
||
EBX=0;
|
||
BL=ident;//[0]; // <20>஢¥à¨¬ ¯¥à¢ë© ᨬ¢®« ¢ ident
|
||
BL-='A';
|
||
$JC HET // <20>¥ ¡ãª¢
|
||
$CMP BL,'Z'-'A';
|
||
$JA HET // ¨ ¥ 'A'...'Z'
|
||
EAX=0;
|
||
EBX=EBX<<2+table;
|
||
EDI=DSDWORD[EBX]; // ‚§ïâì ¤à¥á § ¯¨á¨ ¨§ table
|
||
$OR EDI,EDI;
|
||
$JE HET // <20>¥â § ¯¨á¨ ¤«ï â ª®£® ident...
|
||
TRY0:
|
||
AH=DSBYTE[EDI];
|
||
EDI++; // <20>®¬¥à § ¯¨á¨ ¨§ table ¨ áâப㠢 table
|
||
TRY1:
|
||
ESI=#ident+1;
|
||
ECX=EDX; // ‚§ïâì ident ¤«¨ã - 1
|
||
$REPE $CMPSB;
|
||
$JNE NXT // ‘à ¢¨¬ á § ¯¨áìî ¢ table
|
||
$JCXZ YES1 // ‘®¢¯ «¨ ¯® ¤«¨¥ probe
|
||
NXT:
|
||
EDI--;
|
||
LOOK:
|
||
AL=DSBYTE[EDI];
|
||
EDI++;
|
||
$OR AL,AL;
|
||
$JE TRY0 // <20>஢¥à¨¬ á«¥¤ãîéãî § ¯¨áì
|
||
$CMP AL,'/';
|
||
$JE NEAR TRY1 // <20>஢¥à¨¬ ALIAS
|
||
$CMP AL,_END;
|
||
$JE NEAR HET // Š®¥æ â ¡«¨æë - ¢ë室
|
||
GOTO LOOK;
|
||
HET:
|
||
$CLC;
|
||
GOTO EX; // ident ¥ ©¤¥ ¢ table
|
||
YES1:
|
||
$CMP DSBYTE[EDI],0;
|
||
$JZ YES;
|
||
$CMP DSBYTE[EDI],_END;
|
||
$JZ YES;
|
||
$CMP DSBYTE[EDI],'/';
|
||
$JZ YES;
|
||
GOTO NXT;
|
||
YES:
|
||
AL=AH;
|
||
AH=0;
|
||
$STC // ident ©¤¥ ¢ table
|
||
EX:
|
||
$POP EDX,EDI,ESI,ECX;
|
||
}
|
||
|
||
// ---- ‚뢮¤ áâ â¨á⨪¨ ¯® ª®¬¯¨«ï樨
|
||
FinishMapfile()
|
||
{
|
||
fprint(mapfile,"\n");
|
||
DisplayTree();
|
||
fprint(mapfile,"Component Sizes:\n");
|
||
PrintMemsizes(mapfile);
|
||
wsprintfA(#mapstr,"Run file size: %ld bytes\n",runfilesize);
|
||
fprint(mapfile,#mapstr);
|
||
wsprintfA(#mapstr,"\nEND OF MAP FILE FOR %s.%s\n\n",#rawfilename,"EXE");
|
||
fprint(mapfile,#mapstr);
|
||
_lclose(mapfile);
|
||
mapfile=0;
|
||
list=0;
|
||
}
|
||
|
||
// ---- ‚뢮¤ ¢ ä ©«
|
||
fprint(dword handle,str)
|
||
{
|
||
_lwrite(handle,str,lstrlenA(str));
|
||
}
|
||
|
||
// ---- ‚뤥«¥¨¥ ¯ ¬ï⨠¤«ï ª®¬¯¨«ï樨. <20>ਠ¥ã¤ ç¥ ¢ë室 ¨§ ª®¬¯¨«ïâ®à
|
||
GetMem()
|
||
{
|
||
output=LocalAlloc(0x40,MAXDATA);
|
||
IF(EAX==NULL)outofmemory2();
|
||
LocalUnlock(output);
|
||
outptr=output;
|
||
startptr=output;
|
||
postloc=LocalAlloc(0x40,MAXPOSTS*4);
|
||
IF(EAX==NULL)outofmemory2();
|
||
postnum=LocalAlloc(0x40,MAXPOSTS*4);
|
||
IF(EAX==NULL)outofmemory2();
|
||
posttype=LocalAlloc(0x40,MAXPOSTS);
|
||
IF(EAX==NULL)outofmemory2();
|
||
dbginfo=LocalAlloc(0x40,MAXDBGS*dbg_size);
|
||
IF(EAX==NULL)outofmemory2();
|
||
dbgs=dbginfo;
|
||
}
|
||
|
||
// ---- —⥨¥ ¤¢®©®£® á«®¢
|
||
dword GetDword(dword ptr)
|
||
{
|
||
ESI><ptr;
|
||
$LODSD;
|
||
ESI><ptr;
|
||
}
|
||
|
||
// ---- ˆ¨æ¨ « § æ¨ï ᯨáª
|
||
// „«ï keylist = {"ZAK",0,"AAD",0,"ABC",0,"BAR",0,"AAA",0,"ZZ",0,"BAC",_END};
|
||
// áä®à¬¨àã¥âáï áâàãªâãà ¢ ¯ ¬ï⨠᫥¤ãî饣® ¢ ¤ :
|
||
// table
|
||
// +-----+
|
||
// | 'A' | ---> db 4,'AA',1,'AD',2,'BC',_END
|
||
// +-----+
|
||
// | 'B' | ---> db 6,'AC',3,'AR",_END
|
||
// +-----+
|
||
// | ... |
|
||
// +-----+
|
||
// | 'Z' | ---> db 0,'AK',5,'Z',_END
|
||
// +-----+
|
||
InitList(dword keylist,table)
|
||
dword ptr;
|
||
{
|
||
ptr=LocalAlloc(0x40,SORTSIZE*256);
|
||
IF(EAX==NULL)outofmemory2();
|
||
EDI><EAX; //ptr;
|
||
ESI=keylist;
|
||
ECX=0;
|
||
BL=0;
|
||
// ‡ ¥á¥¨¥ áâப ¨§ keylist ¢ ptr
|
||
for(;;){
|
||
for(;;){
|
||
$PUSH EDI;
|
||
IF(DSBYTE[ESI]!='-')BREAK;
|
||
ESI+=2;
|
||
BL++;
|
||
$POP EDI;
|
||
}
|
||
AL=BL;
|
||
$STOSB // ‘®åà ¨¬ ¯®à浪®¢ë© ®¬¥à áâப¨
|
||
for(;;){
|
||
$LODSB // ‘ª®¯¨à㥬 áâப㠢 ptr
|
||
IF(AL<' ')BREAK;
|
||
$STOSB;
|
||
}
|
||
IF(AL==_END)BREAK;
|
||
$STOSB;
|
||
$POP EDI;
|
||
BL++;
|
||
EDI+=SORTSIZE;
|
||
ECX++;
|
||
}
|
||
ESI=ptr;
|
||
$PUSH ECX // Š®¯¨à®¢ ¨¥ ¢ ptr § ª®ç¥®. ‘®åà ¨¬ ª®«-¢® áâப
|
||
ECX--;
|
||
IF(NOTZEROFLAG){// ‚ᥣ® ®¤ áâப ? - á®àâ¨à®¢ª ¥ ã¦
|
||
// ‘®àâ¨à®¢ª áâப ¢ ptr
|
||
loop(ECX){
|
||
$PUSH ESI,ECX;
|
||
EDI=ESI+SORTSIZE;
|
||
loop(ECX){
|
||
$PUSH ECX,ESI,EDI;
|
||
ECX=SORTSIZE;
|
||
ESI++;
|
||
EDI++;
|
||
$REPE $CMPSB;
|
||
$POP EDI,ESI;
|
||
IF(NOTCARRYFLAG){ // ¯à®¢¥à¨â ãá«®¢¨¥ ????????????‘à ¢¥¨¥ ¤¢ãå áâப
|
||
EAX=ESI;
|
||
EDX=EDI;
|
||
EDI=#Buffer16;
|
||
ECX=SORTSIZE/4; // <20> 諨 ¬¥ìèãî áâபã
|
||
$REP $MOVSD;
|
||
ESI=EDX;
|
||
EDI=EAX;
|
||
ECX=SORTSIZE/4; // -¯®¬¥ï¥¬ ¬¥áâ ¬¨
|
||
$REP $MOVSD;
|
||
ESI=#Buffer16;
|
||
EDI=EDX;
|
||
ECX=SORTSIZE/4;
|
||
$REP $MOVSD;
|
||
ESI=EAX;
|
||
EDI=EDX;
|
||
}
|
||
EDI+=SORTSIZE;
|
||
$POP ECX;
|
||
}
|
||
$POP ECX,ESI;
|
||
ESI+=SORTSIZE;
|
||
}
|
||
}
|
||
// ‘®àâ¨à®¢ª ¢¢¥¤¥ëå áâப ¢ ¡ãä¥à¥ ptr § ª®ç¥
|
||
EDI=table;
|
||
ECX=26;
|
||
EAX=0;
|
||
$REP $STOSD; // Ž¡ã«¥ ¥ table
|
||
$POP ECX;
|
||
ESI=ptr;
|
||
EDI=ESI;
|
||
$PUSH ESI;
|
||
GOTO L42; // ”®à¬ à㥬 â ¡«¨æã
|
||
loop(ECX){
|
||
$PUSH ESI;
|
||
IF(AH!=DSBYTE[ESI+1]){
|
||
EDI--;
|
||
AL=_END;
|
||
$STOSB // Žâ¬¥â¨¬ ª®¥æ â ¡«¨æë ¤«ï ¤ ®£® ᨬ¢®« ¢ AH
|
||
L42:
|
||
AH=DSBYTE[ESI+1];
|
||
EBX=0;
|
||
BL=AH;
|
||
BL-='A';
|
||
EBX=EBX<<2+table; //¤ «ìè¥ ¨¤¥â ªà å
|
||
DSDWORD[EBX]=EDI; // ‡ ¯¨áì 㪠§ â¥«ï ¢ table
|
||
}
|
||
$MOVSB // ‡ ¯®¬¨¬ ¯®à浪®¢ë© ®¬¥à áâப¨
|
||
ESI++; // <20>யã᪠¯¥à¢®£® ᨬ¢®« - ® 㦥 ¨§¢¥áâ¥
|
||
do{
|
||
$LODSB;
|
||
$STOSB;
|
||
}while(AL!=0); // Š®¯¨à㥬 áâப㠢 table
|
||
$POP ESI;
|
||
ESI+=SORTSIZE;
|
||
} // <20>த®«¦¨¬ ¤«ï á«¥¤ãî饩 áâப¨
|
||
EDI--;
|
||
AL=_END;
|
||
$STOSB // table áä®à¬¨à®¢ . Žâ¬¥â¨¬ ª®¥æ
|
||
}
|
||
|
||
// ---- <20>஢¥àª æ¨äàã
|
||
dword IsNumber(dword ch)
|
||
{
|
||
IF(ch<'0')||(ch>'9')EAX=0;
|
||
ELSE EAX=1;
|
||
}
|
||
|
||
// ---- —⥨¥ ¢å®¤®£® ä ©« ¢ ¡ãä¥à
|
||
long LoadInputfile(dword infile)
|
||
dword fhandle, size;
|
||
{
|
||
fhandle=_lopen(infile,0);
|
||
IF(EAX==-1){
|
||
GetLastError();
|
||
return(-2);
|
||
}
|
||
EAX=GetFileSize(EAX,0);
|
||
IF(EAX==-1){
|
||
unabletoopen(infile);
|
||
_lclose(fhandle);
|
||
return(-1);
|
||
}
|
||
size=EAX;
|
||
input=LocalAlloc(0x40,EAX+2); // ‡ ¯®«¥ ï ã«ï¬¨
|
||
IF(EAX==NULL){
|
||
preerror("Not enough memory for input buffer");
|
||
_lclose(fhandle);
|
||
RETURN(-1);
|
||
}
|
||
EAX=_lread(fhandle,input,size);
|
||
IF(EAX!=size){
|
||
preerror("File Read error");
|
||
_lclose(fhandle);
|
||
RETURN(-1);
|
||
}
|
||
_lclose(fhandle);
|
||
inptr = input;
|
||
inptr2 = input;
|
||
endoffile = 0; // <20> ç «¥ ä ©«
|
||
return(0);
|
||
}
|
||
|
||
// ---- Ž¡à ¡®âª ¬ ªà®á
|
||
Macros()
|
||
byte holdcha;
|
||
byte s[STRLEN],s2[STRLEN];
|
||
{
|
||
IF(makemapfile){
|
||
fprint(mapfile,#string);
|
||
fprint(mapfile,"\n");
|
||
}
|
||
holdcha=cha2;
|
||
$PUSH linenum2,inptr2,number,tok2,tok,input,inptr,currmod,
|
||
linenumber,endoffile,displaytokerrors;
|
||
lstrcpyA(#s,#string);
|
||
lstrcpyA(#s2,#string2);
|
||
input=#s;
|
||
inptr=input;
|
||
inptr2=input;
|
||
endoffile=0; // <20> ç «¥ ä ©«
|
||
NextChar();
|
||
cha2=cha;
|
||
inptr2=inptr;
|
||
linenum2 = 1;
|
||
NextTok();
|
||
for(;;){
|
||
IF(tok==tk_eof)BREAK;
|
||
DoCommand();
|
||
}
|
||
lstrcpyA(#string,#s);
|
||
lstrcpyA(#string2,#s2);
|
||
$POP displaytokerrors,endoffile,linenumber,currmod,inptr,input,tok,tok2,
|
||
number,inptr2,linenum2;
|
||
cha2=holdcha;
|
||
}
|
||
|
||
// ---- Žç¨á⪠ᯨ᪠«®ª «ìëå ¯¥à¥¬¥ëå
|
||
KillLocals()
|
||
dword ptr1,ptr2;
|
||
{
|
||
ptr2=locallist;
|
||
WHILE( ptr2 != NULL ){
|
||
ptr1=ptr2;
|
||
IF( DSDWORD[EAX+localtok]==tk_locallabel) // <20>஢¥àª ¥§ ªàëâë¥ ¬¥âª¨
|
||
localunresolved(EAX+localid);
|
||
EAX=ptr2;
|
||
ptr2=DSDWORD[EAX+localnext];
|
||
GlobalFree(ptr1);
|
||
}
|
||
locallist = NULL;
|
||
paramsize = 0;
|
||
localsize = 0;
|
||
}
|
||
|
||
// ---- ‡ ¢¥à襨¥ ⥫ ¯à®æ¥¤ãàë
|
||
LeaveProc()
|
||
{
|
||
IF(localsize > 0)Asm("leave");
|
||
ELSE{
|
||
IF(paramsize > 0)Asm("pop ebp");
|
||
}
|
||
IF( current_proc_type == cpt_far ){
|
||
IF(paramsize == 0)EAX="retf";
|
||
ELSE{
|
||
wsprintfA(#mapstr,"retf %d;",paramsize);
|
||
EAX=#mapstr;
|
||
}
|
||
}
|
||
ELSE{
|
||
IF(paramsize == 0)EAX="ret";
|
||
ELSE{
|
||
wsprintfA(#mapstr,"ret %d;",paramsize);
|
||
EAX=#mapstr;
|
||
}
|
||
}
|
||
Asm(EAX);
|
||
}
|
||
|
||
// ---- —⥨¥ ®ç¥à¥¤®£® ᨬ¢®« ¨§ ¢å®¤®£® ¡ãä¥à
|
||
NextChar()
|
||
{
|
||
ESI><inptr;
|
||
// EAX=0;
|
||
$LODSB
|
||
cha=AL;
|
||
inptr><ESI; // ‡ ¯®¬¨¬ ⥪ãéãî ¯®§ æ¨î ¢ ¡ãä¥à¥
|
||
IF(AL==0)||(AL==26)endoffile = 1;
|
||
IF(AL == 13){ // CR
|
||
linenumber++; // Ž¡ à㦥 ª®¥æ áâப¨
|
||
totallines++;
|
||
ShowSrcLine();
|
||
NextChar();
|
||
}
|
||
}
|
||
|
||
// ---- <20>®«ã票¥ ®ç¥à¥¤®£® token
|
||
void NextTok()
|
||
{
|
||
inptr = inptr2;
|
||
linenumber = linenum2;
|
||
cha = cha2;
|
||
displaytokerrors = 1;
|
||
TokScan(#tok,#type,#src,#post,#string,#number);
|
||
IF(linenumber!=linenum2){ // <20>®¢ ï áâப ?
|
||
IF(dbg){ // ’ॡã¥âáï ®â« ¤ª ?
|
||
$PUSH ESI
|
||
ESI=dbgs*dbg_size+dbginfo;
|
||
EAX=currmod;
|
||
$CMP EAX,DSDWORD[ESI+dbg_mod];
|
||
$JNE DIFF // ’ॡã¥âáï § ¯®¬¨âì ¨ä®à¬ æ¨î ¯® ®¢®© áâப¥
|
||
EAX=linenumber;
|
||
$CMP EAX,DSDWORD[ESI+dbg_line]
|
||
$JNE DIFF // ’ॡã¥âáï § ¯®¬¨âì ¨ä®à¬ æ¨î ¯® ®¢®© áâப¥
|
||
DSDWORD[ESI+dbg_line]=linenumber; // ‡ ¯®¬¨¬ ®¬¥à áâப¨
|
||
GOTO ALL;
|
||
DIFF:
|
||
dbgs++;
|
||
ESI+=dbg_size;
|
||
DSDWORD[ESI+dbg_mod]=currmod;
|
||
DSDWORD[ESI+dbg_line]=linenumber;
|
||
DSDWORD[ESI+dbg_loc]=outptr;
|
||
ALL:
|
||
$POP ESI
|
||
}
|
||
}
|
||
inptr2 = inptr;
|
||
linenum2 = linenumber;
|
||
cha2 = cha;
|
||
displaytokerrors = 0; // <20>¥§ ¢ë¢®¤ á®®¡é¥¨© ®¡ ®è¨¡ª å
|
||
TokScan(#tok2,#type2,#src2,#post2,#string2,#number2);
|
||
linenumber = linenum2;
|
||
}
|
||
|
||
// ---- ‘«¥¤ãî騩 token § ªàëâë© ;
|
||
NextSemiNext ()
|
||
{
|
||
NextTok();
|
||
SemiNext();
|
||
}
|
||
|
||
// ---- ‡ ªàë¢ î騩 ; ¨ token § ¨¬
|
||
SemiNext ()
|
||
{
|
||
IF(tok != tk_semicolon)expected(';');
|
||
NextTok();
|
||
}
|
||
|
||
// ---- ‡ ¯¨áì ¡ ©â ¢ CODE
|
||
OP()
|
||
{
|
||
EDI><outptr;
|
||
$STOSB;
|
||
outptr><EDI;
|
||
}
|
||
|
||
// ---- ‡ ¯¨áì á«®¢ ¢ CODE
|
||
OUTWORD()
|
||
{
|
||
EDI><outptr;
|
||
$STOSW;
|
||
outptr><EDI;
|
||
}
|
||
// ---- ‡ ¯¨áì ¤¢®©®£® á«®¢ ¢ CODE
|
||
OUTDWORD()
|
||
{
|
||
EDI><outptr;
|
||
$STOSD;
|
||
outptr><EDI;
|
||
}
|
||
|
||
// ---- ‚뢮¤ à §¬¥à®¢ CODE&DATA
|
||
PrintMemsizes(dword handle)
|
||
{
|
||
wsprintfA(#mapstr,"Code:%u bytes,\tPost: %u bytes\n",outptr-output,postsize);
|
||
fprint(handle,#mapstr);
|
||
}
|
||
|
||
// ---- Ž¡à ¡®âª ¯à®æ¥¤ãà
|
||
Proc(dword proc_type)
|
||
{
|
||
current_proc_type = proc_type;
|
||
tok = tk_proc;
|
||
number = outptr-output+OptImageBase+OptBaseOfCode;
|
||
ESI=treeptr;
|
||
DSDWORD[ESI+rectok] = tok;
|
||
DSDWORD[ESI+recnumber] = number;
|
||
DSDWORD[ESI+recpost] = 0;
|
||
NextTok();
|
||
expecting(tk_openbracket);
|
||
IF(tok!=tk_closebracket)DeclareParams();
|
||
NextTok();
|
||
IF(paramsize > 0)Asm("push ebp;mov ebp,esp");
|
||
IF( tok != tk_openbrace )DeclareLocals();
|
||
DoBlock(); // Ž¡à ¡®âª ⥫ ¯à®æ¥¤ãàë { ... }
|
||
LeaveProc();
|
||
KillLocals();
|
||
}
|
||
|
||
// ---- ‡ ¯¨áì ¤¢®©®£® á«®¢ ¯® ¤à¥áã
|
||
SetDword(dword ptr, value)
|
||
{
|
||
EDI><ptr;
|
||
EAX><value;
|
||
$STOSD;
|
||
EDI><ptr;
|
||
EAX><value;
|
||
}
|
||
|
||
// ---- ‚뢮¤ áâப¨ ¨á室®£® ⥪áâ
|
||
ShowSrcLine()
|
||
byte str[STRLEN];
|
||
{
|
||
IF(list){
|
||
ESI><inptr;
|
||
$PUSH EDI,ESI;
|
||
ESI++;
|
||
EDI=#str;
|
||
for(;;){
|
||
$LODSB;
|
||
IF(AL==13)||(AL==0)BREAK;
|
||
$STOSB;
|
||
}
|
||
AL=0;
|
||
$STOSB
|
||
$POP ESI,EDI;
|
||
ESI><inptr;
|
||
IF(displaytokerrors){
|
||
fprint(mapfile,#str);
|
||
fprint(mapfile,"\n");
|
||
}
|
||
// AL=cha;
|
||
}
|
||
}
|
||
|
||
// ---- ‘®§¤ ¨¥ ä ©« áâ â¨á⨪¨
|
||
StartMapfile()
|
||
byte mapfilename[80];
|
||
{
|
||
wsprintfA(#mapfilename,"%s.MAP",#rawfilename);
|
||
mapfile=_lcreat(#mapfilename,0x1000);
|
||
IF(EAX==0){
|
||
errmsg();
|
||
WRITESTR("Unable to create map file");
|
||
WRITESTR(#mapfilename);
|
||
ExitProcess(e_cannotopenmapfile);
|
||
}
|
||
wsprintfA(#mapstr,"MAP FILE FOR %s.%s\n\n",#rawfilename,"EXE");
|
||
fprint(mapfile,#mapstr);
|
||
}
|
||
|
||
// ---- ˆ¨æ¨ «¨§ æ¨ï ᯨ᪮¢ १¥à¢ëå á«®¢
|
||
TokInit()
|
||
{
|
||
InitList(#Mnemonics,#St_Mnemonics);
|
||
InitList(#Registers,#St_Registers);
|
||
InitList(#Directives,#St_Directives);
|
||
InitList(#Sizes,#St_Sizes);
|
||
}
|
||
|
||
// ---- ‚®§¢à é ¥â à §¬¥à ¤«ï § ¤ ®£® ⨯ ¤ ëå
|
||
dword TypeSize(dword vartype)
|
||
char holdstr[60];
|
||
{
|
||
IF(vartype==tk_void) RETURN(0);
|
||
IF(vartype==tk_char)||(vartype==tk_byte) RETURN(1);
|
||
IF(vartype==tk_short)||(vartype==tk_word) RETURN(2);
|
||
IF(vartype==tk_dword)||(vartype==tk_int) RETURN(4);
|
||
wsprintfA(#holdstr,"vartype=%d in TypeSize()",vartype);
|
||
internalerror(holdstr);
|
||
return(-1);
|
||
}
|
||
|
||
// ---- <20>யã᪠¯à®¡¥«®¢ ¨ â ¡ã«ï権
|
||
WhiteSpaces()
|
||
{
|
||
for(;;){
|
||
AL=cha;
|
||
IF(AL!=32)&&(AL!=10)&&(AL!=9)BREAK;
|
||
NXT:
|
||
NextChar();
|
||
}
|
||
IF(AL == 13){ // CR
|
||
linenumber++; // Ž¡ à㦥 ª®¥æ áâப¨
|
||
totallines++;
|
||
ShowSrcLine();
|
||
GOTO NXT;
|
||
}
|
||
}
|
||
|
||
// ---- ‚뢮¤ stdout
|
||
WRITESTR()
|
||
{
|
||
fprint(stdout,EAX);
|
||
}
|
||
|
||
//===== Ž¡à ¡®âª ®è¨¡®ª
|
||
// ----
|
||
datatype_expected()
|
||
{
|
||
preerror("byte, word, short, char, dword or int expected");
|
||
}
|
||
|
||
// ----
|
||
errmsg()
|
||
{
|
||
WRITESTR("\nERROR> ");
|
||
}
|
||
|
||
// ----
|
||
expected(dword ch)
|
||
byte hstr[80];
|
||
{
|
||
wsprintfA(#hstr,"'%c' expected",ch);
|
||
preerror(#hstr);
|
||
}
|
||
|
||
// ----
|
||
expectederror(dword str)
|
||
byte hstr[80];
|
||
{
|
||
IF(displaytokerrors){
|
||
wsprintfA(#hstr,"'%s' expected",str);
|
||
preerror(#hstr);
|
||
}
|
||
}
|
||
|
||
// ---- <20>஢¥àª ⥪ã饣® token § ¤ ë© â¨¯
|
||
expecting(dword want)
|
||
{
|
||
if(want!=tok){
|
||
IF(want==tk_closebracket) expected(')');
|
||
else IF(want==tk_openbracket) expected('(');
|
||
ELSE IF(want==tk_semicolon) expected(';');
|
||
ELSE IF(want==tk_colon) expected(':');
|
||
ELSE IF(want==tk_openblock) expected('[');
|
||
ELSE IF(want==tk_closeblock) expected(']');
|
||
ELSE IF(want==tk_openbrace) expected('{');
|
||
ELSE IF(want==tk_closebrace) expected('}');
|
||
ELSE IF(want==tk_comma) expected(',');
|
||
ELSE preerror("expecting a different token");
|
||
}
|
||
NextTok();
|
||
}
|
||
|
||
// ----
|
||
/*idalreadydefined()
|
||
byte holdstr[80];
|
||
{
|
||
wsprintfA(#holdstr,"identifier %s already defined",#string);
|
||
preerror(#holdstr);
|
||
NextTok();
|
||
} */
|
||
|
||
// ----
|
||
idexpected()
|
||
{
|
||
preerror("undefined 'identifier' expected");
|
||
}
|
||
|
||
// ---- ‚ãâà¥ïï ®è¨¡ª ª®¬¯¨«ïâ®à
|
||
internalerror(dword str)
|
||
{
|
||
error++;
|
||
wsprintfA(#mapstr,"%s(%d)#%d> *** SERIOUS COMPILER INTERNAL ERROR ***\n>%s.\n",
|
||
#currentfilename,linenumber,error,str);
|
||
WRITESTR(#mapstr);
|
||
wsprintfA(#mapstr,"STRING:%s\n",#string);
|
||
WRITESTR(#mapstr);
|
||
wsprintfA(#mapstr,"TOK:%d\tPOST:%d\tnumber:%ld\n",tok,post,number);
|
||
WRITESTR(#mapstr);
|
||
wsprintfA(#mapstr,"STRING2:%s\n",#string2);
|
||
WRITESTR(#mapstr);
|
||
wsprintfA(#mapstr,"TOK2:%d\tPOST2:%d\tnumber2:%ld\n",tok2,post2,number2);
|
||
WRITESTR(#mapstr);
|
||
WRITESTR("Oh no.\n");
|
||
IF(makemapfile)CloseHandle(mapfile);
|
||
ExitProcess(e_internalerror);
|
||
}
|
||
|
||
// ----
|
||
localunresolved(dword str)
|
||
byte holdstr[80];
|
||
{
|
||
wsprintfA(#holdstr,"local jump label '%s' unresolved",str);
|
||
preerror(#holdstr);
|
||
}
|
||
|
||
// ----
|
||
maxwordpostserror ()
|
||
{
|
||
preerror("maximum number of word post location references exceeded");
|
||
}
|
||
|
||
// ----
|
||
/*notyet()
|
||
{
|
||
preerror("specified syntax not handled in this version!!!");
|
||
} */
|
||
// ----
|
||
numexpected()
|
||
{
|
||
preerror("'number' expected");
|
||
}
|
||
|
||
// ----
|
||
operatorexpected ()
|
||
{
|
||
preerror("operator identifier expected");
|
||
}
|
||
// ----
|
||
outofmemory()
|
||
{
|
||
preerror("Compiler out of memory");
|
||
IF( makemapfile )CloseHandle(mapfile);
|
||
ExitProcess(e_outofmemory);
|
||
}
|
||
|
||
// ----
|
||
outofmemory2()
|
||
{
|
||
errmsg();
|
||
WRITESTR("Not enough memory for the compiler's buffers.\n");
|
||
ExitProcess(e_outofmemory );
|
||
}
|
||
|
||
// ---- Žè¨¡ª ¢ ⥪ã饩 áâப¥: ¯®ª § ®¬¥à áâப¨ ¨ ¨¬¥¨ ä ©«
|
||
preerror(dword str)
|
||
{
|
||
IF(error < maxerrors){
|
||
error++;
|
||
wsprintfA(#mapstr,"%s (%d)#%d> %s.\n",#currentfilename,linenumber,error,str);
|
||
WRITESTR(#mapstr);
|
||
IF(makemapfile)fprint(mapfile,#mapstr);
|
||
}
|
||
ELSE toomanyerrors();
|
||
}
|
||
|
||
// ----
|
||
/*regnameerror()
|
||
{
|
||
preerror("register name cannot be used as an identifier");
|
||
NextTok();
|
||
} */
|
||
|
||
// ---- ’ॡã¥âáï áâப
|
||
stringexpected()
|
||
{
|
||
preerror("'string' expected");
|
||
}
|
||
|
||
// ---- <20>¥¤®¯ãáâ¨¬ë© ®¯¥à ¤ ¤«ï swap
|
||
swaperror ()
|
||
{
|
||
preerror("invalid or incompatable swap item");
|
||
}
|
||
|
||
// ---- <20>।¥«ì®¥ ç¨á«® ®è¨¡®ª - ¢ë室
|
||
toomanyerrors()
|
||
{
|
||
IF( makemapfile )CloseHandle(mapfile);
|
||
ExitProcess( e_toomanyerrors );
|
||
}
|
||
|
||
// ----
|
||
unabletoopen(dword str)
|
||
byte hstr[80];
|
||
{
|
||
wsprintfA(#hstr,"unable to open file '%s'",str);
|
||
preerror(#hstr);
|
||
}
|
||
|
||
// ----
|
||
undefinederror()
|
||
byte holdstr[80];
|
||
{
|
||
wsprintfA(#holdstr,"'%s' undefined",#string);
|
||
preerror(holdstr);
|
||
}
|
||
|
||
// ----
|
||
unexpectedeof()
|
||
{
|
||
preerror("unexpected END OF FILE");
|
||
}
|
||
// ----
|
||
warning(dword str)
|
||
{
|
||
wsprintfA(#mapstr,"%s (%d)Warning> %s.\n",#currentfilename,linenumber,str);
|
||
WRITESTR(#mapstr);
|
||
IF(makemapfile)fprint(mapfile,#mapstr);
|
||
}
|
||
/*
|
||
void TestProc()
|
||
char buf[20];
|
||
{
|
||
$pushad
|
||
wsprintfA(#buf,"%08X\n",SSDWORD[EBP+4]);
|
||
WRITESTR(#buf);
|
||
$popad
|
||
} */
|