#5: stack refactoring

This commit is contained in:
Louis Rubet 2017-05-02 10:47:03 +02:00
parent 6fe768006a
commit e63e6f98aa
8 changed files with 119 additions and 223 deletions

View file

@ -24,10 +24,8 @@ void rtob()
ARG_MUST_BE_OF_TYPE(0, cmd_number);
number* left = (number*)_stack->pop_back();
binary bin;
bin.set(mpfr_get_sj(left->_value.mpfr, s_mpfr_rnd));
_stack->push_back(&bin, bin.size(), cmd_binary);
binary* bin = (binary*)_stack->allocate_back(sizeof(binary), cmd_binary);
bin->set(mpfr_get_sj(left->_value.mpfr, s_mpfr_rnd));
}
void btor()
@ -36,9 +34,6 @@ void btor()
ARG_MUST_BE_OF_TYPE(0, cmd_binary);
integer_t bin = getb();
void* significand;
number* left = (number*)_stack->allocate_back(sizeof(number), cmd_number, MPFR_128BITS_STORING_LENGTH, &significand);
left->init(significand);
number* left = (number*)_stack->allocate_back(number::calc_size(), cmd_number);
left->set(bin);
}

View file

@ -56,13 +56,13 @@ int rpn_start(branch& myobj)
// farg1 = first value of start command
// farg2 = last value of start command
stack::copy_and_push_back(*_stack, 0, _branch_stack);
myobj.farg2 = (number*)_branch_stack.get_obj(0);
myobj.farg2->init(_branch_stack.get_blob(0));
//myobj.farg2 = (number*)_branch_stack.get_obj(0);
//myobj.farg2->init(_branch_stack.get_blob(0));
_stack->pop_back();
stack::copy_and_push_back(*_stack, 0, _branch_stack);
myobj.farg1 = (number*)_branch_stack.get_obj(0);
myobj.farg1->init(_branch_stack.get_blob(0));
//myobj.farg1 = (number*)_branch_stack.get_obj(0);
//myobj.farg1->init(_branch_stack.get_blob(0));
_stack->pop_back();
return -1;
}
@ -79,17 +79,16 @@ int rpn_for(branch& myobj)
// farg2 = last value of for command
// arg1 = index of symbol to increase
stack::copy_and_push_back(*_stack, 0, _branch_stack);
myobj.farg2 = (number*)_branch_stack.back();
myobj.farg2->init(_branch_stack.back_blob());
//myobj.farg2 = (number*)_branch_stack.back();
//myobj.farg2->init(_branch_stack.back_blob());
stack::copy_and_push_back(*_stack, 0, _branch_stack);
myobj.farg1 = (number*)_branch_stack.back();
myobj.farg1->init(_branch_stack.back_blob());
//myobj.farg1 = (number*)_branch_stack.back();
//myobj.farg1->init(_branch_stack.back_blob());
// store symbol with first value
//TODO
//number* num = (number*)_local_heap.add(string(sym->_value), NULL, sizeof(number), cmd_number);
//number* num = (number*)_local_heap.add(string(sym->_value), NULL, number::calc_size(), cmd_number);
//num->set(myobj.farg1);
//num->ensure_significand();
return myobj.arg1 + 1;
}
@ -174,7 +173,6 @@ int rpn_step(branch& myobj)
if (_local_heap.get(string(var->_value), obj, size, type) && (type == cmd_number))
{
((number*)obj)->_value = myobj.farg1;
((number*)obj)->ensure_significand();
}
}

View file

