⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gvma.cpp

📁 一个RPG术语查询器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
				opspos+=sizeof(int);
				break;
			
			
		}
		working=working->next;	
	
	} while(working!=NULL);
	
	if(fixerupper.fixup(ops)==-1)
	{
		std::cout << "Unable to complete operation!" << std::endl;
		delete[] ops;
		return;
	}



        char fendian;
        char szdouble;
        char szint;
        char version[8];
        int numops;
        int startaddress;

	//write the endian
	fendian=(char) endian;
	strcpy(version,"gVM 1.0");
	szdouble=sizeof(double);
	szint=sizeof(int);
	numops=opspos;
	startaddress=fixerupper.findaddress("main");

	if(startaddress==-1)
	{
		std::cout << "Entry Point Missing (lack of :main in file)" << std::endl;
		delete[] ops;
		return;

	}
	std::cout << "Entry point: " << startaddress << std::endl;
	
	if(outputfile==NULL) outputfile="output.bin";
	FILE *doing=fopen(outputfile,"wb");
	if(doing==NULL)
	{
		std::cout << "Cannot open output file!" << std::endl;
		delete[] ops;
		return;
	}

	
	//num of ops
        test = fwrite(&fendian,1,1,doing);
        test = fwrite(&szdouble,1,1,doing);
        test = fwrite(&szint,1,1,doing);
        test = fwrite(version,1,8,doing);
        test = fwrite(&numops,1,sizeof(int),doing);
        test = fwrite(&startaddress,1,sizeof(int),doing);


	//write the ops
	if(opspos>0) fwrite(ops,sizeof(unsigned char),opspos,doing);
	fclose(doing);
	delete[] ops;
	std::cout << "Done writing " << outputfile << "!" << std::endl;
}

