mirror of
https://github.com/louisrubet/rpn
synced 2024-11-17 07:47:50 +01:00
#97: added sto+, sto-, sto*, sto/, sneg, sinv with tests
This commit is contained in:
parent
5517dced37
commit
3c627e43a9
5 changed files with 156 additions and 41 deletions
|
@ -45,7 +45,8 @@ static ret_value entry(program& prog)
|
|||
ret = parse(entry, prog);
|
||||
|
||||
// keep history
|
||||
add_history(entry);
|
||||
if (entry[0] != 0)
|
||||
add_history(entry);
|
||||
}
|
||||
else
|
||||
ret = ret_internal;
|
||||
|
|
|
@ -109,8 +109,8 @@ program::keyword_t program::s_keywords[] =
|
|||
{ cmd_keyword, "sto-", &program::stosub, "substract to a stored variable. ex: 1 'name' sto- 'name' 2 sto-" },
|
||||
{ cmd_keyword, "sto*", &program::stomul, "multiply a stored variable. ex: 3 'name' sto* 'name' 2 sto*" },
|
||||
{ cmd_keyword, "sto/", &program::stodiv, "divide a stored variable. ex: 3 'name' sto/ 'name' 2 sto/" },
|
||||
/*{ cmd_keyword, "sneg", &program::stoneg, "negate a variable. ex: 'name' sneg" },
|
||||
{ cmd_keyword, "sinv", &program::stoinv, "inverse a variable. ex: 1 'name' sinv" },*/
|
||||
{ cmd_keyword, "sneg", &program::stoneg, "negate a variable. ex: 'name' sneg" },
|
||||
{ cmd_keyword, "sinv", &program::stoinv, "inverse a variable. ex: 1 'name' sinv" },
|
||||
|
||||
//PROGRAM
|
||||
{ cmd_undef, "", NULL, "\nPROGRAM"},
|
||||
|
|
|
@ -19,9 +19,12 @@ void stoadd(void)
|
|||
// get variable value on stack level 1, make op then modify variable
|
||||
string variable(((symbol*)_stack->back())->_value);
|
||||
rcl();
|
||||
plus();
|
||||
_heap->add(variable, _stack->get_obj(0), _stack->get_len(0));
|
||||
_stack->pop_back();
|
||||
if (_err == ret_ok)
|
||||
{
|
||||
plus();
|
||||
_heap->add(variable, _stack->get_obj(0), _stack->get_len(0));
|
||||
_stack->pop_back();
|
||||
}
|
||||
}
|
||||
else if (_stack->get_type(1) == cmd_symbol && _stack->get_type(0) == cmd_number)
|
||||
{
|
||||
|
@ -32,10 +35,13 @@ void stoadd(void)
|
|||
|
||||
string variable(((symbol*)_stack->back())->_value);
|
||||
rcl();
|
||||
stack::copy_and_push_back(_branch_stack, _branch_stack.size()-1, *_stack);
|
||||
plus();
|
||||
_heap->add(variable, _stack->get_obj(0), _stack->get_len(0));
|
||||
_stack->pop_back();
|
||||
if (_err == ret_ok)
|
||||
{
|
||||
stack::copy_and_push_back(_branch_stack, _branch_stack.size()-1, *_stack);
|
||||
plus();
|
||||
_heap->add(variable, _stack->get_obj(0), _stack->get_len(0));
|
||||
_stack->pop_back();
|
||||
}
|
||||
}
|
||||
else
|
||||
ERR_CONTEXT(ret_bad_operand_type);
|
||||
|
@ -50,9 +56,12 @@ void stosub(void)
|
|||
// get variable value on stack level 1, make op then modify variable
|
||||
string variable(((symbol*)_stack->back())->_value);
|
||||
rcl();
|
||||
minus();
|
||||
_heap->add(variable, _stack->get_obj(0), _stack->get_len(0));
|
||||
_stack->pop_back();
|
||||
if (_err == ret_ok)
|
||||
{
|
||||
minus();
|
||||
_heap->add(variable, _stack->get_obj(0), _stack->get_len(0));
|
||||
_stack->pop_back();
|
||||
}
|
||||
}
|
||||
else if (_stack->get_type(1) == cmd_symbol && _stack->get_type(0) == cmd_number)
|
||||
{
|
||||
|
@ -63,10 +72,13 @@ void stosub(void)
|
|||
|
||||
string variable(((symbol*)_stack->back())->_value);
|
||||
rcl();
|
||||
stack::copy_and_push_back(_branch_stack, _branch_stack.size()-1, *_stack);
|
||||
minus();
|
||||
_heap->add(variable, _stack->get_obj(0), _stack->get_len(0));
|
||||
_stack->pop_back();
|
||||
if (_err == ret_ok)
|
||||
{
|
||||
stack::copy_and_push_back(_branch_stack, _branch_stack.size()-1, *_stack);
|
||||
minus();
|
||||
_heap->add(variable, _stack->get_obj(0), _stack->get_len(0));
|
||||
_stack->pop_back();
|
||||
}
|
||||
}
|
||||
else
|
||||
ERR_CONTEXT(ret_bad_operand_type);
|
||||
|
@ -81,9 +93,12 @@ void stomul(void)
|
|||
// get variable value on stack level 1, make op then modify variable
|
||||
string variable(((symbol*)_stack->back())->_value);
|
||||
rcl();
|
||||
mul();
|
||||
_heap->add(variable, _stack->get_obj(0), _stack->get_len(0));
|
||||
_stack->pop_back();
|
||||
if (_err == ret_ok)
|
||||
{
|
||||
mul();
|
||||
_heap->add(variable, _stack->get_obj(0), _stack->get_len(0));
|
||||
_stack->pop_back();
|
||||
}
|
||||
}
|
||||
else if (_stack->get_type(1) == cmd_symbol && _stack->get_type(0) == cmd_number)
|
||||
{
|
||||
|
@ -94,10 +109,13 @@ void stomul(void)
|
|||
|
||||
string variable(((symbol*)_stack->back())->_value);
|
||||
rcl();
|
||||
stack::copy_and_push_back(_branch_stack, _branch_stack.size()-1, *_stack);
|
||||
mul();
|
||||
_heap->add(variable, _stack->get_obj(0), _stack->get_len(0));
|
||||
_stack->pop_back();
|
||||
if (_err == ret_ok)
|
||||
{
|
||||
stack::copy_and_push_back(_branch_stack, _branch_stack.size()-1, *_stack);
|
||||
mul();
|
||||
_heap->add(variable, _stack->get_obj(0), _stack->get_len(0));
|
||||
_stack->pop_back();
|
||||
}
|
||||
}
|
||||
else
|
||||
ERR_CONTEXT(ret_bad_operand_type);
|
||||
|
@ -112,9 +130,12 @@ void stodiv(void)
|
|||
// get variable value on stack level 1, make op then modify variable
|
||||
string variable(((symbol*)_stack->back())->_value);
|
||||
rcl();
|
||||
div();
|
||||
_heap->add(variable, _stack->get_obj(0), _stack->get_len(0));
|
||||
_stack->pop_back();
|
||||
if (_err == ret_ok)
|
||||
{
|
||||
div();
|
||||
_heap->add(variable, _stack->get_obj(0), _stack->get_len(0));
|
||||
_stack->pop_back();
|
||||
}
|
||||
}
|
||||
else if (_stack->get_type(1) == cmd_symbol && _stack->get_type(0) == cmd_number)
|
||||
{
|
||||
|
@ -125,10 +146,53 @@ void stodiv(void)
|
|||
|
||||
string variable(((symbol*)_stack->back())->_value);
|
||||
rcl();
|
||||
stack::copy_and_push_back(_branch_stack, _branch_stack.size()-1, *_stack);
|
||||
div();
|
||||
_heap->add(variable, _stack->get_obj(0), _stack->get_len(0));
|
||||
_stack->pop_back();
|
||||
if (_err == ret_ok)
|
||||
{
|
||||
stack::copy_and_push_back(_branch_stack, _branch_stack.size()-1, *_stack);
|
||||
div();
|
||||
_heap->add(variable, _stack->get_obj(0), _stack->get_len(0));
|
||||
_stack->pop_back();
|
||||
}
|
||||
}
|
||||
else
|
||||
ERR_CONTEXT(ret_bad_operand_type);
|
||||
}
|
||||
|
||||
void stoneg(void)
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
|
||||
if (_stack->get_type(0) == cmd_symbol)
|
||||
{
|
||||
// get variable value on stack level 1, make op then modify variable
|
||||
string variable(((symbol*)_stack->back())->_value);
|
||||
rcl();
|
||||
if (_err == ret_ok)
|
||||
{
|
||||
neg();
|
||||
_heap->add(variable, _stack->get_obj(0), _stack->get_len(0));
|
||||
_stack->pop_back();
|
||||
}
|
||||
}
|
||||
else
|
||||
ERR_CONTEXT(ret_bad_operand_type);
|
||||
}
|
||||
|
||||
void stoinv(void)
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
|
||||
if (_stack->get_type(0) == cmd_symbol)
|
||||
{
|
||||
// get variable value on stack level 1, make op then modify variable
|
||||
string variable(((symbol*)_stack->back())->_value);
|
||||
rcl();
|
||||
if (_err == ret_ok)
|
||||
{
|
||||
inv();
|
||||
_heap->add(variable, _stack->get_obj(0), _stack->get_len(0));
|
||||
_stack->pop_back();
|
||||
}
|
||||
}
|
||||
else
|
||||
ERR_CONTEXT(ret_bad_operand_type);
|
||||
|
@ -199,14 +263,10 @@ void auto_rcl(symbol* symb)
|
|||
eval();
|
||||
}
|
||||
else
|
||||
{
|
||||
stack::copy_and_push_back(symb, *_stack, symb->size());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stack::copy_and_push_back(symb, *_stack, symb->size());
|
||||
}
|
||||
}
|
||||
|
||||
void purge(void)
|
||||
|
@ -227,7 +287,7 @@ void vars(void)
|
|||
string name;
|
||||
|
||||
// heap variables
|
||||
for (int i=0; i<(int)_heap->size(); i++)
|
||||
for (int i=0; i<(int)_heap->count_vars(); i++)
|
||||
{
|
||||
(void)_heap->get_by_index(i, name, obj, size);
|
||||
printf("var %d: name '%s', type %s, value ", i+1, name.c_str(), object::s_cmd_type_string[obj->_type]);
|
||||
|
|
|
@ -204,7 +204,7 @@ public:
|
|||
if (local==NULL || (local!=NULL && size>local->_size))
|
||||
{
|
||||
copy_and_push_back(obj, *this, size);
|
||||
_map[name] = this->size()-1;
|
||||
_map[name] = ((stack*)this)->size()-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -282,13 +282,16 @@ public:
|
|||
|
||||
if (i != _map.end())
|
||||
{
|
||||
// remove variable from map
|
||||
_map.erase(i->first);
|
||||
ret = true;
|
||||
|
||||
// TODO: remove unused stack entries
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned int size() { return _map.size(); }
|
||||
unsigned int count_vars() { return _map.size(); }
|
||||
|
||||
private:
|
||||
map<string, unsigned int> _map;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
## VARS
|
||||
## STORE
|
||||
|
||||
# symbol entry
|
||||
'test'
|
||||
|
@ -36,6 +36,11 @@ erase
|
|||
-> stack should be 2
|
||||
erase
|
||||
|
||||
# sto (3)
|
||||
3 'b' sto b
|
||||
-> stack should be 3
|
||||
erase
|
||||
|
||||
# rcl (1)
|
||||
'a' rcl
|
||||
-> stack should be 2
|
||||
|
@ -43,8 +48,13 @@ erase
|
|||
|
||||
# rcl (2)
|
||||
'b' rcl
|
||||
-> stack should be 3
|
||||
erase
|
||||
|
||||
# rcl (2)
|
||||
'var' rcl
|
||||
-> error should be 5
|
||||
-> stack should be 'b'
|
||||
-> stack should be 'var'
|
||||
erase
|
||||
|
||||
# sto in prog then rcl
|
||||
|
@ -63,6 +73,11 @@ erase
|
|||
-> stack size should be 0
|
||||
erase
|
||||
|
||||
# purge (3)
|
||||
3 'a' sto a 'a' purge
|
||||
-> stack should be 3
|
||||
erase
|
||||
|
||||
# sto+ (1)
|
||||
8 'a' sto
|
||||
2 'a' sto+
|
||||
|
@ -83,6 +98,12 @@ erase
|
|||
-> error should be 2
|
||||
erase
|
||||
|
||||
# sto+ (4)
|
||||
3 'zz' sto+
|
||||
-> stack should be 3, 'zz'
|
||||
-> error should be 5
|
||||
erase
|
||||
|
||||
# sto- (1)
|
||||
2 'a' sto
|
||||
2 'a' sto-
|
||||
|
@ -103,6 +124,12 @@ erase
|
|||
-> error should be 2
|
||||
erase
|
||||
|
||||
# sto- (4)
|
||||
3 'zz' sto-
|
||||
-> stack should be 3, 'zz'
|
||||
-> error should be 5
|
||||
erase
|
||||
|
||||
# sto* (1)
|
||||
2 'a' sto
|
||||
3 'a' sto*
|
||||
|
@ -123,6 +150,12 @@ erase
|
|||
-> error should be 2
|
||||
erase
|
||||
|
||||
# sto* (4)
|
||||
3 'zz' sto*
|
||||
-> stack should be 3, 'zz'
|
||||
-> error should be 5
|
||||
erase
|
||||
|
||||
# sto/ (1)
|
||||
2 'a' sto
|
||||
6 'a' sto/
|
||||
|
@ -143,6 +176,12 @@ erase
|
|||
-> error should be 2
|
||||
erase
|
||||
|
||||
# sto/ (4)
|
||||
3 'zz' sto/
|
||||
-> stack should be 3, 'zz'
|
||||
-> error should be 5
|
||||
erase
|
||||
|
||||
# sneg (1)
|
||||
7 'a' sto
|
||||
'a' sneg
|
||||
|
@ -155,9 +194,15 @@ sneg
|
|||
-> error should be 2
|
||||
erase
|
||||
|
||||
# sneg (3)
|
||||
'zz' sneg
|
||||
-> error should be 5
|
||||
-> stack should be 'zz'
|
||||
erase
|
||||
|
||||
# sinv (1)
|
||||
4 'a' sto
|
||||
'a' sneg
|
||||
'a' sinv
|
||||
a
|
||||
-> stack should be 0.25
|
||||
erase
|
||||
|
@ -166,3 +211,9 @@ erase
|
|||
sinv
|
||||
-> error should be 2
|
||||
erase
|
||||
|
||||
# sinv (3)
|
||||
'zz' sinv
|
||||
-> error should be 5
|
||||
-> stack should be 'zz'
|
||||
erase
|
||||
|
|
Loading…
Reference in a new issue