@ -128,55 +128,25 @@ void sci()
void rpn_version()
{
int naked_entry_len;
int obj_len;
ostring* str;
// entry length without prefix / postfix
naked_entry_len = (int)strlen(version);
// total object length
obj_len = sizeof(ostring)+naked_entry_len+1;
// allocate object
str = (ostring*)malloc(obj_len);
// set it
// allocate and set object
unsigned int naked_entry_len = strlen(version);
ostring* str = (ostring*)_stack->allocate_back(sizeof(ostring)+naked_entry_len+1, cmd_string);
str->set(version, naked_entry_len);
// push in stack
_stack->push_back(str, str->size(), cmd_string);
free(str);
}
void rpn_uname()
{
int naked_entry_len;
int obj_len;
ostring* str;
// entry length without prefix / postfix
naked_entry_len = (int)strlen(uname);
// total object length
obj_len = sizeof(ostring)+naked_entry_len+1;
// allocate object
str = (ostring*)malloc(obj_len);
// set it
// allocate and set object
unsigned int naked_entry_len = strlen(uname);
ostring* str = (ostring*)_stack->allocate_back(sizeof(ostring)+naked_entry_len+1, cmd_string);
str->set(uname, naked_entry_len);
// push in stack
_stack->push_back(str, str->size(), cmd_string);
free(str);
}
void type()
{
MIN_ARGUMENTS(1);
int type = _stack->seq_type(_stack->size()-1);
int type = _stack->pop_back()->_type;
if (type < 0 || type >= (int)cmd_max)
type = (int)cmd_undef;

View file

@ -8,15 +8,15 @@ void eval(void)
if (IS_ARG_TYPE(0, cmd_symbol))
{
// recall a variable
void* obj;
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, type)
|| ((_parent_local_heap != NULL) && _parent_local_heap->get(variable, obj, size, type))
|| _global_heap->get(variable, obj, size, type))
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)
@ -27,9 +27,10 @@ void eval(void)
}
else
{
// else recall variable (i.e. stack its content)
// else recall this variable (i.e. stack its content)
(void)_stack->pop_back();
_stack->push_back(obj, size, type);
object* new_obj = _stack->allocate_back(size, obj->_type);
stack::copy_and_push_back(obj, *_stack, size);
}
}
else

View file

@ -82,8 +82,6 @@ void rot(void)
void depth(void)
{
unsigned long depth = (unsigned long)_stack->size();
void* significand;
number* num = (number*)_stack->allocate_back(sizeof(number), cmd_number, MPFR_128BITS_STORING_LENGTH, &significand);
num->init(significand);
number* num = (number*)_stack->allocate_back(number::calc_size(), cmd_number);
num->set(depth);
}

View file

