#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); 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;

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

View file

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

View file

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

View file

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