TOKEN *gettokensfromline(char *buffer, TOKEN *root, int line)
{
	
	//First token in the line
	TOKEN *working=root;
	int foundlabels=0;
	int tokenworking=EMPTY;
	int tokenpos=0;
	int pos=0;
	
	while(buffer[pos]!=0)
	{
		
		if((buffer[pos]>='A' && buffer[pos]<='Z') || (buffer[pos]>='a' && buffer[pos]<='z') || buffer[pos]=='_')
		{
			switch(tokenworking)
			{
				case TOKENNUM:
					ERRMSG=ERRALPHINNUM;
					return NULL;
					break;
				case EMPTY:
					working->next = new TOKEN(line);
					if(working->next==NULL)
					{
						std::cout << "OUT OF MEMORY!" << std::endl;
						return NULL;
					}
					foundlabels=1;
					working=working->next;
					tokenworking=TOKENALPH;
					working->type=TOKENALPH;
					tokenpos=0;
				default:
					working->token[tokenpos]=buffer[pos];
					++tokenpos;
					break;
			}
			
		}

		else if(buffer[pos]>='0' && buffer[pos]<='9')
		{
			switch(tokenworking)
			{
				case EMPTY:
					working->next = new TOKEN(line);
					if(working->next==NULL)
					{
						std::cout << "OUT OF MEMORY!" << std::endl;
						return NULL;
					}
					foundlabels=1;
					working=working->next;
					tokenworking=TOKENNUM;
					working->type=TOKENNUM;
					tokenpos=0;
				default:
					working->token[tokenpos]=buffer[pos];
					++tokenpos;
					break;
			}
		}
		else
		{
			switch(buffer[pos])
			{
				
				case '.':
								
					switch(tokenworking)
					{
						case EMPTY:
							working->next = new TOKEN(line);
							if(working->next==NULL)
							{
								std::cout << "OUT OF MEMORY!" << std::endl;
								return NULL;
							}
							foundlabels=1;
							working=working->next;
							tokenpos=0;
						//Switch a NUMBER into a float midstream!
						case TOKENNUM:
							tokenworking=TOKENFLOAT;
							working->type=TOKENFLOAT;
						case TOKENALPH:
						case TOKENLABEL:
						case TOKENCOMMENT:
						case TOKENADD:
						case TOKENCHAR:
						case TOKENSTRING:
							working->token[tokenpos]=buffer[pos];
							++tokenpos;
							break;
						
						default:
							ERRMSG=ERRPERIOD;
							return NULL;
							break;
					}
				break;

				case '-':
					switch(tokenworking)
					{
						case TOKENFLOAT:
						case TOKENNUM:
							ERRMSG=ERRMINUS;
							return NULL;
							break;
					
					
						case EMPTY:
							working->next = new TOKEN(line);
							if(working->next==NULL)
							{
								std::cout << "OUT OF MEMORY!" << std::endl;
								return NULL;
							}
							foundlabels=1;
							working=working->next;
							tokenworking=TOKENNUM;
							working->type=TOKENNUM;
							tokenpos=0;
						default:
							working->token[tokenpos]=buffer[pos];
							++tokenpos;
							break;
					}
				break;
				
				case ':':
					switch(tokenworking)
					{
						case EMPTY:
							working->next = new TOKEN(line);
							if(working->next==NULL)
							{
								std::cout << "OUT OF MEMORY!" << std::endl;
								return NULL;
							}
							foundlabels=1;
							working=working->next;
							tokenworking=TOKENLABEL;
							working->type=TOKENLABEL;
							tokenpos=0;
						case TOKENCHAR:
						case TOKENSTRING:
						case TOKENCOMMENT:
							working->token[tokenpos]=buffer[pos];
							++tokenpos;
							break;
						default:
							ERRMSG=ERRCOLON;
							return NULL;
							break;
					}
				break;

				
				//String :D
				case 34:
				
					switch(tokenworking)
					{
						case EMPTY:
							working->next = new TOKEN(line);
							if(working->next==NULL)
							{
								std::cout << "OUT OF MEMORY!" << std::endl;
								return NULL;
							}
							foundlabels=1;
							working=working->next;
							tokenworking=TOKENSTRING;
							working->type=TOKENSTRING;
							//Increase our buffer size to 64k for teh stringage
							working->getbigplease();
							tokenpos=0;
							break;
						case TOKENSTRING:
							working->token[tokenpos]=0;
							tokenworking=EMPTY;
							break;
						
						case TOKENCHAR:
						case TOKENCOMMENT:
							working->token[tokenpos]=buffer[pos];
							++tokenpos;
							break;
						default:
							ERRMSG=ERRCOLON;
							return NULL;
							break;
					}

				break;
				
				case 39:
				
					switch(tokenworking)
					{
						case EMPTY:
							working->next = new TOKEN(line);
							if(working->next==NULL)
							{
								std::cout << "OUT OF MEMORY!" << std::endl;
								return NULL;
							}
							foundlabels=1;
							working=working->next;
							tokenworking=TOKENCHAR;
							working->type=TOKENCHAR;
							//Increase our buffer size to 64k for teh stringage
							working->getbigplease();
							tokenpos=0;
							break;
						case TOKENCHAR:
							working->token[tokenpos]=0;
							tokenworking=EMPTY;
							break;
						
						case TOKENSTRING:
						case TOKENCOMMENT:
							working->token[tokenpos]=buffer[pos];
							++tokenpos;
							break;
						default:
							ERRMSG=ERRCOLON;
							return NULL;
							break;
					}

				break;




				case '_':
					switch(tokenworking)
					{
						case TOKENNUM:
							ERRMSG=ERRALPHINNUM;
							return NULL;
							break;
						case EMPTY:
							working->next = new TOKEN(line);
							if(working->next==NULL)
							{
								std::cout << "OUT OF MEMORY!" << std::endl;
								return NULL;
							}
							foundlabels=1;
							working=working->next;
							tokenworking=TOKENALPH;
							working->type=TOKENALPH;
							tokenpos=0;
						default:
							working->token[tokenpos]=buffer[pos];
							++tokenpos;
							break;
					}
					
					
				break;
					
				
				case ';':
					switch(tokenworking)
					{
						case EMPTY:
							working->next = new TOKEN(line);
							if(working->next==NULL)
							{
								std::cout << "OUT OF MEMORY!" << std::endl;
								return NULL;
							}
							
							
							foundlabels=1;
							working=working->next;
							tokenworking=TOKENCOMMENT;
							working->type=TOKENCOMMENT;
							tokenpos=0;
						case TOKENCHAR:
						case TOKENSTRING:
						case TOKENCOMMENT:
							working->token[tokenpos]=buffer[pos];
							++tokenpos;
							break;
						default:
							ERRMSG=ERRCOMMENT;
							return NULL;
							break;
						
					}
				break;

				case '&':
					switch(tokenworking)
					{
						case EMPTY:
							working->next = new TOKEN(line);
							if(working->next==NULL)
							{
								std::cout << "OUT OF MEMORY!" << std::endl;
								return NULL;
							}
							foundlabels=1;
							working=working->next;
							tokenworking=TOKENADD;
							working->type=TOKENADD;
							tokenpos=0;
						case TOKENCHAR:
						case TOKENSTRING:
						case TOKENCOMMENT:
							working->token[tokenpos]=buffer[pos];
							++tokenpos;
							break;
						default:
							ERRMSG=ERRINVALIDCHAR;
							return NULL;
							break;
					
					}
				break;
					
				case '\t':
				case ' ':
					switch(tokenworking)
					{
						case TOKENCHAR:
						case TOKENSTRING:	
						case TOKENCOMMENT:
							working->token[tokenpos]=buffer[pos];
							++tokenpos;
							break;
						case EMPTY:
							break;
						default:
							working->token[tokenpos]=0;
							tokenworking=EMPTY;
							break;
					}
				break;

				case 13:
					
					break;

				default:
					switch(tokenworking)
					{
						case TOKENCHAR:	
						case TOKENSTRING:	
						case TOKENCOMMENT:
							working->token[tokenpos]=buffer[pos];
							++tokenpos;
							break;
						default:
							ERRMSG=ERRINVALIDCHAR;
							return NULL;
							break;
					}
					
					break;
			}


			//switch chars
			//switch each token state for each set
			

		}
		
		++pos;
	}

	if(foundlabels==1)
	{
		if(tokenworking==TOKENSTRING || tokenworking==TOKENCHAR)
		{
			ERRMSG=ERRSTRING;
			return NULL;
		}
		
		working->token[tokenpos]=0;

	}
	return working;
}


