📄 gvma.cpp
字号:
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include <stdlib.h>
#define FILENOTFOUND 1
#define NOPARAMS 2
#define FILEEMPTY 3
#define EMPTY 0
#define TOKENNUM 1
#define TOKENALPH 2
#define TOKENLABEL 3
#define TOKENCOMMENT 4
#define TOKENADD 5
#define TOKENSTRING 6
#define TOKENFLOAT 7
#define TOKENCHAR 8
#define ERRALPHINNUM -1
#define ERRCOLON -2
#define ERRMINUS -3
#define ERRCOMMENT -4
#define ERRINVALIDCHAR -5
#define ERRSTRING -6
#define ERRPERIOD -7
#define KEYEMPTY 0
#define KEYINT 1
#define KEYBYTE 2
#define KEYFLOAT 3
int ERRMSG = 0;
int nkeywords=0;
union CONVERTDOUBLE
{
char bytes[sizeof(double)];
double data;
};
union CONVERTINT
{
char bytes[sizeof(int)];
int data;
};
class KEYWORD
{
public:
char *token;
int type;
char bvalue;
int value;
double fvalue;
KEYWORD()
{
++nkeywords;
type=KEYEMPTY;
token=NULL;
value=0;
fvalue=0;
bvalue=0;
}
KEYWORD(char *token, int value)
{
++nkeywords;
type=KEYINT;
KEYWORD::token=token;
KEYWORD::value=value;
fvalue=0;
bvalue=0;
}
KEYWORD(char *token, double fvalue)
{
++nkeywords;
type=KEYFLOAT;
KEYWORD::token=token;
KEYWORD::fvalue=fvalue;
value=0;
bvalue=0;
}
KEYWORD(char *token, char bvalue)
{
++nkeywords;
type=KEYBYTE;
KEYWORD::token=token;
KEYWORD::bvalue=bvalue;
value=0;
fvalue=0;
}
};
class LUSAGE
{
public:
int point;
LUSAGE *next;
LUSAGE(int point)
{
LUSAGE::point=point;
next=NULL;
}
~LUSAGE()
{
if(next!=NULL) delete next;
}
};
class LFIXUP
{
public:
LUSAGE *fixes;
char token[256];
int address;
LFIXUP *next;
LFIXUP(char *token,int address)
{
next=NULL;
fixes=NULL;
LFIXUP::address=address;
strcpy(LFIXUP::token,token);
}
~LFIXUP()
{
if(fixes!=NULL) delete fixes;
if(next!=NULL) delete next;
}
};
class LABELFIX
{
public:
LFIXUP *listfixup;
LABELFIX()
{
listfixup=NULL;
}
void addpoint(LFIXUP *fix, int pointtoadd)
{
if(fix==NULL) return;
if(fix->fixes==NULL)
{
fix->fixes=new LUSAGE(pointtoadd);
return;
}
LUSAGE *working=fix->fixes;
while(1)
{
if(working->next==NULL)
{
working->next=new LUSAGE(pointtoadd);
return;
}
working=working->next;
}
}
int fixup(unsigned char *code)
{
if(listfixup==NULL) return 0;
CONVERTINT writeint;
int writeiterate;
LFIXUP *working=listfixup;
LUSAGE *crawler=NULL;
while(1)
{
if(working->fixes!=NULL)
{
crawler=working->fixes;
while(1)
{
if(working->address==-1)
{
std::cout << "Address used without label : " << working->token << std::endl;
return -1;
}
writeint.data=working->address;
for(writeiterate=0;writeiterate<sizeof(int);++writeiterate)
{
code[crawler->point+writeiterate]=writeint.bytes[writeiterate];
}
if(crawler->next==NULL) break;
crawler=crawler->next;
}
}
if(working->next==NULL) return 0;
working=working->next;
}
}
int findaddress(char *label)
{
LFIXUP *working=listfixup;
if(working==NULL) return -1;
while(1)
{
if(strcmp(working->token,label)==0)
{
return working->address;
}
if(working->next==NULL) return -1;
working=working->next;
}
}
int addusage(char *label, int address)
{
//Get rid of the : and &
char *token=label+1;
//Search for a label that matches our address
//If not found, create a new label with
//address of -1 for use later :D
//If we have no entries then
//make one and stop :D
if(listfixup==NULL)
{
listfixup=new LFIXUP(token,-1);
addpoint(listfixup,address);
return 0;
}
//Search for an instance for fixup
//If not found, add a new entry
LFIXUP *working=listfixup;
while(1)
{
if(strcmp(working->token,token)==0)
{
//Found our label, let's add a point
if(working->address==-1)
{
addpoint(working,address);
return 0;
}
else return working->address;
}
if(working->next==NULL)
{
//Make a new entry since one is not found
working->next = new LFIXUP(token,-1);
addpoint(working->next,address);
return 0;
}
working=working->next;
}
}
int addlabel(char *label,int address)
{
//Get rid of the : and *
char *token=label+1;
//If we have no entries then just make this label the first one
//and exit addlabel :)
if(listfixup==NULL)
{
listfixup =new LFIXUP(token, address);
return 0;
}
//Search for an instance for fixup
//If not found, add a new entry
LFIXUP *working=listfixup;
while(1)
{
if(strcmp(working->token,token)==0)
{
//If our label has been referenced, but has no address
//reference our label with this address
if(working->address==-1)
{
working->address=address;
return 0;
}
else return -1;
}
if(working->next==NULL) break;
working=working->next;
}
working->next = new LFIXUP(token,address);
return 0;
}
~LABELFIX()
{
if(listfixup!=NULL) delete listfixup;
}
};
class TOKEN
{
public:
char *token;
int type;
int line;
TOKEN *next;
TOKEN(int line)
{
token = new char[256];
if(token == NULL) std::cout << "Fatal oopsies, token unable to grab 256 bytes!" << std::endl;
TOKEN::line=line;
next=NULL;
token[0]=0;
type=EMPTY;
}
TOKEN()
{
token = new char[256];
if(token == NULL) std::cout << "Fatal oopsies, token unable to grab 256 bytes!" << std::endl;
line=0;
next=NULL;
token[0]=0;
type=EMPTY;
}
void getbigplease()
{
//This is only a request :D
char *huhu = new char[65536];
if(huhu != NULL)
{
memcpy(huhu,token,256);
delete[] token;
token=huhu;
}
else
{
std::cout << "Danger Will Robinson! String can only be 256 chars :D" << std::endl;
}
}
~TOKEN()
{
if(token!=NULL) delete[] token;
if(next!=NULL) delete next;
}
};
int findkeyword(char *word, KEYWORD words[], int nkeywords)
{
int pos=0;
while(pos<nkeywords)
{
if(strcmp(words[pos].token,word)==0) return pos;
++pos;
}
return -1;
}
TOKEN *traverse(TOKEN *root)
{
if(root->next==NULL) return root;
else return traverse(root->next);
}
int findbytes(TOKEN *root,KEYWORD words[])
{
TOKEN *working=root;
int counter=0;
int test;
do
{
switch(working->type)
{
case TOKENCOMMENT:
case TOKENLABEL:
case EMPTY:
break;
case TOKENALPH:
test=findkeyword(working->token,words,nkeywords);
if(test!=-1)
{
switch (words[test].type)
{
case KEYEMPTY:
break;
case KEYBYTE:
counter+=sizeof(int);
break;
case KEYINT:
counter+=sizeof(int);
break;
case KEYFLOAT:
counter+=sizeof(double);
break;
}
}
break;
case TOKENCHAR:
counter+=((strlen(working->token)+(sizeof(int)-1))/sizeof(int))*sizeof(int);
break;
case TOKENSTRING:
counter+=((strlen(working->token)+sizeof(int))/sizeof(int))*sizeof(int);
break;
case TOKENADD:
case TOKENNUM:
counter+=sizeof(int);
break;
case TOKENFLOAT:
counter+=sizeof(double);
break;
}
working=working->next;
} while(working!=NULL);
return counter;
}
void converttokens(TOKEN *root, KEYWORD words[], int nkeywords, char *outputfile, int endian)
{
CONVERTINT writeint;
CONVERTDOUBLE writedouble;
int writeiterate;
LABELFIX fixerupper;
TOKEN *working=root;
int test=findbytes(root,words);
if(test<1)
{
std::cout << "No usable tokens found in file!" << std::endl;
return;
}
unsigned char *ops = new unsigned char[test];
if(ops==NULL)
{
std::cout << "OUT OF MEMORY" << std::endl;
return;
}
std::cout << "Found " << test << " bytes" << std::endl;
int opspos=0;
do
{
switch (working->type)
{
case EMPTY:
break;
case TOKENALPH:
test=findkeyword(working->token,words,nkeywords);
if(test!=-1)
{
switch (words[test].type)
{
case KEYEMPTY:
break;
case KEYBYTE:
writeint.data=(int)words[test].bvalue;
for(writeiterate=0;writeiterate<sizeof(int);++writeiterate)
{
ops[opspos+writeiterate]=writeint.bytes[writeiterate];
}
opspos+=sizeof(int);
break;
case KEYINT:
writeint.data=words[test].value;
for(writeiterate=0;writeiterate<sizeof(int);++writeiterate)
{
ops[opspos+writeiterate]=writeint.bytes[writeiterate];
}
opspos+=sizeof(int);
break;
case KEYFLOAT:
writedouble.data=words[test].fvalue;
for(writeiterate=0;writeiterate<sizeof(double);++writeiterate)
{
ops[opspos+writeiterate]=writedouble.bytes[writeiterate];
}
opspos+=sizeof(double);
break;
}
}
else
{
std::cout << std::endl << "Token Error(" << working->line << "): Keyword not found - " << working->token << std::endl;
delete[] ops;
return;
}
break;
case TOKENNUM:
if(strcmp(working->token,"-")==0)
{
std::cout << std::endl << "Token Error(" << working->line << "): Number missing from '-'"<< std::endl;
delete[] ops;
return;
}
writeint.data=atoi(working->token);
for(writeiterate=0;writeiterate<sizeof(int);++writeiterate)
{
ops[opspos+writeiterate]=writeint.bytes[writeiterate];
}
opspos+=sizeof(int);
break;
case TOKENFLOAT:
if(strcmp(working->token,"-")==0)
{
std::cout << std::endl << "Token Error(" << working->line << "): Number missing from '-'"<< std::endl;
delete[] ops;
return;
}
if(strcmp(working->token,".")==0)
{
std::cout << std::endl << "Token Error(" << working->line << "): Number missing from '.'"<< std::endl;
delete[] ops;
return;
}
writedouble.data=atof(working->token);
for(writeiterate=0;writeiterate<sizeof(double);++writeiterate)
{
ops[opspos+writeiterate]=writedouble.bytes[writeiterate];
}
opspos+=sizeof(double);
break;
case TOKENSTRING:
if(strlen(working->token)>0)
{
strcpy((char *)(ops+opspos),working->token);
opspos+=((strlen(working->token)+sizeof(int))/sizeof(int))*sizeof(int);
}
else
{
std::cout << std::endl << "Token Error(" << working->line << "): Quotes contain no string!"<< std::endl;
delete[] ops;
return;
}
break;
case TOKENCHAR:
if(strlen(working->token)>0)
{
strcpy((char *)(ops+opspos),working->token);
opspos+=((strlen(working->token)+(sizeof(int)-1))/sizeof(int))*sizeof(int);
}
else
{
std::cout << std::endl << "Token Error(" << working->line << "): Single quotes contain no string!"<< std::endl;
delete[] ops;
return;
}
break;
case TOKENLABEL:
if(fixerupper.addlabel(working->token,opspos)==-1)
{
std::cout << std::endl << "Token Error(" << working->line << "): Duplicate label!" << std::endl;
std::cout << "Duplicate " << working->token << std::endl;
delete[] ops;
return;
}
break;
case TOKENADD:
//Label fixup later
if(strcmp(working->token,"&")==0)
{
std::cout << std::endl << "Token Error(" << working->line << "): token missing with address '&'"<< std::endl;
delete[] ops;
return;
}
writeint.data=fixerupper.addusage(working->token,opspos);
for(writeiterate=0;writeiterate<sizeof(int);++writeiterate)
{
ops[opspos+writeiterate]=writeint.bytes[writeiterate];
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -