2014-02-11 11:26:28 +01:00
|
|
|
#ifndef __stack_h__
|
|
|
|
#define __stack_h__
|
|
|
|
|
2014-02-12 11:26:26 +01:00
|
|
|
#include <string.h>
|
|
|
|
|
2014-02-11 11:26:28 +01:00
|
|
|
#include <assert.h>
|
|
|
|
#include <vector>
|
|
|
|
#include <map>
|
|
|
|
using namespace std;
|
|
|
|
|
2017-04-21 17:40:01 +02:00
|
|
|
// allocation base size
|
|
|
|
#define ALLOC_STACK_CHUNK (64*1024)
|
2014-02-11 11:26:28 +01:00
|
|
|
|
|
|
|
//
|
|
|
|
class stack
|
|
|
|
{
|
|
|
|
public:
|
2015-05-19 17:51:03 +02:00
|
|
|
stack()
|
|
|
|
{
|
2017-04-29 15:43:05 +02:00
|
|
|
_base = NULL;
|
|
|
|
_total_size = 0;
|
2017-04-23 15:49:28 +02:00
|
|
|
erase();
|
|
|
|
}
|
2015-05-19 17:51:03 +02:00
|
|
|
|
2017-04-22 00:29:50 +02:00
|
|
|
virtual ~stack()
|
2015-05-19 17:51:03 +02:00
|
|
|
{
|
2017-04-29 15:43:05 +02:00
|
|
|
if (_base != NULL)
|
|
|
|
free(_base);
|
2017-04-22 00:29:50 +02:00
|
|
|
}
|
2017-04-23 15:49:28 +02:00
|
|
|
|
|
|
|
void erase()
|
|
|
|
{
|
|
|
|
_current = _base;
|
|
|
|
_vpointer.clear();
|
|
|
|
_vlen.clear();
|
|
|
|
_count = 0;
|
|
|
|
}
|
2017-05-02 10:47:03 +02:00
|
|
|
|
|
|
|
//
|
|
|
|
static void copy_and_push_back(stack& from, unsigned int index_from, stack& to)
|
2017-04-22 00:29:50 +02:00
|
|
|
{
|
2017-05-02 10:47:03 +02:00
|
|
|
// copy a whole stack entry and push it back to another stack
|
|
|
|
object* allocated = to.allocate_back(from.seq_len(index_from), from.seq_type(index_from));
|
|
|
|
memcpy(allocated, from.seq_obj(index_from), from.seq_len(index_from));
|
2017-04-22 00:29:50 +02:00
|
|
|
|
2017-05-02 10:47:03 +02:00
|
|
|
if (allocated->_type == cmd_number)
|
|
|
|
((number*)allocated)->_value.set_significand(((number*)allocated)+1);
|
2017-04-22 00:29:50 +02:00
|
|
|
}
|
2015-05-19 17:51:03 +02:00
|
|
|
|
2017-04-29 16:48:14 +02:00
|
|
|
//
|
2017-05-02 10:47:03 +02:00
|
|
|
static void copy_and_push_back(object* from, stack& to, unsigned int size)
|
2017-04-22 00:29:50 +02:00
|
|
|
{
|
2017-05-02 10:47:03 +02:00
|
|
|
// copy a whole stack entry and push it back to another stack
|
|
|
|
object* allocated = to.allocate_back(size, from->_type);
|
|
|
|
memcpy(allocated, from, size);
|
2017-04-22 00:29:50 +02:00
|
|
|
|
2017-05-02 10:47:03 +02:00
|
|
|
if (allocated->_type == cmd_number)
|
|
|
|
((number*)allocated)->_value.set_significand(((number*)allocated)+1);
|
2015-05-19 17:51:03 +02:00
|
|
|
}
|
2017-05-02 10:47:03 +02:00
|
|
|
|
|
|
|
object* allocate_back(unsigned int size, cmd_type_t type)
|
2017-04-21 17:40:01 +02:00
|
|
|
{
|
2017-05-02 10:47:03 +02:00
|
|
|
object* allocated;
|
2017-04-21 17:40:01 +02:00
|
|
|
|
2017-05-02 10:47:03 +02:00
|
|
|
// manage memory allocation
|
2017-04-21 17:40:01 +02:00
|
|
|
if (_current + size > _base + _total_size)
|
|
|
|
{
|
2017-04-22 00:29:50 +02:00
|
|
|
unsigned long offset = _current - _base;
|
2017-04-21 17:40:01 +02:00
|
|
|
_total_size += ALLOC_STACK_CHUNK;
|
|
|
|
_base = (char*)realloc(_base, _total_size);
|
2017-04-22 00:29:50 +02:00
|
|
|
_current = _base + offset;
|
2017-04-21 17:40:01 +02:00
|
|
|
}
|
2017-04-29 16:48:14 +02:00
|
|
|
|
2017-05-02 10:47:03 +02:00
|
|
|
// manage stack itself
|
2017-04-21 17:40:01 +02:00
|
|
|
_vlen.push_back(size);
|
2017-05-02 10:47:03 +02:00
|
|
|
_vpointer.push_back((object*)_current);
|
|
|
|
allocated = (object*)_current;
|
2017-04-21 17:40:01 +02:00
|
|
|
_current += size;
|
|
|
|
_count++;
|
|
|
|
|
2017-05-02 10:47:03 +02:00
|
|
|
// init object
|
|
|
|
allocated->_type = type;
|
|
|
|
allocated->_size = size;
|
|
|
|
if (type == cmd_number)
|
|
|
|
((number*)allocated)->_value.init(((number*)allocated)+1);
|
|
|
|
|
2017-04-21 17:40:01 +02:00
|
|
|
return allocated;
|
|
|
|
}
|
|
|
|
|
2017-05-02 10:47:03 +02:00
|
|
|
object* pop_back()
|
2015-05-19 17:51:03 +02:00
|
|
|
{
|
2017-05-02 10:47:03 +02:00
|
|
|
object* back = NULL;
|
2017-04-21 13:58:44 +02:00
|
|
|
|
2015-05-19 17:51:03 +02:00
|
|
|
if (_count > 0)
|
|
|
|
{
|
2017-05-02 10:47:03 +02:00
|
|
|
_current = (char*)_vpointer[_count - 1];
|
2015-05-19 17:51:03 +02:00
|
|
|
_vlen.pop_back();
|
|
|
|
_vpointer.pop_back();
|
2017-04-29 16:48:14 +02:00
|
|
|
|
2015-05-19 17:51:03 +02:00
|
|
|
_count--;
|
2017-04-21 13:58:44 +02:00
|
|
|
|
2017-05-02 10:47:03 +02:00
|
|
|
back = (object*)_current;
|
2015-05-19 17:51:03 +02:00
|
|
|
}
|
2017-04-21 13:58:44 +02:00
|
|
|
|
|
|
|
return back;
|
2015-05-19 17:51:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int size()
|
|
|
|
{
|
|
|
|
return _count;
|
|
|
|
}
|
|
|
|
|
|
|
|
// stack access (index is counted from back)
|
2017-05-02 10:47:03 +02:00
|
|
|
object* get_obj(unsigned int index)
|
2015-05-19 17:51:03 +02:00
|
|
|
{
|
|
|
|
if (index<_count)
|
|
|
|
return _vpointer[_count-index-1];
|
|
|
|
else
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2017-05-02 10:47:03 +02:00
|
|
|
object* operator[](unsigned int index)
|
2015-05-19 17:51:03 +02:00
|
|
|
{
|
|
|
|
return get_obj(index);
|
|
|
|
}
|
|
|
|
|
2017-05-02 10:47:03 +02:00
|
|
|
object* back()
|
2015-05-19 17:51:03 +02:00
|
|
|
{
|
|
|
|
if (_count>0)
|
|
|
|
return _vpointer[_count-1];
|
|
|
|
else
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int get_len(unsigned int index)
|
|
|
|
{
|
|
|
|
if (index<_count)
|
|
|
|
return _vlen[_count-index-1];
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-05-02 10:47:03 +02:00
|
|
|
cmd_type_t get_type(unsigned int index)
|
2015-05-19 17:51:03 +02:00
|
|
|
{
|
|
|
|
if (index<_count)
|
2017-05-02 10:47:03 +02:00
|
|
|
return _vpointer[_count-index-1]->_type;
|
2015-05-19 17:51:03 +02:00
|
|
|
else
|
2017-05-02 10:47:03 +02:00
|
|
|
return cmd_undef;
|
2015-05-19 17:51:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// sequential access (index is counted from front)
|
2017-05-02 10:47:03 +02:00
|
|
|
object* seq_obj(unsigned int index)
|
2015-05-19 17:51:03 +02:00
|
|
|
{
|
|
|
|
if (index<_count)
|
|
|
|
return _vpointer[index];
|
|
|
|
else
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int seq_len(unsigned int index)
|
|
|
|
{
|
|
|
|
if (index<_count)
|
|
|
|
return _vlen[index];
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-05-02 10:47:03 +02:00
|
|
|
cmd_type_t seq_type(unsigned int index)
|
2015-05-19 17:51:03 +02:00
|
|
|
{
|
|
|
|
if (index<_count)
|
2017-05-02 10:47:03 +02:00
|
|
|
return _vpointer[index]->_type;
|
2015-05-19 17:51:03 +02:00
|
|
|
else
|
2017-05-02 10:47:03 +02:00
|
|
|
return cmd_undef;
|
2015-05-19 17:51:03 +02:00
|
|
|
}
|
|
|
|
|
2014-02-11 11:26:28 +01:00
|
|
|
private:
|
2015-05-19 17:51:03 +02:00
|
|
|
char* _base;
|
|
|
|
char* _current;
|
2017-04-21 17:40:01 +02:00
|
|
|
|
2017-05-02 10:47:03 +02:00
|
|
|
vector<object*> _vpointer;//pointer on each entry
|
2017-04-21 17:40:01 +02:00
|
|
|
vector<unsigned int> _vlen;// size of each entry in bytes
|
2017-05-02 10:47:03 +02:00
|
|
|
unsigned int _count;// =_vlen.size()=_vpointer.size()
|
2015-05-19 17:51:03 +02:00
|
|
|
unsigned int _total_size;//total allocated size in bytes
|
2014-02-11 11:26:28 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
//
|
|
|
|
class heap
|
|
|
|
{
|
|
|
|
private:
|
2015-05-19 17:51:03 +02:00
|
|
|
struct local_var
|
|
|
|
{
|
|
|
|
unsigned int length;
|
2017-05-02 10:47:03 +02:00
|
|
|
object obj[0];
|
2015-05-19 17:51:03 +02:00
|
|
|
};
|
2014-02-11 11:26:28 +01:00
|
|
|
|
|
|
|
public:
|
2015-05-19 17:51:03 +02:00
|
|
|
heap() { }
|
|
|
|
virtual ~heap()
|
|
|
|
{
|
|
|
|
for(map<string, struct local_var*>::iterator i=_map.begin(); i!=_map.end(); i++)
|
|
|
|
free(i->second);
|
|
|
|
}
|
|
|
|
|
2017-05-02 10:47:03 +02:00
|
|
|
object* add(const string name, void* obj, unsigned int size, int type = 0)
|
2015-05-19 17:51:03 +02:00
|
|
|
{
|
2017-05-02 10:47:03 +02:00
|
|
|
struct local_var* local = _map[name];
|
|
|
|
if (local == NULL)
|
2015-05-19 17:51:03 +02:00
|
|
|
{
|
2015-02-25 15:38:16 +01:00
|
|
|
//TODO gerer les pbs de memoire
|
2017-05-02 10:47:03 +02:00
|
|
|
local = (struct local_var*)malloc(size + sizeof(local_var));
|
|
|
|
_map[name] = local;
|
2015-03-01 16:30:13 +01:00
|
|
|
}
|
2017-05-02 10:47:03 +02:00
|
|
|
else if (size != local->length)
|
2015-05-19 17:51:03 +02:00
|
|
|
{
|
2015-02-25 15:38:16 +01:00
|
|
|
//TODO gerer les pbs de memoire
|
2017-05-02 10:47:03 +02:00
|
|
|
local = (struct local_var*)realloc(local, size + sizeof(local_var));
|
|
|
|
_map[name] = local;
|
2015-03-01 16:30:13 +01:00
|
|
|
}
|
2017-05-02 10:47:03 +02:00
|
|
|
local->length = size;
|
2017-04-19 23:31:18 +02:00
|
|
|
|
|
|
|
if (obj != NULL)
|
2017-05-02 10:47:03 +02:00
|
|
|
memcpy(local->obj, obj, size);
|
2015-05-19 17:51:03 +02:00
|
|
|
|
2017-05-02 10:47:03 +02:00
|
|
|
return (object*)local->obj;
|
2017-04-19 23:31:18 +02:00
|
|
|
}
|
|
|
|
|
2017-05-02 10:47:03 +02:00
|
|
|
bool get(const string name, object*& obj, unsigned int& size)
|
2015-05-19 17:51:03 +02:00
|
|
|
{
|
|
|
|
map<string, struct local_var*>::iterator i = _map.find(name);
|
|
|
|
if (i != _map.end())
|
|
|
|
{
|
|
|
|
if (i->second != NULL)
|
|
|
|
{
|
2017-05-02 10:47:03 +02:00
|
|
|
obj = i->second->obj;
|
2015-05-19 17:51:03 +02:00
|
|
|
size = i->second->length;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool exist(const string name)
|
|
|
|
{
|
|
|
|
return (_map.find(name) != _map.end());
|
|
|
|
}
|
|
|
|
|
2017-05-02 10:47:03 +02:00
|
|
|
bool get_by_index(int num, string& name, object*& obj, unsigned int& size)
|
2015-05-19 17:51:03 +02:00
|
|
|
{
|
|
|
|
if (num>=0 && num<(int)_map.size())
|
|
|
|
{
|
2017-05-02 10:47:03 +02:00
|
|
|
struct local_var* local;
|
2015-05-19 17:51:03 +02:00
|
|
|
map<string, struct local_var*>::iterator i=_map.begin();
|
|
|
|
|
|
|
|
//TODO moche moche moche
|
|
|
|
for(int j=0;j<num;j++)
|
|
|
|
i++;
|
|
|
|
|
2017-05-02 10:47:03 +02:00
|
|
|
local = (struct local_var*)i->second;
|
|
|
|
assert(local != NULL);
|
2015-05-19 17:51:03 +02:00
|
|
|
|
|
|
|
name = i->first;
|
2017-05-02 10:47:03 +02:00
|
|
|
obj = local->obj;
|
|
|
|
size = local->length;
|
2015-05-19 17:51:03 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
2014-02-11 11:26:28 +01:00
|
|
|
|
2015-03-01 16:30:13 +01:00
|
|
|
bool erase(const string& name)
|
2015-05-19 17:51:03 +02:00
|
|
|
{
|
|
|
|
map<string, struct local_var*>::iterator i = _map.find(name);
|
|
|
|
if (i != _map.end())
|
|
|
|
{
|
2015-03-01 16:30:13 +01:00
|
|
|
free(i->second);
|
2015-05-19 17:51:03 +02:00
|
|
|
_map.erase(i->first);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2014-02-11 11:26:28 +01:00
|
|
|
|
2015-05-19 17:51:03 +02:00
|
|
|
unsigned int size() { return _map.size(); }
|
2014-02-11 11:26:28 +01:00
|
|
|
|
|
|
|
private:
|
2015-05-19 17:51:03 +02:00
|
|
|
map<string, struct local_var*> _map;
|
2014-02-11 11:26:28 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif // __stack_h__
|