int operate(char *file, char *fileout)
{
	
	KEYWORD words[]={ 
						//Opcodes
						
						//32bit processing
						KEYWORD("push",     0),
						KEYWORD("pop",      1),
						KEYWORD("clone",    2),
						KEYWORD("convert",  3),	
						
						KEYWORD("add",      4),
						KEYWORD("sub",      5),
						KEYWORD("mul",      6),
						KEYWORD("div",      7),
						
						KEYWORD("and",      8),
						KEYWORD("or",       9),
						KEYWORD("xor",     10),
						KEYWORD("not",     11),
						
						KEYWORD("exp",     16),
						KEYWORD("mod",     17),
						KEYWORD("shr",     18),
						KEYWORD("shl",     19),
						
						KEYWORD("cmp",     32),
						KEYWORD("jmp",     33),
						KEYWORD("jme",     34),
						KEYWORD("jml",     35),
						KEYWORD("jmg",     36),
						KEYWORD("jle",     37),
						KEYWORD("jge",     38),
						KEYWORD("jne",     39),
						KEYWORD("function",    42),
						KEYWORD("return",     43),
						KEYWORD("dpush",     44),

						KEYWORD("preserve",   46),
						KEYWORD("restore",    47),


						KEYWORD("load",    48),
						KEYWORD("store",   49),

						KEYWORD("loadb",    50),
						KEYWORD("storeb",   51),
						
						//Goodies
						KEYWORD("incl",    52),
						KEYWORD("decl",     53),
						KEYWORD("rstore",   54),


						KEYWORD("api",     61),
						KEYWORD("sys",     62),
						KEYWORD("exit",    63),
						
						
						//Floating Point Processing
						
						KEYWORD("pushf",    64),
						KEYWORD("popf",     65),
						KEYWORD("clonef",   66),
						KEYWORD("convertf", 67),
						

						KEYWORD("addf",     68),
						KEYWORD("subf",     69),
						KEYWORD("divf",     70),
						KEYWORD("mulf",     71),

						//Extras
						KEYWORD("expf",     72),
						KEYWORD("modf",     73),
						KEYWORD("sqrtf",    74),
						KEYWORD("cosf",     75),
						KEYWORD("sinf",     76),
						KEYWORD("tanf",     77),
						
					
						KEYWORD("cmpf",     96),
						
						
						KEYWORD("loadf",    97),
						KEYWORD("storef",   98),
						
						
						//function frame keywords
						KEYWORD("int",      1),
						KEYWORD("float",    2),
						KEYWORD("byte",     3),
						KEYWORD("end",      0),


						
						
						//sys_routines
						KEYWORD("sys_write",     1),
						KEYWORD("sys_read",      2),
						KEYWORD("sys_putchar",   3),
						KEYWORD("sys_endl",      4),
						
						KEYWORD("sys_atoi",      16),
						KEYWORD("sys_itoa",      17),
						KEYWORD("sys_atof",      18),
						KEYWORD("sys_ftoa",      19),
						
						KEYWORD("sys_strlen",    32),
						
						KEYWORD("sys_szdouble",  64),
						KEYWORD("sys_szint",     65),
						
						KEYWORD("sys_thread",  1337),
						KEYWORD("sys_yield",   1338),

						};
	
	
	int mendian;
	union endian {int huhu; char a[sizeof(int)];}; endian bleh;	bleh.huhu=1;
	
	std::cout << "Keywords: " << nkeywords << std::endl;

	if(bleh.a[0]==1)
	{
		std::cout << "Machine is Little Endian (intel)" << std::endl;
		mendian=1;
	}
	else
	{
		std::cout << "Machine is Big Endian (MIPS, Motorola, etc.)" << std::endl;
		mendian=0;
	}



	TOKEN *root=new TOKEN;
	if(root==NULL)
	{
		std::cout << "OUT OF MEMORY!" << std::endl;
		return -1;
	}

	TOKEN *index=root;
	char ftext[65536];
	std::ifstream asmfile;

	asmfile.open(file);
	int founderror=0;
	int lines=1;
	if(asmfile)
	{
		while(asmfile.eof()==0)
		{
			asmfile.getline(ftext,65536);
			index=gettokensfromline(ftext,index,lines);
			if(index==NULL)
			{
				delete root;
				asmfile.close();
				switch (ERRMSG)
				{
					case ERRALPHINNUM:
						std::cout << "E1(" << lines << "): Found letter (a-z,A-Z) in numerical token" << std::endl << " " << ftext << std::endl;
						break;
					case ERRPERIOD:
						std::cout << "E2(" << lines << "): Found additional '.' (math says only one decimal in a float)" << std::endl << " " << ftext << std::endl;
						break;
					
					case ERRCOLON:
						std::cout << "E2(" << lines << "): Found ':' inside token (colons must be at start of token to be valid as labels)" << std::endl << " " << ftext << std::endl;
						break;
					case ERRMINUS:
						std::cout << "E3(" << lines << "): Found '-' in token.  Only valid as first char to negate a numerical token (ie: -1351)" << std::endl << " " << ftext << std::endl;
						break;
					case ERRCOMMENT:
						std::cout << "E4(" << lines << "): Found ';' in token.  Only valid as first char of a comment" << std::endl << " " << ftext << std::endl;
						break;
					case ERRINVALIDCHAR:
						std::cout << "E5(" << lines << "): Found invalid char in token" << std::endl << " " << ftext << std::endl;
						break;
					case ERRSTRING:
						std::cout << "E6(" << lines << "): String not closed (trailing " << (char)34 << " or ' missing) !" << std::endl << " " << ftext << std::endl;
						break;
					default:
						std::cout << "Unexpected error(" << lines << "): closing and quitting!" << std::endl;
				}
				return 1;
			}
			
			++lines;
		}
		asmfile.close();
		converttokens(root,words,nkeywords,fileout,mendian);
		delete root;
	}
	else
	{
		std::cout << "FILE NOT FOUND!" << std::endl;
	}
	
	return 0;
}

int main(int argc,char *argv[])
{
	std::cout << "gVM assembler (it's slow!) by Ryan Broomfield 2003" << std::endl;
	if(argv[1]==NULL) std::cout << "Usage: assembler asmfile.asm vmfile.bin" << std::endl;
	else 
	{
		return operate(argv[1],argv[2]);
	}
	return 0;
		
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -