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);
|
ret = parse(entry, prog);
|
||||||
|
|
||||||
// keep history
|
// keep history
|
||||||
add_history(entry);
|
if (entry[0] != 0)
|
||||||
|
add_history(entry);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ret = ret_internal;
|
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::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::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, "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, "sneg", &program::stoneg, "negate a variable. ex: 'name' sneg" },
|
||||||
{ cmd_keyword, "sinv", &program::stoinv, "inverse a variable. ex: 1 'name' sinv" },*/
|
{ cmd_keyword, "sinv", &program::stoinv, "inverse a variable. ex: 1 'name' sinv" },
|
||||||
|
|
||||||
//PROGRAM
|
//PROGRAM
|
||||||
{ cmd_undef, "", NULL, "\nPROGRAM"},
|
{ cmd_undef, "", NULL, "\nPROGRAM"},
|
||||||
|
|
|
@ -19,9 +19,12 @@ void stoadd(void)
|
||||||
// get variable value on stack level 1, make op then modify variable
|
// get variable value on stack level 1, make op then modify variable
|
||||||
string variable(((symbol*)_stack->back())->_value);
|
string variable(((symbol*)_stack->back())->_value);
|
||||||
rcl();
|
rcl();
|
||||||
plus();
|
if (_err == ret_ok)
|
||||||
_heap->add(variable, _stack->get_obj(0), _stack->get_len(0));
|
{
|
||||||
_stack->pop_back();
|
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)
|
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);
|
string variable(((symbol*)_stack->back())->_value);
|
||||||
rcl();
|
rcl();
|
||||||
stack::copy_and_push_back(_branch_stack, _branch_stack.size()-1, *_stack);
|
if (_err == ret_ok)
|
||||||
plus();
|
{
|
||||||
_heap->add(variable, _stack->get_obj(0), _stack->get_len(0));
|
stack::copy_and_push_back(_branch_stack, _branch_stack.size()-1, *_stack);
|
||||||
_stack->pop_back();
|
plus();
|
||||||
|
_heap->add(variable, _stack->get_obj(0), _stack->get_len(0));
|
||||||
|
_stack->pop_back();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ERR_CONTEXT(ret_bad_operand_type);
|
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
|
// get variable value on stack level 1, make op then modify variable
|
||||||
string variable(((symbol*)_stack->back())->_value);
|
string variable(((symbol*)_stack->back())->_value);
|
||||||
rcl();
|
rcl();
|
||||||
minus();
|
if (_err == ret_ok)
|
||||||
_heap->add(variable, _stack->get_obj(0), _stack->get_len(0));
|
{
|
||||||
_stack->pop_back();
|
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)
|
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);
|
string variable(((symbol*)_stack->back())->_value);
|
||||||
rcl();
|
rcl();
|
||||||
stack::copy_and_push_back(_branch_stack, _branch_stack.size()-1, *_stack);
|
if (_err == ret_ok)
|
||||||
minus();
|
{
|
||||||
_heap->add(variable, _stack->get_obj(0), _stack->get_len(0));
|
stack::copy_and_push_back(_branch_stack, _branch_stack.size()-1, *_stack);
|
||||||
_stack->pop_back();
|
minus();
|
||||||
|
_heap->add(variable, _stack->get_obj(0), _stack->get_len(0));
|
||||||
|
_stack->pop_back();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ERR_CONTEXT(ret_bad_operand_type);
|
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
|
// get variable value on stack level 1, make op then modify variable
|
||||||
string variable(((symbol*)_stack->back())->_value);
|
string variable(((symbol*)_stack->back())->_value);
|
||||||
rcl();
|
rcl();
|
||||||
mul();
|
if (_err == ret_ok)
|
||||||
_heap->add(variable, _stack->get_obj(0), _stack->get_len(0));
|
{
|
||||||
_stack->pop_back();
|
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)
|
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);
|
string variable(((symbol*)_stack->back())->_value);
|
||||||
rcl();
|
rcl();
|
||||||
stack::copy_and_push_back(_branch_stack, _branch_stack.size()-1, *_stack);
|
if (_err == ret_ok)
|
||||||
mul();
|
{
|
||||||
_heap->add(variable, _stack->get_obj(0), _stack->get_len(0));
|
stack::copy_and_push_back(_branch_stack, _branch_stack.size()-1, *_stack);
|
||||||
_stack->pop_back();
|
mul();
|
||||||
|
_heap->add(variable, _stack->get_obj(0), _stack->get_len(0));
|
||||||
|
_stack->pop_back();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ERR_CONTEXT(ret_bad_operand_type);
|
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
|
// get variable value on stack level 1, make op then modify variable
|
||||||
string variable(((symbol*)_stack->back())->_value);
|
string variable(((symbol*)_stack->back())->_value);
|
||||||
rcl();
|
rcl();
|
||||||
div();
|
if (_err == ret_ok)
|
||||||
_heap->add(variable, _stack->get_obj(0), _stack->get_len(0));
|
{
|
||||||
_stack->pop_back();
|
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)
|
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);
|
string variable(((symbol*)_stack->back())->_value);
|
||||||
rcl();
|
rcl();
|
||||||
stack::copy_and_push_back(_branch_stack, _branch_stack.size()-1, *_stack);
|
if (_err == ret_ok)
|
||||||
div();
|
{
|
||||||
_heap->add(variable, _stack->get_obj(0), _stack->get_len(0));
|
stack::copy_and_push_back(_branch_stack, _branch_stack.size()-1, *_stack);
|
||||||
_stack->pop_back();
|
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
|
else
|
||||||
ERR_CONTEXT(ret_bad_operand_type);
|
ERR_CONTEXT(ret_bad_operand_type);
|
||||||
|
@ -199,14 +263,10 @@ void auto_rcl(symbol* symb)
|
||||||
eval();
|
eval();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
stack::copy_and_push_back(symb, *_stack, symb->size());
|
stack::copy_and_push_back(symb, *_stack, symb->size());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
stack::copy_and_push_back(symb, *_stack, symb->size());
|
stack::copy_and_push_back(symb, *_stack, symb->size());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void purge(void)
|
void purge(void)
|
||||||
|
@ -227,7 +287,7 @@ void vars(void)
|
||||||
string name;
|
string name;
|
||||||
|
|
||||||
// heap variables
|
// 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);
|
(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]);
|
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))
|
if (local==NULL || (local!=NULL && size>local->_size))
|
||||||
{
|
{
|
||||||
copy_and_push_back(obj, *this, size);
|
copy_and_push_back(obj, *this, size);
|
||||||
_map[name] = this->size()-1;
|
_map[name] = ((stack*)this)->size()-1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -282,13 +282,16 @@ public:
|
||||||
|
|
||||||
if (i != _map.end())
|
if (i != _map.end())
|
||||||
{
|
{
|
||||||
|
// remove variable from map
|
||||||
_map.erase(i->first);
|
_map.erase(i->first);
|
||||||
ret = true;
|
ret = true;
|
||||||
|
|
||||||
|
// TODO: remove unused stack entries
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int size() { return _map.size(); }
|
unsigned int count_vars() { return _map.size(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
map<string, unsigned int> _map;
|
map<string, unsigned int> _map;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
## VARS
|
## STORE
|
||||||
|
|
||||||
# symbol entry
|
# symbol entry
|
||||||
'test'
|
'test'
|
||||||
|
@ -36,6 +36,11 @@ erase
|
||||||
-> stack should be 2
|
-> stack should be 2
|
||||||
erase
|
erase
|
||||||
|
|
||||||
|
# sto (3)
|
||||||
|
3 'b' sto b
|
||||||
|
-> stack should be 3
|
||||||
|
erase
|
||||||
|
|
||||||
# rcl (1)
|
# rcl (1)
|
||||||
'a' rcl
|
'a' rcl
|
||||||
-> stack should be 2
|
-> stack should be 2
|
||||||
|
@ -43,8 +48,13 @@ erase
|
||||||
|
|
||||||
# rcl (2)
|
# rcl (2)
|
||||||
'b' rcl
|
'b' rcl
|
||||||
|
-> stack should be 3
|
||||||
|
erase
|
||||||
|
|
||||||
|
# rcl (2)
|
||||||
|
'var' rcl
|
||||||
-> error should be 5
|
-> error should be 5
|
||||||
-> stack should be 'b'
|
-> stack should be 'var'
|
||||||
erase
|
erase
|
||||||
|
|
||||||
# sto in prog then rcl
|
# sto in prog then rcl
|
||||||
|
@ -63,6 +73,11 @@ erase
|
||||||
-> stack size should be 0
|
-> stack size should be 0
|
||||||
erase
|
erase
|
||||||
|
|
||||||
|
# purge (3)
|
||||||
|
3 'a' sto a 'a' purge
|
||||||
|
-> stack should be 3
|
||||||
|
erase
|
||||||
|
|
||||||
# sto+ (1)
|
# sto+ (1)
|
||||||
8 'a' sto
|
8 'a' sto
|
||||||
2 'a' sto+
|
2 'a' sto+
|
||||||
|
@ -83,6 +98,12 @@ erase
|
||||||
-> error should be 2
|
-> error should be 2
|
||||||
erase
|
erase
|
||||||
|
|
||||||
|
# sto+ (4)
|
||||||
|
3 'zz' sto+
|
||||||
|
-> stack should be 3, 'zz'
|
||||||
|
-> error should be 5
|
||||||
|
erase
|
||||||
|
|
||||||
# sto- (1)
|
# sto- (1)
|
||||||
2 'a' sto
|
2 'a' sto
|
||||||
2 'a' sto-
|
2 'a' sto-
|
||||||
|
@ -103,6 +124,12 @@ erase
|
||||||
-> error should be 2
|
-> error should be 2
|
||||||
erase
|
erase
|
||||||
|
|
||||||
|
# sto- (4)
|
||||||
|
3 'zz' sto-
|
||||||
|
-> stack should be 3, 'zz'
|
||||||
|
-> error should be 5
|
||||||
|
erase
|
||||||
|
|
||||||
# sto* (1)
|
# sto* (1)
|
||||||
2 'a' sto
|
2 'a' sto
|
||||||
3 'a' sto*
|
3 'a' sto*
|
||||||
|
@ -123,6 +150,12 @@ erase
|
||||||
-> error should be 2
|
-> error should be 2
|
||||||
erase
|
erase
|
||||||
|
|
||||||
|
# sto* (4)
|
||||||
|
3 'zz' sto*
|
||||||
|
-> stack should be 3, 'zz'
|
||||||
|
-> error should be 5
|
||||||
|
erase
|
||||||
|
|
||||||
# sto/ (1)
|
# sto/ (1)
|
||||||
2 'a' sto
|
2 'a' sto
|
||||||
6 'a' sto/
|
6 'a' sto/
|
||||||
|
@ -143,6 +176,12 @@ erase
|
||||||
-> error should be 2
|
-> error should be 2
|
||||||
erase
|
erase
|
||||||
|
|
||||||
|
# sto/ (4)
|
||||||
|
3 'zz' sto/
|
||||||
|
-> stack should be 3, 'zz'
|
||||||
|
-> error should be 5
|
||||||
|
erase
|
||||||
|
|
||||||
# sneg (1)
|
# sneg (1)
|
||||||
7 'a' sto
|
7 'a' sto
|
||||||
'a' sneg
|
'a' sneg
|
||||||
|
@ -155,9 +194,15 @@ sneg
|
||||||
-> error should be 2
|
-> error should be 2
|
||||||
erase
|
erase
|
||||||
|
|
||||||
|
# sneg (3)
|
||||||
|
'zz' sneg
|
||||||
|
-> error should be 5
|
||||||
|
-> stack should be 'zz'
|
||||||
|
erase
|
||||||
|
|
||||||
# sinv (1)
|
# sinv (1)
|
||||||
4 'a' sto
|
4 'a' sto
|
||||||
'a' sneg
|
'a' sinv
|
||||||
a
|
a
|
||||||
-> stack should be 0.25
|
-> stack should be 0.25
|
||||||
erase
|
erase
|
||||||
|
@ -166,3 +211,9 @@ erase
|
||||||
sinv
|
sinv
|
||||||
-> error should be 2
|
-> error should be 2
|
||||||
erase
|
erase
|
||||||
|
|
||||||
|
# sinv (3)
|
||||||
|
'zz' sinv
|
||||||
|
-> error should be 5
|
||||||
|
-> stack should be 'zz'
|
||||||
|
erase
|
||||||
|
|
Loading…
Reference in a new issue