#include #include #include #include #include"masterstring2.h" using namespace std; using namespace masterstring; namespace masasm { class masasmInterpreator { enum { VAR_STRING, VAR_INTEGER, VAR_FLOAT }; class Variables { struct var { string varname; string varval; int var_type; }; public: vector variable; void addvariable(string varname, string varval, int var_type) { var v; v.var_type = var_type; v.varname = varname; v.varval = varval; variable.push_back(v); } size_t size() { return variable.size(); } size_t getvarbyname(string varname) { for(size_t i = 0; i < size(); i++) { if(variable[i].varname == varname) { return (i); } } return (-1); } var operator[](size_t pos) { return variable[i]; } string getvarval(size_t pos) { return variable[i].varval; } string fixstring(string str) { string temp = ""; for(size_t i = 0; i < str.length(); i++) { if(str[i] == '\\' && str[i+1] == 'n') { temp += '\n'; i += 1; continue; } if(str[i] == '\\' && str[i+1] == 't') { temp += '\t'; i += 1; continue; } if(str[i] != '\"') { temp += str[i]; } } return (temp); } }; class Code { struct CodeBlock { string opc; string op1; string op2; string label; }; public: vector code; void addinstruction(string opc, string op1, string op2, string label = "") { CodeBlock icode; icode.opc = opc; icode.op1 = op1; icode.op2 = op2; icode.label = label; code.push_back(icode); } void setlabels() { for(size_t i = 0; i < size(); i++) { if(code[i].label != "") { for(size_t z = 0; z < size(); z++) { switch(atoi(code[z].opc.c_str())) { case 15: case 16: case 17: case 18: case 19: case 20: case 21: { if(code[z].op1 == code[i].label) { char data[25]; itoa(i,data,10); code[z].op1 = data; } } break; } } } } } CodeBlock operator[](size_t pos) { return (code[pos]); } size_t size() { return (code.size()); } }; template class Stack { vector array; size_t off; public: Stack() { off = 0; } void push(type& t) { array.push_back(t); off++; } type pop() { type t; off--; if(off < 0) { off = 0; } t = array[off]; array.pop_back(); return (t); } type operator[](int pos) { return array[pos]; } }; Variables variables; Code code; Stack stack; bool flags[6]; public: void loadbytecode(string sourcefile) { int i; string sourcecode = readfile(sourcefile); int var_pos = qmstrifind(0,(char*)sourcecode.c_str(),"var{"); int var_close = qmstrifind(var_pos + 1,(char*)sourcecode.c_str(),"}"); string pvar = mid(sourcecode,var_pos+4,var_close); TokenizeQuotes vartokens; vartokens.tokenize((char*)pvar.c_str(),','); for(i = 0; i < vartokens.length; i++) { int pos = qmstrifind(0,vartokens[i],":"); string varname = left(vartokens[i],pos); string varval = right(vartokens[i],pos+1); pos = qmstrifind(0,(char*)varname.c_str(),"$"); if(pos != -1) { varname = left(varname,pos); variables.addvariable(varname,varval,VAR_STRING); } pos = qmstrifind(0,(char*)varname.c_str(),"&"); if(pos != -1) { varname = left(varname,pos); variables.addvariable(varname,varval,VAR_INTEGER); } pos = qmstrifind(0,(char*)varname.c_str(),"#"); if(pos != -1) { varname = left(varname,pos); variables.addvariable(varname,varval,VAR_FLOAT); } } int code_pos = qmstrifind(0,(char*)sourcecode.c_str(),"code{"); int code_close = qmstrifind(code_pos+1,(char*)sourcecode.c_str(),"}"); string pcode = mid(sourcecode,code_pos+5,code_close); TokenizeQuotes codetokens; codetokens.tokenize((char*)pcode.c_str(),','); for(i = 0; i < codetokens.length; i++) { int labelpos = qmstrifind(0,codetokens[i],"@"); if(labelpos != -1) { string plabel = left(codetokens[i],labelpos); code.addinstruction("-1","0","0",plabel); continue; } int incpos = qmstrifind(0,codetokens[i],"!"); if(incpos != -1) { int cpos = qmstrifind(incpos+1,codetokens[i],":"); if(cpos != -1) { string opc = left(codetokens[i],incpos); string op1 = mid(codetokens[i],incpos+1,cpos); string op2 = right(codetokens[i],cpos+1); code.addinstruction(opc,op1,op2); } } code.setlabels(); } } void runprogram(string sourcefile) { loadbytecode(sourcefile); debugoutput(); execute(); } void execute() { size_t ip = 0;// instruction pointer while(1) { switch(atoi(code.code[ip].opc.c_str())) { case 0: { return; } break; case -1: { ip++; continue; } break; case 1:// mov { size_t var_pos; var_pos = variables.getvarbyname(code.code[ip].op1); size_t var_pos2; var_pos2 = variables.getvarbyname(code.code[ip].op2); if(var_pos2 == -1) { variables.variable[var_pos].varval = code.code[ip].op2; } else { variables.variable[var_pos].varval = variables.variable[var_pos2].varval; } } break; case 2:// inc { size_t var_pos; var_pos = variables.getvarbyname(code.code[ip].op1); if(var_pos == -1) { cout << "error invalid variable " << code.code[ip].op1 << " on the inc instruction" << endl; } int val = atoi(variables.variable[var_pos].varval.c_str()); val++; char data[25]; itoa(val,data,10); string temp; temp = data; variables.variable[var_pos].varval = temp; } break; case 3:// dec { size_t var_pos; var_pos = variables.getvarbyname(code.code[ip].op1); if(var_pos == -1) { cout << "error invalid variable " << code.code[ip].op1 << " on the inc instruction" << endl; } int val = atoi(variables.variable[var_pos].varval.c_str()); val--; char data[25]; itoa(val,data,10); string temp; temp = data; variables.variable[var_pos].varval = temp; } break; case 4:// add { size_t var_pos1,var_pos2; var_pos1 = variables.getvarbyname(code.code[ip].op1); var_pos2 = variables.getvarbyname(code.code[ip].op2); int total = 0; double dtotal = 0; if(var_pos1 != -1 && var_pos2 != -1) { switch(variables.variable[var_pos1].var_type) { case VAR_INTEGER: { int x,y; x = atoi(variables.variable[var_pos1].varval.c_str()); y = atoi(variables.variable[var_pos2].varval.c_str()); total = x + y; } break; case VAR_FLOAT: { double x,y; x = atof(variables.variable[var_pos1].varval.c_str()); y = atof(variables.variable[var_pos2].varval.c_str()); dtotal = x + y; } break; } } else if(var_pos1 != -1 && var_pos2 == -1) { switch(variables.variable[var_pos1].var_type) { case VAR_INTEGER: { int x,y; x = atoi(variables.variable[var_pos1].varval.c_str()); y = atoi(code.code[ip].op2.c_str()); total = x + y; } break; case VAR_FLOAT: { double x,y; x = atof(variables.variable[var_pos1].varval.c_str()); y = atof(code.code[ip].op2.c_str()); dtotal = x + y; } break; } } string temp; char data[25]; switch(variables.variable[var_pos1].var_type) { case VAR_INTEGER: itoa(total,data,10); break; case VAR_FLOAT: gcvt(dtotal,10,data); break; } temp = data; variables.variable[var_pos1].varval = temp; } break; case 5: // sub { size_t var_pos1,var_pos2; var_pos1 = variables.getvarbyname(code.code[ip].op1); var_pos2 = variables.getvarbyname(code.code[ip].op2); int total = 0; double dtotal = 0; if(var_pos1 != -1 && var_pos2 != -1) { switch(variables.variable[var_pos1].var_type) { case VAR_INTEGER: { int x,y; x = atoi(variables.variable[var_pos1].varval.c_str()); y = atoi(variables.variable[var_pos2].varval.c_str()); total = x - y; } break; case VAR_FLOAT: { double x,y; x = atof(variables.variable[var_pos1].varval.c_str()); y = atof(variables.variable[var_pos2].varval.c_str()); dtotal = x - y; } break; } } else if(var_pos1 != -1 && var_pos2 == -1) { switch(variables.variable[var_pos1].var_type) { case VAR_INTEGER: { int x,y; x = atoi(variables.variable[var_pos1].varval.c_str()); y = atoi(code.code[ip].op2.c_str()); total = x - y; } break; case VAR_FLOAT: { double x,y; x = atof(variables.variable[var_pos1].varval.c_str()); y = atof(code.code[ip].op2.c_str()); dtotal = x - y; } break; } } string temp; char data[25]; switch(variables.variable[var_pos1].var_type) { case VAR_INTEGER: itoa(total,data,10); break; case VAR_FLOAT: gcvt(dtotal,10,data); break; } temp = data; variables.variable[var_pos1].varval = temp; } break; case 6:// mul { size_t var_pos1,var_pos2; var_pos1 = variables.getvarbyname(code.code[ip].op1); var_pos2 = variables.getvarbyname(code.code[ip].op2); int total = 0; double dtotal = 0; if(var_pos1 != -1 && var_pos2 != -1) { switch(variables.variable[var_pos1].var_type) { case VAR_INTEGER: { int x,y; x = atoi(variables.variable[var_pos1].varval.c_str()); y = atoi(variables.variable[var_pos2].varval.c_str()); total = x * y; } break; case VAR_FLOAT: { double x,y; x = atof(variables.variable[var_pos1].varval.c_str()); y = atof(variables.variable[var_pos2].varval.c_str()); dtotal = x * y; } break; } } else if(var_pos1 != -1 && var_pos2 == -1) { switch(variables.variable[var_pos1].var_type) { case VAR_INTEGER: { int x,y; x = atoi(variables.variable[var_pos1].varval.c_str()); y = atoi(code.code[ip].op2.c_str()); total = x * y; } break; case VAR_FLOAT: { double x,y; x = atof(variables.variable[var_pos1].varval.c_str()); y = atof(code.code[ip].op2.c_str()); dtotal = x * y; } break; } } string temp; char data[25]; switch(variables.variable[var_pos1].var_type) { case VAR_INTEGER: itoa(total,data,10); break; case VAR_FLOAT: gcvt(dtotal,10,data); break; } temp = data; variables.variable[var_pos1].varval = temp; } break; case 7:// div { size_t var_pos1,var_pos2; var_pos1 = variables.getvarbyname(code.code[ip].op1); var_pos2 = variables.getvarbyname(code.code[ip].op2); int total = 0; double dtotal = 0; if(var_pos1 != -1 && var_pos2 != -1) { switch(variables.variable[var_pos1].var_type) { case VAR_INTEGER: { int x,y; x = atoi(variables.variable[var_pos1].varval.c_str()); y = atoi(variables.variable[var_pos2].varval.c_str()); if(x == 0 || y == 0) { cout << "division by zero error.. " << endl; x = 1; y = 1; } total = x / y; } break; case VAR_FLOAT: { double x,y; x = atof(variables.variable[var_pos1].varval.c_str()); y = atof(variables.variable[var_pos2].varval.c_str()); if(x == 0 || y == 0) { cout << "division by zero error.. " << endl; x = 1; y = 1; } dtotal = x / y; } break; } } else if(var_pos1 != -1 && var_pos2 == -1) { switch(variables.variable[var_pos1].var_type) { case VAR_INTEGER: { int x,y; x = atoi(variables.variable[var_pos1].varval.c_str()); y = atoi(code.code[ip].op2.c_str()); if(x == 0 || y == 0) { cout << "division by zero error.. " << endl; x = 1; y = 1; } total = x / y; } break; case VAR_FLOAT: { double x,y; x = atof(variables.variable[var_pos1].varval.c_str()); y = atof(code.code[ip].op2.c_str()); if(x == 0 || y == 0) { cout << "division by zero error.. " << endl; x = 1; y = 1; } dtotal = x / y; } break; } } string temp; char data[25]; switch(variables.variable[var_pos1].var_type) { case VAR_INTEGER: itoa(total,data,10); break; case VAR_FLOAT: gcvt(dtotal,10,data); break; } temp = data; variables.variable[var_pos1].varval = temp; } break; case 8:// and { size_t var_pos1,var_pos2; var_pos1 = variables.getvarbyname(code.code[ip].op1); var_pos2 = variables.getvarbyname(code.code[ip].op2); int total = 0; if(var_pos1 != -1 && var_pos2 != -1) { int x,y; x = atoi(variables.variable[var_pos2].varval.c_str()); total += x; y = atoi(variables.variable[var_pos1].varval.c_str()); total = x & y; } else if(var_pos1 != -1 && var_pos2 == -1) { int x,y; x = atoi(variables.variable[var_pos1].varval.c_str()); y = atoi(code.code[ip].op2.c_str()); total = x & y; } string temp; char data[25]; itoa(total,data,10); temp = data; variables.variable[var_pos1].varval = temp; } break; case 9:// or { size_t var_pos1,var_pos2; var_pos1 = variables.getvarbyname(code.code[ip].op1); var_pos2 = variables.getvarbyname(code.code[ip].op2); int total = 0; if(var_pos1 != -1 && var_pos2 != -1) { int x,y; x = atoi(variables.variable[var_pos2].varval.c_str()); total += x; y = atoi(variables.variable[var_pos1].varval.c_str()); total = x | y; } else if(var_pos1 != -1 && var_pos2 == -1) { int x,y; x = atoi(variables.variable[var_pos1].varval.c_str()); y = atoi(code.code[ip].op2.c_str()); total = x | y; } string temp; char data[25]; itoa(total,data,10); temp = data; variables.variable[var_pos1].varval = temp; } break; case 10:// xor { size_t var_pos1,var_pos2; var_pos1 = variables.getvarbyname(code.code[ip].op1); var_pos2 = variables.getvarbyname(code.code[ip].op2); int total = 0; if(var_pos1 != -1 && var_pos2 != -1) { int x,y; x = atoi(variables.variable[var_pos2].varval.c_str()); total += x; y = atoi(variables.variable[var_pos1].varval.c_str()); total = x ^ y; } else if(var_pos1 != -1 && var_pos2 == -1) { int x,y; x = atoi(variables.variable[var_pos1].varval.c_str()); y = atoi(code.code[ip].op2.c_str()); total = x ^ y; } string temp; char data[25]; itoa(total,data,10); temp = data; variables.variable[var_pos1].varval = temp; } break; case 11: // not { size_t var_pos1 = variables.getvarbyname(code.code[ip].op1); if(var_pos1 != -1) { int x; x = atoi(variables.variable[var_pos1].varval.c_str()); x = !x; char data[25]; itoa(x,data,10); variables.variable[var_pos1].varval = data; } else { cout << "error invalid variable on not instruction [" << code.code[ip].op1 << "]" << endl; } } break; case 12:// print { size_t var_pos; var_pos = variables.getvarbyname(code.code[ip].op1); if(var_pos == -1) { cout << variables.fixstring(code.code[ip].op1); } else { cout << variables.fixstring(variables.variable[var_pos].varval); } } break; case 13:// input { size_t var_pos; var_pos = variables.getvarbyname(code.code[ip].op1); if(var_pos != -1) { cin >> variables.variable[var_pos].varval; } else { cout << "invalid variable name: on input instruction " << code.code[ip].op1 << endl; } } break; case 14:// cmp { size_t var_pos1,var_pos2; var_pos1 = variables.getvarbyname(code.code[ip].op1); var_pos2 = variables.getvarbyname(code.code[ip].op2); string operand2; if(var_pos2 == -1) { operand2 = code.code[ip].op2; } else { operand2 = variables.variable[var_pos2].varval; } if(var_pos1 != -1) { int x,y; x = atoi(variables.variable[var_pos1].varval.c_str()); y = atoi(operand2.c_str()); resetflags(); // je if(x == y) { flags[0] = true; } // jne if(x != y) { flags[1] = true; } // jg if(x > y) { flags[2] = true; } // jge if(x >= y) { flags[3] = true; } // jl if(x < y) { flags[4] = true; } // jle if(x <= y) { flags[5] = true; } } else { cout << " error operand one variable not found on cmp instruction " << code.code[ip].op1 << endl; } } break; case 15:// jmp { if(isletter(code.code[ip].op1) == false) { int pos = atoi(code.code[ip].op1.c_str()); ip = pos; continue; } else { cout << "invalid code label " << code.code[ip].op1 << endl; } } break; case 16:// jne { if(isletter(code.code[ip].op1) == false) { if(flags[1] == true) { int pos = atoi(code.code[ip].op1.c_str()); ip = pos; continue; } } else { cout << "invalid code label "<< code.code[ip].op1 << endl; } } break; case 17:// je { if(isletter(code.code[ip].op1) == false) { if(flags[0] == true) { int pos = atoi(code.code[ip].op1.c_str()); ip = pos; continue; } } else { cout << "invalid code label " << code.code[ip].op1 << endl; } } break; case 18:// jge { if(isletter(code.code[ip].op1) == false) { if(flags[3] == true) { int pos = atoi(code.code[ip].op1.c_str()); ip = pos; continue; } } else { cout << " invalid code label " << code.code[ip].op1 << endl; } } break; case 19:// jg { if(isletter(code.code[ip].op1) == false) { if(flags[2] == true) { int pos = atoi(code.code[ip].op1.c_str()); ip = pos; continue; } } else { cout << "invalid code label "<< code.code[ip].op1 << endl; } } break; case 20:// jl { if(isletter(code.code[ip].op1) == false) { if(flags[4] == true) { int pos = atoi(code.code[ip].op1.c_str()); ip = pos; continue; } } else { cout << "invalid code label " << code.code[ip].op1 << endl; } } break; case 21:// jle { if(isletter(code.code[ip].op1) == false) { if(flags[5] == true) { int pos = atoi(code.code[ip].op1.c_str()); ip = pos; continue; } } else { cout << "invalid code label "<< code.code[ip].op1 << endl; } } break; case 22:// push { size_t var_pos; var_pos = variables.getvarbyname(code.code[ip].op1); if(var_pos == -1) { stack.push(code.code[ip].op1); } else { stack.push(variables.variable[var_pos].varval); } } break; case 23:// pop { size_t var_pos; var_pos = variables.getvarbyname(code.code[ip].op1); if(var_pos != -1) { variables.variable[var_pos].varval = stack.pop(); } else { cout << "invalid variable on pop instruction " << endl; } } break; } ip++; if(ip >= code.size()) { break; } } } void resetflags() { for(int i = 0; i <= 5; i++) { flags[i] = false; } } void debugoutput() { size_t i; ofstream dout("debug.html"); dout << ""; dout << "Variables

"; for(i = 0; i < variables.size(); i++) { dout << "" << variables.variable[i].varname << " of type"; switch(variables.variable[i].var_type) { case VAR_INTEGER: dout << " integer (&)"; break; case VAR_STRING: dout << " string ($)"; break; case VAR_FLOAT: dout << " float (#)"; break; } dout <<" = " << variables.variable[i].varval; dout << "
"; } dout << "

Code Layout

" << endl; for(i = 0; i < code.size(); i++) { if(code.code[i].label != "") { dout << "" << code.code[i].label << ":" << "
"; } if(code.code[i].opc != "-1") { dout << "opcode (" << code.code[i].opc << ") operands (" << code.code[i].op1 << "," << code.code[i].op2 << ")
"; } } dout << "
"; } }; } using namespace masasm; int main(int argc, char *argv[]) { if(argc != 2) { cout << "[invalid syntax] to call masinterp type\nmasinterp sourcefile.mas" << endl; system("pause"); return (0); } masasmInterpreator masInterp; if(isfile(argv[1])) { masInterp.runprogram(argv[1]); } else { cout << argv[1] << " file not found.. " << endl; } system("pause"); return (0); }