主页
最近更新
未来程序改
最后更新于 2025-05-01 16:03:48
作者
rzh123
分类
个人记录
复制 Markdown
更新文章内容
UOJ98 背景是预测 THUSC2023 Day2 是解释器但是之前从来没有写过完整的解释器。(结果 Day2 不是解释器) 5.5:`runblock` 没有写完,其他应该没有太大问题,明天写完。 5.6 UPD: 有大问题,wtcl(此时 if-else 匹配有问题,repair 和 dfsblock 是用来修这个的) 5.13 UPD:有更大的问题,wtttttcl(不支持多维数组,buildarray 等用来解决这个问题) 5.15 UPD:虽然 AC 了但是有 bug,在 forrun 里,如果 for 初始化时定义数组理论上会有问题。 UPD: 修好了(见 forrun) (中间因为编码问题注释变成 ? 了) ```cpp /* ??????? ???,?????? */ #include <cstdio> #include <iostream> #include <cstring> #include <cassert> #include <string> #include <vector> #include <stack> #include <queue> #include <map> #include <algorithm> #include <unordered_map> #include <unordered_set> #define ASSERT_MEMORY if(memtop>=MEMSIZE){printf("The memory boomed.\n");exit(0);} #define ASSERT_FUNCTION if(funtop>=FUNSIZE){printf("The function info boomed.\n");exit(0);} #define ASSERT_ARRAY if(memtop>=ARRSIZE){printf("The array info boomed.\n");exit(0);} // #ifdef ONLINE_JUDGE #define fprintf(...) (1) #define cerr cerrn #define freopen(...) (2) // #endif struct cerrn_t{ inline cerrn_t operator<<(const auto &x){(void)x;return *this;} }cerrn; using namespace std; constexpr int MEMSIZE=6e7+6,FUNSIZE=1e5+7,ARRSIZE=1e5+7; struct Token; using Expr=vector<Token>; int n; struct{ int ipos; basic_string<int> input; inline void add(int v){input+=v;} inline int read(){return input[ipos++];} }in; string output; string prog; enum TokType{NAME,RSV,NUM,SYM}; enum ValType{INT,FUN,REF}; enum CmdType{EXPR,IF,ELSE,WHILE,FOR,DEFVAR,DEFFUN,RET,VARGR}; // enum TermiStat{NORMAL,CONTINUE,BREAK,RETURN}; // ???????? continue ? break enum TermiStat{NORMAL,RETURN}; struct Token{ TokType t; int iv; string sv; Token(){} Token(TokType _t,int _i):t(_t),iv(_i),sv(""){} Token(TokType _t,const string &_s):t(_t),iv(0),sv{_s}{} }; struct Func{ string name; vector<string> par; int l,r; }fun[FUNSIZE]; struct ArrInfo{ vector<int> sz; }arrinfo[ARRSIZE]; int memtop,funtop,arrcnt; struct Val{ ValType t; int v; /* INT:value FUN:pos in fun_info OBJ:0=cin,1=cout,2=endl XXX,?? INT REF:pos in mem */ Val(){} Val(ValType _t,int _v):t(_t),v(_v){} }; constexpr int VALCIN=1,VALCOUT=2,VALENDL=-20230505; struct Cmd{ CmdType t; int iv1,iv2,iv3,l,r; bool inl; string sv; Cmd():t(EXPR),iv1(0),iv2(0),iv3(0),l(0),r(0),inl(false),sv(""){} Cmd(CmdType _t,int _i,const string &_s):t(_t),iv1(_i),iv2(0),iv3(0),inl(false),sv(_s){} Cmd(CmdType _t,int _i1,int _i2,int _i3,int _l,int _r):t(_t),iv1(_i1),iv2(_i2),iv3(_i3),l(_l),r(_r),inl(false),sv(""){} }; vector<Token> tk; vector<Expr> expr; vector<Cmd> cmd; int mem[MEMSIZE]; unordered_map<int,int> match; unordered_map<string,int> globvar; unordered_set<string> isfun; inline bool allspace(const string &s){ for(char i:s) if(!isspace(i)&&i!=0&&i!=EOF&&i!='\r') return false; return true; } inline string rline(){ string s{""}; do{ if(!getline(cin,s)) return ""; }while(allspace(s)); // printf("line %s\n",s.c_str()); return s; } inline void readin(){ int t; scanf("%d",&n); while(n--){ scanf("%d",&t); in.add(t); } rline(); rline(); rline(); string s; while(1){ s=rline(); if(s.empty()) break; prog+=s+'\n'; } } inline bool isname(char c){ return isalpha(c)||isdigit(c)||c=='_'; } inline bool isrsv(const string &s){ return s=="int"||s=="if"||s=="else"||s=="while"||s=="for"||s=="return"; } inline void lexer(){ for(unsigned i{0u};i<prog.size();){ char c{prog[i]}; if(isspace(c)||c==0||c==EOF) ++i; else if(isdigit(c)){ int it{c&15}; for(++i;i<prog.size()&&isdigit(prog[i]);++i) it=10*it+(prog[i]&15); tk.emplace_back(NUM,it); } else if(isname(c)){ string st(1,c); for(++i;i<prog.size()&&isname(prog[i]);++i) st+=prog[i]; if(isrsv(st)) tk.emplace_back(RSV,st); else tk.emplace_back(NAME,st); } else{ ++i; bool flg{true}; if(!tk.empty()&&tk.back().t==SYM){ string &lst{tk.back().sv}; if(lst=="<"&&c=='<') lst+=c; else if(lst==">"&&c=='>') lst+=c; else if((lst=="<"||lst==">"||lst=="!"||lst=="=")&&c=='=') lst+=c; else if(lst=="&"&&c=='&') lst+=c; else if(lst=="|"&&c=='|') lst+=c; else flg=false; } else flg=false; if(!flg) tk.emplace_back(SYM,string(1,c)); } } } inline void transsuf(int l,int r,vector<Token> &suf){ suf.clear(); stack<pair<string,bool> > op; static const Token RBRA=Token(SYM,")"); static unordered_map<string,int> pri_mp; if(pri_mp.empty()){ pri_mp.emplace("<<",1),pri_mp.emplace(">>",1), pri_mp.emplace("=",2), pri_mp.emplace("||",3), pri_mp.emplace("&&",4), pri_mp.emplace("^",5), pri_mp.emplace("==",6),pri_mp.emplace("!=",6), pri_mp.emplace("<=",7),pri_mp.emplace(">=",7),pri_mp.emplace("<",7),pri_mp.emplace(">",7), pri_mp.emplace("+",8),pri_mp.emplace("-",8), pri_mp.emplace("*",9),pri_mp.emplace("/",9),pri_mp.emplace("%",9), pri_mp.emplace("!",10),pri_mp.emplace("+u",10),pri_mp.emplace("-u",10), pri_mp.emplace("<>",11), pri_mp.emplace("(",-12),pri_mp.emplace("[",-12), pri_mp.emplace("[]",12); } auto pri=[](const string &s){return pri_mp[s];}; auto asc=[](const string &s){return s=="=";}; bool funfun{false}; for(int i{l};i<=r+1;++i){ const Token &t=((i<=r)?(tk[i]):RBRA); if(t.t==NAME||t.t==NUM){ suf.emplace_back(t); funfun=true; } else{ string s=t.sv; if(s=="("){ op.emplace(s,funfun); } else if(s==")"){ while(!op.empty()&&op.top().first!="("){ suf.emplace_back(SYM,op.top().first); op.pop(); } if(!op.empty()&&op.top().second){ suf.emplace_back(SYM,"<>"); } if(!op.empty()) op.pop(); } else if(s==","){ while(!op.empty()&&op.top().first!="("){ suf.emplace_back(SYM,op.top().first), op.pop(); } } else if(s=="["){ op.emplace("[",false); } else if(s=="]"){ while(!op.empty()&&op.top().first!="["){ suf.emplace_back(SYM,op.top().first), op.pop(); } if(!op.empty()) op.pop(); suf.emplace_back(SYM,"[]"); } else if(s=="!"||((s=="+"||s=="-")&&!funfun)){ if(s=="+"||s=="-") s+="u"; op.emplace(s,false); } else if(asc(s)){ while(!op.empty()&&pri(op.top().first)>pri(s)){ suf.emplace_back(SYM,op.top().first),op.pop(); } op.emplace(s,false); } else{ while(!op.empty()&&pri(op.top().first)>=pri(s)){ suf.emplace_back(SYM,op.top().first),op.pop(); } op.emplace(s,false); } if(s==")"||s=="]") funfun=true; else funfun=false; } } } inline int newvar(const string &s,unordered_map<string,int> &tgt,int v=0){ tgt[s]=++memtop; ASSERT_MEMORY; mem[memtop]=v; return memtop; } inline void buildarray(int id,const ArrInfo &ainfo,int szpos){ int sz=ainfo.sz[szpos]; mem[id]=memtop+1; memtop+=sz; if(szpos<(int)ainfo.sz.size()-1){ for(int i{mem[id]};i<=mem[id]+sz-1;++i){ buildarray(i,ainfo,szpos+1); } } } inline int newarray(const string &s,const ArrInfo &ainfo,unordered_map<string,int> &tgt){ int id=newvar(s,tgt); buildarray(id,ainfo,0); return id; } inline int newfun(const string &s){ ++funtop; fun[funtop].name=s; int id=newvar(s,globvar); mem[id]=funtop; isfun.emplace(s); return funtop; } inline int newexpr(int l,int r){ expr.emplace_back(); transsuf(l,r,expr.back()); return expr.size()-1; } inline void initcompile(){ stack<int> bra; for(unsigned i{0u};i<tk.size();++i){ if(tk[i].t==SYM){ if(tk[i].sv=="("||tk[i].sv=="["||tk[i].sv=="{"){ bra.emplace(i); } else if(tk[i].sv==")"||tk[i].sv=="]"||tk[i].sv=="}"){ if(!bra.empty()){ match[bra.top()]=i, match[i]=bra.top(); bra.pop(); } } } } expr.emplace_back(); cmd.emplace_back(); newfun("putchar"); fun[funtop].par.emplace_back("_c"); fun[funtop].l=fun[funtop].r=-1; newvar("cin",globvar,VALCIN); newvar("cout",globvar,VALCOUT); newvar("endl",globvar,VALENDL); } inline void outexpr(const Expr &x){ for(auto &v:x){ if(v.t==NUM) cerr<<v.iv<<' '; else cerr<<v.sv<<' '; } } inline bool isblockcmd(const Cmd &c){ return c.t==IF||c.t==FOR||c.t==WHILE; } void dfsblock(int u){ if(cmd[u].inl){ int v{cmd[u].l}; if(isblockcmd(cmd[v])){ dfsblock(v); cmd[u].r=cmd[v].r; if(cmd[u].t==IF) cmd[u].iv2=cmd[u].r; } else if(cmd[v].t==DEFVAR){ while(cmd[cmd[u].r].t!=VARGR) ++cmd[u].r; if(cmd[u].t==IF) cmd[u].iv2=cmd[u].r; } } else{ for(int i{cmd[u].l};i<=cmd[u].r;++i){ if(isblockcmd(cmd[i])) dfsblock(i); } } if( cmd[u].t==IF && cmd[u].r==cmd[u].iv2 && cmd[u].r+1<(int)cmd.size() && cmd[cmd[u].r+1].t==ELSE && (cmd[cmd[u].r+1].iv1==0 || cmd[cmd[u].r+1].iv1==u) ){ cmd[cmd[u].r+1].iv1=u; dfsblock(cmd[u].r+1); cmd[u].r=cmd[cmd[u].r+1].r; } } inline void repair(){ /* "??dp" ???? if(a) if(b) c; else d; else f; ? if(a) if(b) if(c) d; ??????? */ // for(unsigned i{0u};i<cmd.size();++i){ // if(cmd[i].t==IF){ // } // // else if(cmd[i].t==ELSE&&tk[cmd[i].iv1-2]){} // } for(unsigned i{0u};i<cmd.size();++i){ if(cmd[i].t==IF||cmd[i].t==WHILE||cmd[i].t==FOR){ dfsblock(i); i=cmd[i].r; } } } inline void compile(){ /* else ????: ?? else ??? token ? } ??? if,??? } ??? if ??????????? inline if */ unordered_map<int,int> bigmat; auto compile_vars=[](unsigned &i,int endp=-1)->void{ int vacnt{0}; for(++i;;){ if(tk[i+1].sv!="["){ cmd.emplace_back(DEFVAR,0,tk[i].sv); ++vacnt; } else{ vector<int> arrsz; string thisname{tk[i].sv}; while(tk[i+1].sv=="["){ arrsz.emplace_back(tk[i+2].iv); i+=3; } arrinfo[++arrcnt].sz=std::move(arrsz); /* move! */ cmd.emplace_back(DEFVAR,arrcnt,thisname); ++vacnt; } if((endp==-1&&tk[i+1].sv==";")||(endp!=-1&&int(i+1)==endp)){ i+=2; break; } else i+=2; } // if(vacnt>1) cmd.emplace_back(VARGR,vacnt,0,0,0,0); // ??? v1 ??? }; initcompile(); for(unsigned i{0u};i<tk.size();){ if(tk[i].t==RSV){ if(tk[i].sv=="int"){ if(tk[i+2].sv=="("){ /* int main(){ } int fun(int a,int b){ } */ int fid=newfun(tk[i+1].sv); fun[fid].l=cmd.size(); if(tk[i+3].sv!=")"){ for(i+=4;;i+=3){ fun[fid].par.emplace_back(tk[i].sv); if(tk[i+1].sv==")"){i+=2;break;} } } else i+=4; bigmat[i]=bigmat[match[i]]=-fid; ++i; } else{ compile_vars(i); } } else if(tk[i].sv=="if"){ int nxt{match[i+1]+1}; cmd.emplace_back(IF,newexpr(i+1,match[i+1]),0,0,0,0); cmd.back().l=cmd.size(); if(tk[nxt].sv=="{") bigmat[nxt]=bigmat[match[nxt]]=cmd.size()-1,i=nxt+1; else cmd.back().iv2=cmd.back().r=cmd.back().l,cmd.back().inl=true,i=nxt; } else if(tk[i].sv=="else"){ int nxt{(int)i+1}; cmd.emplace_back(ELSE,0,0,0,0,0); if(tk[i-1].sv=="}"&&cmd[bigmat[i-1]].t==IF){ int tt{bigmat[i-1]}; cmd.back().iv1=tt; } cmd.back().l=cmd.size(); cerr<<"nxt="<<nxt<<'\n'; if(tk[nxt].sv=="{") bigmat[nxt]=bigmat[match[nxt]]=cmd.size()-1,i=nxt+1; else cmd.back().r=cmd.back().l,cmd.back().inl=true,i=nxt; } else if(tk[i].sv=="while"){ int nxt{match[i+1]+1}; cmd.emplace_back(WHILE,newexpr(i+1,match[i+1]),0,0,0,0); cmd.back().l=cmd.size(); if(tk[nxt].sv=="{") bigmat[nxt]=bigmat[match[nxt]]=cmd.size()-1,i=nxt+1; else cmd.back().r=cmd.back().l,cmd.back().inl=true,i=nxt; } else if(tk[i].sv=="for"){ cmd.emplace_back(FOR,0,0,0,0,0); int thefor=cmd.size()-1; int eo3{match[i+1]}; i+=2; int l{(int)i}; if(tk[i].t==RSV&&tk[i].sv=="int"){ compile_vars(i); cmd[thefor].iv1=-(cmd.size()-1); } else{ for(i=l;tk[i].sv!=";";++i); cmd[thefor].iv1=newexpr(l,i-1); ++i; } for(l=i;tk[i].sv!=";";++i); cmd[thefor].iv2=newexpr(l,i-1); ++i; if(tk[i].t==RSV&&tk[i].sv=="int"){ compile_vars(i,eo3); cmd[thefor].iv3=-(cmd.size()-1); --i; } else{ for(l=i;(int)i!=eo3;++i); cmd[thefor].iv3=newexpr(l,i-1); } ++i; cmd[thefor].l=cmd.size(); if(tk[i].sv=="{") bigmat[i]=bigmat[match[i]]=thefor,++i; else cmd[thefor].r=cmd[thefor].l,cmd[thefor].inl=true; } else if(tk[i].sv=="return"){ ++i; int l{(int)i}; for(;tk[i].sv!=";";++i); cmd.emplace_back(RET,newexpr(l,i-1),0,0,0,0); ++i; } continue; } else if(tk[i].sv=="{"){ expr.emplace_back(); expr.back().emplace_back(NUM,1); int eid{int(expr.size())-1}; cmd.emplace_back(IF,eid,0,0,0,0); cmd.back().l=cmd.size(); bigmat[i]=bigmat[match[i]]=cmd.size()-1; ++i; } else if(tk[i].sv=="}"){ int mt{bigmat[match[i]]}; if(mt<0){ int fid{-mt}; fun[fid].r=cmd.size()-1; ++i; } else{ int cid{mt}; cmd[cid].r=cmd.size()-1; if(cmd[cid].t==IF) cmd[cid].iv2=cmd.size()-1; ++i; } } else{ int l{(int)i},r{0}; for(;tk[i].sv!=";";++i); r=(int)(i-1); cmd.emplace_back(EXPR,newexpr(l,r),""); ++i; } } auto compile_debug=[](){ cerr<<"Exprs:\n"; for(unsigned i{0u};i<expr.size();++i){ auto &x=expr[i]; cerr<<i<<'.'; outexpr(x); cerr<<'\n'; } cerr<<"Arrays:\n"; for(int i{1};i<=arrcnt;++i){ auto &x=arrinfo[i]; cerr<<i<<'.'; for(int v:x.sz) cerr<<v<<' '; cerr<<'\n'; } cerr<<"Funcs:\n"; for(int i{1};i<=funtop;++i){ auto &x=fun[i]; cerr<<i<<'.'<<x.name<<' '<<x.l<<' '<<x.r<<' '<<x.par.size()<<'\n'; } cerr<<"Cmds:\n"; for(unsigned i{0u};i<cmd.size();++i){ auto &x=cmd[i]; cerr<<i<<'.'; switch(x.t){ case EXPR:cerr<<"[EXPR] ";outexpr(expr[x.iv1]);cerr<<'\n';break; case IF:cerr<<"[IF] "<<x.sv<<' '<<x.iv1<<" "<<" ["<<x.l<<','<<x.iv2<<','<<x.r<<"]\n";break; case ELSE:cerr<<"[ELSE] "<<"match "<<x.iv1<<" ["<<x.l<<','<<x.r<<"]\n";break; case WHILE:cerr<<"[WHILE] "<<x.sv<<' '<<x.iv1<<" ["<<x.l<<','<<x.r<<"]\n";break; case FOR:cerr<<"[FOR] "<<x.sv<<' '<<x.iv1<<' '<<x.iv2<<' '<<x.iv3<<" ["<<x.l<<','<<x.r<<"]\n";break; case DEFVAR:cerr<<"[VAR] "<<x.sv<<' '<<x.iv1<<'\n';break; case VARGR:cerr<<"[VAR GROUP] "<<x.iv1<<'\n';break; case RET:cerr<<"[RETURN] ";outexpr(expr[x.iv1]);cerr<<'\n';break; case DEFFUN:cerr<<"[ERROR:FUNCTION] "<<'\n';break; } } }; repair(); } inline int getvarpos(const string &s,unordered_map<string,int> &locvar){ auto it=locvar.find(s); if(it!=locvar.end()) return it->second; it=globvar.find(s); if(it!=globvar.end()) return it->second; return 0; } inline Val getvar(const string &s,unordered_map<string,int> &locvar){ int p{getvarpos(s,locvar)}; if(isfun.find(s)!=isfun.end()) return Val(FUN,mem[p]); else return Val(REF,p); } inline Val refval(const Val &v){ if(v.t!=REF){return v;} return Val(INT,mem[v.v]); } inline Val callfunc(const Func&,const vector<Val>&); inline Val calc(const Expr &suf,unordered_map<string,int> &locvar){ if(suf.empty()) return Val(INT,1); stack<Val> vs; auto doopr=[&vs](const string &o)->void{ if(o=="<>"){ vector<Val> pars; while(!vs.empty()&&vs.top().t!=FUN){ auto t=vs.top(); vs.pop(); if(t.t==REF) t=refval(t); pars.emplace_back(t); } reverse(pars.begin(),pars.end()); auto t=vs.top(); if(t.t==REF) t=refval(t); auto vv=callfunc(fun[t.v],pars); vs.pop(); vs.emplace(vv); return; } Val a,b,c; if(o=="+u"||o=="-u"||o=="!"){ a=vs.top(),vs.pop(); if(a.t==REF) a=refval(a); } else{ b=vs.top(),vs.pop(); if(o!=">>"&&b.t==REF) b=refval(b); a=vs.top(),vs.pop(); if(o!="="&&a.t==REF) a=refval(a); } c.t=INT; if(o=="+u") c.v=a.v; else if(o=="-u") c.v=-a.v; else if(o=="!") c.v=!a.v; else if(o=="[]") c.t=REF,c.v=a.v+b.v; else if(o=="*") c.v=a.v*b.v; else if(o=="/") c.v=a.v/b.v; else if(o=="%") c.v=a.v%b.v; else if(o=="+") c.v=a.v+b.v; else if(o=="-") c.v=a.v-b.v; else if(o=="<=") c.v=(a.v<=b.v); else if(o==">=") c.v=(a.v>=b.v); else if(o=="<") c.v=(a.v<b.v); else if(o==">") c.v=(a.v>b.v); else if(o=="==") c.v=(a.v==b.v); else if(o=="!=") c.v=(a.v!=b.v); else if(o=="^") c.v=(a.v^b.v); else if(o=="&&") c.v=(a.v&&b.v); else if(o=="||") c.v=(a.v||b.v); else if(o=="=") c.v=mem[a.v]=b.v; else if(o=="<<"){ if(b.v==VALENDL) output+="\n"; else output+=to_string(b.v); c.v=a.v; } else if(o==">>") mem[b.v]=in.read(),c.v=a.v; vs.emplace(c); }; for(auto &crt:suf){ if(crt.t==SYM){ string o{crt.sv}; doopr(o); } else{ if(crt.t==NUM) vs.emplace(INT,crt.iv); else vs.emplace(getvar(crt.sv,locvar)); } } if(vs.top().t==REF) vs.top()=refval(vs.top()); return vs.top(); } inline bool tobool(const Val &v){ return bool(v.v); } inline pair<TermiStat,int> runblock(int l,int r,unordered_map<string,int> &locvar){ if(l>r) return make_pair(NORMAL,0); int oldtop{memtop}; stack<pair<string,int> > newvars; pair<TermiStat,int> ret=make_pair(NORMAL,0); for(int i{l};i<=r;++i){ auto &c=cmd[i]; switch(c.t){ // enum CmdType{EXPR,IF,ELSE,WHILE,FOR,DEFVAR,DEFFUN,RET,VARGR}; case EXPR:{ calc(expr[c.iv1],locvar); break; } case DEFVAR:{ newvars.emplace(c.sv,getvarpos(c.sv,locvar)); if(!c.iv1){ newvar(c.sv,locvar); } else{ newarray(c.sv,arrinfo[c.iv1],locvar); } break; } case VARGR:break; case DEFFUN:break; case IF:{ if(tobool(calc(expr[c.iv1],locvar))){ ret=runblock(c.l,c.iv2,locvar); } else{ ret=runblock(c.iv2+2,c.r,locvar); } if(ret.first==RETURN) return ret; i=c.r; break; } case WHILE:{ while(tobool(calc(expr[c.iv1],locvar))){ ret=runblock(c.l,c.r,locvar); if(ret.first==RETURN) return ret; } i=c.r; break; } case FOR:{ auto forrun=[&locvar](int id)->Val { vector<int> defs; if(id>0){ Val rs=calc(expr[id],locvar); return rs; } if(cmd[-id].t==DEFVAR){ defs.emplace_back(-id); } else{ for(int i{-id-cmd[-id].iv1};i<(-id);++i){ defs.emplace_back(i); } } for(int i:defs){ if(cmd[i].iv1==0) newvar(cmd[i].sv,locvar); else newarray(cmd[i].sv,arrinfo[cmd[i].iv1],locvar); } return Val(INT,0); }; for(forrun(c.iv1);tobool(forrun(c.iv2));forrun(c.iv3)){ ret=runblock(c.l,c.r,locvar); if(ret.first==RETURN) return ret; } i=c.r; break; } case ELSE:break; case RET:{ return make_pair(RETURN,calc(expr[c.iv1],locvar).v); } } } if(&locvar!=&globvar){ for(int i{oldtop+1};i<=memtop;++i) mem[i]=0; while(!newvars.empty()){ auto &t=newvars.top(); if(t.second) locvar[t.first]=t.second; else locvar.erase(t.first); newvars.pop(); } memtop=oldtop; } return make_pair(NORMAL,0); } inline Val callfunc(const Func &ff,const vector<Val> &pars){ stack<pair<string,int> > newvars; if(ff.l==-1){ output+=string(1,char(pars[0].v)); return pars[0]; } int oldtop{memtop}; unordered_map<string,int> locvar; for(unsigned i{0u};i<ff.par.size()&&i<pars.size();++i){ newvars.emplace(ff.par[i],getvarpos(ff.par[i],locvar)); newvar(ff.par[i],locvar); mem[memtop]=pars[i].v; } auto ret=runblock(ff.l,ff.r,locvar); while(!newvars.empty()){ auto &t=newvars.top(); if(t.second) locvar[t.first]=t.second; else locvar.erase(t.first); newvars.pop(); } for(int i{oldtop+1};i<=memtop;++i) mem[i]=0; memtop=oldtop; return (ret.first==RETURN)?Val(INT,ret.second):Val(INT,0); } inline void run(){ sort(fun+1,fun+funtop+1, [](const Func &a,const Func &b)->bool { return a.l<b.l; } ); for(int i{1};i<=funtop;++i){ if(fun[i].l==-1) continue; if(i>1) runblock(max(1,fun[i-1].r+1),fun[i].l-1,globvar); } unordered_map<string,int> ___; auto f=fun[getvar("main",___).v]; // return; callfunc(f,vector<Val>()); } signed main(){ freopen("prog.in","r",stdin); readin(); // cout<<"prog=\n"<<prog<<"\n-------"; lexer(); // return 0; compile(); // “???” run(); fputs(output.c_str(),stdout); puts(""); return 0; } ```
Loading...
点赞
1
收藏
0