mirror of
https://github.com/louisrubet/rpn
synced 2024-11-17 07:47:50 +01:00
Added command ->
This commit is contained in:
parent
2278cc9618
commit
4ae5a348b6
3 changed files with 99 additions and 11 deletions
|
@ -92,6 +92,7 @@ program::keyword_t program::_keywords[] =
|
|||
//PROGRAM
|
||||
{ cmd_undef, "", NULL, "\nPROGRAM"},
|
||||
{ cmd_keyword, "eval", &program::eval, "evaluate (run) a program, or recall a variable. ex: 'my_prog' eval" },
|
||||
{ cmd_branch, "->", (program_fn_t)&program::inprog, "load program local variables. ex: << -> n m << 0 n m for i i + next >> >>" },
|
||||
|
||||
//TRIG
|
||||
{ cmd_undef, "", NULL, "\nTRIG"},
|
||||
|
|
|
@ -25,7 +25,7 @@ void eval(void)
|
|||
|
||||
program prog;
|
||||
|
||||
// make program from string in stack level 1
|
||||
// make program from entry
|
||||
if (program::parse(entry, prog) == ret_ok)
|
||||
{
|
||||
// run it
|
||||
|
@ -35,3 +35,86 @@ void eval(void)
|
|||
else
|
||||
ERR_CONTEXT(ret_bad_operand_type);
|
||||
}
|
||||
|
||||
// carefull, this not a command but a branch
|
||||
int inprog(branch& myobj)
|
||||
{
|
||||
string context("->");// for showing errors
|
||||
int count_symbols = 0;
|
||||
bool prog_found = false;
|
||||
|
||||
if (myobj.arg1 == -1)
|
||||
{
|
||||
ERR_CONTEXT(ret_unknown_err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// syntax must be
|
||||
// -> <auto evaluated symbol #1> ... <auto evaluated symbol #n> <oprogram>
|
||||
|
||||
// find next oprogram object
|
||||
for (unsigned int i = myobj.arg1 + 1; i < size(); i++)
|
||||
{
|
||||
// count symbol
|
||||
if (seq_type(i) == cmd_symbol)
|
||||
count_symbols++;
|
||||
// stop if prog
|
||||
else if (seq_type(i) == cmd_program)
|
||||
{
|
||||
prog_found = true;
|
||||
break;
|
||||
}
|
||||
// found something other than symbol
|
||||
else
|
||||
{
|
||||
ERR_CONTEXT(ret_bad_operand_type);
|
||||
show_error(_err, context);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// found 0 symbols
|
||||
if (count_symbols == 0)
|
||||
{
|
||||
ERR_CONTEXT(ret_syntax);
|
||||
show_error(_err, context);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// <oprogram> is missing
|
||||
if (! prog_found)
|
||||
{
|
||||
ERR_CONTEXT(ret_syntax);
|
||||
show_error(_err, context);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// check symbols number vs stack size
|
||||
if (stack_size() < count_symbols)
|
||||
{
|
||||
ERR_CONTEXT(ret_missing_operand);
|
||||
show_error(_err, context);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// load variables
|
||||
for (unsigned int i = myobj.arg1 + count_symbols; i > myobj.arg1; i--)
|
||||
{
|
||||
_heap->add(*((symbol*)seq_obj(i))->_value, _stack->get_obj(0), _stack->get_len(0), _stack->get_type(0));
|
||||
_stack->pop_back();
|
||||
}
|
||||
|
||||
// run the program
|
||||
string& entry = *((oprogram*)seq_obj(myobj.arg1 + count_symbols + 1))->_value;
|
||||
program prog;
|
||||
|
||||
// make the program from entry
|
||||
if (program::parse(entry, prog) == ret_ok)
|
||||
{
|
||||
// run it
|
||||
prog.run(*_stack, *_heap);
|
||||
}
|
||||
|
||||
// point on next command
|
||||
return myobj.arg1 + count_symbols + 2;
|
||||
}
|
||||
|
|
24
src/rpn.cpp
24
src/rpn.cpp
|
@ -270,7 +270,7 @@ public:
|
|||
_stack = &stk;
|
||||
_heap = &hp;
|
||||
_err = ret_ok;
|
||||
_err_context = "";
|
||||
_err_context = "";
|
||||
|
||||
// branches for 'if'
|
||||
ret = preprocess();
|
||||
|
@ -318,7 +318,7 @@ public:
|
|||
go_out = true;
|
||||
|
||||
// error: show it
|
||||
if (show_error(_err, _err_context) == ret_deadly)
|
||||
if (show_error(_err, _err_context) == ret_deadly)
|
||||
{
|
||||
// pb showing error -> go out software
|
||||
ret = ret_good_bye;
|
||||
|
@ -354,8 +354,8 @@ public:
|
|||
{
|
||||
// for if-then-else-end
|
||||
vector<struct if_layout_t> vlayout;
|
||||
int layout_index=-1;// TODO remplaçable par vlayout.size()-1
|
||||
//for start-end-step
|
||||
int layout_index=-1;// TODO remplacable par vlayout.size()-1
|
||||
// for start-end-step
|
||||
vector<int> vstartindex;
|
||||
|
||||
// analyse if-then-else-end branches
|
||||
|
@ -366,7 +366,7 @@ public:
|
|||
if (type == cmd_keyword)
|
||||
{
|
||||
keyword* k = (keyword*)seq_obj(i);
|
||||
if(k->_value->compare("end") == 0)
|
||||
if (k->_value->compare("end") == 0)
|
||||
{
|
||||
int next = i + 1;
|
||||
if (next >= (int)size())
|
||||
|
@ -403,7 +403,7 @@ public:
|
|||
vlayout.push_back(layout);
|
||||
layout_index++;
|
||||
}
|
||||
else if(k->_value->compare("then") == 0)
|
||||
else if (k->_value->compare("then") == 0)
|
||||
{
|
||||
int next = i + 1;
|
||||
if (next >= (int)size())
|
||||
|
@ -432,7 +432,7 @@ public:
|
|||
k->arg1 = next;
|
||||
k->arg3 = vlayout[layout_index].index_if;
|
||||
}
|
||||
else if(k->_value->compare("else") == 0)
|
||||
else if (k->_value->compare("else") == 0)
|
||||
{
|
||||
int next = i + 1;
|
||||
if (next >= (int)size())
|
||||
|
@ -468,11 +468,11 @@ public:
|
|||
k->arg3 = vlayout[layout_index].index_if;
|
||||
((branch*)seq_obj(vlayout[layout_index].index_then))->arg2 = next;// fill branch2 (if was false) of 'then'
|
||||
}
|
||||
else if(k->_value->compare("start") == 0)
|
||||
else if (k->_value->compare("start") == 0)
|
||||
{
|
||||
vstartindex.push_back(i);
|
||||
}
|
||||
else if(k->_value->compare("for") == 0)
|
||||
else if (k->_value->compare("for") == 0)
|
||||
{
|
||||
vstartindex.push_back(i);
|
||||
k->arg1 = i + 1;// arg1 points on symbol variable
|
||||
|
@ -488,7 +488,7 @@ public:
|
|||
k->arg1 = vstartindex[vstartindex.size() - 1];// fill 'next' branch1 = 'start' index
|
||||
vstartindex.pop_back();
|
||||
}
|
||||
else if(k->_value->compare("step") == 0)
|
||||
else if (k->_value->compare("step") == 0)
|
||||
{
|
||||
if (vstartindex.size() == 0)
|
||||
{
|
||||
|
@ -499,6 +499,10 @@ public:
|
|||
k->arg1 = vstartindex[vstartindex.size() - 1];// fill 'step' branch1 = 'start' index
|
||||
vstartindex.pop_back();
|
||||
}
|
||||
else if (k->_value->compare("->") == 0)
|
||||
{
|
||||
k->arg1 = i;// arg1 is '->' command index in program
|
||||
}
|
||||
}
|
||||
}
|
||||
if (layout_index >= 0)
|
||||
|
|
Loading…
Reference in a new issue