diff --git a/README.md b/README.md index 3f92b27..57ace20 100644 --- a/README.md +++ b/README.md @@ -158,6 +158,8 @@ rpn> |then| true-instructions |else| false-instructions |end| (end of if structure) +|ift| similar to if-then-end, ift" +|ifte| similar to if-then-else-end, ifte" |start| repeat instructions several times |for| repeat instructions several times with variable |next| ex: ```1 10 start next``` diff --git a/src/program.cpp b/src/program.cpp index a7b3912..a13765f 100644 --- a/src/program.cpp +++ b/src/program.cpp @@ -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 next" }, { cmd_branch, "step", (program_fn_t)&program::rpn_step, "ex: 1 100 start 4 step" }, + { cmd_keyword, "ift", &program::rpn_ift, "similar to if-then-end, ift" }, + { cmd_keyword, "ifte",&program::rpn_ifte, "similar to if-then-else-end, ifte" }, //STORE { cmd_undef, "", NULL, "\nSTORE"}, diff --git a/src/rpn-branch.hpp b/src/rpn-branch.hpp index 4c46b08..71c85dc 100644 --- a/src/rpn-branch.hpp +++ b/src/rpn-branch.hpp @@ -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; diff --git a/test/04-branch.txt b/test/04-branch.txt index eed00a3..1345064 100644 --- a/test/04-branch.txt +++ b/test/04-branch.txt @@ -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