#97: added sto+, sto-, sto*, sto/, sneg, sinv with tests

This commit is contained in:
Louis Rubet 2017-05-30 22:43:01 +02:00
parent 5517dced37
commit 3c627e43a9
5 changed files with 156 additions and 41 deletions

View file

@ -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;

View file

@ -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"},

View file

@ -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]);

View file

@ -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;

View file

@ -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