@ -5,7 +5,7 @@ void sto(void)
ARG_MUST_BE_OF_TYPE(0, cmd_symbol);
string name(((symbol*)_stack->pop_back())->_value);
_global_heap->add(name, _stack->get_obj(0), _stack->get_len(0), _stack->get_type(0));
_global_heap->add(name, _stack->get_obj(0), _stack->get_len(0));
(void)_stack->pop_back();
}
@ -15,18 +15,19 @@ void rcl(void)
ARG_MUST_BE_OF_TYPE(0, cmd_symbol);
// recall a variable
void* obj;
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, type)
|| ((_parent_local_heap != NULL) && (_parent_local_heap->get(variable, obj, size, type)))
|| _global_heap->get(variable, obj, size, type))
if (_local_heap.get(variable, obj, size)
|| ((_parent_local_heap != NULL) && (_parent_local_heap->get(variable, obj, size)))
|| _global_heap->get(variable, obj, size))
{
(void)_stack->pop_back();
_stack->push_back(obj, size, type);
object* new_obj = _stack->allocate_back(size, obj->_type);
stack::copy_and_push_back(obj, *_stack, size);
}
else
ERR_CONTEXT(ret_unknown_variable);
@ -68,29 +69,31 @@ void edit(void)
// carefull : this is not a langage command
void auto_rcl(symbol* symb)
{
if (symb->_auto_eval)
if (!symb->_auto_eval)
{
void* obj;
object* obj;
unsigned int size;
int type;
string variable(symb->_value);
// mind the order of heaps
if (_local_heap.get(variable, obj, size, type)
|| ((_parent_local_heap != NULL) && (_parent_local_heap->get(variable, obj, size, type)))
|| _global_heap->get(variable, obj, size, type))
if (_local_heap.get(variable, obj, size)
|| ((_parent_local_heap != NULL) && (_parent_local_heap->get(variable, obj, size)))
|| _global_heap->get(variable, obj, size))
{
_stack->push_back(obj, size, type);
stack::copy_and_push_back(obj, *_stack, size);
if (type == cmd_program)
eval();
else if (type == cmd_number)
((number*)_stack->back())->ensure_significand();
}
else
_stack->push_back(symb, symb->size(), cmd_symbol);
{
stack::copy_and_push_back(symb, *_stack, symb->size());
}
}
else
_stack->push_back(symb, symb->size(), cmd_symbol);
{
stack::copy_and_push_back(symb, *_stack, symb->size());
}
}
void purge(void)
@ -125,8 +128,8 @@ void vars(void)
for (int i=0; i<(int)_global_heap->size(); i++)
{
(void)_global_heap->get_by_index(i, name, (void*&)obj, size, type);
cout<<"var "<<i+1<<": name '"<<name<<"', type "<<cmd_type_string[type]<<", value ";
(void)_global_heap->get_by_index(i, name, obj, size);
cout<<"var "<<i+1<<": name '"<<name<<"', type "<<cmd_type_string[obj->_type]<<", value ";
obj->show();
cout<<endl;
}
@ -134,16 +137,16 @@ void vars(void)
{
for (int i=0; i<(int)_parent_local_heap->size(); i++)
{
(void)_parent_local_heap->get_by_index(i, name, (void*&)obj, size, type);
cout<<"local var "<<i+1<<": name '"<<name<<"', type "<<cmd_type_string[type]<<", value ";
(void)_parent_local_heap->get_by_index(i, name, obj, size);
cout<<"local var "<<i+1<<": name '"<<name<<"', type "<<cmd_type_string[obj->_type]<<", value ";
obj->show();
cout<<endl;
}
}
for (int i=0; i<(int)_local_heap.size(); i++)
{
(void)_local_heap.get_by_index(i, name, (void*&)obj, size, type);
cout<<"local var "<<i+1<<": name '"<<name<<"', type "<<cmd_type_string[type]<<", value ";
(void)_local_heap.get_by_index(i, name, obj, size);
cout<<"local var "<<i+1<<": name '"<<name<<"', type "<<cmd_type_string[obj->_type]<<", value ";
obj->show();
cout<<endl;
}

View file

@ -10,11 +10,11 @@ void instr()
((object*)_stack->pop_back())->show(out);
// reserve the correct size in stack
_stack->push_back(NULL, out.str().size(), cmd_string, true);
unsigned int str_size = (unsigned int)out.str().size();
ostring* str = (ostring*)_stack->allocate_back(str_size+1+sizeof(ostring), cmd_string);
// fill the obj
ostring* str = (ostring*)_stack->get_obj(0);
str->set(out.str().c_str(), out.str().size());
str->set(out.str().c_str(), str_size);
}
}

View file

