#113: added BRANCH commands ift, ifte

This commit is contained in:
Louis Rubet 2017-06-01 15:39:21 +02:00
parent 869e3fecc7
commit 8635c870b4
4 changed files with 103 additions and 0 deletions

View file

@ -158,6 +158,8 @@ rpn>
|then| true-instructions
|else| false-instructions
|end| (end of if structure)
|ift| similar to if-then-end, <test-instruction> <true-instruction> ift"
|ifte| similar to if-then-else-end, <test-instruction> <true-instruction> <false-instruction> ifte"
|start| repeat instructions several times
|for| repeat instructions several times with variable
|next| ex: ```1 10 start <instructions> next```

View file

@ -108,6 +108,8 @@ program::keyword_t program::s_keywords[] =
{ cmd_branch, "for", (program_fn_t)&program::rpn_for, "repeat instructions several times with variable" },
{ cmd_branch, "next", (program_fn_t)&program::rpn_next, "ex: 1 10 start <instructions> next" },
{ cmd_branch, "step", (program_fn_t)&program::rpn_step, "ex: 1 100 start <instructions> 4 step" },
{ cmd_keyword, "ift", &program::rpn_ift, "similar to if-then-end, <test-instruction> <true-instruction> ift" },
{ cmd_keyword, "ifte",&program::rpn_ifte, "similar to if-then-else-end, <test-instruction> <true-instruction> <false-instruction> ifte" },
//STORE
{ cmd_undef, "", NULL, "\nSTORE"},

View file

@ -46,6 +46,55 @@ void rpn_end(void)
// nothing
}
//
void rpn_ift(void)
{
MIN_ARGUMENTS(2);
ARG_MUST_BE_OF_TYPE(1, cmd_number);
// check ift arg
// arg is true if number != 0 or if is nan or +/-inf
number* testee = ((number*)_stack->get_obj(1));
if (!mpfr_zero_p(testee->_value.mpfr))
{
CHECK_MPFR(stack::copy_and_push_back(*_stack, _stack->size()-1, _branch_stack));
(void)_stack->pop_back();
(void)_stack->pop_back();
CHECK_MPFR(stack::copy_and_push_back(_branch_stack, _branch_stack.size()-1, *_stack));
(void)_branch_stack.pop_back();
}
else
{
(void)_stack->pop_back();
(void)_stack->pop_back();
}
}
void rpn_ifte(void)
{
MIN_ARGUMENTS(3);
ARG_MUST_BE_OF_TYPE(2, cmd_number);
// check ifte arg
// arg is true if number != 0 or if is nan or +/-inf
number* testee = ((number*)_stack->get_obj(2));
if (!mpfr_zero_p(testee->_value.mpfr))
CHECK_MPFR(stack::copy_and_push_back(*_stack, _stack->size()-2, _branch_stack));
else
CHECK_MPFR(stack::copy_and_push_back(*_stack, _stack->size()-1, _branch_stack));
(void)_stack->pop_back();
(void)_stack->pop_back();
(void)_stack->pop_back();
CHECK_MPFR(stack::copy_and_push_back(_branch_stack, _branch_stack.size()-1, *_stack));
(void)_branch_stack.pop_back();
}
//
int rpn_start(branch& myobj)
{
int ret = -1;

View file

@ -80,6 +80,56 @@ erase
-> error should be 3
erase
# ift (1)
1 'ok' ift
-> stack should be 'ok'
erase
# ift (2)
0 'ok' ift
-> stack size should be 0
erase
# ift (3)
'ok' ift
-> error should be 2
-> stack size should be 1
erase
# ift (4)
ift
-> error should be 2
-> stack size should be 0
erase
# ifte (1)
1 'ok' 'nok' ifte
-> stack should be 'ok'
erase
# ifte (2)
0 'ok' 'nok' ifte
-> stack should be 'nok'
erase
# ifte (3)
'ok' 'nok' ifte
-> error should be 2
-> stack size should be 2
erase
# ifte (4)
'nok' ifte
-> error should be 2
-> stack size should be 1
erase
# ifte (5)
ifte
-> error should be 2
-> stack size should be 0
erase
# start next (1)
1 2 start 0 next
-> stack should be 0, 0