From cff41b52e0f801eede5428d97686661b95b9756a Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Sat, 12 Sep 2015 08:25:21 +0200 Subject: Fix `roll` and add its more general cousin `rotate` --- bf.prn | 2 +- functions.cpp | 42 ++++++++++++++++++++++++++++++++++++++---- reference.md | 3 ++- test.prn | 17 +++++++++++++++++ 4 files changed, 58 insertions(+), 6 deletions(-) diff --git a/bf.prn b/bf.prn index 59e9727..c989655 100644 --- a/bf.prn +++ b/bf.prn @@ -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&,unordered_map &S,unordered_map &variables){ BUILTIN_GUARD_STACKSIZE("roll",1) Stackitem ns=move(S.back()); S.pop_back(); @@ -341,7 +341,6 @@ unordered_map&,unordered_map &S,unordered_map &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 tempstore; + tempstore.reserve(times); + const int ssz=S.size(); + for(int i=ssz-times;i tempstore; + tempstore.reserve(times); + const int ssz=S.size(); + for(int i=0;i &S,unordered_map &variables){ BUILTIN_GUARD_STACKSIZE("stridx",2) @@ -473,15 +505,17 @@ unordered_map&,unordered_map &S,unordered_map &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 &S,unordered_map &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 diff --git a/test.prn b/test.prn index 65549f9..ee29b6e 100644 --- a/test.prn +++ b/test.prn @@ -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 -- cgit v1.2.3-70-g09d2