diff options
| -rw-r--r-- | bf.prn | 2 | ||||
| -rw-r--r-- | functions.cpp | 42 | ||||
| -rw-r--r-- | reference.md | 3 | ||||
| -rw-r--r-- | test.prn | 17 | 
4 files changed, 58 insertions, 6 deletions
@@ -75,7 +75,7 @@ dup 0 > while  			else  				ord 256 %  			end -			#{}"Input put on stack " print dup print lf +			#"Input put on stack " print dup print lf  		end  		c ">" = if -1 roll end  		c "<" = if 1 roll end 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"); diff --git a/reference.md b/reference.md index 13c7b2f..807664a 100644 --- a/reference.md +++ b/reference.md @@ -35,7 +35,8 @@ n `get` | Get value of variable with name `n`  n `swapoutvar` | Get value of variable with name `n`, *moving* onto the stack instead of copying  `enterscope` | Enter a function variable scope  `leavescope` | Leave a function variable scope -n `roll` | Roll the stack by `n`; positive n: roll OFF top to bottom; negative n: roll off bottom ONTO top +t `roll` | Roll the stack `t` times; positive n: roll off bottom ONTO top (clockwise); negative n: roll OFF top to bottom (anti-clockwise) +n t `rotate` | Rotate the top `n` items of the stack `t` times; positive n: rotate off bottom ONTO top (clockwise); negative n: rotate OFF top to bottom (anti-clockwise)  s i `stridx` | Gets the character in string `s` index `i`, leaving `s` on the stack  s `strlen` | Gets the length of string `s`, leaving `s` on the stack  s a b `substr` | Gets the substring in `s` from index `a` to `b`, `b` exclusive; leaving `s` on the stack @@ -20,3 +20,20 @@ end  42 "vv" store  vv print lf + +pop + +1 2 3 4 5 6 stackdump +4 1 rotate stackdump +4 1 rotate stackdump +4 1 rotate stackdump +4 1 rotate stackdump +5 2 rotate stackdump +5 -2 rotate stackdump +lf +6 -1 rotate stackdump +6 5 rotate stackdump +-1 roll stackdump +6 1 rotate stackdump +6 7 rotate stackdump +1 roll stackdump  | 