@ -8,11 +8,8 @@
#include <map>
using namespace std;
#include "debug.h"
// allocation base size
#define ALLOC_STACK_CHUNK (64*1024)
#define ALLOC_BLOB_CHUNK (64*1024)
//
class stack
@ -21,9 +18,7 @@ public:
stack()
{
_base = NULL;
_blob = NULL;
_total_size = 0;
_total_blob_size = 0;
erase();
}
@ -31,51 +26,43 @@ public:
{
if (_base != NULL)
free(_base);
if (_blob != NULL)
free(_blob);
}
void erase()
{
_current = _base;
_current_blob = _blob;
_vpointer.clear();
_vpointer_blob.clear();
_vlen.clear();
_vlen_blob.clear();
_vtype.clear();
_count = 0;
}
void push_back(void* obj, unsigned int size, int type = 0, bool dont_copy = false, void* blob = NULL, unsigned int blob_size = 0)
{
void* allocated_blob;
void* allocated = allocate_back(size, type, blob_size, &allocated_blob);
if (!dont_copy)
{
if (size > 0)
memcpy(allocated, obj, size);
if (blob != NULL && blob_size > 0)
memcpy(allocated_blob, blob, blob_size);
}
}
//
static void copy_and_push_back(stack& from, unsigned int index_from, stack& to)
{
// copy a whole stack entry (with blob) and push it back to another stack
void* allocated_blob;
void* allocated = to.allocate_back(from.seq_len(index_from), from.seq_type(index_from), from.seq_blob_size(index_from), &allocated_blob);
// 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));
memcpy(allocated_blob, from.seq_blob(index_from), from.seq_blob_size(index_from));
if (allocated->_type == cmd_number)
((number*)allocated)->_value.set_significand(((number*)allocated)+1);
}
void* allocate_back(unsigned int size, int type, unsigned int blob_size = 0, void** blob = NULL)
//
static void copy_and_push_back(object* from, stack& to, unsigned int size)
{
void* allocated;
// copy a whole stack entry and push it back to another stack
object* allocated = to.allocate_back(size, from->_type);
memcpy(allocated, from, size);
if (allocated->_type == cmd_number)
((number*)allocated)->_value.set_significand(((number*)allocated)+1);
}
object* allocate_back(unsigned int size, cmd_type_t type)
{
object* allocated;
// manage memory allocation
if (_current + size > _base + _total_size)
{
unsigned long offset = _current - _base;
@ -84,49 +71,35 @@ public:
_current = _base + offset;
}
if (_current_blob + blob_size > _blob + _total_blob_size)
{
unsigned long offset = _current_blob - _blob;
_total_blob_size += ALLOC_BLOB_CHUNK;
_blob = (char*)realloc(_blob, _total_blob_size);
_current_blob = _blob + offset;
}
// manage stack itself
_vlen.push_back(size);
_vpointer.push_back(_current);
allocated = _current;
_vpointer.push_back((object*)_current);
allocated = (object*)_current;
_current += size;
_vlen_blob.push_back(blob_size);
_vpointer_blob.push_back(_current_blob);
if (blob != NULL)
*blob = _current_blob;
_current_blob += blob_size;
_vtype.push_back(type);
_count++;
// init object
allocated->_type = type;
allocated->_size = size;
if (type == cmd_number)
((number*)allocated)->_value.init(((number*)allocated)+1);
return allocated;
}
void* pop_back()
object* pop_back()
{
void* back = NULL;
object* back = NULL;
if (_count > 0)
{
_current = _vpointer[_count - 1];
_current = (char*)_vpointer[_count - 1];
_vlen.pop_back();
_vpointer.pop_back();
_current_blob = _vpointer_blob[_count - 1];
_vlen_blob.pop_back();
_vpointer_blob.pop_back();
_vtype.pop_back();
_count--;
back = _current;
back = (object*)_current;
}
return back;
@ -138,7 +111,7 @@ public:
}
// stack access (index is counted from back)
void* get_obj(unsigned int index)
object* get_obj(unsigned int index)
{
if (index<_count)
return _vpointer[_count-index-1];
@ -146,20 +119,12 @@ public:
return NULL;
}
void* get_blob(unsigned int index)
{
if (index<_count)
return _vpointer_blob[_count-index-1];
else
return NULL;
}
void* operator[](unsigned int index)
object* operator[](unsigned int index)
{
return get_obj(index);
}
void* back()
object* back()
{
if (_count>0)
return _vpointer[_count-1];
@ -167,14 +132,6 @@ public:
return NULL;
}
void* back_blob()
{
if (_count>0)
return _vpointer_blob[_count-1];
else
return NULL;
}
unsigned int get_len(unsigned int index)
{
if (index<_count)
@ -183,16 +140,16 @@ public:
return 0;
}
int get_type(unsigned int index)
cmd_type_t get_type(unsigned int index)
{
if (index<_count)
return _vtype[_count-index-1];
return _vpointer[_count-index-1]->_type;
else
return 0;
return cmd_undef;
}
// sequential access (index is counted from front)
void* seq_obj(unsigned int index)
object* seq_obj(unsigned int index)
{
if (index<_count)
return _vpointer[index];
@ -208,44 +165,22 @@ public:
return 0;
}
void* seq_blob(unsigned int index)
cmd_type_t seq_type(unsigned int index)
{
if (index<_count)
return _vpointer_blob[index];
return _vpointer[index]->_type;
else
return NULL;
}
unsigned int seq_blob_size(unsigned int index)
{
if (index<_count)
return _vlen_blob[index];
else
return 0;
}
int seq_type(unsigned int index)
{
if (index<_count)
return _vtype[index];
else
return 0;
return cmd_undef;
}
private:
char* _base;
char* _blob;
char* _current;
char* _current_blob;
vector<char*> _vpointer;//pointer on each entry
vector<char*> _vpointer_blob;//pointer on each entry blob
vector<object*> _vpointer;//pointer on each entry
vector<unsigned int> _vlen;// size of each entry in bytes
vector<unsigned int> _vlen_blob;// size of each blob entry in bytes
vector<int> _vtype;//type of each entry
unsigned int _count;// =_vlen.size()=_vpointer.size()=_vtype.size()
unsigned int _count;// =_vlen.size()=_vpointer.size()
unsigned int _total_size;//total allocated size in bytes
unsigned int _total_blob_size;//total allocated blob size in bytes
};
//
@ -255,8 +190,7 @@ private:
struct local_var
{
unsigned int length;
int type;
int blob;
object obj[0];
};
public:
@ -267,40 +201,38 @@ public:
free(i->second);
}
void* add(const string name, void* obj, unsigned int size, int type = 0)
object* add(const string name, void* obj, unsigned int size, int type = 0)
{
struct local_var* blob = _map[name];
if (blob == NULL)
struct local_var* local = _map[name];
if (local == NULL)
{
//TODO gerer les pbs de memoire
blob = (struct local_var*)malloc(size + sizeof(local_var));
_map[name] = blob;
local = (struct local_var*)malloc(size + sizeof(local_var));
_map[name] = local;
}
else if (size != blob->length)
else if (size != local->length)
{
//TODO gerer les pbs de memoire
blob = (struct local_var*)realloc(blob, size + sizeof(local_var));
_map[name] = blob;
local = (struct local_var*)realloc(local, size + sizeof(local_var));
_map[name] = local;
}
blob->length = size;
blob->type= type;
local->length = size;
if (obj != NULL)
memcpy(&blob->blob, obj, size);
memcpy(local->obj, obj, size);
return (void*)&blob->blob;
return (object*)local->obj;
}
bool get(const string name, void*& obj, unsigned int& size, int& type)
bool get(const string name, object*& obj, unsigned int& size)
{
map<string, struct local_var*>::iterator i = _map.find(name);
if (i != _map.end())
{
if (i->second != NULL)
{
obj = &i->second->blob;
obj = i->second->obj;
size = i->second->length;
type = i->second->type;
}
return true;
}
@ -313,24 +245,23 @@ public:
return (_map.find(name) != _map.end());
}
bool get_by_index(int num, string& name, void*& obj, unsigned int& size, int& type)
bool get_by_index(int num, string& name, object*& obj, unsigned int& size)
{
if (num>=0 && num<(int)_map.size())
{
struct local_var* blob;
struct local_var* local;
map<string, struct local_var*>::iterator i=_map.begin();
//TODO moche moche moche
for(int j=0;j<num;j++)
i++;
blob = (struct local_var*)i->second;
assert(blob != NULL);
local = (struct local_var*)i->second;
assert(local != NULL);
name = i->first;
obj = &blob->blob;
size = blob->length;
type = blob->type;
obj = local->obj;
size = local->length;
return true;
}
else