From 812bd01d6a6ed6f07521af49cfe4b08f396af4aa Mon Sep 17 00:00:00 2001 From: Louis Rubet Date: Sat, 22 Apr 2017 00:29:50 +0200 Subject: [PATCH] #34: going to significand stored in stack [second part]: end and parse --- src/parse.h | 156 ++++++++++++++++++++++------------------------------ src/rpn.cpp | 78 ++++++++++++++------------ src/stack.h | 76 ++++++++++++++++--------- 3 files changed, 162 insertions(+), 148 deletions(-) diff --git a/src/parse.h b/src/parse.h index c0371f7..637b9d7 100644 --- a/src/parse.h +++ b/src/parse.h @@ -167,9 +167,11 @@ static bool _cut(const char* entry, vector& entries) return entries.size()>0; } -static bool get_keyword(const string& entry, object*& obj, unsigned int& obj_size, cmd_type_t& type) +static bool get_keyword(const string& entry, program& prog, string& remaining_entry) { program_fn_t fn; + unsigned int obj_len; + cmd_type_t type; bool ret = false; // could be a command @@ -178,17 +180,17 @@ static bool get_keyword(const string& entry, object*& obj, unsigned int& obj_siz if (type == cmd_keyword) { // allocate keyword object - obj_size = sizeof(keyword)+entry.size()+1; - obj = (object*)malloc(obj_size); - ((keyword*)obj)->set(fn, entry.c_str(), entry.size()); + obj_len = sizeof(keyword)+entry.size()+1; + keyword* new_obj = (keyword*)prog.allocate_back(obj_len, cmd_keyword); + new_obj->set(fn, entry.c_str(), entry.size()); ret = true; } else if (type == cmd_branch) { // allocate branch object - obj_size = sizeof(branch)+entry.size()+1; - obj = (object*)malloc(obj_size); - ((branch*)obj)->set((branch_fn_t)fn, entry.c_str(), entry.size()); + obj_len = sizeof(branch)+entry.size()+1; + branch* new_obj = (branch*)prog.allocate_back(obj_len, cmd_branch); + new_obj->set((branch_fn_t)fn, entry.c_str(), entry.size()); ret = true; } } @@ -196,10 +198,11 @@ static bool get_keyword(const string& entry, object*& obj, unsigned int& obj_siz return ret; } -static bool get_symbol(const string& entry, object*& obj, unsigned int& obj_len) +static bool get_symbol(const string& entry, program& prog, string& remaining_entry) { bool ret = false; int entry_len = entry.size(); + unsigned int obj_len; if (entry_len>=1 && entry[0]=='\'') { @@ -209,11 +212,9 @@ static bool get_symbol(const string& entry, object*& obj, unsigned int& obj_len) // total object length obj_len = sizeof(symbol)+1; - // allocate object - obj = (symbol*)malloc(obj_len); - - //set it - ((symbol*)obj)->set("", 0); + // allocate and set object + symbol* new_obj = (symbol*)prog.allocate_back(obj_len, cmd_symbol); + new_obj->set("", 0); } else { @@ -224,11 +225,9 @@ static bool get_symbol(const string& entry, object*& obj, unsigned int& obj_len) // total object length obj_len = sizeof(symbol)+naked_entry_len+1; - // allocate object - obj = (symbol*)malloc(obj_len); - - // set it - ((symbol*)obj)->set(entry.substr(1, naked_entry_len).c_str(), naked_entry_len); + // allocate and set object + symbol* new_obj = (symbol*)prog.allocate_back(obj_len, cmd_symbol); + new_obj->set(entry.substr(1, naked_entry_len).c_str(), naked_entry_len); } ret = true; } @@ -236,10 +235,11 @@ static bool get_symbol(const string& entry, object*& obj, unsigned int& obj_len) return ret; } -static bool get_other(const string& entry, object*& obj, unsigned int& obj_len, cmd_type_t& type) +static bool get_other(const string& entry, program& prog, string& remaining_entry) { bool ret = false; int entry_len = entry.size(); + unsigned int obj_len; if (entry_len>=1) { @@ -251,22 +251,20 @@ static bool get_other(const string& entry, object*& obj, unsigned int& obj_len, // total object length obj_len = sizeof(symbol)+naked_entry_len+1; - // allocate object - obj = (symbol*)malloc(obj_len); - - // set it - ((symbol*)obj)->set(entry.c_str(), naked_entry_len); - ((symbol*)obj)->_auto_eval = true; - type = cmd_symbol; + // allocate and set object + symbol* new_obj = (symbol*)prog.allocate_back(obj_len, cmd_symbol); + new_obj->set(entry.c_str(), naked_entry_len); + new_obj->_auto_eval = true; ret = true; } return ret; } -static bool get_string(const string& entry, object*& obj, unsigned int& obj_len) +static bool get_string(const string& entry, program& prog, string& remaining_entry) { bool ret = false; + unsigned int obj_len; int entry_len = entry.size(); if (entry_len>=1 && entry[0]=='"') { @@ -275,11 +273,9 @@ static bool get_string(const string& entry, object*& obj, unsigned int& obj_len) // total object length obj_len = sizeof(ostring)+1; - // allocate object - obj = (ostring*)malloc(obj_len); - - //set it - ((ostring*)obj)->set("", 0); + // allocate and set object + ostring* new_obj = (ostring*)prog.allocate_back(obj_len, cmd_string); + new_obj->set("", 0); } else { @@ -291,11 +287,9 @@ static bool get_string(const string& entry, object*& obj, unsigned int& obj_len) // total object length obj_len = sizeof(ostring)+naked_entry_len+1; - // allocate object - obj = (ostring*)malloc(obj_len); - - // set it - ((ostring*)obj)->set(entry.substr(1, naked_entry_len).c_str(), naked_entry_len); + // allocate and set object + ostring* new_obj = (ostring*)prog.allocate_back(obj_len, cmd_string); + new_obj->set(entry.substr(1, naked_entry_len).c_str(), naked_entry_len); } ret = true; } @@ -303,9 +297,10 @@ static bool get_string(const string& entry, object*& obj, unsigned int& obj_len) return ret; } -static bool get_program(const string& entry, object*& obj, unsigned int& obj_len) +static bool get_program(const string& entry, program& prog, string& remaining_entry) { bool ret = false; + unsigned int obj_len; int entry_len = entry.size(); if (entry_len>=2 && entry[0]=='<' && entry[1]=='<') { @@ -320,11 +315,9 @@ static bool get_program(const string& entry, object*& obj, unsigned int& obj_len // total object length obj_len = sizeof(oprogram)+naked_entry_len+1; - // allocate object - obj = (object*)malloc(obj_len); - - // set it - ((oprogram*)obj)->set(&entry[2], naked_entry_len); + // allocate and set object + oprogram* new_obj = (oprogram*)prog.allocate_back(obj_len, cmd_program); + new_obj->set(&entry[2], naked_entry_len); ret = true; } @@ -332,7 +325,7 @@ static bool get_program(const string& entry, object*& obj, unsigned int& obj_len } // care: not threadsafe -static bool get_float(const string& entry, object*& obj, unsigned int& obj_size, string& remaining_entry) +static bool get_float(const string& entry, program& prog, string& remaining_entry) { static number new_number; char* endptr; @@ -340,25 +333,29 @@ static bool get_float(const string& entry, object*& obj, unsigned int& obj_size, if (entry.size() > 0) { - if ((mpfr_strtofr(&new_number._value.mpfr, entry.c_str(), &endptr, 0, MPFR_DEF_RND) != -1) && (endptr != entry.c_str())) - { - obj = &new_number; - obj_size = sizeof(number); - ret = true; + // TODO dans la mesure du possible, ne pas allouer sur la pile pour désallouer après (?) + // mais faire un parse avec une autre fonction que mpfr_strtofr puis seulement si ok faire mpfr_strtofr + void* significand; + number* num = (number*)prog.allocate_back((unsigned int)sizeof(number), cmd_number, MPFR_128BITS_STORING_LENGTH, &significand); + num->init(significand); + if ((mpfr_strtofr(&num->_value.mpfr, entry.c_str(), &endptr, 0, MPFR_DEF_RND) != -1) && (endptr != entry.c_str())) + { + ret = true; // remaining string if any if (endptr != NULL) remaining_entry = endptr; } + else + (void)prog.pop_back(); } return ret; } // care: not threadsafe -static bool get_binary(const string& entry, object*& obj, unsigned int& obj_size) +static bool get_binary(const string& entry, program& prog, string& remaining_entry) { - static binary new_binary; integer_t val; bool ret = false; @@ -390,9 +387,8 @@ static bool get_binary(const string& entry, object*& obj, unsigned int& obj_size token>>val; if(syntax && !token.fail()) { - new_binary.set(val); - obj = &new_binary; - obj_size = sizeof(binary); + binary* new_binary = (binary*)prog.allocate_back((unsigned int)sizeof(binary), cmd_binary); + new_binary->set(val); ret = true; } } @@ -400,10 +396,8 @@ static bool get_binary(const string& entry, object*& obj, unsigned int& obj_size return ret; } -// care: not threadsafe -static bool get_binary_bin(const string& entry, object*& obj, unsigned int& obj_size) +static bool get_binary_bin(const string& entry, program& prog, string& remaining_entry) { - static binary new_binary; integer_t val; int len = entry.size(); bool ret = false; @@ -420,59 +414,53 @@ static bool get_binary_bin(const string& entry, object*& obj, unsigned int& obj_ exponent/=2; } } - new_binary.set(val); - obj = &new_binary; - obj_size = sizeof(binary); + + binary* new_binary = (binary*)prog.allocate_back((unsigned int)sizeof(binary), cmd_binary); + new_binary->set(val); ret = true; } return ret; } -static bool _obj_from_string(const string& entry, object*& obj, unsigned int& obj_size, cmd_type_t& type, string& remaining_entry) +static bool _obj_from_string(const string& entry, program& prog, string& remaining_entry) { bool ret = false; remaining_entry.erase(); - if (get_float(entry, obj, obj_size, remaining_entry)) + if (get_float(entry, prog, remaining_entry)) { - type = cmd_number; ret = true; } - else if (get_binary(entry, obj, obj_size)) + else if (get_binary(entry, prog, remaining_entry)) { - type = cmd_binary; ret = true; } - else if (get_binary_bin(entry, obj, obj_size)) + else if (get_binary_bin(entry, prog, remaining_entry)) { - type = cmd_binary; ret = true; } - else if (get_symbol(entry, obj, obj_size)) + else if (get_symbol(entry, prog, remaining_entry)) { - type = cmd_symbol; ret = true; } - else if (get_string(entry, obj, obj_size)) + else if (get_string(entry, prog, remaining_entry)) { - type = cmd_string; ret = true; } - else if (get_program(entry, obj, obj_size)) + else if (get_program(entry, prog, remaining_entry)) { - type = cmd_program; ret = true; } - else if (get_keyword(entry, obj, obj_size, type)) + else if (get_keyword(entry, prog, remaining_entry)) { ret = true; } else { // nothing, considered as an auto-evaluated symbol - if (get_other(entry, obj, obj_size, type)) + if (get_other(entry, prog, remaining_entry)) { ret = true; } @@ -526,9 +514,6 @@ static ret_value parse(const char* entry, program& prog) { vector entries; ret_value ret = ret_ok; - cmd_type_t type; - unsigned int obj_size; - object* obj; //1. cut global entry string into shorter strings if (_cut(entry, entries)) @@ -543,17 +528,9 @@ static ret_value parse(const char* entry, program& prog) // remaining_entry is used only in case of concatenated entry // ex: entry="1 2+" -> vector = {"1", "2+"} -> first "1", second "2" and remaining_entry="+" // this remaining entry is treated as an entry - if(_obj_from_string(main_entry, obj, obj_size, type, remaining_entry)) - { - if (type == cmd_number) - { - void* significand; - prog.allocate_back(obj_size, type, MPFR_128BITS_STORING_LENGTH, &significand); - - } - else - prog.push_back(obj, obj_size, type); - } + + // TODO errors ? + _obj_from_string(main_entry, prog, remaining_entry); main_entry = remaining_entry; } } @@ -585,5 +562,6 @@ static ret_value entry(program& prog) else ret = ret_internal; + //TODO free(buf); } diff --git a/src/rpn.cpp b/src/rpn.cpp index 619ef87..04474a3 100644 --- a/src/rpn.cpp +++ b/src/rpn.cpp @@ -106,25 +106,29 @@ typedef long long integer_t; struct floating_t { __mpfr_struct mpfr; - char significand[MPFR_128BITS_STORING_LENGTH]; - floating_t() + void init(void* significand) { mpfr_custom_init(significand, MPFR_128BITS_STORING_LENGTH); - mpfr_custom_init_set(&mpfr, MPFR_NAN_KIND, 0, s_mpfr_prec, significand); + mpfr_custom_init_set(&mpfr, MPFR_ZERO_KIND, 0, s_mpfr_prec, significand); + } + + void set_significand(void* significand) + { + mpfr._mpfr_d = (mp_limb_t*)significand; } floating_t& operator=(const long int val) { - mpfr_custom_init(significand, MPFR_128BITS_STORING_LENGTH); - mpfr_custom_init_set(&mpfr, MPFR_ZERO_KIND, 0, s_mpfr_prec, significand); + //mpfr_custom_init(significand, MPFR_128BITS_STORING_LENGTH); + //mpfr_custom_init_set(&mpfr, MPFR_ZERO_KIND, 0, s_mpfr_prec, significand); mpfr_set_si(&mpfr, val, s_mpfr_rnd); } floating_t& operator=(const integer_t val) { - mpfr_custom_init(significand, MPFR_128BITS_STORING_LENGTH); - mpfr_custom_init_set(&mpfr, MPFR_ZERO_KIND, 0, s_mpfr_prec, significand); + //mpfr_custom_init(significand, MPFR_128BITS_STORING_LENGTH); + //mpfr_custom_init_set(&mpfr, MPFR_ZERO_KIND, 0, s_mpfr_prec, significand); mpfr_set_sj(&mpfr, val, s_mpfr_rnd); } @@ -132,10 +136,10 @@ struct floating_t { return (int)mpfr_get_si(&mpfr, s_mpfr_rnd); } - + void ensure_significand() { - mpfr._mpfr_d = (mp_limb_t*)significand; + //mpfr._mpfr_d = (mp_limb_t*)significand; } bool operator>(const floating_t right) @@ -147,7 +151,7 @@ struct floating_t { return mpfr_cmp(&mpfr, &right.mpfr) < 0; } -}; +} __attribute__((packed)); class program; class object; @@ -157,7 +161,7 @@ typedef void (program::*program_fn_t)(void); typedef union { program_fn_t _fn; -} operand; +} __attribute__((packed)) operand; typedef int (program::*branch_fn_t)(branch&); // @@ -168,19 +172,31 @@ struct object // void show(ostream& stream = cout); -}; +} __attribute__((packed)); struct number : public object { number() { _type = cmd_number; } floating_t _value; + void init(void* significand) + { + _type = cmd_number; + _value.init(significand); + } + + void copy(number& op) + { + _value = op._value; + memcpy(_value.mpfr._mpfr_d, op._value.mpfr._mpfr_d, MPFR_128BITS_STORING_LENGTH); + } + // void set(const floating_t& value) { _type = cmd_number; - _value.mpfr = value.mpfr; - (void)memcpy(_value.significand, value.significand, sizeof(_value.significand)); + _value.mpfr._mpfr_d = value.mpfr._mpfr_d; + //(void)memcpy(_value.significand, value.significand, sizeof(_value.significand)); } void set(long value) { @@ -196,7 +212,7 @@ struct number : public object void ensure_significand() { - _value.mpfr._mpfr_d = (mp_limb_t*)_value.significand; + //_value.mpfr._mpfr_d = (mp_limb_t*)_value.significand; } // @@ -219,7 +235,7 @@ struct number : public object // precision static int s_default_precision; static int s_current_precision; -}; +} __attribute__((packed)); number::mode_enum number::s_default_mode = number::std; number::mode_enum number::s_mode = number::s_default_mode; @@ -247,7 +263,7 @@ struct binary : public object } binary_enum; static binary_enum s_default_mode; static binary_enum s_mode; -}; +} __attribute__((packed)); binary::binary_enum binary::s_default_mode = binary::dec; binary::binary_enum binary::s_mode = binary::s_default_mode; @@ -272,7 +288,7 @@ struct ostring : public object // unsigned int _len; char _value[0]; -}; +} __attribute__((packed)); struct oprogram : public object { @@ -295,7 +311,7 @@ struct oprogram : public object // unsigned int _len; char _value[0]; -}; +} __attribute__((packed)); struct symbol : public object { @@ -320,7 +336,7 @@ struct symbol : public object bool _auto_eval; unsigned int _len; char _value[0]; -}; +} __attribute__((packed)); struct keyword : public object { @@ -345,7 +361,7 @@ struct keyword : public object program_fn_t _fn; unsigned int _len; char _value[0]; -}; +} __attribute__((packed)); struct branch : public object { @@ -380,18 +396,14 @@ struct branch : public object bool arg_bool; unsigned int _len; char _value[0]; -}; +} __attribute__((packed)); void object::show(ostream& stream) { - //TODO please don't do that - char buffer_for_number[256]; switch(_type) { case cmd_number: - ((number*)this)->ensure_significand(); - (void)mpfr_sprintf(buffer_for_number, s_mpfr_printf_format.c_str(), &((number*)this)->_value.mpfr); - stream<_value.mpfr); break; case cmd_binary: { @@ -540,14 +552,12 @@ public: // not a command, but a stack entry, manage it else { - stk.push_back(seq_obj(i), seq_len(i), type); + // copy the program stack entry to the running stack + copy_and_push_back(*this, i, stk); - // numbers: ensure that significand is correctly recorded by object + // manage particular type of entries if (type == cmd_number) - { - number* k = (number*)stk.back(); - k->ensure_significand(); - } + ((number*)stk.back())->_value.set_significand(stk.back_blob()); i++; } @@ -860,7 +870,7 @@ private: #include "rpn-program.h" #include "rpn-trig.h" #include "rpn-logs.h" -}; +} __attribute__((packed)); //keywords declaration #include "rpn-cmd.h" diff --git a/src/stack.h b/src/stack.h index 16cde82..b19031c 100644 --- a/src/stack.h +++ b/src/stack.h @@ -30,32 +30,43 @@ private: public: stack() { - _base = (char*)malloc(ALLOC_STACK_CHUNK); - _blob = (char*)malloc(ALLOC_BLOB_CHUNK); + _base = new char[ALLOC_STACK_CHUNK]; + _blob = new char[ALLOC_BLOB_CHUNK]; _total_size = ALLOC_STACK_CHUNK; + _total_blob_size = ALLOC_BLOB_CHUNK; _current = _base; - _current_blob = _base; + _current_blob = _blob; _count = 0; } - virtual ~stack() { free(_base); } - void push_back(void* obj, unsigned int size, int type = 0, bool dont_copy = false) + virtual ~stack() { - if (_current + size > _base + _total_size) - { - //TODO gerer les pbs de memoire - _total_size += ALLOC_STACK_CHUNK; - _base = (char*)realloc(_base, _total_size); - } + delete[] _base; + delete[] _blob; + } + + 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) - memcpy(_current, obj, size); - _vlen.push_back(size); - _vpointer.push_back(_current); - _vlen_blob.push_back(0); - _vtype.push_back(type); - _count++; - _current += size; + { + 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); + + 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)); } void* allocate_back(unsigned int size, int type, unsigned int blob_size = 0, void** blob = NULL) @@ -65,14 +76,18 @@ public: if (_current + size > _base + _total_size) { //TODO gerer les pbs de memoire + unsigned long offset = _current - _base; _total_size += ALLOC_STACK_CHUNK; _base = (char*)realloc(_base, _total_size); + _current = _base + offset; } if (_current_blob + blob_size > _blob + _total_blob_size) { //TODO gerer les pbs de memoire + unsigned long offset = _current_blob - _blob; _total_blob_size += ALLOC_BLOB_CHUNK; - _blob = (char*)realloc(_base, _total_blob_size); + _blob = (char*)realloc(_blob, _total_blob_size); + _current_blob = _blob + offset; } _vlen.push_back(size); @@ -145,7 +160,7 @@ public: void* back_blob() { if (_count>0) - return _vpointer[_count-1]; + return _vpointer_blob[_count-1]; else return NULL; } @@ -183,6 +198,22 @@ public: return 0; } + void* seq_blob(unsigned int index) + { + if (index<_count) + return _vpointer_blob[index]; + 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) @@ -208,11 +239,6 @@ public: push_back(&local->blob, local->length, local->type); } - void dump(void) - { - dump8((unsigned char*)_base, 0, (unsigned long)(_current - _base)); - } - private: char* _base; char* _blob;