#63: removing vectors from stack

This commit is contained in:
Louis Rubet 2017-05-22 18:22:15 +02:00
parent 1232cb10da
commit dc0061c724
3 changed files with 72 additions and 90 deletions

View file

@ -105,7 +105,7 @@ int rpn_for(branch& myobj)
else
{
// store symbol with first value
_local_heap.add(sym->_value, myobj.farg1, myobj.farg1->size());
_local_heap.add(sym->_value, (object*)myobj.farg1, myobj.farg1->size());
(void)_stack->pop_back();
ret = myobj.arg1 + 1;
}

View file

@ -123,7 +123,7 @@ int inprog(branch& myobj)
heap local_heap;
for (unsigned int i = myobj.arg1 + count_symbols; i > myobj.arg1; i--)
{
local_heap.add(string(((symbol*)seq_obj(i))->_value), _stack->get_obj(0), _stack->get_len(0), _stack->get_type(0));
local_heap.add(string(((symbol*)seq_obj(i))->_value), _stack->get_obj(0), _stack->get_len(0));
(void)_stack->pop_back();
}

View file

@ -2,9 +2,6 @@
#define __stack_h__
#include <string.h>
#include <assert.h>
#include <vector>
#include <map>
using namespace std;
@ -18,7 +15,9 @@ public:
stack()
{
_base = NULL;
_base_pointer = NULL;
_total_size = 0;
_total_count_pointer = 0;
erase();
}
@ -26,12 +25,13 @@ public:
{
if (_base != NULL)
free(_base);
if (_base_pointer != NULL)
free(_base_pointer);
}
void erase()
{
_current = _base;
_vpointer.clear();
_count = 0;
}
@ -68,13 +68,19 @@ public:
_total_size += ALLOC_STACK_CHUNK;
_base = (char*)realloc(_base, _total_size);
_current = _base + offset;
//TODO si realloc alors les pointeurs doivent etre recalculés !
}
if ((_count+1) > _total_count_pointer)
{
_base_pointer = (object**)realloc(_base_pointer, (_total_count_pointer * sizeof(object*)) + ALLOC_STACK_CHUNK);
_total_count_pointer += (ALLOC_STACK_CHUNK / sizeof(object));
}
// manage stack itself
_vpointer.push_back((object*)_current);
_base_pointer[_count++]=(object*)_current;
allocated = (object*)_current;
_current += size;
_count++;
// init object
allocated->_type = type;
@ -91,9 +97,7 @@ public:
if (_count > 0)
{
_current = (char*)_vpointer[_count - 1];
_vpointer.pop_back();
_current = (char*)_base_pointer[_count - 1];
_count--;
back = (object*)_current;
@ -111,7 +115,7 @@ public:
object* get_obj(unsigned int index)
{
if (index<_count)
return _vpointer[_count-index-1];
return _base_pointer[_count - index - 1];
else
return NULL;
}
@ -124,7 +128,7 @@ public:
object* back()
{
if (_count>0)
return _vpointer[_count-1];
return _base_pointer[_count - 1];
else
return NULL;
}
@ -132,7 +136,7 @@ public:
unsigned int get_len(unsigned int index)
{
if (index<_count)
return _vpointer[_count-index-1]->_size;
return _base_pointer[_count - index - 1]->_size;
else
return 0;
}
@ -140,7 +144,7 @@ public:
cmd_type_t get_type(unsigned int index)
{
if (index<_count)
return _vpointer[_count-index-1]->_type;
return _base_pointer[_count - index - 1]->_type;
else
return cmd_undef;
}
@ -149,7 +153,7 @@ public:
object* seq_obj(unsigned int index)
{
if (index<_count)
return _vpointer[index];
return _base_pointer[index];
else
return NULL;
}
@ -157,7 +161,7 @@ public:
unsigned int seq_len(unsigned int index)
{
if (index<_count)
return _vpointer[index]->_size;
return _base_pointer[index]->_size;
else
return 0;
}
@ -165,7 +169,7 @@ public:
cmd_type_t seq_type(unsigned int index)
{
if (index<_count)
return _vpointer[index]->_type;
return _base_pointer[index]->_type;
else
return cmd_undef;
}
@ -173,89 +177,68 @@ public:
private:
char* _base;
char* _current;
object** _base_pointer;
vector<object*> _vpointer;//pointer on each entry
unsigned int _count;// =_vlen.size()=_vpointer.size()
unsigned int _total_count_pointer;//total number of possible pointers
unsigned int _total_size;//total allocated size in bytes
};
//
class heap
class heap : public stack
{
private:
struct local_var
{
unsigned int length;
object obj[0];
};
public:
heap() { }
virtual ~heap()
virtual ~heap() { }
object* add(const string name, object* obj, unsigned int size)
{
for(map<string, struct local_var*>::iterator i=_map.begin(); i!=_map.end(); i++)
free(i->second);
object* local = _map[name];
// variable does not exist in heap or already exists but its size is too short -> allocate
if (local==NULL || (local!=NULL && size>local->_size))
{
copy_and_push_back(obj, *this, size);
_map[name] = back();
}
else
{
// variable already exists in heap but previous was larger -> don't reallocate
// copy a whole stack entry and push it back to another stack
memcpy(local, obj, size);
if (local->_type == cmd_number)
((number*)local)->_value.set_significand(((number*)local)+1);
}
object* add(const string name, object* obj, unsigned int size, int type = 0)
{
struct local_var* local = _map[name];
if (local == NULL)
{
//TODO gerer les pbs de memoire
local = (struct local_var*)malloc(size + sizeof(local_var));
_map[name] = local;
}
else if (size != local->length)
{
//TODO gerer les pbs de memoire
local = (struct local_var*)realloc(local, size + sizeof(local_var));
_map[name] = local;
}
local->length = size;
if (obj != NULL)
{
memcpy(local->obj, obj, size);
if (local->obj->_type == cmd_number)
((number*)local->obj)->_value.set_significand(((number*)local->obj)+1);
}
return local->obj;
return local;
}
bool get(const string name, object*& obj, unsigned int& size)
{
map<string, struct local_var*>::iterator i = _map.find(name);
if (i != _map.end())
bool ret = false;
map<string, object*>::iterator i = _map.find(name);
if (i!=_map.end() && i->second!=NULL)
{
if (i->second != NULL)
{
obj = i->second->obj;
size = i->second->length;
obj = i->second;
size = i->second->_size;
ret = true;
}
return true;
}
else
return false;
return ret;
}
bool replace_value(const string name, object* obj, unsigned int size)
{
bool ret=false;
map<string, struct local_var*>::iterator i = _map.find(name);
map<string, object*>::iterator i = _map.find(name);
if (i != _map.end())
if (i!=_map.end() && i->second!=NULL && size==i->second->_size)
{
if (i->second != NULL && size==i->second->length)
{
(void)memcpy(i->second->obj, obj, size);
if (i->second->obj->_type == cmd_number)
((number*)i->second->obj)->_value.set_significand(((number*)i->second->obj)+1);
(void)memcpy(i->second, obj, size);
if (i->second->_type == cmd_number)
((number*)i->second)->_value.set_significand(((number*)i->second)+1);
ret = true;
}
return true;
}
return ret;
}
bool exist(const string name)
@ -267,19 +250,17 @@ public:
{
if (num>=0 && num<(int)_map.size())
{
struct local_var* local;
map<string, struct local_var*>::iterator i=_map.begin();
object* local;
map<string, object*>::iterator i= _map.begin();
//TODO moche moche moche
//TODO another formulation, please
for(int j=0;j<num;j++)
i++;
local = (struct local_var*)i->second;
assert(local != NULL);
local = (object*)i->second;
name = i->first;
obj = local->obj;
size = local->length;
obj = local;
size = local->_size;
return true;
}
else
@ -288,20 +269,21 @@ public:
bool erase(const string& name)
{
map<string, struct local_var*>::iterator i = _map.find(name);
map<string, object*>::iterator i = _map.find(name);
bool ret = false;
if (i != _map.end())
{
free(i->second);
_map.erase(i->first);
return true;
ret = true;
}
return false;
return ret;
}
unsigned int size() { return _map.size(); }
private:
map<string, struct local_var*> _map;
map<string, object*> _map;
};
#endif // __stack_h__