#include #include #include #include #include #undef RIPMODE #undef DEBUGMODE using namespace std; typedef mpz_class ripint; template int integral(T v){ return (int)v; } template <> int integral(mpz_class v){ return v.get_si(); } template class Llist{ struct Node{ T value; Node *prev,*next; inline Node(void):prev(NULL),next(NULL){} }; Node *first,*last; int sz; public: inline Llist(void):first(NULL),last(NULL),sz(0){} inline ~Llist(void){ Node *n; while(first){ n=first->next; delete first; first=n; } } inline int size(void){return sz;} inline void push_back(T v){ Node *n=new Node; swap(n->value,v); if(last==NULL)first=last=n; else { last->next=n; n->prev=last; last=n; } sz++; } inline void push_front(T v){ Node *n=new Node; swap(n->value,v); if(first==NULL)first=last=n; else { first->prev=n; n->next=first; first=n; } sz++; } inline void pop_back(void){ if(last==NULL)throw length_error("pop_back on empty Llist"); Node *n=last; last=last->prev; if(last==NULL)first=NULL; else last->next=NULL; delete n; sz--; } inline void pop_front(void){ if(first==NULL)throw length_error("pop_front on empty Llist"); Node *n=first; first=first->next; if(first==NULL)last=NULL; else first->prev=NULL; delete n; sz--; } inline T& back(void){ if(last==NULL)throw length_error("back on empty Llist"); return last->value; } inline T& front(void){ if(first==NULL)throw length_error("front on empty Llist"); return first->value; } inline void* itemp(int i){ if(i>=0){ Node *n=first; while(i-->0)n=n->next; return n; } else { Node *n=last; while(++i<0)n=n->prev; return n; } } inline void* frontp(void){return first;} inline void* backp(void){return last;} inline void erase(void *p){ Node *n=(Node*)p; if(n->prev)n->prev->next=n->next; else first=n->next; if(n->next)n->next->prev=n->prev; else last=n->prev; sz--; delete n; } inline void insertafter(void *after,T v){ Node *aftern=(Node*)after; Node *n=new Node; swap(n->value,v); n->prev=aftern; if(aftern->next){ n->next=aftern->next; aftern->next->prev=n; aftern->next=n; } else { aftern->next=n; last=n; } sz++; } static inline void* nextp(void *p){return ((Node*)p)->next;} static inline void* prevp(void *p){return ((Node*)p)->prev;} static inline T& valueof(void *p){return ((Node*)p)->value;} }; #ifdef RIPMODE void riperror(string){ cerr<<"rip"< stack; int i; int iwidx=-1,fidx=-1,lastangleidx=-1; for(i=0;i')break; if(i==len)riperror("Unmatched open '<'"); jumpmap[start]=i; lastangleidx=i; //the '>' } else if(code[i]=='>'){ riperror("Unexpected closing '>'"); } else if(code[i]=='W'||code[i]=='I'){ iwidx=i; } else if(code[i]=='F'){ fidx=i; } if(iwidx!=i)iwidx=-1; if(fidx!=i)fidx=-1; if(lastangleidx!=i)lastangleidx=-1; } } void runcode(const char *code,const int *jumpmap,Llist &stack,const int startat=0){ int i; for(i=startat;code[i];i++){ #ifdef DEBUGMODE cout<<'['; for(void *p=stack.frontp();p;p=Llist::nextp(p)){ cout<::valueof(p)<<' '; } cout<<']'<='0'&&code[i]<='9'){ stack.push_back(code[i]-'0'); continue; } switch(code[i]){ case 'P': stack.pop_back(); break; case 'S':{ const ripint b=move(stack.back()); stack.pop_back(); const ripint a=move(stack.back()); stack.pop_back(); stack.push_back(b); stack.push_back(a); break; } case 'D': stack.push_back(stack.back()); break; case 'i': stack.back()++; break; case 'd': stack.back()--; break; case 'r':{ const int n=integral(move(stack.back())); stack.pop_back(); const ripint value=move(stack.back()); stack.pop_back(); if(n==stack.size()+1)stack.push_front(value); else { void *const before=stack.itemp(-n); stack.insertafter(before,value); } break; } case 'R':{ const int n=integral(move(stack.back())); stack.pop_back(); void *const p=stack.itemp(-n); stack.push_back(Llist::valueof(p)); stack.erase(p); break; } case 'l': stack.push_back(stack.size()); break; case 'a': case 's': case 'm': case 'q': case 'G': case 'L': case 'E':{ const ripint b=move(stack.back()); stack.pop_back(); const ripint a=move(stack.back()); stack.pop_back(); switch(code[i]){ case 'a': stack.push_back(a+b); break; case 's': stack.push_back(a-b); break; case 'm': stack.push_back(a*b); break; case 'q': stack.push_back(a/b); break; case 'G': stack.push_back(a>b); break; case 'L': stack.push_back(a stack; runcode(code,jumpmap,stack); delete[] jumpmap; delete[] code; }