#34: going to significand stored in stack [second part]: end and parse

This commit is contained in:
Louis Rubet 2017-04-22 00:29:50 +02:00
parent e786df74a8
commit 812bd01d6a
3 changed files with 162 additions and 148 deletions

View file

@ -167,9 +167,11 @@ static bool _cut(const char* entry, vector<string>& 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<string> 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<string> = {"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);
}

View file

@ -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<<buffer_for_number;
(void)mpfr_printf(s_mpfr_printf_format.c_str(), &((number*)this)->_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"

View file

@ -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;