diff --git a/src/rpn-program.h b/src/rpn-program.h index 479f22a..d8cafb6 100644 --- a/src/rpn-program.h +++ b/src/rpn-program.h @@ -1,4 +1,33 @@ // +bool find_variable(string& variable, object*& obj, unsigned int& size) +{ + bool found = false; + program* parent = _parent_prog; + + // find variable in local heap, parens heaps, global heap + if (_local_heap.get(variable, obj, size)) + found = true; + else + { + while(parent != NULL) + { + if (parent->_local_heap.get(variable, obj, size)) + { + found = true; + break; + } + parent = parent->_parent_prog; + } + if (!found) + { + if (_heap->get(variable, obj, size)) + found = true; + } + } + + return found; +} + void eval(void) { bool run_prog = false; @@ -10,16 +39,12 @@ void eval(void) // recall a variable object* obj; unsigned int size; - int type; string variable(((symbol*)_stack->back())->_value); - - // mind the order of heaps - if (_local_heap.get(variable, obj, size) - || ((_parent_local_heap != NULL) && _parent_local_heap->get(variable, obj, size)) - || _global_heap->get(variable, obj, size)) + + // if variable holds a program, run this program + if (find_variable(variable, obj, size)) { - // if variable holds a program, run this program - if (type == cmd_program) + if (obj->_type == cmd_program) { prog_text = ((oprogram*)obj)->_value; (void)_stack->pop_back(); @@ -47,13 +72,13 @@ void eval(void) // run prog if any if (run_prog) { - program prog; + program prog(this); // make program from entry if (program::parse(prog_text.c_str(), prog) == ret_ok) { // run it - prog.run(*_stack, *_global_heap, &_local_heap); + prog.run(*_stack, *_heap, &_local_heap); } } } @@ -135,7 +160,7 @@ int inprog(branch& myobj) if (program::parse(entry.c_str(), prog) == ret_ok) { // run it - prog.run(*_stack, *_global_heap, &local_heap); + prog.run(*_stack, *_heap, &local_heap); } // point on next command diff --git a/src/rpn-string.h b/src/rpn-string.h index 4dc0b91..ff34c40 100644 --- a/src/rpn-string.h +++ b/src/rpn-string.h @@ -40,5 +40,5 @@ void strout() // make program from string in stack level 1 if (program::parse(entry.c_str(), prog) == ret_ok) // run it - prog.run(*_stack, *_global_heap, &_local_heap); + prog.run(*_stack, *_heap, &_local_heap); } diff --git a/src/rpn.cpp b/src/rpn.cpp index 627a179..f9dca5e 100644 --- a/src/rpn.cpp +++ b/src/rpn.cpp @@ -394,7 +394,7 @@ struct if_layout_t class program : public stack { public: - program() { } + program(program* parent_prog = NULL) { _parent_prog = parent_prog; } // run this program ret_value run(stack& stk, heap& hp, heap* parent_local_hp = NULL) @@ -407,10 +407,7 @@ public: _stack = &stk; // global heap comes from outside - _global_heap = &hp; - - // parent local heap comes from outside - _parent_local_heap = parent_local_hp; + _heap = &hp; _err = ret_ok; _err_context = ""; @@ -773,15 +770,24 @@ public: } private: + // current error and its context ret_value _err; string _err_context; + // global stack holding results for user stack* _stack; + + // global heap (sto, rcl) + heap* _heap; + + // local heap for local loop vairables (for..next) + heap _local_heap; + + // local stack internally used by branch commands (start, for, next, ..) stack _branch_stack; - heap* _global_heap; - heap _local_heap; - heap* _parent_local_heap; + // parent prog for inheriting heaps + program* _parent_prog; int stack_size() {