#70: generalized parent heaps chaning

This commit is contained in:
Louis Rubet 2017-05-25 12:36:30 +02:00
parent e95c948660
commit a4570c464c
3 changed files with 51 additions and 20 deletions

View file

@ -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) void eval(void)
{ {
bool run_prog = false; bool run_prog = false;
@ -10,16 +39,12 @@ void eval(void)
// recall a variable // recall a variable
object* obj; object* obj;
unsigned int size; unsigned int size;
int type;
string variable(((symbol*)_stack->back())->_value); string variable(((symbol*)_stack->back())->_value);
// mind the order of heaps // if variable holds a program, run this program
if (_local_heap.get(variable, obj, size) if (find_variable(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 (obj->_type == cmd_program)
if (type == cmd_program)
{ {
prog_text = ((oprogram*)obj)->_value; prog_text = ((oprogram*)obj)->_value;
(void)_stack->pop_back(); (void)_stack->pop_back();
@ -47,13 +72,13 @@ void eval(void)
// run prog if any // run prog if any
if (run_prog) if (run_prog)
{ {
program prog; program prog(this);
// make program from entry // make program from entry
if (program::parse(prog_text.c_str(), prog) == ret_ok) if (program::parse(prog_text.c_str(), prog) == ret_ok)
{ {
// run it // 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) if (program::parse(entry.c_str(), prog) == ret_ok)
{ {
// run it // run it
prog.run(*_stack, *_global_heap, &local_heap); prog.run(*_stack, *_heap, &local_heap);
} }
// point on next command // point on next command

View file

@ -40,5 +40,5 @@ void strout()
// make program from string in stack level 1 // make program from string in stack level 1
if (program::parse(entry.c_str(), prog) == ret_ok) if (program::parse(entry.c_str(), prog) == ret_ok)
// run it // run it
prog.run(*_stack, *_global_heap, &_local_heap); prog.run(*_stack, *_heap, &_local_heap);
} }

View file

@ -394,7 +394,7 @@ struct if_layout_t
class program : public stack class program : public stack
{ {
public: public:
program() { } program(program* parent_prog = NULL) { _parent_prog = parent_prog; }
// run this program // run this program
ret_value run(stack& stk, heap& hp, heap* parent_local_hp = NULL) ret_value run(stack& stk, heap& hp, heap* parent_local_hp = NULL)
@ -407,10 +407,7 @@ public:
_stack = &stk; _stack = &stk;
// global heap comes from outside // global heap comes from outside
_global_heap = &hp; _heap = &hp;
// parent local heap comes from outside
_parent_local_heap = parent_local_hp;
_err = ret_ok; _err = ret_ok;
_err_context = ""; _err_context = "";
@ -773,15 +770,24 @@ public:
} }
private: private:
// current error and its context
ret_value _err; ret_value _err;
string _err_context; string _err_context;
// global stack holding results for user
stack* _stack; 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; stack _branch_stack;
heap* _global_heap; // parent prog for inheriting heaps
heap _local_heap; program* _parent_prog;
heap* _parent_local_heap;
int stack_size() int stack_size()
{ {