diff --git a/src/rpn-cmd.h b/src/rpn-cmd.h index 9120a40..5df4a74 100644 --- a/src/rpn-cmd.h +++ b/src/rpn-cmd.h @@ -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"}, diff --git a/src/rpn-program.h b/src/rpn-program.h index 3d1a6fe..095da44 100644 --- a/src/rpn-program.h +++ b/src/rpn-program.h @@ -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 + // -> ... + + // 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; + } + + // 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; +} diff --git a/src/rpn.cpp b/src/rpn.cpp index d214b74..ea1c86b 100644 --- a/src/rpn.cpp +++ b/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 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 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)