#77: added roll, rolld, over, dupn, dropn

This commit is contained in:
Louis Rubet 2017-05-27 14:08:09 +02:00
parent 3059ec233f
commit db567f79ad
4 changed files with 156 additions and 16 deletions

View file

@ -107,13 +107,18 @@ Quick examples:
|swap| swap 2 first stack entries
|drop| drop first stack entry
|drop2| drop 2 first stack entries
|dropn| drop n first stack entries
|erase| drop all stack entries
|rot| rotate 3 first stack entries
|dup| duplicate first stack entry
|dup2| duplicate 2 first stack entries
|dupn| duplicate n first stack entries
|pick| push a copy of the given stack level onto the stack
|depth| give stack depth
|roll| move a stack entry to the top of the stack
|rolld| move the element on top of the stack to a higher stack position
|over| push a copy of the element in stack level 2 onto the stack
|STRING||
|-|-|
|->str| convert an object into a string

View file

@ -71,12 +71,17 @@ program::keyword_t program::s_keywords[] =
{ cmd_keyword, "swap", &program::swap, "swap 2 first stack entries" },
{ cmd_keyword, "drop", &program::drop, "drop first stack entry" },
{ cmd_keyword, "drop2", &program::drop2, "drop 2 first stack entries" },
{ cmd_keyword, "dropn", &program::dropn, "drop n first stack entries" },
{ cmd_keyword, "erase", &program::erase, "drop all stack entries" },
{ cmd_keyword, "rot", &program::rot, "rotate 3 first stack entries" },
{ cmd_keyword, "dup", &program::dup, "duplicate first stack entry" },
{ cmd_keyword, "dup2", &program::dup2, "duplicate 2 first stack entries" },
{ cmd_keyword, "dupn", &program::dupn, "duplicate n first stack entries" },
{ cmd_keyword, "pick", &program::pick, "push a copy of the given stack level onto the stack" },
{ cmd_keyword, "depth", &program::depth, "give stack depth" },
{ cmd_keyword, "roll", &program::roll, "move a stack entry to the top of the stack" },
{ cmd_keyword, "rolld", &program::rolld, "move the element on top of the stack to a higher stack position" },
{ cmd_keyword, "over", &program::over, "push a copy of the element in stack level 2 onto the stack" },
//STRING
{ cmd_undef, "", NULL, "\nSTRING"},

View file

@ -8,8 +8,7 @@ void swap(void)
(void)_stack->pop_back();
stack::copy_and_push_back(_branch_stack, 0, *_stack);
stack::copy_and_push_back(_branch_stack, 1, *_stack);
(void)_branch_stack.pop_back();
(void)_branch_stack.pop_back();
_branch_stack.erase();
}
void drop(void)
@ -25,6 +24,18 @@ void drop2(void)
(void)_stack->pop_back();
}
void dropn(void)
{
MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_number);
int args = (int)mpfr_get_si(((number*)_stack->back())->_value.mpfr, floating_t::s_mpfr_rnd);
MIN_ARGUMENTS(args+1);
for(int i=0;i<args+1;i++)
(void)_stack->pop_back();
}
void erase(void)
{
while(_stack->size()>0)
@ -44,6 +55,19 @@ void dup2(void)
stack::copy_and_push_back(*_stack, _stack->size()-2, *_stack);
}
void dupn(void)
{
MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_number);
int args = (int)mpfr_get_si(((number*)_stack->back())->_value.mpfr, floating_t::s_mpfr_rnd);
MIN_ARGUMENTS(args+1);
_stack->pop_back();
for (int i=0;i<args;i++)
stack::copy_and_push_back(*_stack, _stack->size()-args, *_stack);
}
void pick(void)
{
MIN_ARGUMENTS(1);
@ -74,9 +98,7 @@ void rot(void)
stack::copy_and_push_back(_branch_stack, 1, *_stack);
stack::copy_and_push_back(_branch_stack, 2, *_stack);
stack::copy_and_push_back(_branch_stack, 0, *_stack);
(void)_branch_stack.pop_back();
(void)_branch_stack.pop_back();
(void)_branch_stack.pop_back();
_branch_stack.erase();
}
void depth(void)
@ -85,3 +107,54 @@ void depth(void)
number* num = (number*)_stack->allocate_back(number::calc_size(), cmd_number);
num->set(depth);
}
void roll(void)
{
MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_number);
int args = (int)mpfr_get_si(((number*)_stack->back())->_value.mpfr, floating_t::s_mpfr_rnd);
MIN_ARGUMENTS(args+1);
_stack->pop_back();
for(int i=0;i<args;i++)
{
stack::copy_and_push_back(*_stack, _stack->size()-1, _branch_stack);
(void)_stack->pop_back();
}
for(int i=1;i<args;i++)
stack::copy_and_push_back(_branch_stack, args-1-i, *_stack);
stack::copy_and_push_back(_branch_stack, args-1, *_stack);
_branch_stack.erase();
}
void rolld(void)
{
MIN_ARGUMENTS(2);
ARG_MUST_BE_OF_TYPE(0, cmd_number);
int args = (int)mpfr_get_si(((number*)_stack->back())->_value.mpfr, floating_t::s_mpfr_rnd);
MIN_ARGUMENTS(args+1);
_stack->pop_back();
for(int i=0;i<args;i++)
{
stack::copy_and_push_back(*_stack, _stack->size()-1, _branch_stack);
(void)_stack->pop_back();
}
stack::copy_and_push_back(_branch_stack, 0, *_stack);
for(int i=1;i<args;i++)
stack::copy_and_push_back(_branch_stack, args-i, *_stack);
_branch_stack.erase();
}
void over(void)
{
MIN_ARGUMENTS(2);
stack::copy_and_push_back(*_stack, _stack->size()-2, *_stack);
}

View file

@ -1,15 +1,15 @@
## STACK TEST
# entry depth 1
1
-> stack size should be 1
# entry depth (1)
1 depth
-> stack size should be 2
# entry depth 2
2 3
-> stack size should be 3
-> stack should be 1, 2, 3
# entry depth (2)
erase depth
-> stack should be 0
# drop
drop
erase
1 2 3 drop
-> stack size should be 2
# drop2
@ -20,11 +20,11 @@ drop2
drop
-> error should be 2
# drop2 error
# drop2 error (1)
drop2
-> error should be 2
# drop2 error
# drop2 error (2)
1 drop2
-> error should be 2
drop
@ -65,3 +65,60 @@ erase
# test erase
erase
-> stack size should be 0
# test dropn
erase
1 2 2 dropn
-> stack size should be 0
# test dropn error
erase
1 2 3 dropn
-> stack size should be 3
-> error should be 2
# test dupn
erase
1 2 3 4 3 dupn
-> stack should be 1, 2, 3, 4, 2, 3, 4
# test dupn error
erase
1 2 3 4 5 dupn
-> stack size should be 5
-> error should be 2
# test roll
erase
1 2 3 4 5 4 roll
-> stack should be 1, 3, 4, 5, 2
# test roll error
erase
1 2 3 4 5 6 roll
-> stack size should be 6
-> error should be 2
# test rolld
erase
10 20 30 40 50 3 rolld
-> stack should be 10, 20, 50, 30, 40
# test roll error
erase
1 2 3 4 5 6 roll
-> stack size should be 6
-> error should be 2
# test over
erase
3.14 15.16 over
-> stack should be 3.14, 15.16, 3.14
# test over error
erase
2 over
-> stack size should be 1
-> error should be 2
erase