mirror of
https://github.com/louisrubet/rpn
synced 2024-12-30 10:23:32 +01:00
#47: removed binary type and functions
This commit is contained in:
parent
eedb29a929
commit
6092d15e77
6 changed files with 56 additions and 323 deletions
92
src/parse.h
92
src/parse.h
|
@ -327,8 +327,7 @@ static bool get_program(const string& entry, program& prog, string& remaining_en
|
|||
return ret;
|
||||
}
|
||||
|
||||
// care: not threadsafe
|
||||
static bool get_float(const string& entry, program& prog, string& remaining_entry)
|
||||
static bool get_number(const string& entry, program& prog, string& remaining_entry)
|
||||
{
|
||||
char* endptr;
|
||||
bool ret = false;
|
||||
|
@ -344,6 +343,15 @@ static bool get_float(const string& entry, program& prog, string& remaining_entr
|
|||
int mpfr_ret = mpfr_strtofr(num->_value.mpfr, entry.c_str(), &endptr, 0, MPFR_DEF_RND);
|
||||
if (endptr != NULL && endptr != entry.c_str())
|
||||
{
|
||||
// determine representation
|
||||
string beg = entry.substr(0, 2);
|
||||
if (beg == "0x" || beg == "0X")
|
||||
num->_representation = number::hex;
|
||||
else if (beg == "0b" || beg == "0B")
|
||||
num->_representation = number::bin;
|
||||
else
|
||||
num->_representation = number::dec;
|
||||
|
||||
ret = true;
|
||||
|
||||
// remaining string if any
|
||||
|
@ -357,91 +365,13 @@ static bool get_float(const string& entry, program& prog, string& remaining_entr
|
|||
return ret;
|
||||
}
|
||||
|
||||
// care: not threadsafe
|
||||
static bool get_binary(const string& entry, program& prog, string& remaining_entry)
|
||||
{
|
||||
integer_t val;
|
||||
bool ret = false;
|
||||
|
||||
if ((entry.size() >= 2) && (entry[0] == '#'))
|
||||
{
|
||||
stringstream token;
|
||||
char type = entry[entry.size() - 1];
|
||||
bool syntax;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case 'd':
|
||||
token<<std::dec<<entry.substr(1);
|
||||
syntax = true;
|
||||
break;
|
||||
case 'h':
|
||||
token<<std::hex<<entry.substr(1);
|
||||
syntax = true;
|
||||
break;
|
||||
case 'o':
|
||||
token<<std::oct<<entry.substr(1);
|
||||
syntax = true;
|
||||
break;
|
||||
default:
|
||||
syntax = false;
|
||||
break;
|
||||
}
|
||||
|
||||
token>>val;
|
||||
if(syntax && !token.fail())
|
||||
{
|
||||
binary* new_binary = (binary*)prog.allocate_back((unsigned int)sizeof(binary), cmd_binary);
|
||||
new_binary->set(val);
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool get_binary_bin(const string& entry, program& prog, string& remaining_entry)
|
||||
{
|
||||
integer_t val;
|
||||
int len = entry.size();
|
||||
bool ret = false;
|
||||
|
||||
if ((len > 2) && (entry[0] == '#') && (entry[len - 1] == 'b'))
|
||||
{
|
||||
integer_t val(0);
|
||||
integer_t exponent = (1 << (len-3));
|
||||
for(int i=0; i<(len-2); i++)
|
||||
{
|
||||
if (entry.at(i+1)=='1')
|
||||
{
|
||||
val+=exponent;
|
||||
}
|
||||
exponent>>=1;
|
||||
}
|
||||
|
||||
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, program& prog, string& remaining_entry)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
remaining_entry.erase();
|
||||
|
||||
if (get_float(entry, prog, remaining_entry))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else if (get_binary(entry, prog, remaining_entry))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else if (get_binary_bin(entry, prog, remaining_entry))
|
||||
if (get_number(entry, prog, remaining_entry))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
void dec()
|
||||
{
|
||||
binary::s_mode = binary::dec;
|
||||
}
|
||||
|
||||
void hex()
|
||||
{
|
||||
binary::s_mode = binary::hex;
|
||||
}
|
||||
|
||||
void oct()
|
||||
{
|
||||
binary::s_mode = binary::oct;
|
||||
}
|
||||
|
||||
void bin()
|
||||
{
|
||||
binary::s_mode = binary::bin;
|
||||
}
|
||||
|
||||
void rtob()
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
number* left = (number*)_stack->pop_back();
|
||||
binary* bin = (binary*)_stack->allocate_back(sizeof(binary), cmd_binary);
|
||||
bin->set(mpfr_get_sj(left->_value.mpfr, s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void btor()
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_binary);
|
||||
|
||||
integer_t bin = getb();
|
||||
number* left = (number*)_stack->allocate_back(number::calc_size(), cmd_number);
|
||||
left->set(bin);
|
||||
}
|
|
@ -11,13 +11,10 @@ program::keyword_t program::_keywords[] =
|
|||
{ cmd_keyword, "exit", &program::good_bye, "" },
|
||||
{ cmd_keyword, "test", &program::test, "" }, //not seen by user
|
||||
{ cmd_keyword, "verbose", &program::verbose, "set verbosity, from 0 (not verbose) to > 0" },
|
||||
{ cmd_keyword, "std", &program::std, "standard floating numbers representation. ex: [25] std" },
|
||||
{ cmd_keyword, "fix", &program::fix, "fixed point representation. ex: 6 fix" },
|
||||
{ cmd_keyword, "sci", &program::sci, "scientific floating point representation. ex: 20 sci" },
|
||||
{ cmd_keyword, "version", &program::rpn_version, "show rpn version" },
|
||||
{ cmd_keyword, "uname", &program::rpn_uname, "show rpn complete identification string" },
|
||||
{ cmd_keyword, "type", &program::type, "show first stack entry type" },
|
||||
{ cmd_keyword, "default", &program::rpn_default, "setting precision, float representation, float precision, binary mode and verbosity to default" },
|
||||
{ cmd_keyword, "default", &program::rpn_default, "setting precision, float representation, float precision and verbosity to default" },
|
||||
|
||||
//REAL
|
||||
{ cmd_undef, "", NULL, "\nREAL"},
|
||||
|
@ -34,14 +31,14 @@ program::keyword_t program::_keywords[] =
|
|||
{ cmd_keyword, "sq", &program::square, "unarity operator square" },
|
||||
{ cmd_keyword, "mod", &program::modulo, "binary operator modulo" },
|
||||
|
||||
//BINARY
|
||||
{ cmd_undef, "", NULL, "\nBINARY"},
|
||||
{ cmd_keyword, "dec", &program::dec, "decimal representation for binaries" },
|
||||
{ cmd_keyword, "hex", &program::hex, "hexadecimal representation for binaries" },
|
||||
{ cmd_keyword, "oct", &program::oct, "octal representation for binaries" },
|
||||
{ cmd_keyword, "bin", &program::bin, "binary representation for binaries" },
|
||||
{ cmd_keyword, "r->b", &program::rtob, "real to binary" },
|
||||
{ cmd_keyword, "b->r", &program::btor, "binary to real" },
|
||||
//REAL representation
|
||||
{ cmd_undef, "", NULL, "\nREAL REPRESENTATION"},
|
||||
//{ cmd_keyword, "dec", &program::dec, "decimal representation" },
|
||||
//{ cmd_keyword, "hex", &program::hex, "hexadecimal representation" },
|
||||
//{ cmd_keyword, "bin", &program::bin, "binary representation" },
|
||||
{ cmd_keyword, "std", &program::std, "standard floating numbers representation. ex: [25] std" },
|
||||
{ cmd_keyword, "fix", &program::fix, "fixed point representation. ex: 6 fix" },
|
||||
{ cmd_keyword, "sci", &program::sci, "scientific floating point representation. ex: 20 sci" },
|
||||
|
||||
//TEST
|
||||
{ cmd_undef, "", NULL, "\nTEST"},
|
||||
|
|
|
@ -62,16 +62,6 @@ void help()
|
|||
}
|
||||
|
||||
cout<<endl<<"Current float precision is "<<number::s_current_precision<<endl;
|
||||
|
||||
cout<<"Current binary mode is ";
|
||||
switch(binary::s_mode)
|
||||
{
|
||||
case binary::dec: cout << "'dec'"; break;
|
||||
case binary::hex: cout << "'hex'"; break;
|
||||
case binary::oct: cout << "'oct'"; break;
|
||||
case binary::bin: cout << "'bin'"; break;
|
||||
default: cout << "unknown"; break;
|
||||
}
|
||||
cout<<endl<<endl;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,127 +1,55 @@
|
|||
void plus()
|
||||
{
|
||||
MIN_ARGUMENTS(2);
|
||||
|
||||
// float
|
||||
if (IS_ARG_TYPE(0, cmd_number))
|
||||
{
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
|
||||
number* right = (number*)_stack->pop_back();
|
||||
number* left = (number*)_stack->back();
|
||||
CHECK_MPFR(mpfr_add(left->_value.mpfr, left->_value.mpfr, right->_value.mpfr, s_mpfr_rnd));
|
||||
}
|
||||
// binary
|
||||
else if (IS_ARG_TYPE(0, cmd_binary))
|
||||
{
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_binary);
|
||||
|
||||
binary* right = (binary*)_stack->pop_back();
|
||||
binary* left = (binary*)_stack->back();
|
||||
left->_value += right->_value;
|
||||
}
|
||||
else
|
||||
ERR_CONTEXT(ret_bad_operand_type);
|
||||
}
|
||||
|
||||
void minus()
|
||||
{
|
||||
MIN_ARGUMENTS(2);
|
||||
|
||||
// float
|
||||
if (IS_ARG_TYPE(0, cmd_number))
|
||||
{
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
|
||||
number* right = (number*)_stack->pop_back();
|
||||
number* left = (number*)_stack->back();
|
||||
CHECK_MPFR(mpfr_sub(left->_value.mpfr, left->_value.mpfr, right->_value.mpfr, s_mpfr_rnd));
|
||||
}
|
||||
// binary
|
||||
else if (IS_ARG_TYPE(0, cmd_binary))
|
||||
{
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_binary);
|
||||
|
||||
binary* right = (binary*)_stack->pop_back();
|
||||
binary* left = (binary*)_stack->back();
|
||||
left->_value -= right->_value;
|
||||
}
|
||||
else
|
||||
ERR_CONTEXT(ret_bad_operand_type);
|
||||
}
|
||||
|
||||
void mul()
|
||||
{
|
||||
// float
|
||||
if (IS_ARG_TYPE(0, cmd_number))
|
||||
{
|
||||
MIN_ARGUMENTS(2);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
|
||||
number* right = (number*)_stack->pop_back();
|
||||
number* left = (number*)_stack->back();
|
||||
CHECK_MPFR(mpfr_mul(left->_value.mpfr, left->_value.mpfr, right->_value.mpfr, s_mpfr_rnd));
|
||||
}
|
||||
// binary
|
||||
else if (IS_ARG_TYPE(0, cmd_binary))
|
||||
{
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_binary);
|
||||
|
||||
binary* right = (binary*)_stack->pop_back();
|
||||
binary* left = (binary*)_stack->back();
|
||||
left->_value *= right->_value;
|
||||
}
|
||||
else
|
||||
ERR_CONTEXT(ret_bad_operand_type);
|
||||
}
|
||||
|
||||
void div()
|
||||
{
|
||||
MIN_ARGUMENTS(2);
|
||||
|
||||
// float
|
||||
if (IS_ARG_TYPE(0, cmd_number))
|
||||
{
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||
|
||||
number* right = (number*)_stack->pop_back();
|
||||
number* left = (number*)_stack->back();
|
||||
CHECK_MPFR(mpfr_div(left->_value.mpfr, left->_value.mpfr, right->_value.mpfr, s_mpfr_rnd));
|
||||
}
|
||||
// binary
|
||||
else if (IS_ARG_TYPE(0, cmd_binary))
|
||||
{
|
||||
ARG_MUST_BE_OF_TYPE(1, cmd_binary);
|
||||
if (((binary*)_stack->get_obj(0))->_value == 0)
|
||||
{
|
||||
ERR_CONTEXT(ret_div_by_zero);
|
||||
}
|
||||
else
|
||||
{
|
||||
binary* right = (binary*)_stack->pop_back();
|
||||
binary* left = (binary*)_stack->back();
|
||||
left->_value /= right->_value;
|
||||
}
|
||||
}
|
||||
else
|
||||
ERR_CONTEXT(ret_bad_operand_type);
|
||||
}
|
||||
|
||||
void neg()
|
||||
{
|
||||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
// float
|
||||
if (IS_ARG_TYPE(0, cmd_number))
|
||||
{
|
||||
number* left = (number*)_stack->back();
|
||||
CHECK_MPFR(mpfr_neg(left->_value.mpfr, left->_value.mpfr, s_mpfr_rnd));
|
||||
}
|
||||
// binary
|
||||
else if (IS_ARG_TYPE(0, cmd_binary))
|
||||
((binary*)_stack->back())->_value *= -1;
|
||||
else
|
||||
ERR_CONTEXT(ret_bad_operand_type);
|
||||
}
|
||||
|
||||
void inv()
|
||||
{
|
||||
|
|
97
src/rpn.cpp
97
src/rpn.cpp
|
@ -48,6 +48,8 @@ using namespace std;
|
|||
#define MPFR_128BITS_PREC 128
|
||||
#define MPFR_128BITS_STORING_LENGTH 16
|
||||
|
||||
static string s_mpfr_printf_format_hex = "0x";
|
||||
static string s_mpfr_printf_format_bin = "0b";
|
||||
static string s_mpfr_printf_format_beg = "%.";
|
||||
static string s_mpfr_printf_format_std = "Rg";
|
||||
static string s_mpfr_printf_format_fix = "Rf";
|
||||
|
@ -88,7 +90,6 @@ const char* ret_value_string[ret_max] = {
|
|||
typedef enum {
|
||||
cmd_undef,
|
||||
cmd_number,/* floating value to put in stack */
|
||||
cmd_binary,/* binary (integer) value to put in stack */
|
||||
cmd_string,/* string value to put in stack */
|
||||
cmd_symbol,/* symbol value to put in stack */
|
||||
cmd_program,/* program */
|
||||
|
@ -98,11 +99,9 @@ typedef enum {
|
|||
} cmd_type_t;
|
||||
|
||||
const char* cmd_type_string[cmd_max] = {
|
||||
"undef", "number", "binary", "string", "symbol", "program", "keyword", "keyword"
|
||||
"undef", "number", "string", "symbol", "program", "keyword", "keyword"
|
||||
};
|
||||
|
||||
typedef long long integer_t;
|
||||
|
||||
// MPFR object
|
||||
struct floating_t
|
||||
{
|
||||
|
@ -129,11 +128,6 @@ struct floating_t
|
|||
mpfr_set_ui(mpfr, val, s_mpfr_rnd);
|
||||
}
|
||||
|
||||
floating_t& operator=(const integer_t val)
|
||||
{
|
||||
mpfr_set_sj(mpfr, val, s_mpfr_rnd);
|
||||
}
|
||||
|
||||
operator int()
|
||||
{
|
||||
return (int)mpfr_get_si(mpfr, s_mpfr_rnd);
|
||||
|
@ -153,13 +147,8 @@ struct floating_t
|
|||
class program;
|
||||
class object;
|
||||
class branch;
|
||||
|
||||
typedef void (program::*program_fn_t)(void);
|
||||
|
||||
typedef union
|
||||
{
|
||||
program_fn_t _fn;
|
||||
} operand;
|
||||
|
||||
typedef int (program::*branch_fn_t)(branch&);
|
||||
|
||||
//
|
||||
|
@ -182,6 +171,7 @@ struct number : public object
|
|||
void init(void* significand)
|
||||
{
|
||||
_type = cmd_number;
|
||||
_representation = dec;
|
||||
_value.init(significand);
|
||||
}
|
||||
|
||||
|
@ -210,12 +200,6 @@ struct number : public object
|
|||
_value = value;
|
||||
}
|
||||
|
||||
void set(integer_t value)
|
||||
{
|
||||
_type = cmd_number;
|
||||
_value = value;
|
||||
}
|
||||
|
||||
static unsigned int calc_size()
|
||||
{
|
||||
return (unsigned int)(sizeof(number)+MPFR_128BITS_STORING_LENGTH);
|
||||
|
@ -238,6 +222,12 @@ struct number : public object
|
|||
static mode_enum s_default_mode;
|
||||
static mode_enum s_mode;
|
||||
|
||||
enum {
|
||||
dec,
|
||||
hex,
|
||||
bin
|
||||
} _representation;
|
||||
|
||||
// precision
|
||||
static int s_default_precision;
|
||||
static int s_current_precision;
|
||||
|
@ -248,30 +238,6 @@ number::mode_enum number::s_mode = number::s_default_mode;
|
|||
int number::s_default_precision = DEFAULT_PRECISION;
|
||||
int number::s_current_precision = number::s_default_precision;
|
||||
|
||||
struct binary : public object
|
||||
{
|
||||
integer_t _value;
|
||||
|
||||
//
|
||||
void set(integer_t value)
|
||||
{
|
||||
_type = cmd_binary;
|
||||
_value = value;
|
||||
}
|
||||
|
||||
// representation mode
|
||||
typedef enum {
|
||||
dec,
|
||||
hex,
|
||||
oct,
|
||||
bin,
|
||||
} binary_enum;
|
||||
static binary_enum s_default_mode;
|
||||
static binary_enum s_mode;
|
||||
};
|
||||
binary::binary_enum binary::s_default_mode = binary::dec;
|
||||
binary::binary_enum binary::s_mode = binary::s_default_mode;
|
||||
|
||||
struct ostring : public object
|
||||
{
|
||||
//
|
||||
|
@ -407,35 +373,9 @@ void object::show(ostream& stream)
|
|||
switch(_type)
|
||||
{
|
||||
case cmd_number:
|
||||
//(void)mpfr_printf(s_mpfr_printf_format.c_str(), &((number*)this)->_value.mpfr);
|
||||
(void)mpfr_sprintf(buffer, s_mpfr_printf_format.c_str(), ((number*)this)->_value.mpfr);
|
||||
stream<<buffer;
|
||||
break;
|
||||
case cmd_binary:
|
||||
{
|
||||
// TODO stream and not cout
|
||||
cout << "# ";
|
||||
switch(((binary*)this)->s_mode)
|
||||
{
|
||||
case binary::dec: stream<<std::right<<std::setw(8)<<std::dec<<((binary*)this)->_value<<" d"; break;
|
||||
case binary::hex: stream<<std::right<<std::setw(8)<<std::hex<<((binary*)this)->_value<<" h"; break;
|
||||
case binary::oct: stream<<std::right<<std::setw(8)<<std::oct<<((binary*)this)->_value<<" o"; break;
|
||||
case binary::bin:
|
||||
{
|
||||
string mybin;
|
||||
for (int i = (int)(log((double)((binary*)this)->_value) / log(2.)); i>=0; i--)
|
||||
{
|
||||
if (((binary*)this)->_value & (1 << i))
|
||||
mybin+='1';
|
||||
else
|
||||
mybin+='0';
|
||||
}
|
||||
stream<<std::right<<std::setw(20)<<std::oct<<mybin<<" b";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case cmd_string:
|
||||
stream << "\"" << ((ostring*)this)->_value << "\"";
|
||||
break;
|
||||
|
@ -806,10 +746,9 @@ public:
|
|||
|
||||
static void apply_default()
|
||||
{
|
||||
//default float precision, float mode, binary mode, verbosity
|
||||
//default float precision, float mode, verbosity
|
||||
number::s_mode = number::s_default_mode;
|
||||
number::s_current_precision = number::s_default_precision;
|
||||
binary::s_mode = binary::s_default_mode;
|
||||
|
||||
// format for mpfr_printf
|
||||
stringstream ss;
|
||||
|
@ -830,17 +769,6 @@ private:
|
|||
heap _local_heap;
|
||||
heap* _parent_local_heap;
|
||||
|
||||
// helpers for keywords implementation
|
||||
integer_t getb()
|
||||
{
|
||||
return ((binary*)_stack->pop_back())->_value;
|
||||
}
|
||||
|
||||
void putb(integer_t value)
|
||||
{
|
||||
((binary*)_stack->allocate_back(sizeof(binary), cmd_binary))->set(value);
|
||||
}
|
||||
|
||||
int stack_size()
|
||||
{
|
||||
return _stack->size();
|
||||
|
@ -859,7 +787,6 @@ private:
|
|||
// keywords implementation
|
||||
#include "rpn-general.h"
|
||||
#include "rpn-real.h"
|
||||
#include "rpn-binary.h"
|
||||
#include "rpn-test.h"
|
||||
#include "rpn-stack.h"
|
||||
#include "rpn-string.h"
|
||||
|
|
Loading…
Reference in a new issue