diff options
Diffstat (limited to 'functions.cpp')
-rw-r--r-- | functions.cpp | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/functions.cpp b/functions.cpp index f4beeb9..4e67bfa 100644 --- a/functions.cpp +++ b/functions.cpp @@ -321,7 +321,7 @@ unordered_map<string,function<void(vector<Stackitem>&,unordered_map<string,Stack } scopestack.pop(); }}, - //positive n: roll OFF top to bottom; negative n: roll off bottom ONTO top + //positive n: roll off bottom ONTO top (clockwise); negative n: roll OFF top to bottom (anti-clockwise) {"roll",[](vector<Stackitem> &S,unordered_map<string,Stackitem> &variables){ BUILTIN_GUARD_STACKSIZE("roll",1) Stackitem ns=move(S.back()); S.pop_back(); @@ -341,7 +341,6 @@ unordered_map<string,function<void(vector<Stackitem>&,unordered_map<string,Stack S.insert(S.begin(),n,Stackitem()); for(int i=0;i<n;i++)S[i]=move(tempstore[i]); } else { - //cerr<<"rolling back n="<<n<<endl; vector<Stackitem> tempstore; tempstore.reserve(n); for(int i=0;i<n;i++)tempstore.push_back(move(S[i])); @@ -349,6 +348,39 @@ unordered_map<string,function<void(vector<Stackitem>&,unordered_map<string,Stack for(int i=0;i<n;i++)S.push_back(move(tempstore[i])); } }}, + //positive n: rotate off bottom ONTO top (clockwise); negative n: rotate OFF top to bottom (anti-clockwise) + {"rotate",[](vector<Stackitem> &S,unordered_map<string,Stackitem> &variables){ + BUILTIN_GUARD_STACKSIZE("rotate",2) + Stackitem timess=move(S.back()); S.pop_back(); + Stackitem ns=move(S.back()); S.pop_back(); + if(ns.type!=SIT_INT)throw string("First argument to 'rotate' not a number"); + if(timess.type!=SIT_INT)throw string("Second argument to 'rotate' not a number"); + int n=ns.intval,times=timess.intval; + bool negative=times<0; + if(negative)times=-times; + if(n>S.size()||n<0)throw string("Invalid number of items in builtin 'rotate'"); + if(n==0)return; + if(S.size()<2)return; + times%=n; + if(times==0)return; + + if(negative){ + vector<Stackitem> tempstore; + tempstore.reserve(times); + const int ssz=S.size(); + for(int i=ssz-times;i<ssz;i++)tempstore.push_back(move(S[i])); + S.erase(S.end()-times,S.end()); + S.insert(S.end()-(n-times),times,Stackitem()); + for(int i=0;i<times;i++)S[ssz-n+i]=move(tempstore[i]); + } else { + vector<Stackitem> tempstore; + tempstore.reserve(times); + const int ssz=S.size(); + for(int i=0;i<times;i++)tempstore.push_back(move(S[ssz-n+i])); + S.erase(S.end()-n,S.end()-(n-times)); + for(int i=0;i<times;i++)S.push_back(move(tempstore[i])); + } + }}, //leaves the string on the stack {"stridx",[](vector<Stackitem> &S,unordered_map<string,Stackitem> &variables){ BUILTIN_GUARD_STACKSIZE("stridx",2) @@ -473,15 +505,17 @@ unordered_map<string,function<void(vector<Stackitem>&,unordered_map<string,Stack }}, {"rand",[](vector<Stackitem> &S,unordered_map<string,Stackitem> &variables){ BUILTIN_GUARD_STACKSIZE("rand",0) - assert(RAND_MAX==0x7fffffff); +#if RAND_MAX != 0x7fffffff +# error RAND_MAX should be 0x7fffffff for Postrun +#endif S.emplace_back(rand()); }}, //`to` exclusive {"randr",[](vector<Stackitem> &S,unordered_map<string,Stackitem> &variables){ BUILTIN_GUARD_STACKSIZE("rand",2) assert(RAND_MAX==0x7fffffff); - const Stackitem from=move(S.back()); S.pop_back(); const Stackitem to=move(S.back()); S.pop_back(); + const Stackitem from=move(S.back()); S.pop_back(); if(from.type!=SIT_INT)throw string("First argument to 'randr' not a number"); if(to.type!=SIT_INT)throw string("Second argument to 'randr' not a number"); if(to.intval<=from.intval)throw string("Arguments to 'randr' form an empty range"); |