mirror of
https://github.com/louisrubet/rpn
synced 2025-01-17 06:12:09 +01:00
#72: refactored source code for [quite] conventional cpp and hpp. Includes in class still exist
This commit is contained in:
parent
9a0339079d
commit
9c88a4f679
19 changed files with 191 additions and 1191 deletions
18
Makefile.am
18
Makefile.am
|
@ -3,20 +3,12 @@ ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS}
|
|||
|
||||
|
||||
bin_PROGRAMS = rpn
|
||||
rpn_SOURCES = src/rpn.cpp \
|
||||
src/rpn-branch.h \
|
||||
src/rpn-cmd.h \
|
||||
src/rpn-algebra.h \
|
||||
src/rpn-general-core.h \
|
||||
src/rpn-general.h \
|
||||
src/rpn-logs.h \
|
||||
src/rpn-stack.h \
|
||||
src/rpn-store.h \
|
||||
src/rpn-test.h \
|
||||
src/rpn-trig.h \
|
||||
src/stack.h
|
||||
rpn_SOURCES = src/object.cpp \
|
||||
src/program.cpp \
|
||||
src/main.cpp
|
||||
|
||||
rpn_CFLAGS =
|
||||
|
||||
rpn_CFLAGS = -g
|
||||
rpn_LDFLAGS = -Wl,--no-as-needed -lreadline -lmpfr
|
||||
|
||||
dist_noinst_SCRIPTS = autogen.sh
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
#ifndef CONSTANT_H
|
||||
#define CONSTANT_H
|
||||
|
||||
// default values
|
||||
//
|
||||
|
||||
|
@ -31,8 +34,26 @@
|
|||
|
||||
#define MPFR_RND_STRINGS { "nearest", "toward zero", "toward +inf", "toward -inf", "away from zero" }
|
||||
|
||||
// return values
|
||||
// return values, used by all classes
|
||||
//
|
||||
typedef enum {
|
||||
ret_ok,
|
||||
ret_unknown_err,
|
||||
ret_missing_operand,
|
||||
ret_bad_operand_type,
|
||||
ret_out_of_range,
|
||||
ret_unknown_variable,
|
||||
ret_internal,
|
||||
ret_deadly,
|
||||
ret_good_bye,
|
||||
ret_not_impl,
|
||||
ret_nop,
|
||||
ret_syntax,
|
||||
ret_div_by_zero,
|
||||
ret_runtime_error,
|
||||
ret_max
|
||||
} ret_value;
|
||||
|
||||
#define RET_VALUE_STRINGS { \
|
||||
"ok", "unknown command", "missing operand", "bad operand type", "out of range", "unknown variable", "internal error, aborting", \
|
||||
"deadly", "goodbye", "not implemented", "no operation", "syntax error", "division by zero", "runtime error" \
|
||||
|
@ -41,3 +62,5 @@
|
|||
// command types
|
||||
//
|
||||
#define CMD_TYPE_STRINGS { "undef", "number", "string", "symbol", "program", "keyword", "keyword" }
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
#ifndef DEBUG_H
|
||||
#define DEBUG_H
|
||||
|
||||
static void dump8(unsigned char* to_dump, unsigned long offset,
|
||||
unsigned long size)
|
||||
{
|
||||
|
@ -43,3 +46,4 @@ static void dump8(unsigned char* to_dump, unsigned long offset,
|
|||
//
|
||||
#define TRACE(...) do { (void)printf(__FUNCTION__ ": "); (void)printf(__VA_ARGS__); } while(0)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
#ifndef ESCAPE_H
|
||||
#define ESCAPE_H
|
||||
|
||||
// ANSI escape sequences
|
||||
|
||||
// foreground colors
|
||||
|
@ -29,4 +32,6 @@
|
|||
#define ATTR_REVERSE "\33[7m"
|
||||
#define ATTR_CONCEALED "\33[8m"
|
||||
|
||||
#define ATTR_OFF "\33[0m"
|
||||
#define ATTR_OFF "\33[0m"
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,25 +1,74 @@
|
|||
// keywords declaration
|
||||
struct keyword_t
|
||||
public:
|
||||
static ret_value parse(const char* entry, program& prog)
|
||||
{
|
||||
cmd_type_t type;
|
||||
char name[24];
|
||||
program_fn_t fn;
|
||||
string comment;
|
||||
};
|
||||
static const int g_max_commands = 128;
|
||||
static keyword_t _keywords[g_max_commands];
|
||||
vector<string> entries;
|
||||
ret_value ret = ret_ok;
|
||||
|
||||
//1. cut global entry string into shorter strings
|
||||
if (_cut(entry, entries))
|
||||
{
|
||||
//2. make an object from each entry, and add it to the program
|
||||
for (vector<string>::iterator it = entries.begin(); it != entries.end(); it++)
|
||||
{
|
||||
string remaining_entry;
|
||||
string main_entry = (*it);
|
||||
while(main_entry.size()>0)
|
||||
{
|
||||
// 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
|
||||
|
||||
// TODO errors ?
|
||||
_obj_from_string(main_entry, prog, remaining_entry);
|
||||
main_entry = remaining_entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// interactive entry and decoding
|
||||
static ret_value entry(program& prog)
|
||||
{
|
||||
char* buf;
|
||||
ret_value ret;
|
||||
|
||||
// declare completion fn (bound to '\t' by default)
|
||||
rl_completion_entry_function = entry_completion_generator;
|
||||
|
||||
// get user entry
|
||||
buf = readline(prompt);
|
||||
if (buf != NULL)
|
||||
{
|
||||
// parse it
|
||||
ret = parse(buf, prog);
|
||||
|
||||
// keep history
|
||||
if (buf[0]!=0)
|
||||
add_history(buf);
|
||||
}
|
||||
else
|
||||
ret = ret_internal;
|
||||
|
||||
//TODO
|
||||
free(buf);
|
||||
}
|
||||
|
||||
private:
|
||||
static ret_value get_fn(const char* fn_name, program_fn_t& fn, cmd_type_t& type)
|
||||
{
|
||||
for(unsigned int i=0; (i<sizeof(_keywords)/sizeof(_keywords[0])) && (_keywords[i].type != cmd_max); i++)
|
||||
unsigned int i = 0;
|
||||
while(s_keywords[i].type != cmd_max)
|
||||
{
|
||||
if ((strnlen(_keywords[i].name, sizeof(_keywords[i].name))>0)
|
||||
&& (strncmp(fn_name, _keywords[i].name, sizeof(_keywords[i].name)) == 0))
|
||||
if ((strnlen(s_keywords[i].name, sizeof(s_keywords[i].name))>0)
|
||||
&& (strncmp(fn_name, s_keywords[i].name, sizeof(s_keywords[i].name)) == 0))
|
||||
{
|
||||
fn = _keywords[i].fn;
|
||||
type = _keywords[i].type;
|
||||
fn = s_keywords[i].fn;
|
||||
type = s_keywords[i].type;
|
||||
return ret_ok;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return ret_unknown_err;
|
||||
}
|
||||
|
@ -417,16 +466,16 @@ static char* entry_completion_generator(const char* text, int state)
|
|||
while(too_far == 0)
|
||||
{
|
||||
list_index++;
|
||||
if (_keywords[list_index].fn != NULL)
|
||||
if (s_keywords[list_index].fn != NULL)
|
||||
{
|
||||
// compare list entry with text, return if match
|
||||
if (strncmp(_keywords[list_index].name, text, len) == 0)
|
||||
return entry_completion_dupstr(_keywords[list_index].name);
|
||||
if (strncmp(s_keywords[list_index].name, text, len) == 0)
|
||||
return entry_completion_dupstr(s_keywords[list_index].name);
|
||||
}
|
||||
else
|
||||
{
|
||||
// fn=NULL and size=0 = last entry in list -> go out
|
||||
if (_keywords[list_index].comment.size() == 0)
|
||||
if (s_keywords[list_index].comment.size() == 0)
|
||||
too_far = 1;
|
||||
}
|
||||
}
|
||||
|
@ -443,59 +492,3 @@ static char* entry_completion_dupstr(char* s)
|
|||
strcpy(r, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
static ret_value parse(const char* entry, program& prog)
|
||||
{
|
||||
vector<string> entries;
|
||||
ret_value ret = ret_ok;
|
||||
|
||||
//1. cut global entry string into shorter strings
|
||||
if (_cut(entry, entries))
|
||||
{
|
||||
//2. make an object from each entry, and add it to the program
|
||||
for (vector<string>::iterator it = entries.begin(); it != entries.end(); it++)
|
||||
{
|
||||
string remaining_entry;
|
||||
string main_entry = (*it);
|
||||
while(main_entry.size()>0)
|
||||
{
|
||||
// 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
|
||||
|
||||
// TODO errors ?
|
||||
_obj_from_string(main_entry, prog, remaining_entry);
|
||||
main_entry = remaining_entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// interactive entry and decoding
|
||||
static ret_value entry(program& prog)
|
||||
{
|
||||
char* buf;
|
||||
ret_value ret;
|
||||
|
||||
// declare completion fn (bound to '\t' by default)
|
||||
rl_completion_entry_function = entry_completion_generator;
|
||||
|
||||
// get user entry
|
||||
buf = readline(prompt);
|
||||
if (buf != NULL)
|
||||
{
|
||||
// parse it
|
||||
ret = parse(buf, prog);
|
||||
|
||||
// keep history
|
||||
if (buf[0]!=0)
|
||||
add_history(buf);
|
||||
}
|
||||
else
|
||||
ret = ret_internal;
|
||||
|
||||
//TODO
|
||||
free(buf);
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
//
|
||||
int rpn_if(branch& myobj)
|
||||
{
|
135
src/rpn-cmd.h
135
src/rpn-cmd.h
|
@ -1,135 +0,0 @@
|
|||
program::keyword_t program::_keywords[] =
|
||||
{
|
||||
//GENERAL
|
||||
{ cmd_undef, "", NULL, "\nGENERAL"},
|
||||
{ cmd_keyword, "nop", &program::nop, "no operation"},
|
||||
{ cmd_keyword, "?", &program::help, "" },
|
||||
{ cmd_keyword, "h", &program::help, "" },
|
||||
{ cmd_keyword, "help", &program::help, "(or h or ?) this help message" },
|
||||
{ cmd_keyword, "q", &program::good_bye, "" },
|
||||
{ cmd_keyword, "quit", &program::good_bye, "(or q or exit) quit software" },
|
||||
{ cmd_keyword, "exit", &program::good_bye, "" },
|
||||
{ cmd_keyword, "test", &program::test, "" }, //not seen by user
|
||||
{ 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 type of stack first entry" },
|
||||
{ cmd_keyword, "default", &program::rpn_default, "set float representation and precision to default" },
|
||||
{ cmd_keyword, "prec", &program::precision, "get float precision in bits when first stack is not a number\n\t"
|
||||
"set float precision in bits when first stack entry is a number. ex: 256 prec\n\t" },
|
||||
{ cmd_keyword, "round", &program::round, "set float rounding mode.\n\tex: [\"nearest\", \"toward zero\", \"toward +inf\", \"toward -inf\", \"away from zero\"] round" },
|
||||
|
||||
//REAL
|
||||
{ cmd_undef, "", NULL, "\nREAL"},
|
||||
{ cmd_keyword, "+", &program::plus, "addition" },
|
||||
{ cmd_keyword, "-", &program::minus, "substraction" },
|
||||
{ cmd_keyword, "neg", &program::neg , "negation" },
|
||||
{ cmd_keyword, "*", &program::mul, "multiplication" },
|
||||
{ cmd_keyword, "/", &program::div, "division" },
|
||||
{ cmd_keyword, "inv", &program::inv, "inverse" },
|
||||
{ cmd_keyword, "%", &program::purcent, "purcent" },
|
||||
{ cmd_keyword, "%CH", &program::purcentCH, "inverse purcent" },
|
||||
{ cmd_keyword, "^", &program::power, "(or pow) power" },
|
||||
{ cmd_keyword, "pow", &program::power, "" },
|
||||
{ cmd_keyword, "sqrt", &program::squareroot, "square root" },
|
||||
{ cmd_keyword, "sq", &program::square, "(or sqr) square" },
|
||||
{ cmd_keyword, "sqr", &program::square, "" },
|
||||
{ cmd_keyword, "mod", &program::modulo, "modulo" },
|
||||
{ cmd_keyword, "abs", &program::rpn_abs, "absolute value" },
|
||||
|
||||
//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"},
|
||||
{ cmd_keyword, ">", &program::sup, "binary operator >" },
|
||||
{ cmd_keyword, ">=", &program::sup_eq, "binary operator >=" },
|
||||
{ cmd_keyword, "<", &program::inf, "binary operator <" },
|
||||
{ cmd_keyword, "<=", &program::inf_eq, "binary operator <=" },
|
||||
{ cmd_keyword, "!=", &program::diff, "binary operator != (different)" },
|
||||
{ cmd_keyword, "==", &program::eq , "binary operator == (equal)" },
|
||||
{ cmd_keyword, "and", &program::test_and , "boolean operator and" },
|
||||
{ cmd_keyword, "or", &program::test_or , "boolean operator or" },
|
||||
{ cmd_keyword, "xor", &program::test_xor , "boolean operator xor" },
|
||||
{ cmd_keyword, "not", &program::test_not , "boolean operator not" },
|
||||
{ cmd_keyword, "same", &program::same , "boolean operator same (equal)" },
|
||||
|
||||
//STACK
|
||||
{ cmd_undef, "", NULL, "\nSTACK"},
|
||||
{ cmd_keyword, "swap", &program::swap, "swap 2 first stack entries" },
|
||||
{ cmd_keyword, "drop", &program::drop, "drop first stack entry" },
|
||||
{ cmd_keyword, "drop2", &program::drop2, "drop 2 first stack entries" },
|
||||
{ cmd_keyword, "erase", &program::erase, "drop all stack entries" },
|
||||
{ cmd_keyword, "rot", &program::rot, "rotate 3 first stack entries" },
|
||||
{ cmd_keyword, "dup", &program::dup, "duplicate first stack entry" },
|
||||
{ cmd_keyword, "dup2", &program::dup2, "duplicate 2 first stack entries" },
|
||||
{ cmd_keyword, "pick", &program::pick, "push a copy of the given stack level onto the stack" },
|
||||
{ cmd_keyword, "depth", &program::depth, "give stack depth" },
|
||||
|
||||
//STRING
|
||||
{ cmd_undef, "", NULL, "\nSTRING"},
|
||||
{ cmd_keyword, "->str", &program::instr, "convert an object into a string" },
|
||||
{ cmd_keyword, "str->", &program::strout, "convert a string into an object" },
|
||||
|
||||
//BRANCH
|
||||
{ cmd_undef, "", NULL, "\nBRANCH"},
|
||||
{ cmd_branch, "if", (program_fn_t)&program::rpn_if, "<test-instructions>" },
|
||||
{ cmd_branch, "then", (program_fn_t)&program::rpn_then, "<true-instructions>" },
|
||||
{ cmd_branch, "else", (program_fn_t)&program::rpn_else, "<false-instructions>" },
|
||||
{ cmd_keyword, "end", &program::rpn_end, "(end of if structure)" },
|
||||
{ cmd_branch, "start", (program_fn_t)&program::rpn_start, "repeat instructions several times" },
|
||||
{ cmd_branch, "for", (program_fn_t)&program::rpn_for, "repeat instructions several times with variable" },
|
||||
{ cmd_branch, "next", (program_fn_t)&program::rpn_next, "ex: 1 10 start <instructions> next" },
|
||||
{ cmd_branch, "step", (program_fn_t)&program::rpn_step, "ex: 1 100 start <instructions> 4 step" },
|
||||
|
||||
//STORE
|
||||
{ cmd_undef, "", NULL, "\nSTORE"},
|
||||
{ cmd_keyword, "sto", &program::sto, "store a variable. ex: 1 'name' sto" },
|
||||
{ cmd_keyword, "rcl", &program::rcl, "recall a variable. ex: 'name' rcl" },
|
||||
{ cmd_keyword, "purge", &program::purge, "delete a variable. ex: 'name' purge" },
|
||||
{ cmd_keyword, "vars", &program::vars, "list all variables" },
|
||||
{ cmd_keyword, "edit", &program::edit, "edit a variable content" },
|
||||
|
||||
//PROGRAM
|
||||
{ cmd_undef, "", NULL, "\nPROGRAM"},
|
||||
{ cmd_keyword, "eval", &program::eval, "evaluate (run) a program, or recall a variable. ex: 'my_prog' eval" },
|
||||
{ cmd_branch, "->", (program_fn_t)&program::inprog, "load program local variables. ex: << -> n m << 0 n m for i i + next >> >>" },
|
||||
|
||||
//TRIG
|
||||
{ cmd_undef, "", NULL, "\nTRIG"},
|
||||
{ cmd_keyword, "pi", &program::pi, "PI constant" },
|
||||
{ cmd_keyword, "sin", &program::rpn_sin, "sinus" },
|
||||
{ cmd_keyword, "asin", &program::rpn_asin, "arg sinus" },
|
||||
{ cmd_keyword, "cos", &program::rpn_cos , "cosinus" },
|
||||
{ cmd_keyword, "acos", &program::rpn_acos, "arg cosinus" },
|
||||
{ cmd_keyword, "tan", &program::rpn_tan, "tangent" },
|
||||
{ cmd_keyword, "atan", &program::rpn_atan, "arg tangent" },
|
||||
{ cmd_keyword, "d->r", &program::d2r, "convert degrees to radians" },
|
||||
{ cmd_keyword, "r->d", &program::r2d, "convert radians to degrees" },
|
||||
|
||||
//LOGS
|
||||
{ cmd_undef, "", NULL, "\nLOGS"},
|
||||
{ cmd_keyword, "e", &program::rpn_e, "exp(0) constant" },
|
||||
{ cmd_keyword, "log", &program::rpn_log, "logarithm base 10" },
|
||||
{ cmd_keyword, "alog", &program::rpn_alog, "(or exp10) exponential base 10" },
|
||||
{ cmd_keyword, "exp10", &program::rpn_alog, "" },
|
||||
{ cmd_keyword, "log2", &program::rpn_log2, "logarithm base 2" },
|
||||
{ cmd_keyword, "alog2", &program::rpn_alog2, "(or exp2) exponential base 2" },
|
||||
{ cmd_keyword, "exp2", &program::rpn_alog2, "" },
|
||||
{ cmd_keyword, "ln", &program::rpn_ln, "logarithm base e" },
|
||||
{ cmd_keyword, "exp", &program::rpn_exp, "exponential" },
|
||||
{ cmd_keyword, "sinh", &program::rpn_sinh, "hyperbolic sine" },
|
||||
{ cmd_keyword, "asinh", &program::rpn_asinh, "inverse hyperbolic sine" },
|
||||
{ cmd_keyword, "cosh", &program::rpn_sinh, "hyperbolic cosine" },
|
||||
{ cmd_keyword, "acosh", &program::rpn_acosh, "inverse hyperbolic cosine" },
|
||||
{ cmd_keyword, "tanh", &program::rpn_tanh, "hyperbolic tangent" },
|
||||
{ cmd_keyword, "atanh", &program::rpn_atanh, "inverse hyperbolic tangent" },
|
||||
|
||||
// end
|
||||
{ cmd_max, "", NULL, "" },
|
||||
};
|
|
@ -21,18 +21,20 @@ void help()
|
|||
printf("%s\n", syntax);
|
||||
|
||||
// keywords
|
||||
for(unsigned int i=0; i<sizeof(_keywords)/sizeof(_keywords[0]); i++)
|
||||
unsigned int i = 0;
|
||||
while(s_keywords[i].type != cmd_max)
|
||||
{
|
||||
if (_keywords[i].comment.size() != 0)
|
||||
if (s_keywords[i].comment.size() != 0)
|
||||
{
|
||||
// titles in bold
|
||||
if (_keywords[i].type==cmd_undef)
|
||||
if (s_keywords[i].type==cmd_undef)
|
||||
printf(ATTR_BOLD);
|
||||
// show title or keyword + comment
|
||||
printf("%s\t%s\n", _keywords[i].name, _keywords[i].comment.c_str());
|
||||
if (_keywords[i].type==cmd_undef)
|
||||
printf("%s\t%s\n", s_keywords[i].name, s_keywords[i].comment.c_str());
|
||||
if (s_keywords[i].type==cmd_undef)
|
||||
printf(ATTR_OFF);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
|
@ -48,8 +50,8 @@ void help()
|
|||
printf(" with %d digits\n", number::s_current_precision);
|
||||
|
||||
// calc precision and rounding mode
|
||||
printf("Current floating point precision is %d bits\n", (int)s_mpfr_prec);
|
||||
printf("Current rounding mode is '%s'\n", s_mpfr_rnd_str[s_mpfr_rnd]);
|
||||
printf("Current floating point precision is %d bits\n", (int)floating_t::s_mpfr_prec);
|
||||
printf("Current rounding mode is '%s'\n", floating_t::s_mpfr_rnd_str[floating_t::s_mpfr_rnd]);
|
||||
printf("\n\n");
|
||||
}
|
||||
|
||||
|
@ -71,7 +73,7 @@ void std()
|
|||
// format for mpfr_printf
|
||||
stringstream ss;
|
||||
ss << number::s_current_precision;
|
||||
s_mpfr_printf_format = string(MPFR_FORMAT_BEG) + ss.str() + string(MPFR_FORMAT_STD);
|
||||
number::s_mpfr_printf_format = string(MPFR_FORMAT_BEG) + ss.str() + string(MPFR_FORMAT_STD);
|
||||
}
|
||||
|
||||
void fix()
|
||||
|
@ -87,7 +89,7 @@ void fix()
|
|||
// format for mpfr_printf
|
||||
stringstream ss;
|
||||
ss << number::s_current_precision;
|
||||
s_mpfr_printf_format = string(MPFR_FORMAT_BEG) + ss.str() + string(MPFR_FORMAT_FIX);
|
||||
number::s_mpfr_printf_format = string(MPFR_FORMAT_BEG) + ss.str() + string(MPFR_FORMAT_FIX);
|
||||
}
|
||||
|
||||
void sci()
|
||||
|
@ -103,7 +105,7 @@ void sci()
|
|||
// format for mpfr_printf
|
||||
stringstream ss;
|
||||
ss << number::s_current_precision;
|
||||
s_mpfr_printf_format = string(MPFR_FORMAT_BEG) + ss.str() + string(MPFR_FORMAT_SCI);
|
||||
number::s_mpfr_printf_format = string(MPFR_FORMAT_BEG) + ss.str() + string(MPFR_FORMAT_SCI);
|
||||
}
|
||||
|
||||
void rpn_version()
|
||||
|
@ -130,10 +132,10 @@ void type()
|
|||
if (type < 0 || type >= (int)cmd_max)
|
||||
type = (int)cmd_undef;
|
||||
|
||||
unsigned int string_size = strlen(cmd_type_string[type]);
|
||||
unsigned int string_size = strlen(object::s_cmd_type_string[type]);
|
||||
unsigned int size = sizeof(symbol)+string_size+1;
|
||||
symbol* sym = (symbol*)_stack->allocate_back(size, cmd_symbol);
|
||||
sym->set(cmd_type_string[type], string_size, false);
|
||||
sym->set(object::s_cmd_type_string[type], string_size, false);
|
||||
}
|
||||
|
||||
void rpn_default()
|
||||
|
@ -147,11 +149,11 @@ void precision()
|
|||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
//set MPFR float precision
|
||||
long prec = mpfr_get_si(((number*)_stack->pop_back())->_value.mpfr, s_mpfr_rnd);
|
||||
long prec = mpfr_get_si(((number*)_stack->pop_back())->_value.mpfr, floating_t::s_mpfr_rnd);
|
||||
if (prec >= 0)
|
||||
{
|
||||
s_mpfr_prec = (mpfr_prec_t)prec;
|
||||
s_mpfr_prec_bytes = mpfr_custom_get_size(prec);
|
||||
floating_t::s_mpfr_prec = (mpfr_prec_t)prec;
|
||||
floating_t::s_mpfr_prec_bytes = mpfr_custom_get_size(prec);
|
||||
}
|
||||
else
|
||||
ERR_CONTEXT(ret_out_of_range);
|
||||
|
@ -166,9 +168,9 @@ void round()
|
|||
bool done = false;
|
||||
for(int rnd = (int)MPFR_DEFAULT_RND; rnd <= (int)MPFR_RNDA; rnd++)
|
||||
{
|
||||
if (string(s_mpfr_rnd_str[rnd]) == str->_value)
|
||||
if (string(floating_t::s_mpfr_rnd_str[rnd]) == str->_value)
|
||||
{
|
||||
s_mpfr_rnd = (mpfr_rnd_t)rnd;
|
||||
floating_t::s_mpfr_rnd = (mpfr_rnd_t)rnd;
|
||||
done = true;
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@ void rpn_e(void)
|
|||
{
|
||||
number* euler = (number*)_stack->allocate_back(number::calc_size(), cmd_number);
|
||||
euler->_value = 1L;
|
||||
CHECK_MPFR(mpfr_exp(euler->_value.mpfr, euler->_value.mpfr, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_exp(euler->_value.mpfr, euler->_value.mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void rpn_log()
|
||||
|
@ -11,7 +11,7 @@ void rpn_log()
|
|||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
floating_t* left = &((number*)_stack->get_obj(0))->_value;
|
||||
CHECK_MPFR(mpfr_log10(left->mpfr, left->mpfr, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_log10(left->mpfr, left->mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void rpn_alog()
|
||||
|
@ -20,7 +20,7 @@ void rpn_alog()
|
|||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
floating_t* left = &((number*)_stack->get_obj(0))->_value;
|
||||
CHECK_MPFR(mpfr_exp10(left->mpfr, left->mpfr, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_exp10(left->mpfr, left->mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void rpn_log2()
|
||||
|
@ -29,7 +29,7 @@ void rpn_log2()
|
|||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
floating_t* left = &((number*)_stack->get_obj(0))->_value;
|
||||
CHECK_MPFR(mpfr_log2(left->mpfr, left->mpfr, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_log2(left->mpfr, left->mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void rpn_alog2()
|
||||
|
@ -38,7 +38,7 @@ void rpn_alog2()
|
|||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
floating_t* left = &((number*)_stack->get_obj(0))->_value;
|
||||
CHECK_MPFR(mpfr_exp2(left->mpfr, left->mpfr, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_exp2(left->mpfr, left->mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void rpn_ln()
|
||||
|
@ -47,7 +47,7 @@ void rpn_ln()
|
|||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
floating_t* left = &((number*)_stack->get_obj(0))->_value;
|
||||
CHECK_MPFR(mpfr_log(left->mpfr, left->mpfr, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_log(left->mpfr, left->mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void rpn_exp()
|
||||
|
@ -56,7 +56,7 @@ void rpn_exp()
|
|||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
floating_t* left = &((number*)_stack->get_obj(0))->_value;
|
||||
CHECK_MPFR(mpfr_exp(left->mpfr, left->mpfr, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_exp(left->mpfr, left->mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void rpn_sinh()
|
||||
|
@ -65,7 +65,7 @@ void rpn_sinh()
|
|||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
floating_t* left = &((number*)_stack->get_obj(0))->_value;
|
||||
CHECK_MPFR(mpfr_sinh(left->mpfr, left->mpfr, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_sinh(left->mpfr, left->mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void rpn_asinh()
|
||||
|
@ -74,7 +74,7 @@ void rpn_asinh()
|
|||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
floating_t* left = &((number*)_stack->get_obj(0))->_value;
|
||||
CHECK_MPFR(mpfr_asinh(left->mpfr, left->mpfr, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_asinh(left->mpfr, left->mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void rpn_cosh()
|
||||
|
@ -83,7 +83,7 @@ void rpn_cosh()
|
|||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
floating_t* left = &((number*)_stack->get_obj(0))->_value;
|
||||
CHECK_MPFR(mpfr_cosh(left->mpfr, left->mpfr, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_cosh(left->mpfr, left->mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void rpn_acosh()
|
||||
|
@ -92,7 +92,7 @@ void rpn_acosh()
|
|||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
floating_t* left = &((number*)_stack->get_obj(0))->_value;
|
||||
CHECK_MPFR(mpfr_cosh(left->mpfr, left->mpfr, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_cosh(left->mpfr, left->mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void rpn_tanh()
|
||||
|
@ -101,7 +101,7 @@ void rpn_tanh()
|
|||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
floating_t* left = &((number*)_stack->get_obj(0))->_value;
|
||||
CHECK_MPFR(mpfr_tanh(left->mpfr, left->mpfr, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_tanh(left->mpfr, left->mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void rpn_atanh()
|
||||
|
@ -110,5 +110,5 @@ void rpn_atanh()
|
|||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
floating_t* left = &((number*)_stack->get_obj(0))->_value;
|
||||
CHECK_MPFR(mpfr_atanh(left->mpfr, left->mpfr, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_atanh(left->mpfr, left->mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
|
@ -6,7 +6,7 @@ void plus()
|
|||
|
||||
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));
|
||||
CHECK_MPFR(mpfr_add(left->_value.mpfr, left->_value.mpfr, right->_value.mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void minus()
|
||||
|
@ -17,7 +17,7 @@ void minus()
|
|||
|
||||
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));
|
||||
CHECK_MPFR(mpfr_sub(left->_value.mpfr, left->_value.mpfr, right->_value.mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void mul()
|
||||
|
@ -28,7 +28,7 @@ void mul()
|
|||
|
||||
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));
|
||||
CHECK_MPFR(mpfr_mul(left->_value.mpfr, left->_value.mpfr, right->_value.mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void div()
|
||||
|
@ -39,7 +39,7 @@ void div()
|
|||
|
||||
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));
|
||||
CHECK_MPFR(mpfr_div(left->_value.mpfr, left->_value.mpfr, right->_value.mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void neg()
|
||||
|
@ -48,7 +48,7 @@ void neg()
|
|||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
number* left = (number*)_stack->back();
|
||||
CHECK_MPFR(mpfr_neg(left->_value.mpfr, left->_value.mpfr, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_neg(left->_value.mpfr, left->_value.mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void inv()
|
||||
|
@ -57,7 +57,7 @@ void inv()
|
|||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
number* left = (number*)_stack->back();
|
||||
CHECK_MPFR(mpfr_si_div(left->_value.mpfr, 1L, left->_value.mpfr, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_si_div(left->_value.mpfr, 1L, left->_value.mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void purcent()
|
||||
|
@ -69,8 +69,8 @@ void purcent()
|
|||
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));
|
||||
CHECK_MPFR(mpfr_div_si(left->_value.mpfr, left->_value.mpfr, 100L, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_mul(left->_value.mpfr, left->_value.mpfr, right->_value.mpfr, floating_t::s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_div_si(left->_value.mpfr, left->_value.mpfr, 100L, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void purcentCH()
|
||||
|
@ -82,8 +82,8 @@ void purcentCH()
|
|||
number* right = (number*)_stack->pop_back();
|
||||
number* left = (number*)_stack->back();
|
||||
|
||||
CHECK_MPFR(mpfr_mul_si(right->_value.mpfr, right->_value.mpfr, 100L, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_div(left->_value.mpfr, right->_value.mpfr, left->_value.mpfr, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_mul_si(right->_value.mpfr, right->_value.mpfr, 100L, floating_t::s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_div(left->_value.mpfr, right->_value.mpfr, left->_value.mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void power()
|
||||
|
@ -94,7 +94,7 @@ void power()
|
|||
|
||||
number* right = (number*)_stack->pop_back();
|
||||
number* left = (number*)_stack->back();
|
||||
CHECK_MPFR(mpfr_pow(left->_value.mpfr, left->_value.mpfr, right->_value.mpfr, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_pow(left->_value.mpfr, left->_value.mpfr, right->_value.mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void squareroot()
|
||||
|
@ -103,7 +103,7 @@ void squareroot()
|
|||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
number* left = (number*)_stack->back();
|
||||
CHECK_MPFR(mpfr_sqrt(left->_value.mpfr, left->_value.mpfr, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_sqrt(left->_value.mpfr, left->_value.mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void square()
|
||||
|
@ -112,7 +112,7 @@ void square()
|
|||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
number* left = (number*)_stack->back();
|
||||
CHECK_MPFR(mpfr_sqr(left->_value.mpfr, left->_value.mpfr, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_sqr(left->_value.mpfr, left->_value.mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void modulo()
|
||||
|
@ -124,7 +124,7 @@ void modulo()
|
|||
number* right = (number*)_stack->pop_back();
|
||||
number* left = (number*)_stack->back();
|
||||
|
||||
CHECK_MPFR(mpfr_fmod(left->_value.mpfr, left->_value.mpfr, right->_value.mpfr, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_fmod(left->_value.mpfr, left->_value.mpfr, right->_value.mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void rpn_abs()
|
||||
|
@ -134,7 +134,7 @@ void rpn_abs()
|
|||
|
||||
number* left = (number*)_stack->back();
|
||||
|
||||
CHECK_MPFR(mpfr_abs(left->_value.mpfr, left->_value.mpfr, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_abs(left->_value.mpfr, left->_value.mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void hex()
|
|
@ -105,7 +105,7 @@ void vars(void)
|
|||
for (int i=0; i<(int)_heap->size(); i++)
|
||||
{
|
||||
(void)_heap->get_by_index(i, name, obj, size);
|
||||
printf("var %d: name '%s', type %s, value ", i+1, name.c_str(), cmd_type_string[obj->_type]);
|
||||
printf("var %d: name '%s', type %s, value ", i+1, name.c_str(), object::s_cmd_type_string[obj->_type]);
|
||||
obj->show();
|
||||
printf("\n");
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ void vars(void)
|
|||
for (int i=0; i<(int)parent->_local_heap.size(); i++)
|
||||
{
|
||||
(void)parent->_local_heap.get_by_index(i, name, obj, size);
|
||||
printf("local var %d: name '%s', type %s, value ", i+1, name.c_str(), cmd_type_string[obj->_type]);
|
||||
printf("local var %d: name '%s', type %s, value ", i+1, name.c_str(), object::s_cmd_type_string[obj->_type]);
|
||||
obj->show();
|
||||
printf("\n");
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ void vars(void)
|
|||
for (int i=0; i<(int)_local_heap.size(); i++)
|
||||
{
|
||||
(void)_local_heap.get_by_index(i, name, obj, size);
|
||||
printf("local var %d: name '%s', type %s, value ", i+1, name.c_str(), cmd_type_string[obj->_type]);
|
||||
printf("local var %d: name '%s', type %s, value ", i+1, name.c_str(), object::s_cmd_type_string[obj->_type]);
|
||||
obj->show();
|
||||
printf("\n");
|
||||
}
|
|
@ -8,9 +8,9 @@ void sup(void)
|
|||
number* left = (number*)_stack->back();
|
||||
|
||||
if (mpfr_cmp(left->_value.mpfr, right->_value.mpfr) > 0)
|
||||
mpfr_set_si(left->_value.mpfr, 1, s_mpfr_rnd);
|
||||
mpfr_set_si(left->_value.mpfr, 1, floating_t::s_mpfr_rnd);
|
||||
else
|
||||
mpfr_set_si(left->_value.mpfr, 0, s_mpfr_rnd);
|
||||
mpfr_set_si(left->_value.mpfr, 0, floating_t::s_mpfr_rnd);
|
||||
}
|
||||
|
||||
void sup_eq(void)
|
||||
|
@ -23,9 +23,9 @@ void sup_eq(void)
|
|||
number* left = (number*)_stack->back();
|
||||
|
||||
if (mpfr_cmp(left->_value.mpfr, right->_value.mpfr) >= 0)
|
||||
mpfr_set_si(left->_value.mpfr, 1, s_mpfr_rnd);
|
||||
mpfr_set_si(left->_value.mpfr, 1, floating_t::s_mpfr_rnd);
|
||||
else
|
||||
mpfr_set_si(left->_value.mpfr, 0, s_mpfr_rnd);
|
||||
mpfr_set_si(left->_value.mpfr, 0, floating_t::s_mpfr_rnd);
|
||||
}
|
||||
|
||||
void inf(void)
|
||||
|
@ -38,9 +38,9 @@ void inf(void)
|
|||
number* left = (number*)_stack->back();
|
||||
|
||||
if (mpfr_cmp(left->_value.mpfr, right->_value.mpfr) < 0)
|
||||
mpfr_set_si(left->_value.mpfr, 1, s_mpfr_rnd);
|
||||
mpfr_set_si(left->_value.mpfr, 1, floating_t::s_mpfr_rnd);
|
||||
else
|
||||
mpfr_set_si(left->_value.mpfr, 0, s_mpfr_rnd);
|
||||
mpfr_set_si(left->_value.mpfr, 0, floating_t::s_mpfr_rnd);
|
||||
}
|
||||
|
||||
void inf_eq(void)
|
||||
|
@ -53,9 +53,9 @@ void inf_eq(void)
|
|||
number* left = (number*)_stack->back();
|
||||
|
||||
if (mpfr_cmp(left->_value.mpfr, right->_value.mpfr) <= 0)
|
||||
mpfr_set_si(left->_value.mpfr, 1, s_mpfr_rnd);
|
||||
mpfr_set_si(left->_value.mpfr, 1, floating_t::s_mpfr_rnd);
|
||||
else
|
||||
mpfr_set_si(left->_value.mpfr, 0, s_mpfr_rnd);
|
||||
mpfr_set_si(left->_value.mpfr, 0, floating_t::s_mpfr_rnd);
|
||||
}
|
||||
|
||||
void diff(void)
|
||||
|
@ -68,9 +68,9 @@ void diff(void)
|
|||
number* left = (number*)_stack->back();
|
||||
|
||||
if (mpfr_cmp(left->_value.mpfr, right->_value.mpfr) != 0)
|
||||
mpfr_set_si(left->_value.mpfr, 1, s_mpfr_rnd);
|
||||
mpfr_set_si(left->_value.mpfr, 1, floating_t::s_mpfr_rnd);
|
||||
else
|
||||
mpfr_set_si(left->_value.mpfr, 0, s_mpfr_rnd);
|
||||
mpfr_set_si(left->_value.mpfr, 0, floating_t::s_mpfr_rnd);
|
||||
}
|
||||
|
||||
void eq(void)
|
||||
|
@ -83,9 +83,9 @@ void eq(void)
|
|||
number* left = (number*)_stack->back();
|
||||
|
||||
if (mpfr_cmp(left->_value.mpfr, right->_value.mpfr) == 0)
|
||||
mpfr_set_si(left->_value.mpfr, 1, s_mpfr_rnd);
|
||||
mpfr_set_si(left->_value.mpfr, 1, floating_t::s_mpfr_rnd);
|
||||
else
|
||||
mpfr_set_si(left->_value.mpfr, 0, s_mpfr_rnd);
|
||||
mpfr_set_si(left->_value.mpfr, 0, floating_t::s_mpfr_rnd);
|
||||
}
|
||||
|
||||
void test_and(void)
|
||||
|
@ -99,9 +99,9 @@ void test_and(void)
|
|||
|
||||
if ((mpfr_cmp_si(left->_value.mpfr, 0) != 0)
|
||||
&& (mpfr_cmp_si(right->_value.mpfr, 0) != 0))
|
||||
mpfr_set_si(left->_value.mpfr, 1, s_mpfr_rnd);
|
||||
mpfr_set_si(left->_value.mpfr, 1, floating_t::s_mpfr_rnd);
|
||||
else
|
||||
mpfr_set_si(left->_value.mpfr, 0, s_mpfr_rnd);
|
||||
mpfr_set_si(left->_value.mpfr, 0, floating_t::s_mpfr_rnd);
|
||||
}
|
||||
|
||||
void test_or(void)
|
||||
|
@ -115,9 +115,9 @@ void test_or(void)
|
|||
|
||||
if ((mpfr_cmp_si(left->_value.mpfr, 0) != 0)
|
||||
|| (mpfr_cmp_si(right->_value.mpfr, 0) != 0))
|
||||
mpfr_set_si(left->_value.mpfr, 1, s_mpfr_rnd);
|
||||
mpfr_set_si(left->_value.mpfr, 1, floating_t::s_mpfr_rnd);
|
||||
else
|
||||
mpfr_set_si(left->_value.mpfr, 0, s_mpfr_rnd);
|
||||
mpfr_set_si(left->_value.mpfr, 0, floating_t::s_mpfr_rnd);
|
||||
}
|
||||
|
||||
void test_xor(void)
|
||||
|
@ -132,16 +132,16 @@ void test_xor(void)
|
|||
if (mpfr_cmp_si(left->_value.mpfr, 0) == 0)
|
||||
{
|
||||
if (mpfr_cmp_si(right->_value.mpfr, 0) != 0)
|
||||
mpfr_set_si(left->_value.mpfr, 1, s_mpfr_rnd);
|
||||
mpfr_set_si(left->_value.mpfr, 1, floating_t::s_mpfr_rnd);
|
||||
else
|
||||
mpfr_set_si(left->_value.mpfr, 0, s_mpfr_rnd);
|
||||
mpfr_set_si(left->_value.mpfr, 0, floating_t::s_mpfr_rnd);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mpfr_cmp_si(right->_value.mpfr, 0) == 0)
|
||||
mpfr_set_si(left->_value.mpfr, 1, s_mpfr_rnd);
|
||||
mpfr_set_si(left->_value.mpfr, 1, floating_t::s_mpfr_rnd);
|
||||
else
|
||||
mpfr_set_si(left->_value.mpfr, 0, s_mpfr_rnd);
|
||||
mpfr_set_si(left->_value.mpfr, 0, floating_t::s_mpfr_rnd);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,9 +152,9 @@ void test_not(void)
|
|||
|
||||
number* left = (number*)_stack->back();
|
||||
if (mpfr_cmp_si(left->_value.mpfr, 0) == 0)
|
||||
mpfr_set_si(left->_value.mpfr, 1, s_mpfr_rnd);
|
||||
mpfr_set_si(left->_value.mpfr, 1, floating_t::s_mpfr_rnd);
|
||||
else
|
||||
mpfr_set_si(left->_value.mpfr, 0, s_mpfr_rnd);
|
||||
mpfr_set_si(left->_value.mpfr, 0, floating_t::s_mpfr_rnd);
|
||||
}
|
||||
|
||||
void same(void)
|
|
@ -2,7 +2,7 @@
|
|||
void pi(void)
|
||||
{
|
||||
number* pi = (number*)_stack->allocate_back(number::calc_size(), cmd_number);
|
||||
CHECK_MPFR(mpfr_const_pi(pi->_value.mpfr, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_const_pi(pi->_value.mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void d2r(void)
|
||||
|
@ -12,9 +12,9 @@ void d2r(void)
|
|||
|
||||
floating_t pi;
|
||||
floating_t* left = &((number*)_stack->get_obj(0))->_value;
|
||||
CHECK_MPFR(mpfr_const_pi(pi.mpfr, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_mul(left->mpfr, left->mpfr, pi.mpfr, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_div_si(left->mpfr, left->mpfr, 180, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_const_pi(pi.mpfr, floating_t::s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_mul(left->mpfr, left->mpfr, pi.mpfr, floating_t::s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_div_si(left->mpfr, left->mpfr, 180, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void r2d(void)
|
||||
|
@ -24,9 +24,9 @@ void r2d(void)
|
|||
|
||||
floating_t pi;
|
||||
floating_t* left = &((number*)_stack->get_obj(0))->_value;
|
||||
CHECK_MPFR(mpfr_const_pi(pi.mpfr, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_mul_si(left->mpfr, left->mpfr, 180, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_div(left->mpfr, left->mpfr, pi.mpfr, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_const_pi(pi.mpfr, floating_t::s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_mul_si(left->mpfr, left->mpfr, 180, floating_t::s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_div(left->mpfr, left->mpfr, pi.mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void rpn_sin(void)
|
||||
|
@ -35,7 +35,7 @@ void rpn_sin(void)
|
|||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
floating_t* left = &((number*)_stack->get_obj(0))->_value;
|
||||
CHECK_MPFR(mpfr_sin(left->mpfr, left->mpfr, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_sin(left->mpfr, left->mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void rpn_asin(void)
|
||||
|
@ -44,7 +44,7 @@ void rpn_asin(void)
|
|||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
floating_t* left = &((number*)_stack->get_obj(0))->_value;
|
||||
CHECK_MPFR(mpfr_asin(left->mpfr, left->mpfr, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_asin(left->mpfr, left->mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void rpn_cos(void)
|
||||
|
@ -53,7 +53,7 @@ void rpn_cos(void)
|
|||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
floating_t* left = &((number*)_stack->get_obj(0))->_value;
|
||||
CHECK_MPFR(mpfr_cos(left->mpfr, left->mpfr, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_cos(left->mpfr, left->mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void rpn_acos(void)
|
||||
|
@ -62,7 +62,7 @@ void rpn_acos(void)
|
|||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
floating_t* left = &((number*)_stack->get_obj(0))->_value;
|
||||
CHECK_MPFR(mpfr_acos(left->mpfr, left->mpfr, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_acos(left->mpfr, left->mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void rpn_tan(void)
|
||||
|
@ -71,7 +71,7 @@ void rpn_tan(void)
|
|||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
floating_t* left = &((number*)_stack->get_obj(0))->_value;
|
||||
CHECK_MPFR(mpfr_tan(left->mpfr, left->mpfr, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_tan(left->mpfr, left->mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
||||
|
||||
void rpn_atan(void)
|
||||
|
@ -80,5 +80,5 @@ void rpn_atan(void)
|
|||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||
|
||||
floating_t* left = &((number*)_stack->get_obj(0))->_value;
|
||||
CHECK_MPFR(mpfr_atan(left->mpfr, left->mpfr, s_mpfr_rnd));
|
||||
CHECK_MPFR(mpfr_atan(left->mpfr, left->mpfr, floating_t::s_mpfr_rnd));
|
||||
}
|
883
src/rpn.cpp
883
src/rpn.cpp
|
@ -1,883 +0,0 @@
|
|||
/*
|
||||
* rpn.cpp
|
||||
*
|
||||
* Copyright 2013 <louis@rubet.fr>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*
|
||||
*
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h> //for intmax_t
|
||||
#include <mpfr.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "constant.h"
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
extern "C" {
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
}
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
using namespace std;
|
||||
|
||||
static string s_mpfr_printf_format = string(MPFR_DEFAULT_FORMAT);
|
||||
static mpfr_prec_t s_mpfr_prec = MPFR_DEFAULT_PREC_BITS;
|
||||
static unsigned int s_mpfr_prec_bytes = MPFR_DEFAULT_STORING_LENGTH_BYTES;
|
||||
|
||||
static mpfr_rnd_t s_mpfr_rnd = MPFR_DEFAULT_RND;
|
||||
static const char* s_mpfr_rnd_str[5] = MPFR_RND_STRINGS;
|
||||
|
||||
//
|
||||
#include "escape.h"
|
||||
#include "version.h"
|
||||
|
||||
typedef enum {
|
||||
ret_ok,
|
||||
ret_unknown_err,
|
||||
ret_missing_operand,
|
||||
ret_bad_operand_type,
|
||||
ret_out_of_range,
|
||||
ret_unknown_variable,
|
||||
ret_internal,
|
||||
ret_deadly,
|
||||
ret_good_bye,
|
||||
ret_not_impl,
|
||||
ret_nop,
|
||||
ret_syntax,
|
||||
ret_div_by_zero,
|
||||
ret_runtime_error,
|
||||
ret_max
|
||||
} ret_value;
|
||||
|
||||
static const char* ret_value_string[ret_max] = RET_VALUE_STRINGS;
|
||||
|
||||
typedef enum {
|
||||
cmd_undef,
|
||||
cmd_number,/* floating value to put in stack */
|
||||
cmd_string,/* string value to put in stack */
|
||||
cmd_symbol,/* symbol value to put in stack */
|
||||
cmd_program,/* program */
|
||||
cmd_keyword,/* langage keyword */
|
||||
cmd_branch,/* langage branch keyword */
|
||||
cmd_max
|
||||
} cmd_type_t;
|
||||
|
||||
const char* cmd_type_string[cmd_max] = CMD_TYPE_STRINGS;
|
||||
|
||||
// MPFR object
|
||||
struct floating_t
|
||||
{
|
||||
mpfr_t mpfr;
|
||||
|
||||
void init(void* significand)
|
||||
{
|
||||
mpfr_custom_init(significand, MPFR_DEFAULT_PREC_BITS);
|
||||
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_set_si(mpfr, val, s_mpfr_rnd);
|
||||
}
|
||||
|
||||
floating_t& operator=(const unsigned long val)
|
||||
{
|
||||
mpfr_set_ui(mpfr, val, s_mpfr_rnd);
|
||||
}
|
||||
|
||||
operator int()
|
||||
{
|
||||
return (int)mpfr_get_si(mpfr, s_mpfr_rnd);
|
||||
}
|
||||
|
||||
bool operator>(const floating_t right)
|
||||
{
|
||||
return mpfr_cmp(mpfr, right.mpfr) > 0;
|
||||
}
|
||||
|
||||
bool operator<(const floating_t right)
|
||||
{
|
||||
return mpfr_cmp(mpfr, right.mpfr) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
class program;
|
||||
class object;
|
||||
class branch;
|
||||
|
||||
typedef void (program::*program_fn_t)(void);
|
||||
typedef int (program::*branch_fn_t)(branch&);
|
||||
|
||||
//
|
||||
struct object
|
||||
{
|
||||
// object type
|
||||
cmd_type_t _type;
|
||||
unsigned int _size;
|
||||
|
||||
//
|
||||
unsigned int size() { return _size; }
|
||||
void show(FILE* stream = stdout);
|
||||
};
|
||||
|
||||
struct number : public object
|
||||
{
|
||||
number() { _type = cmd_number; }
|
||||
floating_t _value;
|
||||
|
||||
void init(void* significand)
|
||||
{
|
||||
_type = cmd_number;
|
||||
_representation = dec;
|
||||
_value.init(significand);
|
||||
}
|
||||
|
||||
void copy(number& op)
|
||||
{
|
||||
_value = op._value;
|
||||
memcpy(_value.mpfr->_mpfr_d, op._value.mpfr->_mpfr_d, s_mpfr_prec_bytes);
|
||||
}
|
||||
|
||||
//
|
||||
void set(const floating_t& value)
|
||||
{
|
||||
_type = cmd_number;
|
||||
_value.mpfr->_mpfr_d = value.mpfr->_mpfr_d;
|
||||
}
|
||||
|
||||
void set(long value)
|
||||
{
|
||||
_type = cmd_number;
|
||||
_value = value;
|
||||
}
|
||||
|
||||
void set(unsigned long value)
|
||||
{
|
||||
_type = cmd_number;
|
||||
_value = value;
|
||||
}
|
||||
|
||||
static unsigned int calc_size()
|
||||
{
|
||||
return (unsigned int)(sizeof(number)+s_mpfr_prec_bytes);
|
||||
}
|
||||
|
||||
//
|
||||
number operator=(const number& op)
|
||||
{
|
||||
number num;
|
||||
num.set((const floating_t&)op._value);
|
||||
return num;
|
||||
}
|
||||
|
||||
// representation mode
|
||||
typedef enum {
|
||||
std,
|
||||
fix,
|
||||
sci
|
||||
} mode_enum;
|
||||
static mode_enum s_mode;
|
||||
|
||||
enum {
|
||||
dec,
|
||||
hex,
|
||||
bin
|
||||
} _representation;
|
||||
|
||||
// precision
|
||||
static int s_current_precision;
|
||||
};
|
||||
|
||||
number::mode_enum number::s_mode = DEFAULT_MODE;
|
||||
int number::s_current_precision = DEFAULT_PRECISION;
|
||||
|
||||
struct ostring : public object
|
||||
{
|
||||
//
|
||||
void set(const char* value, unsigned int len)
|
||||
{
|
||||
_type = cmd_string;
|
||||
if (value != NULL)
|
||||
{
|
||||
if (len>0)
|
||||
(void)memcpy(_value, value, len);
|
||||
_value[len] = 0;
|
||||
_len = len;
|
||||
}
|
||||
else
|
||||
len = 0;
|
||||
}
|
||||
|
||||
//
|
||||
unsigned int _len;
|
||||
char _value[0];
|
||||
};
|
||||
|
||||
struct oprogram : public object
|
||||
{
|
||||
//
|
||||
void set(const char* value, unsigned int len)
|
||||
{
|
||||
_type = cmd_program;
|
||||
if (value != NULL)
|
||||
{
|
||||
if (len>0)
|
||||
(void)memcpy(_value, value, len);
|
||||
_value[len] = 0;
|
||||
_len = len;
|
||||
}
|
||||
else
|
||||
len = 0;
|
||||
}
|
||||
|
||||
//
|
||||
unsigned int _len;
|
||||
char _value[0];
|
||||
};
|
||||
|
||||
struct symbol : public object
|
||||
{
|
||||
//
|
||||
void set(const char* value, unsigned int len, bool auto_eval)
|
||||
{
|
||||
_type = cmd_symbol;
|
||||
_auto_eval = auto_eval;
|
||||
|
||||
if (value != NULL)
|
||||
{
|
||||
if (len>0)
|
||||
(void)memcpy(_value, value, len);
|
||||
_value[len] = 0;
|
||||
_len = len;
|
||||
}
|
||||
else
|
||||
len = 0;
|
||||
}
|
||||
|
||||
//
|
||||
bool _auto_eval;
|
||||
unsigned int _len;
|
||||
char _value[0];
|
||||
};
|
||||
|
||||
struct keyword : public object
|
||||
{
|
||||
//
|
||||
void set(program_fn_t fn, const char* value, unsigned int len)
|
||||
{
|
||||
_type = cmd_keyword;
|
||||
_fn = fn;
|
||||
if (value != NULL)
|
||||
{
|
||||
if (len>0)
|
||||
(void)memcpy(_value, value, len);
|
||||
_value[len] = 0;
|
||||
_len = len;
|
||||
}
|
||||
else
|
||||
len = 0;
|
||||
}
|
||||
|
||||
//
|
||||
program_fn_t _fn;
|
||||
unsigned int _len;
|
||||
char _value[0];
|
||||
};
|
||||
|
||||
struct branch : public object
|
||||
{
|
||||
//
|
||||
void set(branch_fn_t fn, const char* value, unsigned int len)
|
||||
{
|
||||
_type = cmd_branch;
|
||||
_fn = fn;
|
||||
arg1 = -1;
|
||||
arg2 = -1;
|
||||
arg3 = -1;
|
||||
farg1 = NULL;
|
||||
farg2 = NULL;
|
||||
arg_bool = 0;
|
||||
if (value != NULL)
|
||||
{
|
||||
if (len>0)
|
||||
(void)memcpy(_value, value, len);
|
||||
_value[len] = 0;
|
||||
_len = len;
|
||||
}
|
||||
else
|
||||
len = 0;
|
||||
}
|
||||
|
||||
// branch function
|
||||
branch_fn_t _fn;
|
||||
// args used by cmd_branch cmds
|
||||
int arg1, arg2, arg3;
|
||||
number *farg1, *farg2;
|
||||
bool arg_bool;
|
||||
unsigned int _len;
|
||||
char _value[0];
|
||||
};
|
||||
|
||||
void object::show(FILE* stream)
|
||||
{
|
||||
switch(_type)
|
||||
{
|
||||
case cmd_number:
|
||||
switch(((number*)this)->_representation)
|
||||
{
|
||||
case number::dec:
|
||||
mpfr_fprintf(stream, s_mpfr_printf_format.c_str(), ((number*)this)->_value.mpfr);
|
||||
break;
|
||||
case number::hex:
|
||||
mpfr_fprintf(stream, string(MPFR_FORMAT_HEX).c_str(), ((number*)this)->_value.mpfr);
|
||||
break;
|
||||
case number::bin:
|
||||
fprintf(stream, "<binary representation TODO>\n");
|
||||
}
|
||||
break;
|
||||
case cmd_string:
|
||||
fprintf(stream, "\"%s\"", ((ostring*)this)->_value);
|
||||
break;
|
||||
case cmd_program:
|
||||
fprintf(stream, "<<%s>>", ((oprogram*)this)->_value);
|
||||
break;
|
||||
case cmd_symbol:
|
||||
fprintf(stream, "'%s'", ((symbol*)this)->_value);
|
||||
break;
|
||||
case cmd_keyword:
|
||||
case cmd_branch:
|
||||
fprintf(stream, "%s", ((keyword*)this)->_value);
|
||||
break;
|
||||
default:
|
||||
fprintf(stream, "< unknown object representation >");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
struct if_layout_t
|
||||
{
|
||||
if_layout_t():index_then(-1),index_else(-1),index_end(-1) { }
|
||||
int index_if;
|
||||
int index_then;
|
||||
int index_else;
|
||||
int index_end;
|
||||
};
|
||||
|
||||
#include "stack.h"
|
||||
|
||||
class program : public stack
|
||||
{
|
||||
public:
|
||||
program(program* parent_prog = NULL) { _parent_prog = parent_prog; }
|
||||
|
||||
// run this program
|
||||
ret_value run(stack& stk, heap& hp, heap* parent_local_hp = NULL)
|
||||
{
|
||||
bool go_out = false;
|
||||
ret_value ret = ret_ok;
|
||||
cmd_type_t type;
|
||||
|
||||
// stack comes from outside
|
||||
_stack = &stk;
|
||||
|
||||
// global heap comes from outside
|
||||
_heap = &hp;
|
||||
|
||||
_err = ret_ok;
|
||||
_err_context = "";
|
||||
|
||||
// branches for 'if'
|
||||
ret = preprocess();
|
||||
if (ret != ret_ok)
|
||||
return ret;
|
||||
|
||||
// iterate commands
|
||||
for(int i = 0; (go_out==false) && (i<(int)size());)
|
||||
{
|
||||
type = (cmd_type_t)seq_type(i);
|
||||
|
||||
// could be an auto-evaluated symbol
|
||||
if (type == cmd_symbol)
|
||||
{
|
||||
auto_rcl((symbol*)seq_obj(i));
|
||||
i++;
|
||||
}
|
||||
|
||||
// a keyword
|
||||
else if (type == cmd_keyword)
|
||||
{
|
||||
keyword* k = (keyword*)seq_obj(i);
|
||||
// call matching function
|
||||
(this->*(k->_fn))();
|
||||
switch(_err)
|
||||
{
|
||||
// no pb -> go on
|
||||
case ret_ok:
|
||||
break;
|
||||
// explicit go out software
|
||||
case ret_good_bye:
|
||||
go_out = true;
|
||||
ret = ret_good_bye;
|
||||
break;
|
||||
default:
|
||||
// error: abort prog
|
||||
go_out = true;
|
||||
|
||||
// error: show it
|
||||
if (show_error(_err, _err_context) == ret_deadly)
|
||||
{
|
||||
// pb showing error -> go out software
|
||||
ret = ret_good_bye;
|
||||
}
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
// a branch keyword
|
||||
else if (type == cmd_branch)
|
||||
{
|
||||
// call matching function
|
||||
branch* b = (branch*)seq_obj(i);
|
||||
int next_cmd = (this->*(b->_fn))(*b);
|
||||
switch (next_cmd)
|
||||
{
|
||||
case -1:
|
||||
i++; // meaning 'next command'
|
||||
break;
|
||||
case -(int)ret_runtime_error:
|
||||
// error: show it
|
||||
(void)show_error(_err, _err_context);
|
||||
go_out = true;// end of run
|
||||
break;
|
||||
default:
|
||||
i = next_cmd;// new direction
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// not a command, but a stack entry, manage it
|
||||
else
|
||||
{
|
||||
// copy the program stack entry to the running stack
|
||||
stack::copy_and_push_back(*this, i, stk);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool compare_keyword(keyword* k, const char* str_to_compare, int len)
|
||||
{
|
||||
if (k->_len >= len)
|
||||
return strncmp(k->_value, str_to_compare, len) == 0;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool compare_branch(branch* b, const char* str_to_compare, int len)
|
||||
{
|
||||
if (b->_len >= len)
|
||||
return strncmp(b->_value, str_to_compare, len) == 0;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
ret_value preprocess(void)
|
||||
{
|
||||
// for if-then-else-end
|
||||
vector<struct if_layout_t> vlayout;
|
||||
int layout_index=-1;
|
||||
// for start-end-step
|
||||
vector<int> vstartindex;
|
||||
|
||||
// analyse if-then-else-end branches
|
||||
// analyse start-{next, step} branches
|
||||
for(int i=0; i<(int)size(); i++)
|
||||
{
|
||||
int type = seq_type(i);
|
||||
if (type == cmd_keyword)
|
||||
{
|
||||
keyword* k = (keyword*)seq_obj(i);
|
||||
if (compare_keyword(k, "end", 3))
|
||||
{
|
||||
int next = i + 1;
|
||||
if (next >= (int)size())
|
||||
next = -1;
|
||||
|
||||
if (layout_index<0)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("missing if before end");
|
||||
return ret_syntax;
|
||||
}
|
||||
if (vlayout[layout_index].index_end != -1)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("duplicate end");
|
||||
return ret_syntax;
|
||||
}
|
||||
if (vlayout[layout_index].index_else != -1)
|
||||
//fill 'end' branch of 'else'
|
||||
((branch*)seq_obj(vlayout[layout_index].index_else))->arg2 = i;
|
||||
else
|
||||
{
|
||||
//fill 'end' branch of 'then'
|
||||
if (vlayout[layout_index].index_then != -1)
|
||||
((branch*)seq_obj(vlayout[layout_index].index_then))->arg2 = i;
|
||||
else
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("missing then before end");
|
||||
return ret_syntax;
|
||||
}
|
||||
}
|
||||
layout_index--;
|
||||
}
|
||||
}
|
||||
else if (type == cmd_branch)
|
||||
{
|
||||
branch* k = (branch*)seq_obj(i);
|
||||
if (compare_branch(k, "if", 2))
|
||||
{
|
||||
if_layout_t layout;
|
||||
layout.index_if = i;
|
||||
vlayout.push_back(layout);
|
||||
layout_index++;
|
||||
}
|
||||
else if (compare_branch(k, "then", 4))
|
||||
{
|
||||
int next = i + 1;
|
||||
if (next >= (int)size())
|
||||
next = -1;
|
||||
|
||||
// nothing after 'then' -> error
|
||||
if (next == -1)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("missing end after then");
|
||||
return ret_syntax;
|
||||
}
|
||||
if (layout_index<0)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("missing if before then");
|
||||
return ret_syntax;
|
||||
}
|
||||
if (vlayout[layout_index].index_then != -1)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("duplicate then");
|
||||
return ret_syntax;
|
||||
}
|
||||
vlayout[layout_index].index_then = i;
|
||||
k->arg1 = next;
|
||||
k->arg3 = vlayout[layout_index].index_if;
|
||||
}
|
||||
else if (compare_branch(k, "else", 4))
|
||||
{
|
||||
int next = i + 1;
|
||||
if (next >= (int)size())
|
||||
next = -1;
|
||||
|
||||
// nothing after 'else' -> error
|
||||
if (next == -1)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("missing end after else");
|
||||
return ret_syntax;
|
||||
}
|
||||
if (layout_index<0)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("missing if before else");
|
||||
return ret_syntax;
|
||||
}
|
||||
if (vlayout[layout_index].index_then == -1)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("missing then before else");
|
||||
return ret_syntax;
|
||||
}
|
||||
if (vlayout[layout_index].index_else != -1)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("duplicate else");
|
||||
return ret_syntax;
|
||||
}
|
||||
vlayout[layout_index].index_else = i;
|
||||
k->arg1 = next;// fill branch1 (if was false) of 'else'
|
||||
k->arg3 = vlayout[layout_index].index_if;
|
||||
((branch*)seq_obj(vlayout[layout_index].index_then))->arg2 = next;// fill branch2 (if was false) of 'then'
|
||||
}
|
||||
else if (compare_branch(k, "start", 5))
|
||||
{
|
||||
vstartindex.push_back(i);
|
||||
}
|
||||
else if (compare_branch(k, "for", 3))
|
||||
{
|
||||
vstartindex.push_back(i);
|
||||
k->arg1 = i + 1;// arg1 points on symbol variable
|
||||
}
|
||||
else if(compare_branch(k, "next", 4))
|
||||
{
|
||||
if (vstartindex.size() == 0)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("missing start or for before next");
|
||||
return ret_syntax;
|
||||
}
|
||||
k->arg1 = vstartindex[vstartindex.size() - 1]; // 'next' arg1 = 'start' index
|
||||
((branch*)seq_obj(vstartindex[vstartindex.size() - 1]))->arg2 = i; // 'for' or 'start' arg2 = 'next' index
|
||||
vstartindex.pop_back();
|
||||
}
|
||||
else if (compare_branch(k, "step", 4))
|
||||
{
|
||||
if (vstartindex.size() == 0)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("missing start or for before step");
|
||||
return ret_syntax;
|
||||
}
|
||||
k->arg1 = vstartindex[vstartindex.size() - 1];// fill 'step' branch1 = 'start' index
|
||||
((branch*)seq_obj(vstartindex[vstartindex.size() - 1]))->arg2 = i; // 'for' or 'start' arg2 = 'next' index
|
||||
vstartindex.pop_back();
|
||||
}
|
||||
else if (compare_branch(k, "->", 2))
|
||||
{
|
||||
k->arg1 = i;// arg1 is '->' command index in program
|
||||
}
|
||||
}
|
||||
}
|
||||
if (layout_index >= 0)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("missing end");
|
||||
return ret_syntax;
|
||||
}
|
||||
if (vstartindex.size() > 0)
|
||||
{
|
||||
// error: show it
|
||||
show_syntax_error("missing next or step after for or start");
|
||||
return ret_syntax;
|
||||
}
|
||||
return ret_ok;
|
||||
}
|
||||
|
||||
ret_value show_error()
|
||||
{
|
||||
ret_value ret;
|
||||
|
||||
// show last recorded error
|
||||
cerr<<ret_value_string[_err]<<"("<<_err<<"): "<<_err_context<<endl;
|
||||
switch(_err)
|
||||
{
|
||||
case ret_internal:
|
||||
case ret_deadly:
|
||||
ret = ret_deadly;
|
||||
default:
|
||||
ret = ret_ok;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret_value show_error(ret_value err, string& context)
|
||||
{
|
||||
// record error
|
||||
_err = err;
|
||||
_err_context = context;
|
||||
return show_error();
|
||||
}
|
||||
|
||||
ret_value show_error(ret_value err, const char* context)
|
||||
{
|
||||
// record error
|
||||
_err = err;
|
||||
_err_context = context;
|
||||
return show_error();
|
||||
}
|
||||
|
||||
void show_syntax_error(const char* context)
|
||||
{
|
||||
// record error
|
||||
_err = ret_syntax;
|
||||
_err_context = context;
|
||||
(void)show_error();
|
||||
}
|
||||
|
||||
ret_value get_err(void) { return _err; }
|
||||
|
||||
#include "parse.h"
|
||||
|
||||
static void show_stack(stack& st, const string& separator = g_show_stack_separator)
|
||||
{
|
||||
if (st.size() == 1)
|
||||
{
|
||||
((object*)st.back())->show();
|
||||
printf("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
bool show_sep = (! separator.empty());
|
||||
for (int i = st.size()-1; i>=0; i--)
|
||||
{
|
||||
if (show_sep)
|
||||
printf("%d%s", i+1, separator.c_str());
|
||||
((object*)st[i])->show();
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void apply_default()
|
||||
{
|
||||
//default float precision, float mode, verbosity
|
||||
number::s_mode = DEFAULT_MODE;
|
||||
number::s_current_precision = DEFAULT_PRECISION;
|
||||
|
||||
// format for mpfr_printf
|
||||
stringstream ss;
|
||||
ss << number::s_current_precision;
|
||||
s_mpfr_printf_format = string(MPFR_FORMAT_BEG) + ss.str() + string(MPFR_FORMAT_STD);
|
||||
}
|
||||
|
||||
private:
|
||||
// current error and its context
|
||||
ret_value _err;
|
||||
string _err_context;
|
||||
|
||||
// global stack holding results for user
|
||||
stack* _stack;
|
||||
|
||||
// global heap (sto, rcl)
|
||||
heap* _heap;
|
||||
|
||||
// local heap for local loop vairables (for..next)
|
||||
heap _local_heap;
|
||||
|
||||
// local stack internally used by branch commands (start, for, next, ..)
|
||||
stack _branch_stack;
|
||||
|
||||
// parent prog for inheriting heaps
|
||||
program* _parent_prog;
|
||||
|
||||
int stack_size()
|
||||
{
|
||||
return _stack->size();
|
||||
}
|
||||
|
||||
private:
|
||||
// carefull : some of these macros modify program flow
|
||||
#define ERR_CONTEXT(err) do { _err = (err); _err_context = __FUNCTION__; } while(0)
|
||||
#define MIN_ARGUMENTS(num) do { if (stack_size()<(num)) { ERR_CONTEXT(ret_missing_operand); return; } } while(0)
|
||||
#define MIN_ARGUMENTS_RET(num, ret) do { if (stack_size()<(num)) { ERR_CONTEXT(ret_missing_operand); return (ret); } } while(0)
|
||||
#define ARG_MUST_BE_OF_TYPE(num, type) do { if (_stack->get_type(num) != (type)) { ERR_CONTEXT(ret_bad_operand_type); return; } } while(0)
|
||||
#define ARG_MUST_BE_OF_TYPE_RET(num, type, ret) do { if (_stack->get_type(num) != (type)) { ERR_CONTEXT(ret_bad_operand_type); return (ret); } } while(0)
|
||||
#define IS_ARG_TYPE(num, type) (_stack->get_type(num) == (type))
|
||||
#define CHECK_MPFR(op) do { (void)(op); } while(0)
|
||||
|
||||
// keywords implementation
|
||||
#include "rpn-general.h"
|
||||
#include "rpn-real.h"
|
||||
#include "rpn-test.h"
|
||||
#include "rpn-stack.h"
|
||||
#include "rpn-string.h"
|
||||
#include "rpn-branch.h"
|
||||
#include "rpn-store.h"
|
||||
#include "rpn-program.h"
|
||||
#include "rpn-trig.h"
|
||||
#include "rpn-logs.h"
|
||||
#include "rpn-test-core.h"
|
||||
};
|
||||
|
||||
//keywords declaration
|
||||
#include "rpn-cmd.h"
|
||||
|
||||
//
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
heap global_heap;
|
||||
stack global_stack;
|
||||
int ret = 0;
|
||||
|
||||
// apply default configuration
|
||||
program::apply_default();
|
||||
|
||||
// run with interactive prompt
|
||||
if (argc == 1)
|
||||
{
|
||||
//
|
||||
for (;;)
|
||||
{
|
||||
// make program from interactive entry
|
||||
program prog;
|
||||
if (program::entry(prog) == ret_good_bye)
|
||||
break;
|
||||
else
|
||||
{
|
||||
// run it
|
||||
if (prog.run(global_stack, global_heap) == ret_good_bye)
|
||||
break;
|
||||
else
|
||||
program::show_stack(global_stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
// run with cmd line arguments
|
||||
else
|
||||
{
|
||||
program prog;
|
||||
string entry;
|
||||
int i;
|
||||
|
||||
// make one string from entry
|
||||
for (i=1; i<argc; i++)
|
||||
{
|
||||
entry += argv[i];
|
||||
entry += ' ';
|
||||
}
|
||||
|
||||
// make program
|
||||
ret = program::parse(entry.c_str(), prog);
|
||||
if (ret == ret_ok)
|
||||
{
|
||||
string separator = "";
|
||||
|
||||
// run it
|
||||
ret = prog.run(global_stack, global_heap);
|
||||
program::show_stack(global_stack, separator);
|
||||
}
|
||||
}
|
||||
|
||||
mpfr_free_cache();
|
||||
|
||||
return ret;
|
||||
}
|
Loading…
Reference in a new issue