mirror of
https://github.com/louisrubet/rpn
synced 2025-01-19 10:26:22 +01:00
#70: generalized parent heaps chaning
This commit is contained in:
parent
e95c948660
commit
a4570c464c
3 changed files with 51 additions and 20 deletions
|
@ -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 (type == cmd_program)
|
||||
if (find_variable(variable, obj, size))
|
||||
{
|
||||
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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
22
src/rpn.cpp
22
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()
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue