10个点同时RE的那种
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<string>
#include<vector>
#include<stack>
#include<functional>
#include<map>
using namespace std;
int R1,R2,R3,R4,E1,E2,E3,E4,Flag,Val,Ret,Line;
int codeLine;
int MemoryPool[16 * 1024 * 1024];
vector<pair<int, vector<string> > > originalCode;
stack<int> sAddr;
stack<int> cAddr;
map<string,int> functionLine;
map<string,int> operatorMatch;
bool CodeAlive=true;
int getNumber(){int x;scanf("%d",&x);return x;}
char getChar(){char x;scanf("%c",&x);return x;}
int toNumber(string str,int st){
int ret=0;
for(int i=st;i<str.length();i++)
ret=ret*10+(str[i]-'0');
return ret;
}
void ModifyVal(string str,int num){
if(str[0]=='#'){
Line=num;
return;
}
for(int i=str.length()-1;i>=0;i--)
if(str[i]>='a' && str[i]<='z')
str[i]-=('a'-'A');
if(str[0]=='%'){
if(str=="%R1"){R1=num;return;}
if(str=="%R2"){R2=num;return;}
if(str=="%R3"){R3=num;return;}
if(str=="%R4"){R4=num;return;}
if(str=="%E1"){E1=num;return;}
if(str=="%E2"){E2=num;return;}
if(str=="%E3"){E3=num;return;}
if(str=="%E4"){E4=num;return;}
if(str=="%FLAG"){Flag=num;return;}
if(str=="%VAL"){Val=num;return;}
if(str=="%RET"){Ret=num;return;}
if(str=="%LINE"){Line=num;return;}
}
if(str[0]=='@'){
if(str=="@%R1"){MemoryPool[R1]=num;return;}
if(str=="@%R2"){MemoryPool[R2]=num;return;}
if(str=="@%R3"){MemoryPool[R3]=num;return;}
if(str=="@%R4"){MemoryPool[R4]=num;return;}
if(str=="@%E1"){MemoryPool[E1]=num;return;}
if(str=="@%E2"){MemoryPool[E2]=num;return;}
if(str=="@%E3"){MemoryPool[E3]=num;return;}
if(str=="@%E4"){MemoryPool[E4]=num;return;}
if(str=="@%FLAG"){MemoryPool[Flag]=num;return;}
if(str=="@%VAL"){MemoryPool[Val]=num;return;}
if(str=="@%RET"){MemoryPool[Ret]=num;return;}
if(str=="@%LINE"){MemoryPool[Line]=num;return;}
if(str[0]=='@'){MemoryPool[toNumber(str,1)]=num;return;}
}
return;
}
int getVal(string str){
if(str[0]=='#')
return Line;
for(int i=str.length()-1;i>=0;i--)
if(str[i]>='a' && str[i]<='z')
str[i]-=('a'-'A');
if(str[0]=='%'){
if(str=="%R1"){return R1;}
if(str=="%R2"){return R2;}
if(str=="%R3"){return R3;}
if(str=="%R4"){return R4;}
if(str=="%E1"){return E1;}
if(str=="%E2"){return E2;}
if(str=="%E3"){return E3;}
if(str=="%E4"){return E4;}
if(str=="%FLAG"){return Flag;}
if(str=="%VAL"){return Val;}
if(str=="%RET"){return Ret;}
if(str=="%LINE"){return Line;}
}
if(str[0]=='@'){
if(str=="@%R1"){return MemoryPool[R1];}
if(str=="@%R2"){return MemoryPool[R2];}
if(str=="@%R3"){return MemoryPool[R3];}
if(str=="@%R4"){return MemoryPool[R4];}
if(str=="@%E1"){return MemoryPool[E1];}
if(str=="@%E2"){return MemoryPool[E2];}
if(str=="@%E3"){return MemoryPool[E3];}
if(str=="@%E4"){return MemoryPool[E4];}
if(str=="@%FLAG"){return MemoryPool[Flag];}
if(str=="@%VAL"){return MemoryPool[Val];}
if(str=="@%RET"){return MemoryPool[Ret];}
if(str=="@%LINE"){return MemoryPool[Line];}
if(str[0]=='@'){return MemoryPool[toNumber(str,1)];}
}
return toNumber(str,0);
}
struct Statement{
string name;
int argc;
function<void(vector<string>)> relatedCode;
Statement(string name="",int argc=0,function<void(vector<string>)> relatedCode=[](vector<string> argv){})
:name(name),argc(argc),relatedCode(relatedCode){}
}Oper[30];
#define StoreVal(x,y) if(argv.size()<=x)Val=(y);else ModifyVal(argv[x],(y))
#define StoreLogicVal(x,y) if(argv.size()<=x)Flag=(y);else ModifyVal(argv[x],(y))
int main(){
cAddr.push(0);
sAddr.push(0);
Oper[0] = Statement("UDEF" , 0 , [](vector<string> argv){++Line;});
Oper[1] = Statement("HLT" , 0 , [](vector<string> argv){CodeAlive=false;});
Oper[2] = Statement("NOP" , 0 , [](vector<string> argv){++Line;});
Oper[3] = Statement("SET" , 2 , [](vector<string> argv){ModifyVal(argv[1],getVal(argv[0]));++Line;});
Oper[4] = Statement("JMP" , 1 , [](vector<string> argv){Line=getVal(argv[0]);});
Oper[5] = Statement("JIF" , 1 , [](vector<string> argv){
if(((int)argv.size()>1 && getVal(argv[1])!=0) || ((int)argv.size()==1 && Flag))Line=cAddr.top()+getVal(argv[0]);else ++Line;});
Oper[6] = Statement("CALL" , 1 , [](vector<string> argv){sAddr.push(Line);Line=sAddr.top()+getVal(argv[0]);++Line;});
Oper[7] = Statement("RET" , 0 , [](vector<string> argv){
Line=sAddr.top();sAddr.pop();if(argv.size()!=0)Ret=getVal(argv[0]);cAddr.pop();++Line;});
Oper[8] = Statement("INV" , 1 , [](vector<string> argv){StoreVal(1,!getVal(argv[0]));});
Oper[9] = Statement("ADD" , 2 , [](vector<string> argv){StoreVal(2,getVal(argv[0])+getVal(argv[1]));++Line;});
Oper[10] = Statement("SUB" , 2 , [](vector<string> argv){StoreVal(2,getVal(argv[0])-getVal(argv[1]));++Line;});
Oper[11] = Statement("MULT" , 2 , [](vector<string> argv){StoreVal(2,getVal(argv[0])*getVal(argv[1]));++Line;});
Oper[12] = Statement("IDIV" , 2 , [](vector<string> argv){StoreVal(2,getVal(argv[0])/getVal(argv[1]));++Line;});
Oper[13] = Statement("MOD" , 2 , [](vector<string> argv){StoreVal(2,getVal(argv[0])%getVal(argv[1]));++Line;});
Oper[14] = Statement("LSFT" , 2 , [](vector<string> argv){StoreVal(2,getVal(argv[0])<<getVal(argv[1]));++Line;});
Oper[15] = Statement("RSFT" , 2 , [](vector<string> argv){StoreVal(2,getVal(argv[0])>>getVal(argv[1]));++Line;});
Oper[16] = Statement("BAND" , 2 , [](vector<string> argv){StoreVal(2,getVal(argv[0])&getVal(argv[1]));++Line;});
Oper[17] = Statement("BOR" , 2 , [](vector<string> argv){StoreVal(2,getVal(argv[0])|getVal(argv[1]));++Line;});
Oper[18] = Statement("BXOR" , 2 , [](vector<string> argv){StoreVal(2,getVal(argv[0])^getVal(argv[1]));++Line;});
Oper[19] = Statement("LGR" , 2 , [](vector<string> argv){StoreLogicVal(2,getVal(argv[0])>getVal(argv[1]));++Line;});
Oper[20] = Statement("LLS" , 2 , [](vector<string> argv){StoreLogicVal(2,getVal(argv[0])<getVal(argv[1]));++Line;});
Oper[21] = Statement("LGE" , 2 , [](vector<string> argv){StoreLogicVal(2,getVal(argv[0])>=getVal(argv[1]));++Line;});
Oper[22] = Statement("LLE" , 2 , [](vector<string> argv){StoreLogicVal(2,getVal(argv[0])<=getVal(argv[1]));++Line;});
Oper[23] = Statement("LEQL" , 2 , [](vector<string> argv){StoreLogicVal(2,getVal(argv[0])==getVal(argv[1]));++Line;});
Oper[24] = Statement("LAND" , 2 , [](vector<string> argv){StoreLogicVal(2,getVal(argv[0])&&getVal(argv[1]));++Line;});
Oper[25] = Statement("LOR" , 2 , [](vector<string> argv){StoreLogicVal(2,getVal(argv[0])||getVal(argv[1]));++Line;});
Oper[26] = Statement("RINT" , 0 , [](vector<string> argv){ModifyVal((argv.size()?argv[0]:"%val"),getNumber());++Line;});
Oper[27] = Statement("RCH" , 0 , [](vector<string> argv){ModifyVal((argv.size()?argv[0]:"%val"),(int)getChar());++Line;});
Oper[28] = Statement("WINT" , 0 , [](vector<string> argv){printf("%d",getVal((argv.size()?argv[0]:"%val")));++Line;});
Oper[29] = Statement("WCH" , 0 , [](vector<string> argv){printf("%c",(char)getVal((argv.size()?argv[0]:"%val")));++Line;});
Oper[30] = Statement("CALLFUNC" , 1 , [](vector<string> argv){sAddr.push(Line);Line=functionLine[argv[0]];cAddr.push(Line);++Line;});
operatorMatch["FUNCTION"]=-1;
for(int i=0;i<31;i++)
operatorMatch[Oper[i].name]=i;
scanf("%d",&codeLine);
vector<string> nope;nope.clear();
originalCode.push_back(make_pair(0,nope));
char ch;
while(ch=getchar())
if(ch!='\n' && ch!='\r')
break;
bool usedFirst=false;
for(int i=1;i<=codeLine;i++){
pair<int,vector<string> > x;
string u="";bool fir=false;
while(1){
if(usedFirst)
ch=getchar();
usedFirst=true;
if(ch=='['){
int p=1;
while(p){
ch=getchar();
if(ch=='\n'){
if(i==originalCode.size())
originalCode.push_back(make_pair(0,nope));
++i;
if(i>codeLine) break;
}
else if(ch=='[') ++p;
else if(ch==']') --p;
}
}
else if(ch==' ' || ch==';'){
if(u=="") continue;
if(fir==false){
for(int i=u.length()-1;i>=0;i--)
if(u[i]>='a' && u[i]<='z')
u[i]-=('a'-'A');
x.first=operatorMatch[u];
fir=true;
}
else
x.second.push_back(u);
u="";
if(ch==';'){
originalCode.push_back(x);
if(x.first==-1)
functionLine[x.second[0]]=i;
x=make_pair(0,nope);
fir=false;
}
}
else if(ch!='\n' && ch!='\r')
u+=ch;
else if(ch=='\n'){
if(i==originalCode.size())
originalCode.push_back(make_pair(0,nope));
++i;
if(i>codeLine)
break;
}
}
if(fir==false){
originalCode.push_back(x);
if(x.first==-1)
functionLine[x.second[0]]=i;
}
}
Line=1;
while(CodeAlive){
while(originalCode[Line].first==0) ++Line;
if(originalCode[Line].first!=-1)
(Oper[originalCode[Line].first].relatedCode)(originalCode[Line].second);
}
return 0;
}