enum names and values

This commit is contained in:
Louis Rubet 2022-02-25 14:16:55 +01:00
parent d0c7304ffd
commit 2a980eb74d
22 changed files with 676 additions and 675 deletions

View file

@ -4,19 +4,19 @@
#include <cstring> #include <cstring>
vector<string>* Input::_ac_list = nullptr; vector<string>* Input::ac_list_ = nullptr;
Input::Input(string& entry, vector<string>& autocompletion_list, string prompt, string multiline_prompt) Input::Input(string& entry, vector<string>& autocompletion_list, string prompt, string multiline_prompt)
: status(cont) { : status(InputStatus::kContinue) {
char* c_entry = nullptr; char* c_entry = nullptr;
bool multiline = false; bool multiline = false;
int entry_len; int entry_len;
_ac_list = &autocompletion_list; ac_list_ = &autocompletion_list;
// linenoise for entry // linenoise for entry
linenoiseSetCompletionCallback(entry_completion_generator); linenoiseSetCompletionCallback(entry_completion_generator);
while (status == cont) { while (status == InputStatus::kContinue) {
// get user entry // get user entry
if (multiline) if (multiline)
c_entry = linenoise(multiline_prompt.c_str(), &entry_len); c_entry = linenoise(multiline_prompt.c_str(), &entry_len);
@ -26,9 +26,9 @@ Input::Input(string& entry, vector<string>& autocompletion_list, string prompt,
// Ctrl-C // Ctrl-C
if (linenoiseKeyType() == 1) { if (linenoiseKeyType() == 1) {
if (entry_len > 0 || multiline) if (entry_len > 0 || multiline)
status = abort; status = InputStatus::kAbort;
else else
status = ctrlc; status = InputStatus::kCtrlc;
} else if (linenoiseKeyType() == 3) { } else if (linenoiseKeyType() == 3) {
multiline = true; multiline = true;
if (c_entry != nullptr) entry += c_entry; if (c_entry != nullptr) entry += c_entry;
@ -38,9 +38,9 @@ Input::Input(string& entry, vector<string>& autocompletion_list, string prompt,
entry += c_entry; entry += c_entry;
// keep history // keep history
if (c_entry[0] != 0) (void)linenoiseHistoryAdd(entry.c_str()); if (c_entry[0] != 0) (void)linenoiseHistoryAdd(entry.c_str());
status = ok; status = InputStatus::kOk;
} else { } else {
status = error; status = InputStatus::kError;
} }
} }
} }
@ -54,16 +54,16 @@ Input::Input(string& entry, vector<string>& autocompletion_list, string prompt,
/// @param lc the completion object to add strings with linenoiseAddCompletion() /// @param lc the completion object to add strings with linenoiseAddCompletion()
/// ///
void Input::entry_completion_generator(const char* text, linenoiseCompletions* lc) { void Input::entry_completion_generator(const char* text, linenoiseCompletions* lc) {
if (Input::_ac_list == nullptr || text == nullptr) return; if (Input::ac_list_ == nullptr || text == nullptr) return;
int text_len = strnlen(text, 6); int text_len = strnlen(text, 6);
if (text_len == 0) if (text_len == 0)
// propose all keywords // propose all keywords
for (string& ac : *Input::_ac_list) linenoiseAddCompletion(lc, ac.c_str()); for (string& ac : *Input::ac_list_) linenoiseAddCompletion(lc, ac.c_str());
else else
// propose only keywords matching to text begining // propose only keywords matching to text begining
for (string& ac : *Input::_ac_list) for (string& ac : *Input::ac_list_)
// compare list entry with text, return if match // compare list entry with text, return if match
if (ac.compare(0, text_len, text) == 0) linenoiseAddCompletion(lc, ac.c_str()); if (ac.compare(0, text_len, text) == 0) linenoiseAddCompletion(lc, ac.c_str());
} }

View file

@ -14,13 +14,13 @@ using std::vector;
class Input { class Input {
public: public:
Input(string& entry, vector<string>& autocompletion_list, string prompt = "rpn> ", string multiline_prompt = ">"); Input(string& entry, vector<string>& autocompletion_list, string prompt = "rpn> ", string multiline_prompt = ">");
enum { ok, cont, abort, ctrlc, error } status; enum class InputStatus { kOk, kContinue, kAbort, kCtrlc, kError } status;
static void preload(const char* preloadText); static void preload(const char* preloadText);
private: private:
static void entry_completion_generator(const char* text, linenoiseCompletions* lc); static void entry_completion_generator(const char* text, linenoiseCompletions* lc);
static vector<string>* _ac_list; static vector<string>* ac_list_;
}; };
#endif // SRC_INPUT_HPP_ #endif // SRC_INPUT_HPP_

View file

@ -55,13 +55,13 @@ bool Lexer::parseString(string& entry, size_t idx, size_t& next_idx, vector<SynE
for (size_t i = idx + 1; i < entry.size(); i++) { for (size_t i = idx + 1; i < entry.size(); i++) {
if (entry[i] == '"') { if (entry[i] == '"') {
if (entry[i] - 1 != '\\') { if (entry[i] - 1 != '\\') {
elements.push_back({cmd_string, .value = entry.substr(idx + 1, i - idx - 1)}); elements.push_back({kString, .value = entry.substr(idx + 1, i - idx - 1)});
next_idx = i + 1; next_idx = i + 1;
return true; return true;
} }
} }
} }
elements.push_back({cmd_string, .value = entry.substr(idx + 1, entry.size() - idx - 1)}); elements.push_back({kString, .value = entry.substr(idx + 1, entry.size() - idx - 1)});
next_idx = entry.size(); next_idx = entry.size();
return true; return true;
} }
@ -71,12 +71,12 @@ bool Lexer::parseSymbol(string& entry, size_t idx, size_t& next_idx, vector<SynE
// here we are sure that entry[0] is at least '\'' // here we are sure that entry[0] is at least '\''
for (size_t i = idx + 1; i < entry.size(); i++) { for (size_t i = idx + 1; i < entry.size(); i++) {
if (entry[i] == '\'') { if (entry[i] == '\'') {
elements.push_back({cmd_symbol, .value = entry.substr(idx + 1, i - idx - 1), .autoEval = false}); elements.push_back({kSymbol, .value = entry.substr(idx + 1, i - idx - 1), .autoEval = false});
next_idx = i + 1; next_idx = i + 1;
return true; return true;
} }
} }
elements.push_back({cmd_symbol, .value = entry.substr(idx + 1, entry.size() - idx - 1)}); elements.push_back({kSymbol, .value = entry.substr(idx + 1, entry.size() - idx - 1)});
next_idx = entry.size(); next_idx = entry.size();
return true; return true;
} }
@ -93,7 +93,7 @@ bool Lexer::parseProgram(string& entry, size_t idx, size_t& next_idx, vector<Syn
if (countNested == 0) { if (countNested == 0) {
string prg = entry.substr(idx + 2, i - idx - 2); string prg = entry.substr(idx + 2, i - idx - 2);
trim(prg); trim(prg);
elements.push_back({cmd_program, .value = prg}); elements.push_back({kProgram, .value = prg});
next_idx = i + 2; next_idx = i + 2;
return true; return true;
} else { } else {
@ -103,7 +103,7 @@ bool Lexer::parseProgram(string& entry, size_t idx, size_t& next_idx, vector<Syn
} }
string prg = entry.substr(idx + 2, entry.size() - idx - 2); string prg = entry.substr(idx + 2, entry.size() - idx - 2);
trim(prg); trim(prg);
elements.push_back({cmd_program, .value = prg}); elements.push_back({kProgram, .value = prg});
next_idx = entry.size(); next_idx = entry.size();
return true; return true;
} }
@ -185,7 +185,7 @@ bool Lexer::parseNumber(string& entry, size_t idx, size_t& next_idx, vector<SynE
mpreal* r = nullptr; mpreal* r = nullptr;
int base = 10; int base = 10;
if (getNumberAt(entry, idx, next_idx, base, &r)) { if (getNumberAt(entry, idx, next_idx, base, &r)) {
elements.push_back({cmd_number, .re = r, .reBase = base}); elements.push_back({kNumber, .re = r, .reBase = base});
return true; return true;
} else { } else {
errors.push_back({entry.size(), "unterminated number"}); errors.push_back({entry.size(), "unterminated number"});
@ -199,19 +199,19 @@ bool Lexer::parseComplex(string& entry, size_t idx, size_t& next_idx, vector<Syn
mpreal* im = nullptr; mpreal* im = nullptr;
int reBase, imBase = 10; int reBase, imBase = 10;
if (idx + 1 == entry.size()) { if (idx + 1 == entry.size()) {
elements.push_back({cmd_symbol, .value = entry.substr(idx, entry.size() - idx)}); elements.push_back({kSymbol, .value = entry.substr(idx, entry.size() - idx)});
next_idx = entry.size(); next_idx = entry.size();
return true; // complex format error, return a symbol return true; // complex format error, return a symbol
} }
if (!getNumberAt(entry, idx + 1, next_idx, reBase, &re, ',')) { if (!getNumberAt(entry, idx + 1, next_idx, reBase, &re, ',')) {
elements.push_back({cmd_symbol, .value = entry.substr(idx, entry.size() - idx)}); elements.push_back({kSymbol, .value = entry.substr(idx, entry.size() - idx)});
next_idx = entry.size(); next_idx = entry.size();
return true; // complex format error, return a symbol return true; // complex format error, return a symbol
} }
size_t i = next_idx; size_t i = next_idx;
if (i >= entry.size()) { if (i >= entry.size()) {
elements.push_back({cmd_symbol, .value = entry.substr(idx, entry.size() - idx)}); elements.push_back({kSymbol, .value = entry.substr(idx, entry.size() - idx)});
next_idx = entry.size(); next_idx = entry.size();
if (re != nullptr) delete re; if (re != nullptr) delete re;
if (im != nullptr) delete im; if (im != nullptr) delete im;
@ -219,13 +219,13 @@ bool Lexer::parseComplex(string& entry, size_t idx, size_t& next_idx, vector<Syn
} }
if (!getNumberAt(entry, i, next_idx, imBase, &im, ')')) { if (!getNumberAt(entry, i, next_idx, imBase, &im, ')')) {
elements.push_back({cmd_symbol, .value = entry.substr(idx, entry.size() - idx)}); elements.push_back({kSymbol, .value = entry.substr(idx, entry.size() - idx)});
next_idx = entry.size(); next_idx = entry.size();
if (re != nullptr) delete re; if (re != nullptr) delete re;
if (im != nullptr) delete im; if (im != nullptr) delete im;
return true; // complex format error, return a symbol return true; // complex format error, return a symbol
} }
elements.push_back({cmd_complex, .re = re, .im = im, .reBase = reBase, .imBase = imBase}); elements.push_back({kComplex, .re = re, .im = im, .reBase = reBase, .imBase = imBase});
next_idx++; next_idx++;
return true; return true;
} }
@ -249,7 +249,7 @@ bool Lexer::parseUnknown(string& entry, size_t idx, size_t& next_idx, vector<Syn
stringstream ss(entry.substr(idx)); stringstream ss(entry.substr(idx));
string token; string token;
ss >> token; ss >> token;
elements.push_back({cmd_symbol, .value = token, .autoEval = true}); elements.push_back({kSymbol, .value = token, .autoEval = true});
next_idx = token.size() + idx; next_idx = token.size() + idx;
return true; return true;
} }

View file

@ -19,7 +19,7 @@ class Lexer {
public: public:
// a structure to describe a syntaxical element and its value // a structure to describe a syntaxical element and its value
struct SynElement { struct SynElement {
cmd_type_t type; ObjectType type;
string value; string value;
mpreal* re; mpreal* re;
mpreal* im; mpreal* im;
@ -35,7 +35,7 @@ class Lexer {
}; };
struct ReservedWord { struct ReservedWord {
cmd_type_t type; ObjectType type;
program_fn_t fn; program_fn_t fn;
}; };

View file

@ -94,16 +94,16 @@ int main(int argc, char* argv[]) {
program prog(stack, heap); program prog(stack, heap);
string entry; string entry;
switch (Input(entry, program::getAutocompletionWords()).status) { switch (Input(entry, program::getAutocompletionWords()).status) {
case Input::ok: case Input::InputStatus::kOk:
// user could stop prog with CtrlC // user could stop prog with CtrlC
CatchSignals(&prog); CatchSignals(&prog);
// run it // run it
if (prog.parse(entry) == ret_ok && prog.run() == ret_good_bye) if (prog.parse(entry) == kOk && prog.run() == kGoodbye)
go_on = false; go_on = false;
else else
prog.show_stack(); prog.show_stack();
break; break;
case Input::ctrlc: case Input::InputStatus::kCtrlc:
go_on = false; go_on = false;
break; break;
default: default:
@ -125,7 +125,7 @@ int main(int argc, char* argv[]) {
// make program // make program
ret = prog.parse(entry); ret = prog.parse(entry);
if (ret == ret_ok) { if (ret == kOk) {
// user could stop prog with CtrlC // user could stop prog with CtrlC
CatchSignals(&prog); CatchSignals(&prog);
@ -137,6 +137,6 @@ int main(int argc, char* argv[]) {
mpfr_free_cache(); mpfr_free_cache();
if (ret != ret_ok) return EXIT_FAILURE; if (ret != kOk) return EXIT_FAILURE;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View file

@ -20,37 +20,36 @@ using std::complex;
// definitions for objects // definitions for objects
/// ///
typedef enum { typedef enum {
ret_ok, kOk,
ret_unknown_err, kUnknownError,
ret_missing_operand, kMissingOperand,
ret_bad_operand_type, kBadOperandType,
ret_out_of_range, kOutOfRange,
ret_unknown_variable, kUnknownVariable,
ret_internal, kInternalError,
ret_deadly, kDeadlyError,
ret_good_bye, kGoodbye,
ret_not_impl, kNotImplemented,
ret_nop, kNop,
ret_syntax, kSyntaxError,
ret_div_by_zero, kDivByZero,
ret_runtime_error, kRuntimeError,
ret_abort_current_entry, kAbortCurrentEntry,
ret_out_of_memory, kOutOfMemory,
ret_bad_value, kBadValue,
ret_test_failed kTestFailed
} ret_value; } RetValue;
typedef enum { typedef enum {
cmd_undef, kUndef,
cmd_number, // floating point number kNumber, // 3.1416, 1e-1234, 0x12ab, 2b110, 50ba12
cmd_complex, // complex, couple of floating point numbers kComplex, // (1,2)
cmd_string, // "string" kString, // "string"
cmd_symbol, // 'symbol' kSymbol, // 'symbol'
cmd_program, // << instructions >> «instructions» kProgram, // << instructions >> «instructions»
cmd_keyword, // langage (reserved) keyword kKeyword, // langage (reserved) keyword (rot, dup, swap ..)
cmd_branch, // langage (reserved) branch keyword kBranch // langage (reserved) branch keyword (for, if, then ..)
cmd_max } ObjectType;
} cmd_type_t;
class program; class program;
class Branch; class Branch;
@ -61,9 +60,9 @@ typedef size_t (program::*branch_fn_t)(Branch&);
/// @brief Object - a generic stack object /// @brief Object - a generic stack object
/// ///
struct Object { struct Object {
explicit Object(cmd_type_t type = cmd_undef) : _type(type) {} explicit Object(ObjectType type = kUndef) : _type(type) {}
virtual ~Object() {} virtual ~Object() {}
cmd_type_t _type; ObjectType _type;
virtual Object* clone() { virtual Object* clone() {
Object* o = new Object(); Object* o = new Object();
if (o != nullptr) *o = *this; if (o != nullptr) *o = *this;
@ -83,9 +82,9 @@ struct Object {
/// @brief stack objects derived from Object /// @brief stack objects derived from Object
/// ///
struct Number : Object { struct Number : Object {
Number() : Object(cmd_number), base(10) {} Number() : Object(kNumber), base(10) {}
explicit Number(const mpreal& value_, int base_ = 10) : Object(cmd_number), base(base_), value(value_) {} explicit Number(const mpreal& value_, int base_ = 10) : Object(kNumber), base(base_), value(value_) {}
explicit Number(int value_, int base_ = 10) : Object(cmd_number), base(base_), value(value_) {} explicit Number(int value_, int base_ = 10) : Object(kNumber), base(base_), value(value_) {}
int base; int base;
mpreal value; mpreal value;
@ -95,9 +94,9 @@ struct Number : Object {
virtual ostream& show(ostream& out) { return showValue(out, value, s_mode, s_digits, base); } virtual ostream& show(ostream& out) { return showValue(out, value, s_mode, s_digits, base); }
// representation mode // representation mode
typedef enum { std, fix, sci } mode_enum; typedef enum { kStd, kFix, kSci } mode_enum;
static mode_enum s_mode; static mode_enum s_mode;
static constexpr mode_enum DEFAULT_MODE = Number::std; static constexpr mode_enum DEFAULT_MODE = Number::kStd;
// precision // precision
static constexpr mpfr_prec_t MPFR_DEFAULT_PREC_BITS = 128; static constexpr mpfr_prec_t MPFR_DEFAULT_PREC_BITS = 128;
@ -109,9 +108,9 @@ struct Number : Object {
stringstream format; stringstream format;
format << "%." << digits; format << "%." << digits;
switch ( mode ) { switch ( mode ) {
case std: format << "R*g"; break; case kStd: format << "R*g"; break;
case fix: format << "R*f"; break; case kFix: format << "R*f"; break;
case sci: format << "R*e"; break; case kSci: format << "R*e"; break;
} }
return format.str(); return format.str();
} }
@ -128,13 +127,13 @@ struct Number : Object {
/// @brief stack objects inheriting Object /// @brief stack objects inheriting Object
/// ///
struct Complex : Object { struct Complex : Object {
Complex() : Object(cmd_complex), reBase(10), imBase(10) {} Complex() : Object(kComplex), reBase(10), imBase(10) {}
explicit Complex(complex<mpreal>& value_, int reb = 10, int imb = 10) explicit Complex(complex<mpreal>& value_, int reb = 10, int imb = 10)
: Object(cmd_complex), reBase(reb), imBase(imb) { : Object(kComplex), reBase(reb), imBase(imb) {
value = value_; value = value_;
} }
explicit Complex(mpreal& re_, mpreal& im_, int reb = 10, int imb = 10) explicit Complex(mpreal& re_, mpreal& im_, int reb = 10, int imb = 10)
: Object(cmd_complex), reBase(reb), imBase(imb) { : Object(kComplex), reBase(reb), imBase(imb) {
value.real(re_); value.real(re_);
value.imag(im_); value.imag(im_);
} }
@ -154,8 +153,8 @@ struct Complex : Object {
}; };
struct String : Object { struct String : Object {
String() : Object(cmd_string) {} String() : Object(kString) {}
explicit String(const string& value_) : Object(cmd_string), value(value_) {} explicit String(const string& value_) : Object(kString), value(value_) {}
virtual Object* clone() { return new String(value); } virtual Object* clone() { return new String(value); }
virtual string name() { return string("string"); } virtual string name() { return string("string"); }
virtual ostream& show(ostream& out) { return out << "\"" << value << "\""; } virtual ostream& show(ostream& out) { return out << "\"" << value << "\""; }
@ -163,8 +162,8 @@ struct String : Object {
}; };
struct Program : Object { struct Program : Object {
Program() : Object(cmd_program) {} Program() : Object(kProgram) {}
explicit Program(const string& value_) : Object(cmd_program), value(value_) {} explicit Program(const string& value_) : Object(kProgram), value(value_) {}
virtual Object* clone() { return new Program(value); } virtual Object* clone() { return new Program(value); }
virtual string name() { return string("program"); } virtual string name() { return string("program"); }
virtual ostream& show(ostream& out) { return out << "«" << value << "»"; } virtual ostream& show(ostream& out) { return out << "«" << value << "»"; }
@ -172,9 +171,9 @@ struct Program : Object {
}; };
struct Symbol : Object { struct Symbol : Object {
explicit Symbol(bool autoEval_ = true) : Object(cmd_symbol), autoEval(autoEval_) {} explicit Symbol(bool autoEval_ = true) : Object(kSymbol), autoEval(autoEval_) {}
explicit Symbol(const string& value_, bool autoEval_ = true) explicit Symbol(const string& value_, bool autoEval_ = true)
: Object(cmd_symbol), value(value_), autoEval(autoEval_) {} : Object(kSymbol), value(value_), autoEval(autoEval_) {}
virtual Object* clone() { return new Symbol(value, autoEval); } virtual Object* clone() { return new Symbol(value, autoEval); }
virtual string name() { return string("symbol"); } virtual string name() { return string("symbol"); }
virtual ostream& show(ostream& out) { return out << "'" << value << "'"; } virtual ostream& show(ostream& out) { return out << "'" << value << "'"; }
@ -183,8 +182,8 @@ struct Symbol : Object {
}; };
struct Keyword : Object { struct Keyword : Object {
Keyword() : Object(cmd_keyword) {} Keyword() : Object(kKeyword) {}
explicit Keyword(program_fn_t fn_, const string& value_) : Object(cmd_keyword), fn(fn_), value(value_) {} explicit Keyword(program_fn_t fn_, const string& value_) : Object(kKeyword), fn(fn_), value(value_) {}
virtual Object* clone() { return new Keyword(fn, value); } virtual Object* clone() { return new Keyword(fn, value); }
virtual string name() { return string("keyword"); } virtual string name() { return string("keyword"); }
program_fn_t fn; program_fn_t fn;
@ -192,8 +191,8 @@ struct Keyword : Object {
}; };
struct Branch : Object { struct Branch : Object {
Branch() : Object(cmd_branch) {} Branch() : Object(kBranch) {}
explicit Branch(branch_fn_t fn_, const string& value_) : Object(cmd_branch) { explicit Branch(branch_fn_t fn_, const string& value_) : Object(kBranch) {
fn = fn_; fn = fn_;
arg1 = static_cast<size_t>(-1); arg1 = static_cast<size_t>(-1);
arg2 = static_cast<size_t>(-1); arg2 = static_cast<size_t>(-1);
@ -201,7 +200,7 @@ struct Branch : Object {
arg_bool = 0; arg_bool = 0;
value = value_; value = value_;
} }
explicit Branch(Branch& other) : Object(cmd_branch) { explicit Branch(Branch& other) : Object(kBranch) {
fn = other.fn; fn = other.fn;
arg1 = other.arg1; arg1 = other.arg1;
arg2 = other.arg2; arg2 = other.arg2;

View file

@ -2,205 +2,205 @@
#include "program.hpp" #include "program.hpp"
//< language reserved keywords (allowed types are cmd_keyword, cmd_branch or cmd_undef) //< language reserved keywords (allowed types are kKeyword, kBranch or kUndef)
vector<program::keyword_t> program::_keywords{ vector<program::keyword_t> program::_keywords{
// GENERAL // GENERAL
{cmd_undef, "", nullptr, "\nGENERAL"}, {kUndef, "", nullptr, "\nGENERAL"},
{cmd_keyword, "nop", &program::rpn_nop, "no operation"}, {kKeyword, "nop", &program::rpn_nop, "no operation"},
{cmd_keyword, "help", &program::rpn_help, "this help message"}, {kKeyword, "help", &program::rpn_help, "this help message"},
{cmd_keyword, "h", &program::rpn_help, ""}, {kKeyword, "h", &program::rpn_help, ""},
{cmd_keyword, "?", &program::rpn_help, ""}, {kKeyword, "?", &program::rpn_help, ""},
{cmd_keyword, "quit", &program::rpn_good_bye, "quit software"}, {kKeyword, "quit", &program::rpn_good_bye, "quit software"},
{cmd_keyword, "q", &program::rpn_good_bye, ""}, {kKeyword, "q", &program::rpn_good_bye, ""},
{cmd_keyword, "exit", &program::rpn_good_bye, ""}, {kKeyword, "exit", &program::rpn_good_bye, ""},
{cmd_keyword, "test", &program::rpn_test, ""}, // not seen by user {kKeyword, "test", &program::rpn_test, ""}, // not seen by user
{cmd_keyword, "version", &program::rpn_version, "show rpn version"}, {kKeyword, "version", &program::rpn_version, "show rpn version"},
{cmd_keyword, "uname", &program::rpn_uname, "show rpn complete identification string"}, {kKeyword, "uname", &program::rpn_uname, "show rpn complete identification string"},
{cmd_keyword, "history", &program::rpn_history, "see commands history"}, {kKeyword, "history", &program::rpn_history, "see commands history"},
// USUAL OPERATIONS ON REALS AND COMPLEXES // USUAL OPERATIONS ON REALS AND COMPLEXES
{cmd_undef, "", nullptr, "\nUSUAL OPERATIONS ON REALS AND COMPLEXES"}, {kUndef, "", nullptr, "\nUSUAL OPERATIONS ON REALS AND COMPLEXES"},
{cmd_keyword, "+", &program::rpn_plus, "addition"}, {kKeyword, "+", &program::rpn_plus, "addition"},
{cmd_keyword, "-", &program::rpn_minus, "substraction"}, {kKeyword, "-", &program::rpn_minus, "substraction"},
{cmd_keyword, "*", &program::rpn_mul, "multiplication"}, {kKeyword, "*", &program::rpn_mul, "multiplication"},
{cmd_keyword, "/", &program::rpn_div, "division"}, {kKeyword, "/", &program::rpn_div, "division"},
{cmd_keyword, "inv", &program::rpn_inv, "inverse"}, {kKeyword, "inv", &program::rpn_inv, "inverse"},
{cmd_keyword, "chs", &program::rpn_neg, "negation"}, {kKeyword, "chs", &program::rpn_neg, "negation"},
{cmd_keyword, "neg", &program::rpn_neg, ""}, {kKeyword, "neg", &program::rpn_neg, ""},
{cmd_keyword, "^", &program::rpn_power, "power"}, {kKeyword, "^", &program::rpn_power, "power"},
{cmd_keyword, "pow", &program::rpn_power, ""}, {kKeyword, "pow", &program::rpn_power, ""},
{cmd_keyword, "sqrt", &program::rpn_squareroot, "rpn_square root"}, {kKeyword, "sqrt", &program::rpn_squareroot, "rpn_square root"},
{cmd_keyword, "sq", &program::rpn_square, "rpn_square"}, {kKeyword, "sq", &program::rpn_square, "rpn_square"},
{cmd_keyword, "abs", &program::rpn_abs, "absolute value (norm for a complex)"}, {kKeyword, "abs", &program::rpn_abs, "absolute value (norm for a complex)"},
{cmd_keyword, "sign", &program::rpn_sign, "sign of a number or z/|z| for a complex"}, {kKeyword, "sign", &program::rpn_sign, "sign of a number or z/|z| for a complex"},
// OPERATIONS ON REALS // OPERATIONS ON REALS
{cmd_undef, "", nullptr, "\nOPERATIONS ON REALS"}, {kUndef, "", nullptr, "\nOPERATIONS ON REALS"},
{cmd_keyword, "%", &program::rpn_purcent, "purcent"}, {kKeyword, "%", &program::rpn_purcent, "purcent"},
{cmd_keyword, "%CH", &program::rpn_purcentCH, "inverse purcent"}, {kKeyword, "%CH", &program::rpn_purcentCH, "inverse purcent"},
{cmd_keyword, "mod", &program::rpn_modulo, "modulo"}, {kKeyword, "mod", &program::rpn_modulo, "modulo"},
{cmd_keyword, "fact", &program::rpn_fact, "n! for integer n or Gamma(x+1) for fractional x"}, {kKeyword, "fact", &program::rpn_fact, "n! for integer n or Gamma(x+1) for fractional x"},
{cmd_keyword, "mant", &program::rpn_mant, "mantissa of a real number"}, {kKeyword, "mant", &program::rpn_mant, "mantissa of a real number"},
{cmd_keyword, "xpon", &program::rpn_xpon, "exponant of a real number"}, {kKeyword, "xpon", &program::rpn_xpon, "exponant of a real number"},
{cmd_keyword, "floor", &program::rpn_floor, "largest number <="}, {kKeyword, "floor", &program::rpn_floor, "largest number <="},
{cmd_keyword, "ceil", &program::rpn_ceil, "smallest number >="}, {kKeyword, "ceil", &program::rpn_ceil, "smallest number >="},
{cmd_keyword, "ip", &program::rpn_ip, "integer part"}, {kKeyword, "ip", &program::rpn_ip, "integer part"},
{cmd_keyword, "fp", &program::rpn_fp, "fractional part"}, {kKeyword, "fp", &program::rpn_fp, "fractional part"},
{cmd_keyword, "min", &program::rpn_min, "min of 2 real numbers"}, {kKeyword, "min", &program::rpn_min, "min of 2 real numbers"},
{cmd_keyword, "max", &program::rpn_max, "max of 2 real numbers"}, {kKeyword, "max", &program::rpn_max, "max of 2 real numbers"},
// OPERATIONS ON COMPLEXES // OPERATIONS ON COMPLEXES
{cmd_undef, "", nullptr, "\nOPERATIONS ON COMPLEXES"}, {kUndef, "", nullptr, "\nOPERATIONS ON COMPLEXES"},
{cmd_keyword, "re", &program::rpn_re, "complex real part"}, {kKeyword, "re", &program::rpn_re, "complex real part"},
{cmd_keyword, "im", &program::rpn_im, "complex imaginary part"}, {kKeyword, "im", &program::rpn_im, "complex imaginary part"},
{cmd_keyword, "conj", &program::rpn_conj, "complex conjugate"}, {kKeyword, "conj", &program::rpn_conj, "complex conjugate"},
{cmd_keyword, "arg", &program::rpn_arg, "complex argument in radians"}, {kKeyword, "arg", &program::rpn_arg, "complex argument in radians"},
{cmd_keyword, "c->r", &program::rpn_c2r, "transform a complex in 2 reals"}, {kKeyword, "c->r", &program::rpn_c2r, "transform a complex in 2 reals"},
{cmd_keyword, "r->c", &program::rpn_r2c, "transform 2 reals in a complex"}, {kKeyword, "r->c", &program::rpn_r2c, "transform 2 reals in a complex"},
{cmd_keyword, "p->r", &program::rpn_p2r, "cartesian to polar"}, {kKeyword, "p->r", &program::rpn_p2r, "cartesian to polar"},
{cmd_keyword, "r->p", &program::rpn_r2p, "polar to cartesian"}, {kKeyword, "r->p", &program::rpn_r2p, "polar to cartesian"},
// MODE // MODE
{cmd_undef, "", nullptr, "\nMODE"}, {kUndef, "", nullptr, "\nMODE"},
{cmd_keyword, "std", &program::rpn_std, "standard floating numbers representation. ex: std"}, {kKeyword, "std", &program::rpn_std, "standard floating numbers representation. ex: std"},
{cmd_keyword, "fix", &program::rpn_fix, "fixed point representation. ex: 6 fix"}, {kKeyword, "fix", &program::rpn_fix, "fixed point representation. ex: 6 fix"},
{cmd_keyword, "sci", &program::rpn_sci, "scientific floating point representation. ex: 20 sci"}, {kKeyword, "sci", &program::rpn_sci, "scientific floating point representation. ex: 20 sci"},
{cmd_keyword, "prec", &program::rpn_precision, "set float precision in bits. ex: 256 prec"}, {kKeyword, "prec", &program::rpn_precision, "set float precision in bits. ex: 256 prec"},
{cmd_keyword, "round", &program::rpn_round, {kKeyword, "round", &program::rpn_round,
"set float rounding mode.\n\tex: [\"nearest (even)\", \"toward zero\", \"toward " "set float rounding mode.\n\tex: [\"nearest (even)\", \"toward zero\", \"toward "
"+inf\", \"toward -inf\", \"away from zero\", \"faithful rounding\", \"nearest (away from zero)\"] round"}, "+inf\", \"toward -inf\", \"away from zero\", \"faithful rounding\", \"nearest (away from zero)\"] round"},
{cmd_keyword, "default", &program::rpn_default, "set float representation and precision to default"}, {kKeyword, "default", &program::rpn_default, "set float representation and precision to default"},
{cmd_keyword, "type", &program::rpn_type, "show type of stack first entry"}, {kKeyword, "type", &program::rpn_type, "show type of stack first entry"},
{cmd_keyword, "hex", &program::rpn_hex, "hexadecimal representation, applies on stack level 0 only"}, {kKeyword, "hex", &program::rpn_hex, "hexadecimal representation, applies on stack level 0 only"},
{cmd_keyword, "dec", &program::rpn_dec, "decimal representation, applies on stack level 0 only"}, {kKeyword, "dec", &program::rpn_dec, "decimal representation, applies on stack level 0 only"},
{cmd_keyword, "bin", &program::rpn_bin, "binary representation, applies on stack level 0 only"}, {kKeyword, "bin", &program::rpn_bin, "binary representation, applies on stack level 0 only"},
{cmd_keyword, "base", &program::rpn_base, "arbitrary base representation, applies on stack level 0 only"}, {kKeyword, "base", &program::rpn_base, "arbitrary base representation, applies on stack level 0 only"},
// TESTS // TESTS
{cmd_undef, "", nullptr, "\nTEST"}, {kUndef, "", nullptr, "\nTEST"},
{cmd_keyword, ">", &program::rpn_sup, "binary operator >"}, {kKeyword, ">", &program::rpn_sup, "binary operator >"},
{cmd_keyword, ">=", &program::rpn_sup_eq, "binary operator >="}, {kKeyword, ">=", &program::rpn_sup_eq, "binary operator >="},
{cmd_keyword, "<", &program::rpn_inf, "binary operator <"}, {kKeyword, "<", &program::rpn_inf, "binary operator <"},
{cmd_keyword, "<=", &program::rpn_inf_eq, "binary operator <="}, {kKeyword, "<=", &program::rpn_inf_eq, "binary operator <="},
{cmd_keyword, "!=", &program::rpn_diff, "binary operator != (different)"}, {kKeyword, "!=", &program::rpn_diff, "binary operator != (different)"},
{cmd_keyword, "==", &program::rpn_eq, "binary operator == (equal)"}, {kKeyword, "==", &program::rpn_eq, "binary operator == (equal)"},
{cmd_keyword, "and", &program::rpn_test_and, "boolean operator and"}, {kKeyword, "and", &program::rpn_test_and, "boolean operator and"},
{cmd_keyword, "or", &program::rpn_test_or, "boolean operator or"}, {kKeyword, "or", &program::rpn_test_or, "boolean operator or"},
{cmd_keyword, "xor", &program::rpn_test_xor, "boolean operator xor"}, {kKeyword, "xor", &program::rpn_test_xor, "boolean operator xor"},
{cmd_keyword, "not", &program::rpn_test_not, "boolean operator not"}, {kKeyword, "not", &program::rpn_test_not, "boolean operator not"},
{cmd_keyword, "same", &program::rpn_same, "boolean operator same (equal)"}, {kKeyword, "same", &program::rpn_same, "boolean operator same (equal)"},
// STACK // STACK
{cmd_undef, "", nullptr, "\nSTACK"}, {kUndef, "", nullptr, "\nSTACK"},
{cmd_keyword, "swap", &program::rpn_swap, "swap 2 first stack entries"}, {kKeyword, "swap", &program::rpn_swap, "swap 2 first stack entries"},
{cmd_keyword, "drop", &program::rpn_drop, "drop first stack entry"}, {kKeyword, "drop", &program::rpn_drop, "drop first stack entry"},
{cmd_keyword, "drop2", &program::rpn_drop2, "drop 2 first stack entries"}, {kKeyword, "drop2", &program::rpn_drop2, "drop 2 first stack entries"},
{cmd_keyword, "dropn", &program::rpn_dropn, "drop n first stack entries"}, {kKeyword, "dropn", &program::rpn_dropn, "drop n first stack entries"},
{cmd_keyword, "del", &program::rpn_erase, "drop all stack entries"}, {kKeyword, "del", &program::rpn_erase, "drop all stack entries"},
{cmd_keyword, "erase", &program::rpn_erase, ""}, {kKeyword, "erase", &program::rpn_erase, ""},
{cmd_keyword, "rot", &program::rpn_rot, "rotate 3 first stack entries"}, {kKeyword, "rot", &program::rpn_rot, "rotate 3 first stack entries"},
{cmd_keyword, "dup", &program::rpn_dup, "duplicate first stack entry"}, {kKeyword, "dup", &program::rpn_dup, "duplicate first stack entry"},
{cmd_keyword, "dup2", &program::rpn_dup2, "duplicate 2 first stack entries"}, {kKeyword, "dup2", &program::rpn_dup2, "duplicate 2 first stack entries"},
{cmd_keyword, "dupn", &program::rpn_dupn, "duplicate n first stack entries"}, {kKeyword, "dupn", &program::rpn_dupn, "duplicate n first stack entries"},
{cmd_keyword, "pick", &program::rpn_pick, "push a copy of the given stack level onto the stack"}, {kKeyword, "pick", &program::rpn_pick, "push a copy of the given stack level onto the stack"},
{cmd_keyword, "depth", &program::rpn_depth, "give stack depth"}, {kKeyword, "depth", &program::rpn_depth, "give stack depth"},
{cmd_keyword, "roll", &program::rpn_roll, "move a stack entry to the top of the stack"}, {kKeyword, "roll", &program::rpn_roll, "move a stack entry to the top of the stack"},
{cmd_keyword, "rolld", &program::rpn_rolld, "move the element on top of the stack to a higher stack position"}, {kKeyword, "rolld", &program::rpn_rolld, "move the element on top of the stack to a higher stack position"},
{cmd_keyword, "over", &program::rpn_over, "push a copy of the element in stack level 2 onto the stack"}, {kKeyword, "over", &program::rpn_over, "push a copy of the element in stack level 2 onto the stack"},
// STRING // STRING
{cmd_undef, "", nullptr, "\nSTRING"}, {kUndef, "", nullptr, "\nSTRING"},
{cmd_keyword, "->str", &program::rpn_instr, "convert an object into a string"}, {kKeyword, "->str", &program::rpn_instr, "convert an object into a string"},
{cmd_keyword, "str->", &program::rpn_strout, "convert a string into an object"}, {kKeyword, "str->", &program::rpn_strout, "convert a string into an object"},
{cmd_keyword, "chr", &program::rpn_chr, "convert ASCII character code in stack level 1 into a string"}, {kKeyword, "chr", &program::rpn_chr, "convert ASCII character code in stack level 1 into a string"},
{cmd_keyword, "num", &program::rpn_num, {kKeyword, "num", &program::rpn_num,
"return ASCII code of the first character of the string in stack level 1 as a real number"}, "return ASCII code of the first character of the string in stack level 1 as a real number"},
{cmd_keyword, "size", &program::rpn_strsize, "return the length of the string"}, {kKeyword, "size", &program::rpn_strsize, "return the length of the string"},
{cmd_keyword, "pos", &program::rpn_strpos, "seach for the string in level 1 within the string in level 2"}, {kKeyword, "pos", &program::rpn_strpos, "seach for the string in level 1 within the string in level 2"},
{cmd_keyword, "sub", &program::rpn_strsub, "return a substring of the string in level 3"}, {kKeyword, "sub", &program::rpn_strsub, "return a substring of the string in level 3"},
// BRANCH // BRANCH
{cmd_undef, "", nullptr, "\nBRANCH"}, {kUndef, "", nullptr, "\nBRANCH"},
{cmd_branch, "if", (program_fn_t)&program::rpn_if, {kBranch, "if", (program_fn_t)&program::rpn_if,
"if <test-instruction> then <true-instructions> else <false-instructions> " "if <test-instruction> then <true-instructions> else <false-instructions> "
"end"}, "end"},
{cmd_branch, "then", (program_fn_t)&program::rpn_then, "used with if"}, {kBranch, "then", (program_fn_t)&program::rpn_then, "used with if"},
{cmd_branch, "else", (program_fn_t)&program::rpn_else, "used with if"}, {kBranch, "else", (program_fn_t)&program::rpn_else, "used with if"},
{cmd_branch, "end", (program_fn_t)&program::rpn_end, "used with various branch instructions"}, {kBranch, "end", (program_fn_t)&program::rpn_end, "used with various branch instructions"},
{cmd_branch, "start", (program_fn_t)&program::rpn_start, "<start> <end> start <instructions> next|<step> step"}, {kBranch, "start", (program_fn_t)&program::rpn_start, "<start> <end> start <instructions> next|<step> step"},
{cmd_branch, "for", (program_fn_t)&program::rpn_for, {kBranch, "for", (program_fn_t)&program::rpn_for,
"<start> <end> for <variable> <instructions> next|<step> step"}, "<start> <end> for <variable> <instructions> next|<step> step"},
{cmd_branch, "next", (program_fn_t)&program::rpn_next, "used with start and for"}, {kBranch, "next", (program_fn_t)&program::rpn_next, "used with start and for"},
{cmd_branch, "step", (program_fn_t)&program::rpn_step, "used with start and for"}, {kBranch, "step", (program_fn_t)&program::rpn_step, "used with start and for"},
{cmd_keyword, "ift", &program::rpn_ift, "similar to if-then-end, <test-instruction> <true-instruction> ift"}, {kKeyword, "ift", &program::rpn_ift, "similar to if-then-end, <test-instruction> <true-instruction> ift"},
{cmd_keyword, "ifte", &program::rpn_ifte, {kKeyword, "ifte", &program::rpn_ifte,
"similar to if-then-else-end, <test-instruction> <true-instruction> " "similar to if-then-else-end, <test-instruction> <true-instruction> "
"<false-instruction> ifte"}, "<false-instruction> ifte"},
{cmd_branch, "do", (program_fn_t)&program::rpn_do, "do <instructions> until <condition> end"}, {kBranch, "do", (program_fn_t)&program::rpn_do, "do <instructions> until <condition> end"},
{cmd_branch, "until", (program_fn_t)&program::rpn_until, "used with do"}, {kBranch, "until", (program_fn_t)&program::rpn_until, "used with do"},
{cmd_branch, "while", (program_fn_t)&program::rpn_while, "while <test-instruction> repeat <loop-instructions> end"}, {kBranch, "while", (program_fn_t)&program::rpn_while, "while <test-instruction> repeat <loop-instructions> end"},
{cmd_branch, "repeat", (program_fn_t)&program::rpn_repeat, "used with while"}, {kBranch, "repeat", (program_fn_t)&program::rpn_repeat, "used with while"},
// STORE // STORE
{cmd_undef, "", nullptr, "\nSTORE"}, {kUndef, "", nullptr, "\nSTORE"},
{cmd_keyword, "sto", &program::rpn_sto, "store a variable. ex: 1 'name' sto"}, {kKeyword, "sto", &program::rpn_sto, "store a variable. ex: 1 'name' sto"},
{cmd_keyword, "rcl", &program::rpn_rcl, "recall a variable. ex: 'name' rcl"}, {kKeyword, "rcl", &program::rpn_rcl, "recall a variable. ex: 'name' rcl"},
{cmd_keyword, "purge", &program::rpn_purge, "delete a variable. ex: 'name' purge"}, {kKeyword, "purge", &program::rpn_purge, "delete a variable. ex: 'name' purge"},
{cmd_keyword, "vars", &program::rpn_vars, "list all variables"}, {kKeyword, "vars", &program::rpn_vars, "list all variables"},
{cmd_keyword, "clusr", &program::rpn_clusr, "erase all variables"}, {kKeyword, "clusr", &program::rpn_clusr, "erase all variables"},
{cmd_keyword, "edit", &program::rpn_edit, "edit a variable content"}, {kKeyword, "edit", &program::rpn_edit, "edit a variable content"},
{cmd_keyword, "sto+", &program::rpn_stoadd, "add to a stored variable. ex: 1 'name' sto+ 'name' 2 sto+"}, {kKeyword, "sto+", &program::rpn_stoadd, "add to a stored variable. ex: 1 'name' sto+ 'name' 2 sto+"},
{cmd_keyword, "sto-", &program::rpn_stosub, "substract to a stored variable. ex: 1 'name' sto- 'name' 2 sto-"}, {kKeyword, "sto-", &program::rpn_stosub, "substract to a stored variable. ex: 1 'name' sto- 'name' 2 sto-"},
{cmd_keyword, "sto*", &program::rpn_stomul, "multiply a stored variable. ex: 3 'name' sto* 'name' 2 sto*"}, {kKeyword, "sto*", &program::rpn_stomul, "multiply a stored variable. ex: 3 'name' sto* 'name' 2 sto*"},
{cmd_keyword, "sto/", &program::rpn_stodiv, "divide a stored variable. ex: 3 'name' sto/ 'name' 2 sto/"}, {kKeyword, "sto/", &program::rpn_stodiv, "divide a stored variable. ex: 3 'name' sto/ 'name' 2 sto/"},
{cmd_keyword, "sneg", &program::rpn_stoneg, "negate a variable. ex: 'name' sneg"}, {kKeyword, "sneg", &program::rpn_stoneg, "negate a variable. ex: 'name' sneg"},
{cmd_keyword, "sinv", &program::rpn_stoinv, "inverse a variable. ex: 1 'name' sinv"}, {kKeyword, "sinv", &program::rpn_stoinv, "inverse a variable. ex: 1 'name' sinv"},
// PROGRAM // PROGRAM
{cmd_undef, "", nullptr, "\nPROGRAM"}, {kUndef, "", nullptr, "\nPROGRAM"},
{cmd_keyword, "eval", &program::rpn_eval, "evaluate (run) a program, or recall a variable. ex: 'my_prog' eval"}, {kKeyword, "eval", &program::rpn_eval, "evaluate (run) a program, or recall a variable. ex: 'my_prog' eval"},
{cmd_branch, "->", (program_fn_t)&program::rpn_inprog, {kBranch, "->", (program_fn_t)&program::rpn_inprog,
"load program local variables. ex: << -> n m << 0 n m for i i + next >> " "load program local variables. ex: << -> n m << 0 n m for i i + next >> "
">>"}, ">>"},
// TRIG ON REALS AND COMPLEXES // TRIG ON REALS AND COMPLEXES
{cmd_undef, "", nullptr, "\nTRIG ON REALS AND COMPLEXES"}, {kUndef, "", nullptr, "\nTRIG ON REALS AND COMPLEXES"},
{cmd_keyword, "pi", &program::rpn_pi, "pi constant"}, {kKeyword, "pi", &program::rpn_pi, "pi constant"},
{cmd_keyword, "sin", &program::rpn_sin, "sinus"}, {kKeyword, "sin", &program::rpn_sin, "sinus"},
{cmd_keyword, "asin", &program::rpn_asin, "arg sinus"}, {kKeyword, "asin", &program::rpn_asin, "arg sinus"},
{cmd_keyword, "cos", &program::rpn_cos, "cosinus"}, {kKeyword, "cos", &program::rpn_cos, "cosinus"},
{cmd_keyword, "acos", &program::rpn_acos, "arg cosinus"}, {kKeyword, "acos", &program::rpn_acos, "arg cosinus"},
{cmd_keyword, "tan", &program::rpn_tan, "tangent"}, {kKeyword, "tan", &program::rpn_tan, "tangent"},
{cmd_keyword, "atan", &program::rpn_atan, "arg tangent"}, {kKeyword, "atan", &program::rpn_atan, "arg tangent"},
{cmd_keyword, "d->r", &program::rpn_d2r, "convert degrees to radians"}, {kKeyword, "d->r", &program::rpn_d2r, "convert degrees to radians"},
{cmd_keyword, "r->d", &program::rpn_r2d, "convert radians to degrees"}, {kKeyword, "r->d", &program::rpn_r2d, "convert radians to degrees"},
// LOGS ON REALS AND COMPLEXES // LOGS ON REALS AND COMPLEXES
{cmd_undef, "", nullptr, "\nLOGS ON REALS AND COMPLEXES"}, {kUndef, "", nullptr, "\nLOGS ON REALS AND COMPLEXES"},
{cmd_keyword, "e", &program::rpn_e, "Euler constant"}, {kKeyword, "e", &program::rpn_e, "Euler constant"},
{cmd_keyword, "ln", &program::rpn_ln, "logarithm base e"}, {kKeyword, "ln", &program::rpn_ln, "logarithm base e"},
{cmd_keyword, "log", &program::rpn_ln, ""}, {kKeyword, "log", &program::rpn_ln, ""},
{cmd_keyword, "lnp1", &program::rpn_lnp1, "ln(1+x) which is useful when x is close to 0"}, {kKeyword, "lnp1", &program::rpn_lnp1, "ln(1+x) which is useful when x is close to 0"},
{cmd_keyword, "exp", &program::rpn_exp, "exponential"}, {kKeyword, "exp", &program::rpn_exp, "exponential"},
{cmd_keyword, "expm", &program::rpn_expm, "exp(x)-1 which is useful when x is close to 0"}, {kKeyword, "expm", &program::rpn_expm, "exp(x)-1 which is useful when x is close to 0"},
{cmd_keyword, "log10", &program::rpn_log10, "logarithm base 10"}, {kKeyword, "log10", &program::rpn_log10, "logarithm base 10"},
{cmd_keyword, "alog10", &program::rpn_alog10, "exponential base 10"}, {kKeyword, "alog10", &program::rpn_alog10, "exponential base 10"},
{cmd_keyword, "exp10", &program::rpn_alog10, ""}, {kKeyword, "exp10", &program::rpn_alog10, ""},
{cmd_keyword, "log2", &program::rpn_log2, "logarithm base 2"}, {kKeyword, "log2", &program::rpn_log2, "logarithm base 2"},
{cmd_keyword, "alog2", &program::rpn_alog2, "exponential base 2"}, {kKeyword, "alog2", &program::rpn_alog2, "exponential base 2"},
{cmd_keyword, "exp2", &program::rpn_alog2, ""}, {kKeyword, "exp2", &program::rpn_alog2, ""},
{cmd_keyword, "sinh", &program::rpn_sinh, "hyperbolic sine"}, {kKeyword, "sinh", &program::rpn_sinh, "hyperbolic sine"},
{cmd_keyword, "asinh", &program::rpn_asinh, "inverse hyperbolic sine"}, {kKeyword, "asinh", &program::rpn_asinh, "inverse hyperbolic sine"},
{cmd_keyword, "cosh", &program::rpn_cosh, "hyperbolic cosine"}, {kKeyword, "cosh", &program::rpn_cosh, "hyperbolic cosine"},
{cmd_keyword, "acosh", &program::rpn_acosh, "inverse hyperbolic cosine"}, {kKeyword, "acosh", &program::rpn_acosh, "inverse hyperbolic cosine"},
{cmd_keyword, "tanh", &program::rpn_tanh, "hyperbolic tangent"}, {kKeyword, "tanh", &program::rpn_tanh, "hyperbolic tangent"},
{cmd_keyword, "atanh", &program::rpn_atanh, "inverse hyperbolic tangent"}, {kKeyword, "atanh", &program::rpn_atanh, "inverse hyperbolic tangent"},
// TIME AND DATE // TIME AND DATE
{cmd_undef, "", nullptr, "\nTIME AND DATE"}, {kUndef, "", nullptr, "\nTIME AND DATE"},
{cmd_keyword, "time", &program::rpn_time, "time in local format"}, {kKeyword, "time", &program::rpn_time, "time in local format"},
{cmd_keyword, "date", &program::rpn_date, "date in local format"}, {kKeyword, "date", &program::rpn_date, "date in local format"},
{cmd_keyword, "ticks", &program::rpn_ticks, "system tick in µs"}, {kKeyword, "ticks", &program::rpn_ticks, "system tick in µs"},
}; };
/// autocompletion vector for linenoise autocompletion /// autocompletion vector for linenoise autocompletion
@ -214,19 +214,19 @@ vector<string>& program::getAutocompletionWords() {
/// @brief run a program on a stack and a heap /// @brief run a program on a stack and a heap
/// ///
/// @return ret_value see this type /// @return RetValue see this type
/// ///
ret_value program::run() { RetValue program::run() {
bool go_out = false; bool go_out = false;
ret_value ret = ret_ok; RetValue ret = kOk;
cmd_type_t type; ObjectType type;
_err = ret_ok; _err = kOk;
_err_context = ""; _err_context = "";
// branches for 'if' // branches for 'if'
ret = preprocess(); ret = preprocess();
if (ret != ret_ok) { if (ret != kOk) {
// free allocated // free allocated
for (Object* o : *this) delete o; for (Object* o : *this) delete o;
_local_heap.clear(); _local_heap.clear();
@ -238,36 +238,36 @@ ret_value program::run() {
Object* o = at(i); Object* o = at(i);
switch (o->_type) { switch (o->_type) {
// could be an auto-evaluated symbol // could be an auto-evaluated symbol
case cmd_symbol: case kSymbol:
auto_rcl(reinterpret_cast<Symbol*>(o)); auto_rcl(reinterpret_cast<Symbol*>(o));
i++; i++;
break; break;
// a keyword // a keyword
case cmd_keyword: { case kKeyword: {
Keyword* k = reinterpret_cast<Keyword*>(o); Keyword* k = reinterpret_cast<Keyword*>(o);
// call the matching function // call the matching function
(this->*(k->fn))(); (this->*(k->fn))();
switch (_err) { switch (_err) {
// no pb -> go on // no pb -> go on
case ret_ok: case kOk:
break; break;
// explicit go out software // explicit go out software
case ret_good_bye: case kGoodbye:
go_out = true; go_out = true;
ret = ret_good_bye; ret = kGoodbye;
break; break;
default: default:
// error: abort prog // error: abort prog
go_out = true; go_out = true;
// test error: make rpn return EXIT_FAILURE // test error: make rpn return EXIT_FAILURE
if (_err == ret_test_failed) ret = ret_test_failed; if (_err == kTestFailed) ret = kTestFailed;
// error: show it // error: show it
if (show_error(_err, _err_context) == ret_deadly) if (show_error(_err, _err_context) == kDeadlyError)
// pb showing error -> go out software // pb showing error -> go out software
ret = ret_good_bye; ret = kGoodbye;
break; break;
} }
i++; i++;
@ -275,15 +275,15 @@ ret_value program::run() {
} }
// a branch keyword // a branch keyword
case cmd_branch: { case kBranch: {
// call matching function // call matching function
Branch* b = reinterpret_cast<Branch*>(o); Branch* b = reinterpret_cast<Branch*>(o);
size_t next_cmd = (this->*(b->fn))(*b); size_t next_cmd = (this->*(b->fn))(*b);
switch (next_cmd) { switch (next_cmd) {
case step_out: // step out case kStepOut: // step out
i++; // meaning 'next command' i++; // meaning 'next command'
break; break;
case runtime_error: // runtime error case kRtError: // runtime error
(void)show_error(_err, _err_context); (void)show_error(_err, _err_context);
go_out = true; go_out = true;
break; break;
@ -315,9 +315,9 @@ ret_value program::run() {
/// inner members of branch or keyword objects are filled by this function /// inner members of branch or keyword objects are filled by this function
/// these inner members store for example the index of the next keyword to execute etc. /// these inner members store for example the index of the next keyword to execute etc.
/// ///
/// @return ret_value see this type /// @return RetValue see this type
/// ///
ret_value program::preprocess(void) { RetValue program::preprocess(void) {
struct if_layout_t { struct if_layout_t {
if_layout_t() if_layout_t()
: index_then_or_unti_or_repeat(-1), : index_then_or_unti_or_repeat(-1),
@ -341,7 +341,7 @@ ret_value program::preprocess(void) {
// analyse if-then-else-end branches // analyse if-then-else-end branches
// analyse start-{next, step} branches // analyse start-{next, step} branches
for (size_t i = 0; i < size(); i++) { for (size_t i = 0; i < size(); i++) {
if (at(i)->_type == cmd_branch) { if (at(i)->_type == kBranch) {
Branch* k = reinterpret_cast<Branch*>(at(i)); Branch* k = reinterpret_cast<Branch*>(at(i));
if (k->value == "if") { if (k->value == "if") {
if_layout_t layout; if_layout_t layout;
@ -350,51 +350,51 @@ ret_value program::preprocess(void) {
layout_index++; layout_index++;
} else if (k->value == "then") { } else if (k->value == "then") {
size_t next = i + 1; size_t next = i + 1;
if (next >= size()) next = step_out; if (next >= size()) next = kStepOut;
// nothing after 'then' -> error // nothing after 'then' -> error
if (next == step_out) { if (next == kStepOut) {
// error: show it // error: show it
show_syntax_error("missing end after then"); show_syntax_error("missing end after then");
return ret_syntax; return kSyntaxError;
} }
if (layout_index < 0) { if (layout_index < 0) {
// error: show it // error: show it
show_syntax_error("missing if before then"); show_syntax_error("missing if before then");
return ret_syntax; return kSyntaxError;
} }
if (vlayout[layout_index].index_then_or_unti_or_repeat != -1) { if (vlayout[layout_index].index_then_or_unti_or_repeat != -1) {
// error: show it // error: show it
show_syntax_error("duplicate then"); show_syntax_error("duplicate then");
return ret_syntax; return kSyntaxError;
} }
vlayout[layout_index].index_then_or_unti_or_repeat = i; vlayout[layout_index].index_then_or_unti_or_repeat = i;
k->arg1 = next; k->arg1 = next;
k->arg3 = vlayout[layout_index].index_if_or_do_or_while; k->arg3 = vlayout[layout_index].index_if_or_do_or_while;
} else if (k->value == "else") { } else if (k->value == "else") {
size_t next = i + 1; size_t next = i + 1;
if (next >= size()) next = step_out; if (next >= size()) next = kStepOut;
// nothing after 'else' -> error // nothing after 'else' -> error
if (next == step_out) { if (next == kStepOut) {
// error: show it // error: show it
show_syntax_error("missing end after else"); show_syntax_error("missing end after else");
return ret_syntax; return kSyntaxError;
} }
if (layout_index < 0) { if (layout_index < 0) {
// error: show it // error: show it
show_syntax_error("missing if before else"); show_syntax_error("missing if before else");
return ret_syntax; return kSyntaxError;
} }
if (vlayout[layout_index].index_then_or_unti_or_repeat == -1) { if (vlayout[layout_index].index_then_or_unti_or_repeat == -1) {
// error: show it // error: show it
show_syntax_error("missing then before else"); show_syntax_error("missing then before else");
return ret_syntax; return kSyntaxError;
} }
if (vlayout[layout_index].index_else != -1) { if (vlayout[layout_index].index_else != -1) {
// error: show it // error: show it
show_syntax_error("duplicate else"); show_syntax_error("duplicate else");
return ret_syntax; return kSyntaxError;
} }
vlayout[layout_index].index_else = i; vlayout[layout_index].index_else = i;
k->arg1 = next; // fill branch1 (if was false) of 'else' k->arg1 = next; // fill branch1 (if was false) of 'else'
@ -410,7 +410,7 @@ ret_value program::preprocess(void) {
if (vstart_index.size() == 0) { if (vstart_index.size() == 0) {
// error: show it // error: show it
show_syntax_error("missing start or for before next"); show_syntax_error("missing start or for before next");
return ret_syntax; return kSyntaxError;
} }
k->arg1 = vstart_index[vstart_index.size() - 1]; // 'next' arg1 = 'start' index k->arg1 = vstart_index[vstart_index.size() - 1]; // 'next' arg1 = 'start' index
reinterpret_cast<Branch*>(at(vstart_index[vstart_index.size() - 1]))->arg2 = reinterpret_cast<Branch*>(at(vstart_index[vstart_index.size() - 1]))->arg2 =
@ -420,7 +420,7 @@ ret_value program::preprocess(void) {
if (vstart_index.size() == 0) { if (vstart_index.size() == 0) {
// error: show it // error: show it
show_syntax_error("missing start or for before step"); show_syntax_error("missing start or for before step");
return ret_syntax; return kSyntaxError;
} }
k->arg1 = vstart_index[vstart_index.size() - 1]; // fill 'step' branch1 = 'start' index k->arg1 = vstart_index[vstart_index.size() - 1]; // fill 'step' branch1 = 'start' index
reinterpret_cast<Branch*>(at(vstart_index[vstart_index.size() - 1]))->arg2 = reinterpret_cast<Branch*>(at(vstart_index[vstart_index.size() - 1]))->arg2 =
@ -436,23 +436,23 @@ ret_value program::preprocess(void) {
layout_index++; layout_index++;
} else if (k->value == "until") { } else if (k->value == "until") {
size_t next = i + 1; size_t next = i + 1;
if (next >= size()) next = step_out; if (next >= size()) next = kStepOut;
// nothing after 'unti' -> error // nothing after 'unti' -> error
if (next == step_out) { if (next == kStepOut) {
// error: show it // error: show it
show_syntax_error("missing end"); show_syntax_error("missing end");
return ret_syntax; return kSyntaxError;
} }
if (layout_index < 0 || !vlayout[layout_index].is_do_unti) { if (layout_index < 0 || !vlayout[layout_index].is_do_unti) {
// error: show it // error: show it
show_syntax_error("missing do"); show_syntax_error("missing do");
return ret_syntax; return kSyntaxError;
} }
if (vlayout[layout_index].index_then_or_unti_or_repeat != -1) { if (vlayout[layout_index].index_then_or_unti_or_repeat != -1) {
// error: show it // error: show it
show_syntax_error("duplicate until"); show_syntax_error("duplicate until");
return ret_syntax; return kSyntaxError;
} }
vlayout[layout_index].index_then_or_unti_or_repeat = i; vlayout[layout_index].index_then_or_unti_or_repeat = i;
} else if (k->value == "while") { } else if (k->value == "while") {
@ -465,35 +465,35 @@ ret_value program::preprocess(void) {
if (layout_index < 0 || !vlayout[layout_index].is_while_repeat) { if (layout_index < 0 || !vlayout[layout_index].is_while_repeat) {
// error: show it // error: show it
show_syntax_error("missing while"); show_syntax_error("missing while");
return ret_syntax; return kSyntaxError;
} }
if (vlayout[layout_index].index_then_or_unti_or_repeat != -1) { if (vlayout[layout_index].index_then_or_unti_or_repeat != -1) {
// error: show it // error: show it
show_syntax_error("duplicate repeat"); show_syntax_error("duplicate repeat");
return ret_syntax; return kSyntaxError;
} }
vlayout[layout_index].index_then_or_unti_or_repeat = i; vlayout[layout_index].index_then_or_unti_or_repeat = i;
} else if (k->value == "end") { } else if (k->value == "end") {
size_t next = i + 1; size_t next = i + 1;
if (next >= size()) next = step_out; if (next >= size()) next = kStepOut;
if (layout_index < 0) { if (layout_index < 0) {
// error: show it // error: show it
show_syntax_error("missing branch instruction before end"); show_syntax_error("missing branch instruction before end");
return ret_syntax; return kSyntaxError;
} else { } else {
if (vlayout[layout_index].is_do_unti) { if (vlayout[layout_index].is_do_unti) {
// this end closes a do..unti // this end closes a do..unti
if (vlayout[layout_index].index_end != -1) { if (vlayout[layout_index].index_end != -1) {
// error: show it // error: show it
show_syntax_error("duplicate end"); show_syntax_error("duplicate end");
return ret_syntax; return kSyntaxError;
} }
if (vlayout[layout_index].index_then_or_unti_or_repeat == -1) { if (vlayout[layout_index].index_then_or_unti_or_repeat == -1) {
// error: show it // error: show it
show_syntax_error("missing until"); show_syntax_error("missing until");
return ret_syntax; return kSyntaxError;
} }
k->arg1 = vlayout[layout_index].index_if_or_do_or_while + 1; k->arg1 = vlayout[layout_index].index_if_or_do_or_while + 1;
@ -503,7 +503,7 @@ ret_value program::preprocess(void) {
if (vlayout[layout_index].index_end != -1) { if (vlayout[layout_index].index_end != -1) {
// error: show it // error: show it
show_syntax_error("duplicate end"); show_syntax_error("duplicate end");
return ret_syntax; return kSyntaxError;
} }
k->arg2 = vlayout[layout_index].index_if_or_do_or_while + 1; k->arg2 = vlayout[layout_index].index_if_or_do_or_while + 1;
@ -511,7 +511,7 @@ ret_value program::preprocess(void) {
if (vlayout[layout_index].index_then_or_unti_or_repeat == -1) { if (vlayout[layout_index].index_then_or_unti_or_repeat == -1) {
// error: show it // error: show it
show_syntax_error("missing repeat"); show_syntax_error("missing repeat");
return ret_syntax; return kSyntaxError;
} }
// fill 'repeat' arg1 with 'end+1' // fill 'repeat' arg1 with 'end+1'
@ -522,7 +522,7 @@ ret_value program::preprocess(void) {
if (vlayout[layout_index].index_end != -1) { if (vlayout[layout_index].index_end != -1) {
// error: show it // error: show it
show_syntax_error("duplicate end"); show_syntax_error("duplicate end");
return ret_syntax; return kSyntaxError;
} }
if (vlayout[layout_index].index_else != -1) { if (vlayout[layout_index].index_else != -1) {
// fill 'end' branch of 'else' // fill 'end' branch of 'else'
@ -535,7 +535,7 @@ ret_value program::preprocess(void) {
} else { } else {
// error: show it // error: show it
show_syntax_error("missing then"); show_syntax_error("missing then");
return ret_syntax; return kSyntaxError;
} }
} }
layout_index--; layout_index--;
@ -547,27 +547,27 @@ ret_value program::preprocess(void) {
if (layout_index >= 0) { if (layout_index >= 0) {
// error: show it // error: show it
show_syntax_error("missing end"); show_syntax_error("missing end");
return ret_syntax; return kSyntaxError;
} }
if (vstart_index.size() > 0) { if (vstart_index.size() > 0) {
// error: show it // error: show it
show_syntax_error("missing next or step after for or start"); show_syntax_error("missing next or step after for or start");
return ret_syntax; return kSyntaxError;
} }
return ret_ok; return kOk;
} }
/// @brief parse an entry string: cut it into objects chunks and add them to a program /// @brief parse an entry string: cut it into objects chunks and add them to a program
/// ///
/// @param entry the entry string /// @param entry the entry string
/// @param prog the program to be filled /// @param prog the program to be filled
/// @return ret_value see this type /// @return RetValue see this type
/// ///
ret_value program::parse(string& entry) { RetValue program::parse(string& entry) {
static map<string, Lexer::ReservedWord> keywords_map; static map<string, Lexer::ReservedWord> keywords_map;
vector<Lexer::SynElement> elements; vector<Lexer::SynElement> elements;
vector<Lexer::SynError> errors; vector<Lexer::SynError> errors;
ret_value ret = ret_ok; RetValue ret = kOk;
// prepare map for finding reserved keywords // prepare map for finding reserved keywords
if (keywords_map.empty()) if (keywords_map.empty())
@ -579,29 +579,29 @@ ret_value program::parse(string& entry) {
// make objects from parsed elements // make objects from parsed elements
for (Lexer::SynElement& element : elements) { for (Lexer::SynElement& element : elements) {
switch (element.type) { switch (element.type) {
case cmd_number: case kNumber:
push_back(new Number(*element.re, element.reBase)); push_back(new Number(*element.re, element.reBase));
break; break;
case cmd_complex: case kComplex:
push_back(new Complex(*element.re, *element.im, element.reBase, element.imBase)); push_back(new Complex(*element.re, *element.im, element.reBase, element.imBase));
break; break;
case cmd_string: case kString:
push_back(new String(element.value)); push_back(new String(element.value));
break; break;
case cmd_symbol: case kSymbol:
push_back(new Symbol(element.value, element.autoEval)); push_back(new Symbol(element.value, element.autoEval));
break; break;
case cmd_program: case kProgram:
push_back(new Program(element.value)); push_back(new Program(element.value));
break; break;
case cmd_keyword: case kKeyword:
push_back(new Keyword(element.fn, element.value)); push_back(new Keyword(element.fn, element.value));
break; break;
case cmd_branch: case kBranch:
push_back(new Branch((branch_fn_t)element.fn, element.value)); push_back(new Branch((branch_fn_t)element.fn, element.value));
break; break;
default: default:
show_error(ret_unknown_err, "error creating program from entry"); show_error(kUnknownError, "error creating program from entry");
break; break;
} }
if (element.re != nullptr) delete element.re; if (element.re != nullptr) delete element.re;
@ -616,27 +616,29 @@ ret_value program::parse(string& entry) {
/// @brief show the last error set /// @brief show the last error set
/// ///
/// @return ret_value see this type /// @return RetValue see this type
/// ///
ret_value program::show_error() { RetValue program::show_error() {
ret_value ret; RetValue ret;
// clang-format off // clang-format off
vector<string> errorStrings {"ok", "unknown command", "missing operand", "bad operand type", map<RetValue, string> errorStrings{{kOk, "ok"}, {kUnknownError, "unknown command"},
"out of range", "unknown variable", "internal error, aborting", "deadly", "goodbye", "not implemented", {kMissingOperand, "missing operand"}, {kBadOperandType, "bad operand type"},
"no operation", "syntax error", "division by zero", "runtime error", "aborted current entry", "out of memory", {kOutOfRange, "out of range"}, {kUnknownVariable, "unknown variable"},
"bad value", "test failed"}; {kInternalError, "internal error, aborting"}, {kDeadlyError, "deadly"},
{kGoodbye, "goodbye"}, {kNotImplemented, "not implemented"},
{kNop, "no operation"}, {kSyntaxError, "syntax error"},
{kDivByZero, "division by zero"}, {kRuntimeError, "runtime error"},
{kAbortCurrentEntry, "aborted current entry"}, {kOutOfMemory, "out of memory"},
{kBadValue, "bad value"}, {kTestFailed, "test failed"}
};
// clang-format on // clang-format on
// show last recorded error
if (static_cast<size_t>(_err) < errorStrings.size())
cerr << _err_context << ": error " << _err << ": " << errorStrings[_err] << endl; cerr << _err_context << ": error " << _err << ": " << errorStrings[_err] << endl;
else
cerr << _err_context << " (unknown error code)" << endl;
switch (_err) { switch (_err) {
case ret_internal: case kInternalError:
case ret_deadly: case kDeadlyError:
ret = ret_deadly; ret = kDeadlyError;
default: default:
ret = ret_ok; ret = kOk;
} }
return ret; return ret;
@ -646,9 +648,9 @@ ret_value program::show_error() {
/// ///
/// @param err the error to record /// @param err the error to record
/// @param context a context string /// @param context a context string
/// @return ret_value see this type /// @return RetValue see this type
/// ///
ret_value program::show_error(ret_value err, string& context) { RetValue program::show_error(RetValue err, string& context) {
// record error // record error
_err = err; _err = err;
_err_context = context; _err_context = context;
@ -659,9 +661,9 @@ ret_value program::show_error(ret_value err, string& context) {
/// ///
/// @param err the error to record /// @param err the error to record
/// @param context a context string /// @param context a context string
/// @return ret_value see this type /// @return RetValue see this type
/// ///
ret_value program::show_error(ret_value err, const char* context) { RetValue program::show_error(RetValue err, const char* context) {
// record error // record error
_err = err; _err = err;
_err_context = context; _err_context = context;
@ -672,20 +674,20 @@ ret_value program::show_error(ret_value err, const char* context) {
/// ///
/// @param err the error to record /// @param err the error to record
/// @param context a context string /// @param context a context string
/// @return ret_value see this type /// @return RetValue see this type
/// ///
void program::show_syntax_error(const char* context) { void program::show_syntax_error(const char* context) {
// record error // record error
_err = ret_syntax; _err = kSyntaxError;
_err_context = context; _err_context = context;
(void)show_error(); (void)show_error();
} }
/// @brief return the last error set /// @brief return the last error set
/// ///
/// @return ret_value see this type /// @return RetValue see this type
/// ///
ret_value program::get_err(void) { return _err; } RetValue program::get_err(void) { return _err; }
/// @brief show a stack (show its different objects) /// @brief show a stack (show its different objects)
/// generally a stack is associated to a running program /// generally a stack is associated to a running program

View file

@ -28,19 +28,19 @@ class program : public deque<Object*>, public Lexer {
} }
// parser // parser
ret_value parse(string& entry); RetValue parse(string& entry);
static ret_value get_fn(const char* fn_name, program_fn_t& fn, cmd_type_t& type); static RetValue get_fn(const char* fn_name, program_fn_t& fn, ObjectType& type);
// running // running
ret_value run(); RetValue run();
void stop(); void stop();
ret_value preprocess(void); RetValue preprocess(void);
ret_value show_error(); RetValue show_error();
ret_value show_error(ret_value err, string& context); RetValue show_error(RetValue err, string& context);
ret_value show_error(ret_value err, const char* context); RetValue show_error(RetValue err, const char* context);
void show_syntax_error(const char* context); void show_syntax_error(const char* context);
ret_value get_err(void); RetValue get_err(void);
void show_stack(bool show_separator = true); void show_stack(bool show_separator = true);
@ -50,7 +50,7 @@ class program : public deque<Object*>, public Lexer {
private: private:
// current error and its context // current error and its context
ret_value _err; RetValue _err;
string _err_context; string _err_context;
// global stack holding results for user // global stack holding results for user
@ -68,7 +68,7 @@ class program : public deque<Object*>, public Lexer {
private: private:
// keywords // keywords
struct keyword_t { struct keyword_t {
cmd_type_t type; ObjectType type;
string name; string name;
program_fn_t fn; program_fn_t fn;
string comment; string comment;
@ -93,7 +93,7 @@ class program : public deque<Object*>, public Lexer {
size_t rpn_for(Branch& myobj); size_t rpn_for(Branch& myobj);
size_t rpn_next(Branch& myobj); size_t rpn_next(Branch& myobj);
size_t rpn_step(Branch& myobj); size_t rpn_step(Branch& myobj);
enum { step_out = static_cast<size_t>(-1), runtime_error = static_cast<size_t>(-2) }; enum { kStepOut = static_cast<size_t>(-1), kRtError = static_cast<size_t>(-2) };
// complex // complex
void rpn_re(); void rpn_re();
@ -259,7 +259,7 @@ class program : public deque<Object*>, public Lexer {
#define MIN_ARGUMENTS(num) \ #define MIN_ARGUMENTS(num) \
do { \ do { \
if ((num) >= 0 && _stack.size() < (num)) { \ if ((num) >= 0 && _stack.size() < (num)) { \
setErrorContext(ret_missing_operand); \ setErrorContext(kMissingOperand); \
return; \ return; \
} \ } \
} while (0) } while (0)
@ -267,7 +267,7 @@ class program : public deque<Object*>, public Lexer {
#define MIN_ARGUMENTS_RET(num, ret) \ #define MIN_ARGUMENTS_RET(num, ret) \
do { \ do { \
if ((num) >= 0 && _stack.size() < (num)) { \ if ((num) >= 0 && _stack.size() < (num)) { \
setErrorContext(ret_missing_operand); \ setErrorContext(kMissingOperand); \
return (ret); \ return (ret); \
} \ } \
} while (0) } while (0)
@ -275,7 +275,7 @@ class program : public deque<Object*>, public Lexer {
#define ARG_MUST_BE_OF_TYPE(num, type) \ #define ARG_MUST_BE_OF_TYPE(num, type) \
do { \ do { \
if ((num) >= 0 && _stack.at(num)->_type != (type)) { \ if ((num) >= 0 && _stack.at(num)->_type != (type)) { \
setErrorContext(ret_bad_operand_type); \ setErrorContext(kBadOperandType); \
return; \ return; \
} \ } \
} while (0) } while (0)
@ -283,7 +283,7 @@ class program : public deque<Object*>, public Lexer {
#define ARG_MUST_BE_OF_TYPE_RET(num, type, ret) \ #define ARG_MUST_BE_OF_TYPE_RET(num, type, ret) \
do { \ do { \
if ((num) >= 0 && _stack.at(num)->_type != (type)) { \ if ((num) >= 0 && _stack.at(num)->_type != (type)) { \
setErrorContext(ret_bad_operand_type); \ setErrorContext(kBadOperandType); \
return (ret); \ return (ret); \
} \ } \
} while (0) } while (0)

View file

@ -6,28 +6,28 @@
/// ///
/// @param myobj the current branch object /// @param myobj the current branch object
/// @return size_t index of the next object to run in the current program /// @return size_t index of the next object to run in the current program
/// @return step_out next object to run in the current program is current + 1 /// @return kStepOut next object to run in the current program is current + 1
/// @return runtime_error something went wrong with preprocess, abort branch /// @return kRtError something went wrong with preprocess, abort branch
/// ///
size_t program::rpn_if(Branch& myobj) { size_t program::rpn_if(Branch& myobj) {
// myobj.arg1 = 'if' condition evaluation value // myobj.arg1 = 'if' condition evaluation value
MIN_ARGUMENTS_RET(1, runtime_error); MIN_ARGUMENTS_RET(1, kRtError);
ARG_MUST_BE_OF_TYPE_RET(0, cmd_number, runtime_error); ARG_MUST_BE_OF_TYPE_RET(0, kNumber, kRtError);
if (_stack.value<Number>(0) != 0) if (_stack.value<Number>(0) != 0)
myobj.arg1 = 1; myobj.arg1 = 1;
else else
myobj.arg1 = 0; myobj.arg1 = 0;
_stack.pop(); _stack.pop();
return step_out; return kStepOut;
} }
/// @brief then keyword (branch) implementation /// @brief then keyword (branch) implementation
/// ///
/// @param myobj the current branch object /// @param myobj the current branch object
/// @return size_t index of the next object to run in the current program /// @return size_t index of the next object to run in the current program
/// @return step_out next object to run in the current program is current + 1 /// @return kStepOut next object to run in the current program is current + 1
/// @return runtime_error something went wrong with preprocess, abort Branch /// @return kRtError something went wrong with preprocess, abort Branch
/// ///
size_t program::rpn_then(Branch& myobj) { size_t program::rpn_then(Branch& myobj) {
// myobj.arg1 = index of then + 1 // myobj.arg1 = index of then + 1
@ -36,9 +36,9 @@ size_t program::rpn_then(Branch& myobj) {
// if condition is true -> arg1 (= jump to then + 1) // if condition is true -> arg1 (= jump to then + 1)
// else -> arg2 (= jump to else + 1 or end + 1) // else -> arg2 (= jump to else + 1 or end + 1)
Branch* if_cmd; Branch* if_cmd;
if (myobj.arg3 >= size() || at(myobj.arg3)->_type != cmd_branch) { if (myobj.arg3 >= size() || at(myobj.arg3)->_type != kBranch) {
setErrorContext(ret_missing_operand); setErrorContext(kMissingOperand);
return runtime_error; return kRtError;
} }
if_cmd = reinterpret_cast<Branch*>(at(myobj.arg3)); if_cmd = reinterpret_cast<Branch*>(at(myobj.arg3));
if (if_cmd->arg1 == 1) if (if_cmd->arg1 == 1)
@ -51,8 +51,8 @@ size_t program::rpn_then(Branch& myobj) {
/// ///
/// @param myobj the current branch object /// @param myobj the current branch object
/// @return size_t index of the next object to run in the current program /// @return size_t index of the next object to run in the current program
/// @return step_out next object to run in the current program is current + 1 /// @return kStepOut next object to run in the current program is current + 1
/// @return runtime_error something went wrong with preprocess, abort branch /// @return kRtError something went wrong with preprocess, abort branch
/// ///
size_t program::rpn_else(Branch& myobj) { size_t program::rpn_else(Branch& myobj) {
// myobj.arg1 = index of else + 1 // myobj.arg1 = index of else + 1
@ -61,9 +61,9 @@ size_t program::rpn_else(Branch& myobj) {
// if condition was false -> arg1 (= jump to else + 1) // if condition was false -> arg1 (= jump to else + 1)
// if condition was true -> arg2 (= jump to end + 1) // if condition was true -> arg2 (= jump to end + 1)
Branch* if_cmd; Branch* if_cmd;
if (myobj.arg3 >= size() || at(myobj.arg3)->_type != cmd_branch) { if (myobj.arg3 >= size() || at(myobj.arg3)->_type != kBranch) {
setErrorContext(ret_missing_operand); setErrorContext(kMissingOperand);
return runtime_error; return kRtError;
} }
if_cmd = reinterpret_cast<Branch*>(at(myobj.arg3)); if_cmd = reinterpret_cast<Branch*>(at(myobj.arg3));
if (if_cmd->arg1 == 1) if (if_cmd->arg1 == 1)
@ -76,22 +76,22 @@ size_t program::rpn_else(Branch& myobj) {
/// ///
/// @param myobj the current branch object /// @param myobj the current branch object
/// @return size_t index of the next object to run in the current program /// @return size_t index of the next object to run in the current program
/// @return step_out next object to run in the current program is current + 1 /// @return kStepOut next object to run in the current program is current + 1
/// @return runtime_error something went wrong with preprocess, abort branch /// @return kRtError something went wrong with preprocess, abort branch
/// ///
size_t program::rpn_end(Branch& myobj) { size_t program::rpn_end(Branch& myobj) {
size_t ret = step_out; size_t ret = kStepOut;
// arg1 = index of do+1 in case of do..unti..end // arg1 = index of do+1 in case of do..unti..end
if (myobj.arg1 != -1) { if (myobj.arg1 != -1) {
// in a template do..until..end // in a template do..until..end
MIN_ARGUMENTS_RET(1, runtime_error); MIN_ARGUMENTS_RET(1, kRtError);
ARG_MUST_BE_OF_TYPE_RET(0, cmd_number, runtime_error); ARG_MUST_BE_OF_TYPE_RET(0, kNumber, kRtError);
// check arg // check arg
if (_stack.value<Number>(0) == 0) ret = myobj.arg1; if (_stack.value<Number>(0) == 0) ret = myobj.arg1;
_stack.pop(); _stack.pop();
} else if (myobj.arg2 != step_out) { } else if (myobj.arg2 != kStepOut) {
// arg2 = index of while+1 in case of while..repeat..end // arg2 = index of while+1 in case of while..repeat..end
ret = myobj.arg2; ret = myobj.arg2;
} }
@ -103,36 +103,36 @@ size_t program::rpn_end(Branch& myobj) {
/// ///
/// @param myobj the current branch object /// @param myobj the current branch object
/// @return size_t index of the next object to run in the current program /// @return size_t index of the next object to run in the current program
/// @return step_out next object to run in the current program is current + 1 /// @return kStepOut next object to run in the current program is current + 1
/// @return runtime_error something went wrong with preprocess, abort branch /// @return kRtError something went wrong with preprocess, abort branch
/// ///
size_t program::rpn_do(Branch& myobj) { size_t program::rpn_do(Branch& myobj) {
// nothing // nothing
return step_out; return kStepOut;
} }
/// @brief until keyword (branch) implementation /// @brief until keyword (branch) implementation
/// ///
/// @param myobj the current branch object /// @param myobj the current branch object
/// @return size_t index of the next object to run in the current program /// @return size_t index of the next object to run in the current program
/// @return step_out next object to run in the current program is current + 1 /// @return kStepOut next object to run in the current program is current + 1
/// @return runtime_error something went wrong with preprocess, abort Branch /// @return kRtError something went wrong with preprocess, abort Branch
/// ///
size_t program::rpn_until(Branch& myobj) { size_t program::rpn_until(Branch& myobj) {
// nothing // nothing
return step_out; return kStepOut;
} }
/// @brief ift keyword (branch) implementation /// @brief ift keyword (branch) implementation
/// ///
/// @param myobj the current branch object /// @param myobj the current branch object
/// @return size_t index of the next object to run in the current program /// @return size_t index of the next object to run in the current program
/// @return step_out next object to run in the current program is current + 1 /// @return kStepOut next object to run in the current program is current + 1
/// @return runtime_error something went wrong with preprocess, abort branch /// @return kRtError something went wrong with preprocess, abort branch
/// ///
void program::rpn_ift(void) { void program::rpn_ift(void) {
MIN_ARGUMENTS(2); MIN_ARGUMENTS(2);
ARG_MUST_BE_OF_TYPE(1, cmd_number); ARG_MUST_BE_OF_TYPE(1, kNumber);
// check ift arg // check ift arg
// arg is true if Number != 0 or if is nan or +/-inf // arg is true if Number != 0 or if is nan or +/-inf
@ -146,12 +146,12 @@ void program::rpn_ift(void) {
/// ///
/// @param myobj the current branch object /// @param myobj the current branch object
/// @return size_t index of the next object to run in the current program /// @return size_t index of the next object to run in the current program
/// @return step_out next object to run in the current program is current + 1 /// @return kStepOut next object to run in the current program is current + 1
/// @return runtime_error something went wrong with preprocess, abort branch /// @return kRtError something went wrong with preprocess, abort branch
/// ///
void program::rpn_ifte(void) { void program::rpn_ifte(void) {
MIN_ARGUMENTS(3); MIN_ARGUMENTS(3);
ARG_MUST_BE_OF_TYPE(2, cmd_number); ARG_MUST_BE_OF_TYPE(2, kNumber);
// check ifte arg // check ifte arg
if (_stack.value<Number>(2) != 0) { if (_stack.value<Number>(2) != 0) {
@ -167,26 +167,26 @@ void program::rpn_ifte(void) {
/// ///
/// @param myobj the current branch object /// @param myobj the current branch object
/// @return size_t index of the next object to run in the current program /// @return size_t index of the next object to run in the current program
/// @return step_out next object to run in the current program is current + 1 /// @return kStepOut next object to run in the current program is current + 1
/// @return runtime_error something went wrong with preprocess, abort branch /// @return kRtError something went wrong with preprocess, abort branch
/// ///
size_t program::rpn_while(Branch& myobj) { size_t program::rpn_while(Branch& myobj) {
// nothing // nothing
return step_out; return kStepOut;
} }
/// @brief repeat keyword (branch) implementation /// @brief repeat keyword (branch) implementation
/// ///
/// @param myobj the current branch object /// @param myobj the current branch object
/// @return size_t index of the next object to run in the current program /// @return size_t index of the next object to run in the current program
/// @return step_out next object to run in the current program is current + 1 /// @return kStepOut next object to run in the current program is current + 1
/// @return runtime_error something went wrong with preprocess, abort branch /// @return kRtError something went wrong with preprocess, abort branch
/// ///
size_t program::rpn_repeat(Branch& myobj) { size_t program::rpn_repeat(Branch& myobj) {
size_t ret = step_out; size_t ret = kStepOut;
MIN_ARGUMENTS_RET(1, runtime_error); MIN_ARGUMENTS_RET(1, kRtError);
ARG_MUST_BE_OF_TYPE_RET(0, cmd_number, runtime_error); ARG_MUST_BE_OF_TYPE_RET(0, kNumber, kRtError);
// check arg // check arg
// myobj.arg1 is end+1 // myobj.arg1 is end+1
@ -200,15 +200,15 @@ size_t program::rpn_repeat(Branch& myobj) {
/// ///
/// @param myobj the current branch object /// @param myobj the current branch object
/// @return size_t index of the next object to run in the current program /// @return size_t index of the next object to run in the current program
/// @return step_out next object to run in the current program is current + 1 /// @return kStepOut next object to run in the current program is current + 1
/// @return runtime_error something went wrong with preprocess, abort branch /// @return kRtError something went wrong with preprocess, abort branch
/// ///
size_t program::rpn_start(Branch& myobj) { size_t program::rpn_start(Branch& myobj) {
size_t ret = step_out; size_t ret = kStepOut;
MIN_ARGUMENTS_RET(2, runtime_error); MIN_ARGUMENTS_RET(2, kRtError);
ARG_MUST_BE_OF_TYPE_RET(0, cmd_number, runtime_error); ARG_MUST_BE_OF_TYPE_RET(0, kNumber, kRtError);
ARG_MUST_BE_OF_TYPE_RET(1, cmd_number, runtime_error); ARG_MUST_BE_OF_TYPE_RET(1, kNumber, kRtError);
// loop boundaries // loop boundaries
myobj.firstIndex = _stack.value<Number>(1); myobj.firstIndex = _stack.value<Number>(1);
@ -229,20 +229,20 @@ size_t program::rpn_start(Branch& myobj) {
/// ///
/// @param myobj the current branch object /// @param myobj the current branch object
/// @return size_t index of the next object to run in the current program /// @return size_t index of the next object to run in the current program
/// @return step_out next object to run in the current program is current + 1 /// @return kStepOut next object to run in the current program is current + 1
/// @return runtime_error something went wrong with preprocess, abort branch /// @return kRtError something went wrong with preprocess, abort branch
/// ///
size_t program::rpn_for(Branch& myobj) { size_t program::rpn_for(Branch& myobj) {
size_t ret; size_t ret;
MIN_ARGUMENTS_RET(2, runtime_error); MIN_ARGUMENTS_RET(2, kRtError);
ARG_MUST_BE_OF_TYPE_RET(0, cmd_number, runtime_error); ARG_MUST_BE_OF_TYPE_RET(0, kNumber, kRtError);
ARG_MUST_BE_OF_TYPE_RET(1, cmd_number, runtime_error); ARG_MUST_BE_OF_TYPE_RET(1, kNumber, kRtError);
Symbol* sym; Symbol* sym;
if (myobj.arg1 >= size() || at(myobj.arg1)->_type != cmd_symbol) { if (myobj.arg1 >= size() || at(myobj.arg1)->_type != kSymbol) {
setErrorContext(ret_missing_operand); setErrorContext(kMissingOperand);
return runtime_error; return kRtError;
} }
sym = reinterpret_cast<Symbol*>(at(myobj.arg1)); // arg1 = loop variable index sym = reinterpret_cast<Symbol*>(at(myobj.arg1)); // arg1 = loop variable index
@ -276,16 +276,16 @@ size_t program::rpn_for(Branch& myobj) {
/// ///
/// @param myobj the current branch object /// @param myobj the current branch object
/// @return size_t index of the next object to run in the current program /// @return size_t index of the next object to run in the current program
/// @return step_out next object to run in the current program is current + 1 /// @return kStepOut next object to run in the current program is current + 1
/// @return runtime_error something went wrong with preprocess, abort branch /// @return kRtError something went wrong with preprocess, abort branch
/// ///
size_t program::rpn_next(Branch& myobj) { size_t program::rpn_next(Branch& myobj) {
// arg1 = loop variable index // arg1 = loop variable index
// firstIndex = current point in the loop // firstIndex = current point in the loop
Branch* start_or_for; Branch* start_or_for;
if (myobj.arg1 >= size() || at(myobj.arg1)->_type != cmd_branch) { if (myobj.arg1 >= size() || at(myobj.arg1)->_type != kBranch) {
setErrorContext(ret_missing_operand); setErrorContext(kMissingOperand);
return runtime_error; return kRtError;
} }
start_or_for = reinterpret_cast<Branch*>(at(myobj.arg1)); start_or_for = reinterpret_cast<Branch*>(at(myobj.arg1));
if (!myobj.arg_bool) { if (!myobj.arg_bool) {
@ -301,9 +301,9 @@ size_t program::rpn_next(Branch& myobj) {
if (start_or_for->arg1 != -1) { if (start_or_for->arg1 != -1) {
Object* obj; Object* obj;
Symbol* var; Symbol* var;
if (start_or_for->arg1 >= size() || at(start_or_for->arg1)->_type != cmd_symbol) { if (start_or_for->arg1 >= size() || at(start_or_for->arg1)->_type != kSymbol) {
setErrorContext(ret_missing_operand); setErrorContext(kMissingOperand);
return runtime_error; return kRtError;
} }
var = reinterpret_cast<Symbol*>(at(start_or_for->arg1)); var = reinterpret_cast<Symbol*>(at(start_or_for->arg1));
@ -315,7 +315,7 @@ size_t program::rpn_next(Branch& myobj) {
if (myobj.firstIndex > start_or_for->lastIndex) { if (myobj.firstIndex > start_or_for->lastIndex) {
// end of loop // end of loop
myobj.arg_bool = false; // init again next time myobj.arg_bool = false; // init again next time
return step_out; return kStepOut;
} else { } else {
// for command: next instruction will be after symbol variable // for command: next instruction will be after symbol variable
if (start_or_for->arg1 != -1) return start_or_for->arg1 + 1; if (start_or_for->arg1 != -1) return start_or_for->arg1 + 1;
@ -329,27 +329,27 @@ size_t program::rpn_next(Branch& myobj) {
/// ///
/// @param myobj the current branch object /// @param myobj the current branch object
/// @return size_t index of the next object to run in the current program /// @return size_t index of the next object to run in the current program
/// @return step_out next object to run in the current program is current + 1 /// @return kStepOut next object to run in the current program is current + 1
/// @return runtime_error something went wrong with preprocess, abort branch /// @return kRtError something went wrong with preprocess, abort branch
/// ///
size_t program::rpn_step(Branch& myobj) { size_t program::rpn_step(Branch& myobj) {
size_t ret; size_t ret;
MIN_ARGUMENTS_RET(1, runtime_error); MIN_ARGUMENTS_RET(1, kRtError);
ARG_MUST_BE_OF_TYPE_RET(0, cmd_number, runtime_error); ARG_MUST_BE_OF_TYPE_RET(0, kNumber, kRtError);
mpreal step = _stack.value<Number>(0); mpreal step = _stack.value<Number>(0);
_stack.pop(); _stack.pop();
// end of loop if step is negative or zero // end of loop if step is negative or zero
if (step <= 0) { if (step <= 0) {
ret = step_out; ret = kStepOut;
} else { } else {
// arg1 = loop variable index // arg1 = loop variable index
// firstIndex = current count // firstIndex = current count
Branch* start_or_for; Branch* start_or_for;
if (myobj.arg1 >= size() || at(myobj.arg1)->_type != cmd_branch) { if (myobj.arg1 >= size() || at(myobj.arg1)->_type != kBranch) {
setErrorContext(ret_missing_operand); setErrorContext(kMissingOperand);
return runtime_error; return kRtError;
} }
start_or_for = reinterpret_cast<Branch*>(at(myobj.arg1)); start_or_for = reinterpret_cast<Branch*>(at(myobj.arg1));
if (!myobj.arg_bool) { if (!myobj.arg_bool) {
@ -366,9 +366,9 @@ size_t program::rpn_step(Branch& myobj) {
Symbol* var; Symbol* var;
// for command: increment symbol too // for command: increment symbol too
if (start_or_for->arg1 >= size() || at(start_or_for->arg1)->_type != cmd_symbol) { if (start_or_for->arg1 >= size() || at(start_or_for->arg1)->_type != kSymbol) {
setErrorContext(ret_missing_operand); setErrorContext(kMissingOperand);
return runtime_error; return kRtError;
} }
var = reinterpret_cast<Symbol*>(at(start_or_for->arg1)); var = reinterpret_cast<Symbol*>(at(start_or_for->arg1));
// increase symbol variable // increase symbol variable
@ -379,7 +379,7 @@ size_t program::rpn_step(Branch& myobj) {
if (myobj.firstIndex > start_or_for->lastIndex) { if (myobj.firstIndex > start_or_for->lastIndex) {
// end of loop // end of loop
myobj.arg_bool = false; // init again next time myobj.arg_bool = false; // init again next time
ret = step_out; ret = kStepOut;
} else { } else {
// for command: next instruction will be after symbol variable // for command: next instruction will be after symbol variable
if (start_or_for->arg1 != -1) ret = start_or_for->arg1 + 1; if (start_or_for->arg1 != -1) ret = start_or_for->arg1 + 1;

View file

@ -7,7 +7,7 @@
/// ///
void program::rpn_re() { void program::rpn_re() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_complex); ARG_MUST_BE_OF_TYPE(0, kComplex);
_stack.push_front(new Number(real(_stack.value<Complex>(0)))); _stack.push_front(new Number(real(_stack.value<Complex>(0))));
_stack.erase(1); _stack.erase(1);
} }
@ -17,7 +17,7 @@ void program::rpn_re() {
/// ///
void program::rpn_im() { void program::rpn_im() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_complex); ARG_MUST_BE_OF_TYPE(0, kComplex);
_stack.push_front(new Number(imag(_stack.value<Complex>(0)))); _stack.push_front(new Number(imag(_stack.value<Complex>(0))));
_stack.erase(1); _stack.erase(1);
} }
@ -27,7 +27,7 @@ void program::rpn_im() {
/// ///
void program::rpn_arg() { void program::rpn_arg() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_complex); ARG_MUST_BE_OF_TYPE(0, kComplex);
_stack.push_front(new Number(arg(_stack.value<Complex>(0)))); _stack.push_front(new Number(arg(_stack.value<Complex>(0))));
_stack.erase(1); _stack.erase(1);
} }
@ -37,7 +37,7 @@ void program::rpn_arg() {
/// ///
void program::rpn_conj() { void program::rpn_conj() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_complex); ARG_MUST_BE_OF_TYPE(0, kComplex);
_stack.value<Complex>(0) = conj(_stack.value<Complex>(0)); _stack.value<Complex>(0) = conj(_stack.value<Complex>(0));
} }
@ -46,8 +46,8 @@ void program::rpn_conj() {
/// ///
void program::rpn_r2c() { void program::rpn_r2c() {
MIN_ARGUMENTS(2); MIN_ARGUMENTS(2);
ARG_MUST_BE_OF_TYPE(0, cmd_number); ARG_MUST_BE_OF_TYPE(0, kNumber);
ARG_MUST_BE_OF_TYPE(1, cmd_number); ARG_MUST_BE_OF_TYPE(1, kNumber);
_stack.push(new Complex(_stack.value<Number>(1), _stack.value<Number>(0), _stack.obj<Complex>(1).reBase, _stack.obj<Complex>(0).reBase)); _stack.push(new Complex(_stack.value<Number>(1), _stack.value<Number>(0), _stack.obj<Complex>(1).reBase, _stack.obj<Complex>(0).reBase));
_stack.erase(1, 2); _stack.erase(1, 2);
} }
@ -57,7 +57,7 @@ void program::rpn_r2c() {
/// ///
void program::rpn_c2r() { void program::rpn_c2r() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_complex); ARG_MUST_BE_OF_TYPE(0, kComplex);
_stack.push(new Number(real(_stack.value<Complex>(0)), _stack.obj<Complex>(0).reBase)); _stack.push(new Number(real(_stack.value<Complex>(0)), _stack.obj<Complex>(0).reBase));
_stack.push(new Number(imag(_stack.value<Complex>(1)), _stack.obj<Complex>(1).imBase)); _stack.push(new Number(imag(_stack.value<Complex>(1)), _stack.obj<Complex>(1).imBase));
_stack.erase(2); _stack.erase(2);
@ -68,7 +68,7 @@ void program::rpn_c2r() {
/// ///
void program::rpn_r2p() { void program::rpn_r2p() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_complex); ARG_MUST_BE_OF_TYPE(0, kComplex);
mpreal rho = abs(_stack.value<Complex>(0)); mpreal rho = abs(_stack.value<Complex>(0));
mpreal theta = arg(_stack.value<Complex>(0)); mpreal theta = arg(_stack.value<Complex>(0));
_stack.value<Complex>(0).real(rho); _stack.value<Complex>(0).real(rho);
@ -80,6 +80,6 @@ void program::rpn_r2p() {
/// ///
void program::rpn_p2r() { void program::rpn_p2r() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_complex); ARG_MUST_BE_OF_TYPE(0, kComplex);
_stack.value<Complex>(0) = polar(abs(_stack.value<Complex>(0)), arg(_stack.value<Complex>(0))); _stack.value<Complex>(0) = polar(abs(_stack.value<Complex>(0)), arg(_stack.value<Complex>(0)));
} }

View file

@ -40,7 +40,7 @@ void program::rpn_nop() {
/// @brief quit keyword implementation /// @brief quit keyword implementation
/// ///
void program::rpn_good_bye() { setErrorContext(ret_good_bye); } void program::rpn_good_bye() { setErrorContext(kGoodbye); }
/// @brief nop keyword implementation /// @brief nop keyword implementation
/// the result is written on stdout /// the result is written on stdout
@ -60,23 +60,23 @@ void program::rpn_help() {
for (auto& kw : _keywords) for (auto& kw : _keywords)
if (!kw.comment.empty()) { if (!kw.comment.empty()) {
// titles in bold // titles in bold
if (kw.type == cmd_undef) cout << ATTR_BOLD; if (kw.type == kUndef) cout << ATTR_BOLD;
// show title or keyword + comment // show title or keyword + comment
cout << kw.name << '\t' << kw.comment << endl; cout << kw.name << '\t' << kw.comment << endl;
if (kw.type == cmd_undef) cout << ATTR_OFF; if (kw.type == kUndef) cout << ATTR_OFF;
} }
cout << endl; cout << endl;
// show mode // show mode
cout << "Current float mode is "; cout << "Current float mode is ";
switch (Number::s_mode) { switch (Number::s_mode) {
case Number::std: case Number::kStd:
cout << "'std'"; cout << "'std'";
break; break;
case Number::fix: case Number::kFix:
cout << "'fix'"; cout << "'fix'";
break; break;
case Number::sci: case Number::kSci:
cout << "'sci'"; cout << "'sci'";
break; break;
default: default:
@ -108,17 +108,17 @@ static bool check_decimal_digits(int precision) { return precision >= 0; }
/// ///
void program::rpn_std() { void program::rpn_std() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_number); ARG_MUST_BE_OF_TYPE(0, kNumber);
int digits = static_cast<int>(_stack.value<Number>(0).toLong()); int digits = static_cast<int>(_stack.value<Number>(0).toLong());
if (check_decimal_digits(digits)) { if (check_decimal_digits(digits)) {
// set mode, decimal digits and print format // set mode, decimal digits and print format
Number::s_mode = Number::std; Number::s_mode = Number::kStd;
Number::s_digits = digits; Number::s_digits = digits;
_stack.pop(); _stack.pop();
} else { } else {
setErrorContext(ret_out_of_range); setErrorContext(kOutOfRange);
} }
} }
@ -126,17 +126,17 @@ void program::rpn_std() {
/// ///
void program::rpn_fix() { void program::rpn_fix() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_number); ARG_MUST_BE_OF_TYPE(0, kNumber);
int digits = static_cast<int>(_stack.value<Number>(0).toLong()); int digits = static_cast<int>(_stack.value<Number>(0).toLong());
if (check_decimal_digits(digits)) { if (check_decimal_digits(digits)) {
// set mode, decimal digits and print format // set mode, decimal digits and print format
Number::s_mode = Number::fix; Number::s_mode = Number::kFix;
Number::s_digits = digits; Number::s_digits = digits;
_stack.pop(); _stack.pop();
} else { } else {
setErrorContext(ret_out_of_range); setErrorContext(kOutOfRange);
} }
} }
@ -144,17 +144,17 @@ void program::rpn_fix() {
/// ///
void program::rpn_sci() { void program::rpn_sci() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_number); ARG_MUST_BE_OF_TYPE(0, kNumber);
int digits = static_cast<int>(_stack.value<Number>(0).toLong()); int digits = static_cast<int>(_stack.value<Number>(0).toLong());
if (check_decimal_digits(digits)) { if (check_decimal_digits(digits)) {
// set mode, decimal digits and print format // set mode, decimal digits and print format
Number::s_mode = Number::sci; Number::s_mode = Number::kSci;
Number::s_digits = digits; Number::s_digits = digits;
_stack.pop(); _stack.pop();
} else { } else {
setErrorContext(ret_out_of_range); setErrorContext(kOutOfRange);
} }
} }
@ -195,7 +195,7 @@ void program::rpn_default() { program::apply_default(); }
/// ///
void program::rpn_precision() { void program::rpn_precision() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_number); ARG_MUST_BE_OF_TYPE(0, kNumber);
// set precision // set precision
int prec = static_cast<int>(_stack.value<Number>(0).toLong()); int prec = static_cast<int>(_stack.value<Number>(0).toLong());
@ -203,13 +203,13 @@ void program::rpn_precision() {
mpreal::set_default_prec(prec); mpreal::set_default_prec(prec);
// modify digits seen by user if std mode // modify digits seen by user if std mode
if (Number::s_mode == Number::std) { if (Number::s_mode == Number::kStd) {
// calc max nb of digits user can see with the current bit precision // calc max nb of digits user can see with the current bit precision
Number::s_digits = mpfr::bits2digits(mpreal::get_default_prec()); Number::s_digits = mpfr::bits2digits(mpreal::get_default_prec());
} }
_stack.pop(); _stack.pop();
} else { } else {
setErrorContext(ret_out_of_range); setErrorContext(kOutOfRange);
} }
} }
@ -217,7 +217,7 @@ void program::rpn_precision() {
/// ///
void program::rpn_round() { void program::rpn_round() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_string); ARG_MUST_BE_OF_TYPE(0, kString);
map<string, mpfr_rnd_t> matchRound{MPFR_ROUND}; map<string, mpfr_rnd_t> matchRound{MPFR_ROUND};
@ -225,6 +225,6 @@ void program::rpn_round() {
if (found != matchRound.end()) if (found != matchRound.end())
mpreal::set_default_rnd(found->second); mpreal::set_default_rnd(found->second);
else else
setErrorContext(ret_out_of_range); setErrorContext(kOutOfRange);
_stack.pop(); _stack.pop();
} }

View file

@ -10,166 +10,166 @@ void program::rpn_e(void) { _stack.push(new Number(mpfr::const_euler())); }
/// ///
void program::rpn_log10() { void program::rpn_log10() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
if (_stack.type(0) == cmd_number) if (_stack.type(0) == kNumber)
_stack.value<Number>(0) = log10(_stack.value<Number>(0)); _stack.value<Number>(0) = log10(_stack.value<Number>(0));
else if (_stack.type(0) == cmd_complex) else if (_stack.type(0) == kComplex)
_stack.value<Complex>(0) = log10(_stack.value<Complex>(0)); _stack.value<Complex>(0) = log10(_stack.value<Complex>(0));
else else
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
/// @brief alog10 keyword implementation /// @brief alog10 keyword implementation
/// ///
void program::rpn_alog10() { void program::rpn_alog10() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
if (_stack.type(0) == cmd_number) if (_stack.type(0) == kNumber)
_stack.value<Number>(0) = exp(log(mpreal(10)) * _stack.value<Number>(0)); _stack.value<Number>(0) = exp(log(mpreal(10)) * _stack.value<Number>(0));
else if (_stack.type(0) == cmd_complex) else if (_stack.type(0) == kComplex)
_stack.value<Complex>(0) = exp(log(mpreal(10)) * _stack.value<Complex>(0)); _stack.value<Complex>(0) = exp(log(mpreal(10)) * _stack.value<Complex>(0));
else else
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
/// @brief log2 keyword implementation /// @brief log2 keyword implementation
/// ///
void program::rpn_log2() { void program::rpn_log2() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
if (_stack.type(0) == cmd_number) if (_stack.type(0) == kNumber)
_stack.value<Number>(0) = log(_stack.value<Number>(0)) / mpfr::const_log2(); _stack.value<Number>(0) = log(_stack.value<Number>(0)) / mpfr::const_log2();
else if (_stack.type(0) == cmd_complex) else if (_stack.type(0) == kComplex)
_stack.value<Complex>(0) = log(_stack.value<Complex>(0)) / mpfr::const_log2(); _stack.value<Complex>(0) = log(_stack.value<Complex>(0)) / mpfr::const_log2();
else else
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
/// @brief alog2 keyword implementation /// @brief alog2 keyword implementation
/// ///
void program::rpn_alog2() { void program::rpn_alog2() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
if (_stack.type(0) == cmd_number) if (_stack.type(0) == kNumber)
_stack.value<Number>(0) = exp(mpfr::const_log2() * _stack.value<Number>(0)); _stack.value<Number>(0) = exp(mpfr::const_log2() * _stack.value<Number>(0));
else if (_stack.type(0) == cmd_complex) else if (_stack.type(0) == kComplex)
_stack.value<Complex>(0) = exp(mpfr::const_log2() * _stack.value<Complex>(0)); _stack.value<Complex>(0) = exp(mpfr::const_log2() * _stack.value<Complex>(0));
else else
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
/// @brief ln keyword implementation /// @brief ln keyword implementation
/// ///
void program::rpn_ln() { void program::rpn_ln() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
if (_stack.type(0) == cmd_number) if (_stack.type(0) == kNumber)
_stack.value<Number>(0) = log(_stack.value<Number>(0)); _stack.value<Number>(0) = log(_stack.value<Number>(0));
else if (_stack.type(0) == cmd_complex) else if (_stack.type(0) == kComplex)
_stack.value<Complex>(0) = log(_stack.value<Complex>(0)); _stack.value<Complex>(0) = log(_stack.value<Complex>(0));
else else
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
/// @brief exp keyword implementation /// @brief exp keyword implementation
/// ///
void program::rpn_exp() { void program::rpn_exp() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
if (_stack.type(0) == cmd_number) if (_stack.type(0) == kNumber)
_stack.value<Number>(0) = exp(_stack.value<Number>(0)); _stack.value<Number>(0) = exp(_stack.value<Number>(0));
else if (_stack.type(0) == cmd_complex) else if (_stack.type(0) == kComplex)
_stack.value<Complex>(0) = exp(_stack.value<Complex>(0)); _stack.value<Complex>(0) = exp(_stack.value<Complex>(0));
else else
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
/// @brief expm keyword implementation /// @brief expm keyword implementation
/// ///
void program::rpn_expm() { void program::rpn_expm() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
if (_stack.type(0) == cmd_number) if (_stack.type(0) == kNumber)
_stack.value<Number>(0) = exp(_stack.value<Number>(0)) - mpreal(1); _stack.value<Number>(0) = exp(_stack.value<Number>(0)) - mpreal(1);
else if (_stack.type(0) == cmd_complex) else if (_stack.type(0) == kComplex)
_stack.value<Complex>(0) = exp(_stack.value<Complex>(0)) - mpreal(1); _stack.value<Complex>(0) = exp(_stack.value<Complex>(0)) - mpreal(1);
else else
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
/// @brief lnp1 keyword implementation /// @brief lnp1 keyword implementation
/// ///
void program::rpn_lnp1() { void program::rpn_lnp1() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
if (_stack.type(0) == cmd_number) if (_stack.type(0) == kNumber)
_stack.value<Number>(0) = log(_stack.value<Number>(0) + 1); _stack.value<Number>(0) = log(_stack.value<Number>(0) + 1);
else if (_stack.type(0) == cmd_complex) else if (_stack.type(0) == kComplex)
_stack.value<Complex>(0) = log(_stack.value<Complex>(0) + mpreal(1)); _stack.value<Complex>(0) = log(_stack.value<Complex>(0) + mpreal(1));
else else
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
/// @brief sinh keyword implementation /// @brief sinh keyword implementation
/// ///
void program::rpn_sinh() { void program::rpn_sinh() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
if (_stack.type(0) == cmd_number) if (_stack.type(0) == kNumber)
_stack.value<Number>(0) = sinh(_stack.value<Number>(0)); _stack.value<Number>(0) = sinh(_stack.value<Number>(0));
else if (_stack.type(0) == cmd_complex) else if (_stack.type(0) == kComplex)
_stack.value<Complex>(0) = sinh(_stack.value<Complex>(0)); _stack.value<Complex>(0) = sinh(_stack.value<Complex>(0));
else else
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
/// @brief asinh keyword implementation /// @brief asinh keyword implementation
/// ///
void program::rpn_asinh() { void program::rpn_asinh() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
if (_stack.type(0) == cmd_number) if (_stack.type(0) == kNumber)
_stack.value<Number>(0) = asinh(_stack.value<Number>(0)); _stack.value<Number>(0) = asinh(_stack.value<Number>(0));
else if (_stack.type(0) == cmd_complex) else if (_stack.type(0) == kComplex)
_stack.value<Complex>(0) = asinh(_stack.value<Complex>(0)); _stack.value<Complex>(0) = asinh(_stack.value<Complex>(0));
else else
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
/// @brief cosh keyword implementation /// @brief cosh keyword implementation
/// ///
void program::rpn_cosh() { void program::rpn_cosh() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
if (_stack.type(0) == cmd_number) if (_stack.type(0) == kNumber)
_stack.value<Number>(0) = cosh(_stack.value<Number>(0)); _stack.value<Number>(0) = cosh(_stack.value<Number>(0));
else if (_stack.type(0) == cmd_complex) else if (_stack.type(0) == kComplex)
_stack.value<Complex>(0) = cosh(_stack.value<Complex>(0)); _stack.value<Complex>(0) = cosh(_stack.value<Complex>(0));
else else
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
/// @brief acosh keyword implementation /// @brief acosh keyword implementation
/// ///
void program::rpn_acosh() { void program::rpn_acosh() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
if (_stack.type(0) == cmd_number) if (_stack.type(0) == kNumber)
_stack.value<Number>(0) = acosh(_stack.value<Number>(0)); _stack.value<Number>(0) = acosh(_stack.value<Number>(0));
else if (_stack.type(0) == cmd_complex) else if (_stack.type(0) == kComplex)
_stack.value<Complex>(0) = acosh(_stack.value<Complex>(0)); _stack.value<Complex>(0) = acosh(_stack.value<Complex>(0));
else else
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
/// @brief tanh keyword implementation /// @brief tanh keyword implementation
/// ///
void program::rpn_tanh() { void program::rpn_tanh() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
if (_stack.type(0) == cmd_number) if (_stack.type(0) == kNumber)
_stack.value<Number>(0) = tanh(_stack.value<Number>(0)); _stack.value<Number>(0) = tanh(_stack.value<Number>(0));
else if (_stack.type(0) == cmd_complex) else if (_stack.type(0) == kComplex)
_stack.value<Complex>(0) = tanh(_stack.value<Complex>(0)); _stack.value<Complex>(0) = tanh(_stack.value<Complex>(0));
else else
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
/// @brief atanh keyword implementation /// @brief atanh keyword implementation
/// ///
void program::rpn_atanh() { void program::rpn_atanh() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
if (_stack.type(0) == cmd_number) if (_stack.type(0) == kNumber)
_stack.value<Number>(0) = atanh(_stack.value<Number>(0)); _stack.value<Number>(0) = atanh(_stack.value<Number>(0));
else if (_stack.type(0) == cmd_complex) else if (_stack.type(0) == kComplex)
_stack.value<Complex>(0) = atanh(_stack.value<Complex>(0)); _stack.value<Complex>(0) = atanh(_stack.value<Complex>(0));
else else
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }

View file

@ -38,7 +38,7 @@ void program::rpn_eval(void) {
string prog_text; string prog_text;
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
if (_stack.type(0) == cmd_symbol) { if (_stack.type(0) == kSymbol) {
// recall a variable // recall a variable
Object* obj; Object* obj;
string variable(_stack.value<Symbol>(0)); string variable(_stack.value<Symbol>(0));
@ -46,7 +46,7 @@ void program::rpn_eval(void) {
// if variable holds a program, run this program // if variable holds a program, run this program
if (find_variable(variable, obj)) { if (find_variable(variable, obj)) {
if (obj->_type == cmd_program) { if (obj->_type == kProgram) {
prog_text = _stack.value<Program>(0); prog_text = _stack.value<Program>(0);
_stack.pop(); _stack.pop();
run_prog = true; run_prog = true;
@ -55,15 +55,15 @@ void program::rpn_eval(void) {
_stack.push_front(obj); _stack.push_front(obj);
} }
} else { } else {
setErrorContext(ret_unknown_variable); setErrorContext(kUnknownVariable);
} }
} else if (_stack.type(0) == cmd_program) { } else if (_stack.type(0) == kProgram) {
// eval a program // eval a program
prog_text = _stack.value<Program>(0); prog_text = _stack.value<Program>(0);
_stack.pop(); _stack.pop();
run_prog = true; run_prog = true;
} else { } else {
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
// run prog if any // run prog if any
@ -71,7 +71,7 @@ void program::rpn_eval(void) {
program prog(_stack, _heap, this); program prog(_stack, _heap, this);
// make program from entry // make program from entry
if (prog.parse(prog_text) == ret_ok) { if (prog.parse(prog_text) == kOk) {
// run it // run it
prog.run(); prog.run();
} }
@ -86,7 +86,7 @@ int program::rpn_inprog(Branch& inprog_obj) {
bool prog_found = false; bool prog_found = false;
if (inprog_obj.arg1 == -1) { if (inprog_obj.arg1 == -1) {
setErrorContext(ret_unknown_err); setErrorContext(kUnknownError);
return -1; return -1;
} }
@ -96,15 +96,15 @@ int program::rpn_inprog(Branch& inprog_obj) {
// find next Program object // find next Program object
for (unsigned int i = inprog_obj.arg1 + 1; i < size(); i++) { for (unsigned int i = inprog_obj.arg1 + 1; i < size(); i++) {
// count symbol // count symbol
if (at(i)->_type == cmd_symbol) { if (at(i)->_type == kSymbol) {
count_symbols++; count_symbols++;
} else if (at(i)->_type == cmd_program) { } else if (at(i)->_type == kProgram) {
// stop if prog // stop if prog
prog_found = true; prog_found = true;
break; break;
} else { } else {
// found something other than symbol // found something other than symbol
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
show_error(_err, context); show_error(_err, context);
return -1; return -1;
} }
@ -112,21 +112,21 @@ int program::rpn_inprog(Branch& inprog_obj) {
// found 0 symbols // found 0 symbols
if (count_symbols == 0) { if (count_symbols == 0) {
setErrorContext(ret_syntax); setErrorContext(kSyntaxError);
show_error(_err, context); show_error(_err, context);
return -1; return -1;
} }
// <program> is missing // <program> is missing
if (!prog_found) { if (!prog_found) {
setErrorContext(ret_syntax); setErrorContext(kSyntaxError);
show_error(_err, context); show_error(_err, context);
return -1; return -1;
} }
// check symbols Number vs stack size // check symbols Number vs stack size
if (_stack.size() < count_symbols) { if (_stack.size() < count_symbols) {
setErrorContext(ret_missing_operand); setErrorContext(kMissingOperand);
show_error(_err, context); show_error(_err, context);
return -1; return -1;
} }
@ -142,7 +142,7 @@ int program::rpn_inprog(Branch& inprog_obj) {
program prog(_stack, _heap, this); program prog(_stack, _heap, this);
// make the program from entry // make the program from entry
if (prog.parse(entry) == ret_ok) { if (prog.parse(entry) == kOk) {
// run it // run it
prog.run(); prog.run();
} }

View file

@ -6,24 +6,24 @@
/// ///
void program::rpn_plus() { void program::rpn_plus() {
MIN_ARGUMENTS(2); MIN_ARGUMENTS(2);
if (_stack.type(0) == cmd_string && _stack.type(1) == cmd_string) { if (_stack.type(0) == kString && _stack.type(1) == kString) {
_stack.value<String>(1) += _stack.value<String>(0); _stack.value<String>(1) += _stack.value<String>(0);
_stack.pop(); _stack.pop();
} else if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) { } else if (_stack.type(0) == kNumber && _stack.type(1) == kNumber) {
_stack.value<Number>(1) += _stack.value<Number>(0); _stack.value<Number>(1) += _stack.value<Number>(0);
_stack.pop(); _stack.pop();
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_complex) { } else if (_stack.type(0) == kComplex && _stack.type(1) == kComplex) {
_stack.value<Complex>(1) += _stack.value<Complex>(0); _stack.value<Complex>(1) += _stack.value<Complex>(0);
_stack.pop(); _stack.pop();
} else if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_complex) { } else if (_stack.type(0) == kNumber && _stack.type(1) == kComplex) {
_stack.value<Complex>(1) += _stack.value<Number>(0); _stack.value<Complex>(1) += _stack.value<Number>(0);
_stack.pop(); _stack.pop();
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_number) { } else if (_stack.type(0) == kComplex && _stack.type(1) == kNumber) {
rpn_swap(); rpn_swap();
_stack.value<Complex>(1) += _stack.value<Number>(0); _stack.value<Complex>(1) += _stack.value<Number>(0);
_stack.pop(); _stack.pop();
} else { } else {
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
} }
@ -31,21 +31,21 @@ void program::rpn_plus() {
/// ///
void program::rpn_minus() { void program::rpn_minus() {
MIN_ARGUMENTS(2); MIN_ARGUMENTS(2);
if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) { if (_stack.type(0) == kNumber && _stack.type(1) == kNumber) {
_stack.value<Number>(1) -= _stack.value<Number>(0); _stack.value<Number>(1) -= _stack.value<Number>(0);
_stack.pop(); _stack.pop();
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_complex) { } else if (_stack.type(0) == kComplex && _stack.type(1) == kComplex) {
_stack.value<Complex>(1) -= _stack.value<Complex>(0); _stack.value<Complex>(1) -= _stack.value<Complex>(0);
_stack.pop(); _stack.pop();
} else if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_complex) { } else if (_stack.type(0) == kNumber && _stack.type(1) == kComplex) {
_stack.value<Complex>(1) -= _stack.value<Number>(0); _stack.value<Complex>(1) -= _stack.value<Number>(0);
_stack.pop(); _stack.pop();
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_number) { } else if (_stack.type(0) == kComplex && _stack.type(1) == kNumber) {
rpn_swap(); rpn_swap();
_stack.value<Complex>(1) = _stack.value<Number>(0) - _stack.value<Complex>(1); _stack.value<Complex>(1) = _stack.value<Number>(0) - _stack.value<Complex>(1);
_stack.pop(); _stack.pop();
} else { } else {
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
} }
@ -53,21 +53,21 @@ void program::rpn_minus() {
/// ///
void program::rpn_mul() { void program::rpn_mul() {
MIN_ARGUMENTS(2); MIN_ARGUMENTS(2);
if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) { if (_stack.type(0) == kNumber && _stack.type(1) == kNumber) {
_stack.value<Number>(1) *= _stack.value<Number>(0); _stack.value<Number>(1) *= _stack.value<Number>(0);
_stack.pop(); _stack.pop();
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_complex) { } else if (_stack.type(0) == kComplex && _stack.type(1) == kComplex) {
_stack.value<Complex>(1) *= _stack.value<Complex>(0); _stack.value<Complex>(1) *= _stack.value<Complex>(0);
_stack.pop(); _stack.pop();
} else if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_complex) { } else if (_stack.type(0) == kNumber && _stack.type(1) == kComplex) {
_stack.value<Complex>(1) *= _stack.value<Number>(0); _stack.value<Complex>(1) *= _stack.value<Number>(0);
_stack.pop(); _stack.pop();
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_number) { } else if (_stack.type(0) == kComplex && _stack.type(1) == kNumber) {
rpn_swap(); rpn_swap();
_stack.value<Complex>(1) *= _stack.value<Number>(0); _stack.value<Complex>(1) *= _stack.value<Number>(0);
_stack.pop(); _stack.pop();
} else { } else {
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
} }
@ -75,21 +75,21 @@ void program::rpn_mul() {
/// ///
void program::rpn_div() { void program::rpn_div() {
MIN_ARGUMENTS(2); MIN_ARGUMENTS(2);
if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) { if (_stack.type(0) == kNumber && _stack.type(1) == kNumber) {
_stack.value<Number>(1) /= _stack.value<Number>(0); _stack.value<Number>(1) /= _stack.value<Number>(0);
_stack.pop(); _stack.pop();
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_complex) { } else if (_stack.type(0) == kComplex && _stack.type(1) == kComplex) {
_stack.value<Complex>(1) /= _stack.value<Complex>(0); _stack.value<Complex>(1) /= _stack.value<Complex>(0);
_stack.pop(); _stack.pop();
} else if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_complex) { } else if (_stack.type(0) == kNumber && _stack.type(1) == kComplex) {
_stack.value<Complex>(1) /= _stack.value<Number>(0); _stack.value<Complex>(1) /= _stack.value<Number>(0);
_stack.pop(); _stack.pop();
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_number) { } else if (_stack.type(0) == kComplex && _stack.type(1) == kNumber) {
rpn_swap(); rpn_swap();
_stack.value<Complex>(1) = _stack.value<Number>(0) / _stack.value<Complex>(1); _stack.value<Complex>(1) = _stack.value<Number>(0) / _stack.value<Complex>(1);
_stack.pop(); _stack.pop();
} else { } else {
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
} }
@ -97,31 +97,31 @@ void program::rpn_div() {
/// ///
void program::rpn_neg() { void program::rpn_neg() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
if (_stack.type(0) == cmd_number) if (_stack.type(0) == kNumber)
_stack.value<Number>(0) = -_stack.value<Number>(0); _stack.value<Number>(0) = -_stack.value<Number>(0);
else if (_stack.type(0) == cmd_complex) else if (_stack.type(0) == kComplex)
_stack.value<Complex>(0) = -_stack.value<Complex>(0); _stack.value<Complex>(0) = -_stack.value<Complex>(0);
else else
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
/// @brief inv keyword implementation /// @brief inv keyword implementation
/// ///
void program::rpn_inv() { void program::rpn_inv() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
if (_stack.type(0) == cmd_number) if (_stack.type(0) == kNumber)
_stack.value<Number>(0) = 1 / _stack.value<Number>(0); _stack.value<Number>(0) = 1 / _stack.value<Number>(0);
else if (_stack.type(0) == cmd_complex) else if (_stack.type(0) == kComplex)
_stack.value<Complex>(0) = mpreal(1) / _stack.value<Complex>(0); _stack.value<Complex>(0) = mpreal(1) / _stack.value<Complex>(0);
else else
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
/// @brief power keyword implementation /// @brief power keyword implementation
/// ///
void program::rpn_power() { void program::rpn_power() {
MIN_ARGUMENTS(2); MIN_ARGUMENTS(2);
if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) { if (_stack.type(0) == kNumber && _stack.type(1) == kNumber) {
if (_stack.value<Number>(1) >= 0) { if (_stack.value<Number>(1) >= 0) {
_stack.value<Number>(1) = pow(_stack.value<Number>(1), _stack.value<Number>(0)); _stack.value<Number>(1) = pow(_stack.value<Number>(1), _stack.value<Number>(0));
_stack.pop(); _stack.pop();
@ -131,18 +131,18 @@ void program::rpn_power() {
_stack.value<Complex>(0) = pow(_stack.value<Complex>(0), _stack.value<Number>(1)); _stack.value<Complex>(0) = pow(_stack.value<Complex>(0), _stack.value<Number>(1));
_stack.erase(1, 2); _stack.erase(1, 2);
} }
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_complex) { } else if (_stack.type(0) == kComplex && _stack.type(1) == kComplex) {
_stack.value<Complex>(1) = pow(_stack.value<Complex>(1), _stack.value<Complex>(0)); _stack.value<Complex>(1) = pow(_stack.value<Complex>(1), _stack.value<Complex>(0));
_stack.pop(); _stack.pop();
} else if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_complex) { } else if (_stack.type(0) == kNumber && _stack.type(1) == kComplex) {
_stack.value<Complex>(1) = pow(_stack.value<Complex>(1), _stack.value<Number>(0)); _stack.value<Complex>(1) = pow(_stack.value<Complex>(1), _stack.value<Number>(0));
_stack.pop(); _stack.pop();
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_number) { } else if (_stack.type(0) == kComplex && _stack.type(1) == kNumber) {
rpn_swap(); rpn_swap();
_stack.value<Complex>(1) = pow(_stack.value<Number>(0), _stack.value<Complex>(1)); _stack.value<Complex>(1) = pow(_stack.value<Number>(0), _stack.value<Complex>(1));
_stack.pop(); _stack.pop();
} else { } else {
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
} }
@ -150,7 +150,7 @@ void program::rpn_power() {
/// ///
void program::rpn_squareroot() { void program::rpn_squareroot() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
if (_stack.type(0) == cmd_number) { if (_stack.type(0) == kNumber) {
if (_stack.value<Number>(0) >= 0) { if (_stack.value<Number>(0) >= 0) {
_stack.value<Number>(0) = sqrt(_stack.value<Number>(0)); _stack.value<Number>(0) = sqrt(_stack.value<Number>(0));
} else { } else {
@ -161,10 +161,10 @@ void program::rpn_squareroot() {
_stack.value<Complex>(0) = sqrt(_stack.value<Complex>(0)); _stack.value<Complex>(0) = sqrt(_stack.value<Complex>(0));
_stack.erase(1); _stack.erase(1);
} }
} else if (_stack.type(0) == cmd_complex) { } else if (_stack.type(0) == kComplex) {
_stack.value<Complex>(0) = sqrt(_stack.value<Complex>(0)); _stack.value<Complex>(0) = sqrt(_stack.value<Complex>(0));
} else { } else {
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
} }
@ -172,13 +172,13 @@ void program::rpn_squareroot() {
/// ///
void program::rpn_hex() { void program::rpn_hex() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
if (_stack.type(0) == cmd_number) { if (_stack.type(0) == kNumber) {
_stack.obj<Number>(0).base = 16; _stack.obj<Number>(0).base = 16;
} else if (_stack.type(0) == cmd_complex) { } else if (_stack.type(0) == kComplex) {
_stack.obj<Complex>(0).reBase = 16; _stack.obj<Complex>(0).reBase = 16;
_stack.obj<Complex>(0).imBase = 16; _stack.obj<Complex>(0).imBase = 16;
} else { } else {
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
} }
@ -186,13 +186,13 @@ void program::rpn_hex() {
/// ///
void program::rpn_bin() { void program::rpn_bin() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
if (_stack.type(0) == cmd_number) { if (_stack.type(0) == kNumber) {
_stack.obj<Number>(0).base = 2; _stack.obj<Number>(0).base = 2;
} else if (_stack.type(0) == cmd_complex) { } else if (_stack.type(0) == kComplex) {
_stack.obj<Complex>(0).reBase = 2; _stack.obj<Complex>(0).reBase = 2;
_stack.obj<Complex>(0).imBase = 2; _stack.obj<Complex>(0).imBase = 2;
} else { } else {
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
} }
@ -200,13 +200,13 @@ void program::rpn_bin() {
/// ///
void program::rpn_dec() { void program::rpn_dec() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
if (_stack.type(0) == cmd_number) { if (_stack.type(0) == kNumber) {
_stack.obj<Number>(0).base = 10; _stack.obj<Number>(0).base = 10;
} else if (_stack.type(0) == cmd_complex) { } else if (_stack.type(0) == kComplex) {
_stack.obj<Complex>(0).reBase = 10; _stack.obj<Complex>(0).reBase = 10;
_stack.obj<Complex>(0).imBase = 10; _stack.obj<Complex>(0).imBase = 10;
} else { } else {
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
} }
@ -214,21 +214,21 @@ void program::rpn_dec() {
/// ///
void program::rpn_base() { void program::rpn_base() {
MIN_ARGUMENTS(2); MIN_ARGUMENTS(2);
if (_stack.type(1) == cmd_number || _stack.type(1) == cmd_complex) { if (_stack.type(1) == kNumber || _stack.type(1) == kComplex) {
int base = static_cast<int>(_stack.value<Number>(0).toLong()); int base = static_cast<int>(_stack.value<Number>(0).toLong());
_stack.pop(); _stack.pop();
if (base >= 2 && base <= 62) { if (base >= 2 && base <= 62) {
if (_stack.type(0) == cmd_number) { if (_stack.type(0) == kNumber) {
_stack.obj<Number>(0).base = base; _stack.obj<Number>(0).base = base;
} else { } else {
_stack.obj<Complex>(0).reBase = base; _stack.obj<Complex>(0).reBase = base;
_stack.obj<Complex>(0).imBase = base; _stack.obj<Complex>(0).imBase = base;
} }
} else { } else {
setErrorContext(ret_out_of_range); setErrorContext(kOutOfRange);
} }
} else { } else {
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
} }
@ -236,8 +236,8 @@ void program::rpn_base() {
/// ///
void program::rpn_purcent() { void program::rpn_purcent() {
MIN_ARGUMENTS(2); MIN_ARGUMENTS(2);
ARG_MUST_BE_OF_TYPE(0, cmd_number); ARG_MUST_BE_OF_TYPE(0, kNumber);
ARG_MUST_BE_OF_TYPE(1, cmd_number); ARG_MUST_BE_OF_TYPE(1, kNumber);
_stack.value<Number>(1) *= _stack.value<Number>(0) / 100; _stack.value<Number>(1) *= _stack.value<Number>(0) / 100;
_stack.pop(); _stack.pop();
} }
@ -246,8 +246,8 @@ void program::rpn_purcent() {
/// ///
void program::rpn_purcentCH() { void program::rpn_purcentCH() {
MIN_ARGUMENTS(2); MIN_ARGUMENTS(2);
ARG_MUST_BE_OF_TYPE(0, cmd_number); ARG_MUST_BE_OF_TYPE(0, kNumber);
ARG_MUST_BE_OF_TYPE(1, cmd_number); ARG_MUST_BE_OF_TYPE(1, kNumber);
_stack.value<Number>(1) = (_stack.value<Number>(0) * 100) / _stack.value<Number>(1); _stack.value<Number>(1) = (_stack.value<Number>(0) * 100) / _stack.value<Number>(1);
_stack.pop(); _stack.pop();
} }
@ -256,20 +256,20 @@ void program::rpn_purcentCH() {
/// ///
void program::rpn_square() { void program::rpn_square() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
if (_stack.type(0) == cmd_number) if (_stack.type(0) == kNumber)
_stack.value<Number>(0) *= _stack.value<Number>(0); _stack.value<Number>(0) *= _stack.value<Number>(0);
else if (_stack.at(0)->_type == cmd_complex) else if (_stack.at(0)->_type == kComplex)
_stack.value<Complex>(0) *= _stack.value<Complex>(0); _stack.value<Complex>(0) *= _stack.value<Complex>(0);
else else
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
/// @brief mod keyword implementation /// @brief mod keyword implementation
/// ///
void program::rpn_modulo() { void program::rpn_modulo() {
MIN_ARGUMENTS(2); MIN_ARGUMENTS(2);
ARG_MUST_BE_OF_TYPE(0, cmd_number); ARG_MUST_BE_OF_TYPE(0, kNumber);
ARG_MUST_BE_OF_TYPE(1, cmd_number); ARG_MUST_BE_OF_TYPE(1, kNumber);
_stack.value<Number>(1) = fmod(_stack.value<Number>(1), _stack.value<Number>(0)); _stack.value<Number>(1) = fmod(_stack.value<Number>(1), _stack.value<Number>(0));
_stack.pop(); _stack.pop();
} }
@ -278,13 +278,13 @@ void program::rpn_modulo() {
/// ///
void program::rpn_abs() { void program::rpn_abs() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
if (_stack.type(0) == cmd_number) { if (_stack.type(0) == kNumber) {
_stack.value<Number>(0) = abs(_stack.value<Number>(0)); _stack.value<Number>(0) = abs(_stack.value<Number>(0));
} else if (_stack.type(0) == cmd_complex) { } else if (_stack.type(0) == kComplex) {
_stack.push(new Number(abs(_stack.value<Complex>(0)))); _stack.push(new Number(abs(_stack.value<Complex>(0))));
_stack.erase(1); _stack.erase(1);
} else { } else {
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
} }
@ -292,7 +292,7 @@ void program::rpn_abs() {
/// ///
void program::rpn_fact() { void program::rpn_fact() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_number); ARG_MUST_BE_OF_TYPE(0, kNumber);
// fact(n) = gamma(n+1) // fact(n) = gamma(n+1)
_stack.value<Number>(0) = gamma(_stack.value<Number>(0) + 1); _stack.value<Number>(0) = gamma(_stack.value<Number>(0) + 1);
} }
@ -301,21 +301,21 @@ void program::rpn_fact() {
/// ///
void program::rpn_sign() { void program::rpn_sign() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
if (_stack.type(0) == cmd_number) if (_stack.type(0) == kNumber)
_stack.value<Number>(0) = sgn(_stack.value<Number>(0)); _stack.value<Number>(0) = sgn(_stack.value<Number>(0));
else if (_stack.at(0)->_type == cmd_complex) else if (_stack.at(0)->_type == kComplex)
_stack.value<Complex>(0) = _stack.value<Complex>(0) / abs(_stack.value<Complex>(0)); _stack.value<Complex>(0) = _stack.value<Complex>(0) / abs(_stack.value<Complex>(0));
else else
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
/// @brief mant keyword implementation /// @brief mant keyword implementation
/// ///
void program::rpn_mant() { void program::rpn_mant() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_number); ARG_MUST_BE_OF_TYPE(0, kNumber);
if (!isfinite(_stack.value<Number>(0))) { if (!isfinite(_stack.value<Number>(0))) {
setErrorContext(ret_out_of_range); setErrorContext(kOutOfRange);
return; return;
} }
mp_exp_t exp; mp_exp_t exp;
@ -326,9 +326,9 @@ void program::rpn_mant() {
/// ///
void program::rpn_xpon() { void program::rpn_xpon() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_number); ARG_MUST_BE_OF_TYPE(0, kNumber);
if (!isfinite(_stack.value<Number>(0))) { if (!isfinite(_stack.value<Number>(0))) {
setErrorContext(ret_out_of_range); setErrorContext(kOutOfRange);
return; return;
} }
mp_exp_t exp; mp_exp_t exp;
@ -340,7 +340,7 @@ void program::rpn_xpon() {
/// ///
void program::rpn_floor() { void program::rpn_floor() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_number); ARG_MUST_BE_OF_TYPE(0, kNumber);
_stack.value<Number>(0) = floor(_stack.value<Number>(0)); _stack.value<Number>(0) = floor(_stack.value<Number>(0));
} }
@ -348,7 +348,7 @@ void program::rpn_floor() {
/// ///
void program::rpn_ceil() { void program::rpn_ceil() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_number); ARG_MUST_BE_OF_TYPE(0, kNumber);
_stack.value<Number>(0) = ceil(_stack.value<Number>(0)); _stack.value<Number>(0) = ceil(_stack.value<Number>(0));
} }
@ -356,7 +356,7 @@ void program::rpn_ceil() {
/// ///
void program::rpn_fp() { void program::rpn_fp() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_number); ARG_MUST_BE_OF_TYPE(0, kNumber);
_stack.value<Number>(0) = frac(_stack.value<Number>(0)); _stack.value<Number>(0) = frac(_stack.value<Number>(0));
} }
@ -364,7 +364,7 @@ void program::rpn_fp() {
/// ///
void program::rpn_ip() { void program::rpn_ip() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_number); ARG_MUST_BE_OF_TYPE(0, kNumber);
_stack.value<Number>(0) = trunc(_stack.value<Number>(0)); _stack.value<Number>(0) = trunc(_stack.value<Number>(0));
} }
@ -372,8 +372,8 @@ void program::rpn_ip() {
/// ///
void program::rpn_min() { void program::rpn_min() {
MIN_ARGUMENTS(2); MIN_ARGUMENTS(2);
ARG_MUST_BE_OF_TYPE(0, cmd_number); ARG_MUST_BE_OF_TYPE(0, kNumber);
ARG_MUST_BE_OF_TYPE(1, cmd_number); ARG_MUST_BE_OF_TYPE(1, kNumber);
_stack.value<Number>(0) = min(_stack.value<Number>(0), _stack.value<Number>(1)); _stack.value<Number>(0) = min(_stack.value<Number>(0), _stack.value<Number>(1));
_stack.erase(1); _stack.erase(1);
} }
@ -382,8 +382,8 @@ void program::rpn_min() {
/// ///
void program::rpn_max() { void program::rpn_max() {
MIN_ARGUMENTS(2); MIN_ARGUMENTS(2);
ARG_MUST_BE_OF_TYPE(0, cmd_number); ARG_MUST_BE_OF_TYPE(0, kNumber);
ARG_MUST_BE_OF_TYPE(1, cmd_number); ARG_MUST_BE_OF_TYPE(1, kNumber);
_stack.value<Number>(0) = max(_stack.value<Number>(0), _stack.value<Number>(1)); _stack.value<Number>(0) = max(_stack.value<Number>(0), _stack.value<Number>(1));
_stack.erase(1); _stack.erase(1);
} }

View file

@ -29,7 +29,7 @@ void program::rpn_drop2(void) {
/// ///
void program::rpn_dropn(void) { void program::rpn_dropn(void) {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_number); ARG_MUST_BE_OF_TYPE(0, kNumber);
int args = static_cast<int>(_stack.value<Number>(0).toLong()); int args = static_cast<int>(_stack.value<Number>(0).toLong());
MIN_ARGUMENTS(args + 1); MIN_ARGUMENTS(args + 1);
@ -51,7 +51,7 @@ void program::rpn_dup(void) {
/// ///
void program::rpn_dupn(void) { void program::rpn_dupn(void) {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_number); ARG_MUST_BE_OF_TYPE(0, kNumber);
int args = static_cast<int>(_stack.value<Number>(0).toLong()); int args = static_cast<int>(_stack.value<Number>(0).toLong());
_stack.pop(); _stack.pop();
@ -72,14 +72,14 @@ void program::rpn_dup2(void) {
/// ///
void program::rpn_pick(void) { void program::rpn_pick(void) {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_number); ARG_MUST_BE_OF_TYPE(0, kNumber);
int to_pick = static_cast<int>(_stack.value<Number>(0).toLong()); int to_pick = static_cast<int>(_stack.value<Number>(0).toLong());
_stack.pop(); _stack.pop();
// treat stack depth errors // treat stack depth errors
if ((to_pick == 0) || (to_pick > _stack.size())) { if ((to_pick == 0) || (to_pick > _stack.size())) {
setErrorContext(ret_out_of_range); setErrorContext(kOutOfRange);
return; return;
} }
@ -103,7 +103,7 @@ void program::rpn_depth(void) { _stack.push_front(new Number(_stack.size())); }
/// ///
void program::rpn_roll(void) { void program::rpn_roll(void) {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_number); ARG_MUST_BE_OF_TYPE(0, kNumber);
int args = static_cast<int>(_stack.value<Number>(0).toLong()); int args = static_cast<int>(_stack.value<Number>(0).toLong());
_stack.pop(); _stack.pop();
@ -118,7 +118,7 @@ void program::rpn_roll(void) {
/// ///
void program::rpn_rolld(void) { void program::rpn_rolld(void) {
MIN_ARGUMENTS(2); MIN_ARGUMENTS(2);
ARG_MUST_BE_OF_TYPE(0, cmd_number); ARG_MUST_BE_OF_TYPE(0, kNumber);
int args = static_cast<int>(_stack.value<Number>(0).toLong()); int args = static_cast<int>(_stack.value<Number>(0).toLong());
_stack.pop(); _stack.pop();

View file

@ -7,7 +7,7 @@
/// ///
void program::rpn_sto(void) { void program::rpn_sto(void) {
MIN_ARGUMENTS(2); MIN_ARGUMENTS(2);
ARG_MUST_BE_OF_TYPE(0, cmd_symbol); ARG_MUST_BE_OF_TYPE(0, kSymbol);
// store symbol with first value // store symbol with first value
const auto it = _heap.find(_stack.value<String>(0)); const auto it = _heap.find(_stack.value<String>(0));
@ -23,9 +23,9 @@ void program::rpn_sto(void) {
/// ///
void program::rpn_stoadd(void) { void program::rpn_stoadd(void) {
MIN_ARGUMENTS(2); MIN_ARGUMENTS(2);
ARG_MUST_BE_OF_TYPE(0, cmd_symbol); ARG_MUST_BE_OF_TYPE(0, kSymbol);
if (_heap.find(_stack.value<String>(0)) == _heap.end()) { if (_heap.find(_stack.value<String>(0)) == _heap.end()) {
setErrorContext(ret_unknown_variable); setErrorContext(kUnknownVariable);
return; return;
} }
rpn_dup(); rpn_dup();
@ -40,9 +40,9 @@ void program::rpn_stoadd(void) {
/// ///
void program::rpn_stosub(void) { void program::rpn_stosub(void) {
MIN_ARGUMENTS(2); MIN_ARGUMENTS(2);
ARG_MUST_BE_OF_TYPE(0, cmd_symbol); ARG_MUST_BE_OF_TYPE(0, kSymbol);
if (_heap.find(_stack.value<String>(0)) == _heap.end()) { if (_heap.find(_stack.value<String>(0)) == _heap.end()) {
setErrorContext(ret_unknown_variable); setErrorContext(kUnknownVariable);
return; return;
} }
rpn_dup(); rpn_dup();
@ -57,9 +57,9 @@ void program::rpn_stosub(void) {
/// ///
void program::rpn_stomul(void) { void program::rpn_stomul(void) {
MIN_ARGUMENTS(2); MIN_ARGUMENTS(2);
ARG_MUST_BE_OF_TYPE(0, cmd_symbol); ARG_MUST_BE_OF_TYPE(0, kSymbol);
if (_heap.find(_stack.value<String>(0)) == _heap.end()) { if (_heap.find(_stack.value<String>(0)) == _heap.end()) {
setErrorContext(ret_unknown_variable); setErrorContext(kUnknownVariable);
return; return;
} }
rpn_dup(); rpn_dup();
@ -74,9 +74,9 @@ void program::rpn_stomul(void) {
/// ///
void program::rpn_stodiv(void) { void program::rpn_stodiv(void) {
MIN_ARGUMENTS(2); MIN_ARGUMENTS(2);
ARG_MUST_BE_OF_TYPE(0, cmd_symbol); ARG_MUST_BE_OF_TYPE(0, kSymbol);
if (_heap.find(_stack.value<String>(0)) == _heap.end()) { if (_heap.find(_stack.value<String>(0)) == _heap.end()) {
setErrorContext(ret_unknown_variable); setErrorContext(kUnknownVariable);
return; return;
} }
rpn_dup(); rpn_dup();
@ -91,9 +91,9 @@ void program::rpn_stodiv(void) {
/// ///
void program::rpn_stoneg(void) { void program::rpn_stoneg(void) {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_symbol); ARG_MUST_BE_OF_TYPE(0, kSymbol);
if (_heap.find(_stack.value<String>(0)) == _heap.end()) { if (_heap.find(_stack.value<String>(0)) == _heap.end()) {
setErrorContext(ret_unknown_variable); setErrorContext(kUnknownVariable);
return; return;
} }
rpn_dup(); rpn_dup();
@ -107,9 +107,9 @@ void program::rpn_stoneg(void) {
/// ///
void program::rpn_stoinv(void) { void program::rpn_stoinv(void) {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_symbol); ARG_MUST_BE_OF_TYPE(0, kSymbol);
if (_heap.find(_stack.value<String>(0)) == _heap.end()) { if (_heap.find(_stack.value<String>(0)) == _heap.end()) {
setErrorContext(ret_unknown_variable); setErrorContext(kUnknownVariable);
return; return;
} }
rpn_dup(); rpn_dup();
@ -123,7 +123,7 @@ void program::rpn_stoinv(void) {
/// ///
void program::rpn_rcl(void) { void program::rpn_rcl(void) {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_symbol); ARG_MUST_BE_OF_TYPE(0, kSymbol);
// recall a variable // recall a variable
Object* obj; Object* obj;
@ -134,7 +134,7 @@ void program::rpn_rcl(void) {
(void)_stack.pop(); (void)_stack.pop();
_stack.push_front(obj->clone()); _stack.push_front(obj->clone());
} else { } else {
setErrorContext(ret_unknown_variable); setErrorContext(kUnknownVariable);
} }
} }
@ -165,7 +165,7 @@ void program::auto_rcl(Symbol* symb) {
// mind the order of heaps // mind the order of heaps
if (find_variable(variable, obj)) { if (find_variable(variable, obj)) {
_stack.push_front(obj->clone()); _stack.push_front(obj->clone());
if (obj->_type == cmd_program) rpn_eval(); if (obj->_type == kProgram) rpn_eval();
} else { } else {
_stack.push_front(symb->clone()); _stack.push_front(symb->clone());
} }
@ -178,14 +178,14 @@ void program::auto_rcl(Symbol* symb) {
/// ///
void program::rpn_purge(void) { void program::rpn_purge(void) {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_symbol); ARG_MUST_BE_OF_TYPE(0, kSymbol);
const auto i = _heap.find(_stack.value<Symbol>(0)); const auto i = _heap.find(_stack.value<Symbol>(0));
if (i != _heap.end()) { if (i != _heap.end()) {
delete i->second; delete i->second;
_heap.erase(i); _heap.erase(i);
} else { } else {
setErrorContext(ret_unknown_variable); setErrorContext(kUnknownVariable);
} }
_stack.pop(); _stack.pop();
} }

View file

@ -10,7 +10,7 @@ void program::rpn_instr() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
// stringify only if not already a string // stringify only if not already a string
if (_stack.type(0) != cmd_string) { if (_stack.type(0) != kString) {
stringstream ss; stringstream ss;
ss << _stack.at(0); ss << _stack.at(0);
_stack.pop(); _stack.pop();
@ -22,14 +22,14 @@ void program::rpn_instr() {
/// ///
void program::rpn_strout() { void program::rpn_strout() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_string); ARG_MUST_BE_OF_TYPE(0, kString);
string entry(_stack.value<String>(0)); string entry(_stack.value<String>(0));
program prog(_stack, _heap); program prog(_stack, _heap);
_stack.pop(); _stack.pop();
// make program from string in stack level 1 // make program from string in stack level 1
if (prog.parse(entry) == ret_ok) if (prog.parse(entry) == kOk)
// run it // run it
prog.run(); prog.run();
} }
@ -38,7 +38,7 @@ void program::rpn_strout() {
/// ///
void program::rpn_chr() { void program::rpn_chr() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_number); ARG_MUST_BE_OF_TYPE(0, kNumber);
char the_chr = static_cast<char>(_stack.value<Number>(0).toLong()); char the_chr = static_cast<char>(_stack.value<Number>(0).toLong());
_stack.pop(); _stack.pop();
if (the_chr < 32 || the_chr > 126) the_chr = '.'; if (the_chr < 32 || the_chr > 126) the_chr = '.';
@ -49,7 +49,7 @@ void program::rpn_chr() {
/// ///
void program::rpn_num() { void program::rpn_num() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_string); ARG_MUST_BE_OF_TYPE(0, kString);
if (_stack.value<String>(0).size() > 0) if (_stack.value<String>(0).size() > 0)
_stack.push_front(new Number(_stack.value<String>(0)[0])); _stack.push_front(new Number(_stack.value<String>(0)[0]));
else else
@ -61,7 +61,7 @@ void program::rpn_num() {
/// ///
void program::rpn_strsize() { void program::rpn_strsize() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_string); ARG_MUST_BE_OF_TYPE(0, kString);
_stack.push_front(new Number(_stack.value<String>(0).size())); _stack.push_front(new Number(_stack.value<String>(0).size()));
_stack.erase(1); _stack.erase(1);
} }
@ -70,8 +70,8 @@ void program::rpn_strsize() {
/// ///
void program::rpn_strpos() { void program::rpn_strpos() {
MIN_ARGUMENTS(2); MIN_ARGUMENTS(2);
ARG_MUST_BE_OF_TYPE(0, cmd_string); ARG_MUST_BE_OF_TYPE(0, kString);
ARG_MUST_BE_OF_TYPE(1, cmd_string); ARG_MUST_BE_OF_TYPE(1, kString);
size_t pos = _stack.value<String>(1).find(_stack.value<String>(0)) + 1; size_t pos = _stack.value<String>(1).find(_stack.value<String>(0)) + 1;
_stack.erase(0, 2); _stack.erase(0, 2);
@ -82,9 +82,9 @@ void program::rpn_strpos() {
/// ///
void program::rpn_strsub() { void program::rpn_strsub() {
MIN_ARGUMENTS(3); MIN_ARGUMENTS(3);
ARG_MUST_BE_OF_TYPE(0, cmd_number); ARG_MUST_BE_OF_TYPE(0, kNumber);
ARG_MUST_BE_OF_TYPE(1, cmd_number); ARG_MUST_BE_OF_TYPE(1, kNumber);
ARG_MUST_BE_OF_TYPE(2, cmd_string); ARG_MUST_BE_OF_TYPE(2, kString);
size_t first = _stack.value<Number>(1).toULong(); size_t first = _stack.value<Number>(1).toULong();
size_t len = _stack.value<Number>(0).toULong() - first + 1; size_t len = _stack.value<Number>(0).toULong() - first + 1;

View file

@ -69,7 +69,7 @@ static void testShowResult(string title, int tests, int tests_failed, int steps,
/// ///
void program::rpn_test() { void program::rpn_test() {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_string); ARG_MUST_BE_OF_TYPE(0, kString);
int total_tests = 0; int total_tests = 0;
int total_tests_failed = 0; int total_tests_failed = 0;
@ -84,7 +84,7 @@ void program::rpn_test() {
// notify to caller that test succeeded or not // notify to caller that test succeeded or not
if (total_tests_failed > 0) { if (total_tests_failed > 0) {
_err = ret_test_failed; _err = kTestFailed;
_err_context = string("rpn version ") + RPN_VERSION + ", test file " + test_filename; _err_context = string("rpn version ") + RPN_VERSION + ", test file " + test_filename;
} }
} }
@ -113,7 +113,7 @@ void program::test(string test_filename, int& total_tests, int& total_tests_fail
if (test_file.is_open()) { if (test_file.is_open()) {
string test_title; string test_title;
string entry; string entry;
ret_value ret; RetValue ret;
rpnstack stk; rpnstack stk;
heap hp; heap hp;
bool failed = false; bool failed = false;
@ -246,7 +246,7 @@ void program::test(string test_filename, int& total_tests, int& total_tests_fail
if (!entry.empty()) { if (!entry.empty()) {
program prog(stk, hp); program prog(stk, hp);
ret = prog.parse(entry); ret = prog.parse(entry);
if (ret == ret_ok) { if (ret == kOk) {
// run it // run it
(void)prog.run(); (void)prog.run();
last_err = static_cast<int>(prog.get_err()); last_err = static_cast<int>(prog.get_err());

View file

@ -19,14 +19,14 @@ static int CmpStringOnStackTop(rpnstack& stk) {
/// ///
void program::rpn_sup(void) { void program::rpn_sup(void) {
MIN_ARGUMENTS(2); MIN_ARGUMENTS(2);
if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) { if (_stack.type(0) == kNumber && _stack.type(1) == kNumber) {
_stack.push_front(new Number(_stack.value<Number>(1) > _stack.value<Number>(0))); _stack.push_front(new Number(_stack.value<Number>(1) > _stack.value<Number>(0)));
_stack.erase(1, 2); _stack.erase(1, 2);
} else if (_stack.type(0) == cmd_string && _stack.type(1) == cmd_string) { } else if (_stack.type(0) == kString && _stack.type(1) == kString) {
_stack.push_front(new Number(CmpStringOnStackTop(_stack) == 1)); _stack.push_front(new Number(CmpStringOnStackTop(_stack) == 1));
_stack.erase(1, 2); _stack.erase(1, 2);
} else { } else {
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
} }
@ -34,14 +34,14 @@ void program::rpn_sup(void) {
/// ///
void program::rpn_sup_eq(void) { void program::rpn_sup_eq(void) {
MIN_ARGUMENTS(2); MIN_ARGUMENTS(2);
if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) { if (_stack.type(0) == kNumber && _stack.type(1) == kNumber) {
_stack.push_front(new Number(_stack.value<Number>(1) >= _stack.value<Number>(0))); _stack.push_front(new Number(_stack.value<Number>(1) >= _stack.value<Number>(0)));
_stack.erase(1, 2); _stack.erase(1, 2);
} else if (_stack.type(0) == cmd_string && _stack.type(1) == cmd_string) { } else if (_stack.type(0) == kString && _stack.type(1) == kString) {
_stack.push_front(new Number(CmpStringOnStackTop(_stack) != -1)); _stack.push_front(new Number(CmpStringOnStackTop(_stack) != -1));
_stack.erase(1, 2); _stack.erase(1, 2);
} else { } else {
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
} }
@ -50,14 +50,14 @@ void program::rpn_sup_eq(void) {
void program::rpn_inf(void) { void program::rpn_inf(void) {
MIN_ARGUMENTS(2); MIN_ARGUMENTS(2);
if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) { if (_stack.type(0) == kNumber && _stack.type(1) == kNumber) {
_stack.push_front(new Number(_stack.value<Number>(1) < _stack.value<Number>(0))); _stack.push_front(new Number(_stack.value<Number>(1) < _stack.value<Number>(0)));
_stack.erase(1, 2); _stack.erase(1, 2);
} else if (_stack.type(0) == cmd_string && _stack.type(1) == cmd_string) { } else if (_stack.type(0) == kString && _stack.type(1) == kString) {
_stack.push_front(new Number(CmpStringOnStackTop(_stack) == -1)); _stack.push_front(new Number(CmpStringOnStackTop(_stack) == -1));
_stack.erase(1, 2); _stack.erase(1, 2);
} else { } else {
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
} }
@ -65,14 +65,14 @@ void program::rpn_inf(void) {
/// ///
void program::rpn_inf_eq(void) { void program::rpn_inf_eq(void) {
MIN_ARGUMENTS(2); MIN_ARGUMENTS(2);
if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) { if (_stack.type(0) == kNumber && _stack.type(1) == kNumber) {
_stack.push_front(new Number(_stack.value<Number>(1) <= _stack.value<Number>(0))); _stack.push_front(new Number(_stack.value<Number>(1) <= _stack.value<Number>(0)));
_stack.erase(1, 2); _stack.erase(1, 2);
} else if (_stack.type(0) == cmd_string && _stack.type(1) == cmd_string) { } else if (_stack.type(0) == kString && _stack.type(1) == kString) {
_stack.push_front(new Number(CmpStringOnStackTop(_stack) != 1)); _stack.push_front(new Number(CmpStringOnStackTop(_stack) != 1));
_stack.erase(1, 2); _stack.erase(1, 2);
} else { } else {
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
} }
@ -80,17 +80,17 @@ void program::rpn_inf_eq(void) {
/// ///
void program::rpn_diff(void) { void program::rpn_diff(void) {
MIN_ARGUMENTS(2); MIN_ARGUMENTS(2);
if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) { if (_stack.type(0) == kNumber && _stack.type(1) == kNumber) {
_stack.push_front(new Number(_stack.value<Number>(1) != _stack.value<Number>(0))); _stack.push_front(new Number(_stack.value<Number>(1) != _stack.value<Number>(0)));
_stack.erase(1, 2); _stack.erase(1, 2);
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_complex) { } else if (_stack.type(0) == kComplex && _stack.type(1) == kComplex) {
_stack.push_front(new Number(_stack.value<Complex>(1) != _stack.value<Complex>(0))); _stack.push_front(new Number(_stack.value<Complex>(1) != _stack.value<Complex>(0)));
_stack.erase(1, 2); _stack.erase(1, 2);
} else if (_stack.type(0) == cmd_string && _stack.type(1) == cmd_string) { } else if (_stack.type(0) == kString && _stack.type(1) == kString) {
_stack.push_front(new Number(CmpStringOnStackTop(_stack) != 0)); _stack.push_front(new Number(CmpStringOnStackTop(_stack) != 0));
_stack.erase(1, 2); _stack.erase(1, 2);
} else { } else {
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
} }
@ -98,17 +98,17 @@ void program::rpn_diff(void) {
/// ///
void program::rpn_eq(void) { void program::rpn_eq(void) {
MIN_ARGUMENTS(2); MIN_ARGUMENTS(2);
if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) { if (_stack.type(0) == kNumber && _stack.type(1) == kNumber) {
_stack.push_front(new Number(_stack.value<Number>(1) == _stack.value<Number>(0))); _stack.push_front(new Number(_stack.value<Number>(1) == _stack.value<Number>(0)));
_stack.erase(1, 2); _stack.erase(1, 2);
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_complex) { } else if (_stack.type(0) == kComplex && _stack.type(1) == kComplex) {
_stack.push_front(new Number(_stack.value<Complex>(1) == _stack.value<Complex>(0))); _stack.push_front(new Number(_stack.value<Complex>(1) == _stack.value<Complex>(0)));
_stack.erase(1, 2); _stack.erase(1, 2);
} else if (_stack.type(0) == cmd_string && _stack.type(1) == cmd_string) { } else if (_stack.type(0) == kString && _stack.type(1) == kString) {
_stack.push_front(new Number(CmpStringOnStackTop(_stack) == 0)); _stack.push_front(new Number(CmpStringOnStackTop(_stack) == 0));
_stack.erase(1, 2); _stack.erase(1, 2);
} else { } else {
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
} }
@ -116,8 +116,8 @@ void program::rpn_eq(void) {
/// ///
void program::rpn_test_and(void) { void program::rpn_test_and(void) {
MIN_ARGUMENTS(2); MIN_ARGUMENTS(2);
ARG_MUST_BE_OF_TYPE(0, cmd_number); ARG_MUST_BE_OF_TYPE(0, kNumber);
ARG_MUST_BE_OF_TYPE(1, cmd_number); ARG_MUST_BE_OF_TYPE(1, kNumber);
if (_stack.value<Number>(0) != 0 && _stack.value<Number>(1) != 0) if (_stack.value<Number>(0) != 0 && _stack.value<Number>(1) != 0)
_stack.push(new Number(1)); _stack.push(new Number(1));
else else
@ -129,8 +129,8 @@ void program::rpn_test_and(void) {
/// ///
void program::rpn_test_or(void) { void program::rpn_test_or(void) {
MIN_ARGUMENTS(2); MIN_ARGUMENTS(2);
ARG_MUST_BE_OF_TYPE(0, cmd_number); ARG_MUST_BE_OF_TYPE(0, kNumber);
ARG_MUST_BE_OF_TYPE(1, cmd_number); ARG_MUST_BE_OF_TYPE(1, kNumber);
if (_stack.value<Number>(0) != 0 || _stack.value<Number>(1) != 0) if (_stack.value<Number>(0) != 0 || _stack.value<Number>(1) != 0)
_stack.push(new Number(1)); _stack.push(new Number(1));
else else
@ -142,8 +142,8 @@ void program::rpn_test_or(void) {
/// ///
void program::rpn_test_xor(void) { void program::rpn_test_xor(void) {
MIN_ARGUMENTS(2); MIN_ARGUMENTS(2);
ARG_MUST_BE_OF_TYPE(0, cmd_number); ARG_MUST_BE_OF_TYPE(0, kNumber);
ARG_MUST_BE_OF_TYPE(1, cmd_number); ARG_MUST_BE_OF_TYPE(1, kNumber);
if (_stack.value<Number>(0) != 0 ^ _stack.value<Number>(1) != 0) if (_stack.value<Number>(0) != 0 ^ _stack.value<Number>(1) != 0)
_stack.push(new Number(1)); _stack.push(new Number(1));
else else
@ -155,7 +155,7 @@ void program::rpn_test_xor(void) {
/// ///
void program::rpn_test_not(void) { void program::rpn_test_not(void) {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_number); ARG_MUST_BE_OF_TYPE(0, kNumber);
_stack.push(new Number(_stack.value<Number>(0) == 0 ? 1 : 0)); _stack.push(new Number(_stack.value<Number>(0) == 0 ? 1 : 0));
_stack.erase(1, 1); _stack.erase(1, 1);

View file

@ -25,7 +25,7 @@ void program::rpn_time() {
_stack.push(new Number(date)); _stack.push(new Number(date));
_stack.value<Number>(0) /= 10000000000.0; _stack.value<Number>(0) /= 10000000000.0;
} else { } else {
setErrorContext(ret_internal); setErrorContext(kInternalError);
} }
} }
@ -51,7 +51,7 @@ void program::rpn_date() {
_stack.push(new Number(date)); _stack.push(new Number(date));
_stack.value<Number>(0) /= 1000000.0; _stack.value<Number>(0) /= 1000000.0;
} else { } else {
setErrorContext(ret_internal); setErrorContext(kInternalError);
} }
} }
@ -71,6 +71,6 @@ void program::rpn_ticks() {
date = 1000000.0 * static_cast<double>(ts.tv_sec) + static_cast<double>(ts.tv_nsec / 1000); date = 1000000.0 * static_cast<double>(ts.tv_sec) + static_cast<double>(ts.tv_nsec / 1000);
_stack.push(new Number(date)); _stack.push(new Number(date));
} else { } else {
setErrorContext(ret_internal); setErrorContext(kInternalError);
} }
} }

View file

@ -12,7 +12,7 @@ void program::rpn_pi(void) {
/// ///
void program::rpn_d2r(void) { void program::rpn_d2r(void) {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_number); ARG_MUST_BE_OF_TYPE(0, kNumber);
_stack.value<Number>(0) *= mpfr::const_pi(); _stack.value<Number>(0) *= mpfr::const_pi();
_stack.value<Number>(0) /= 180; _stack.value<Number>(0) /= 180;
} }
@ -21,7 +21,7 @@ void program::rpn_d2r(void) {
/// ///
void program::rpn_r2d(void) { void program::rpn_r2d(void) {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_number); ARG_MUST_BE_OF_TYPE(0, kNumber);
_stack.value<Number>(0) /= mpfr::const_pi(); _stack.value<Number>(0) /= mpfr::const_pi();
_stack.value<Number>(0) *= 180; _stack.value<Number>(0) *= 180;
} }
@ -30,70 +30,70 @@ void program::rpn_r2d(void) {
/// ///
void program::rpn_sin(void) { void program::rpn_sin(void) {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
if (_stack.type(0) == cmd_number) if (_stack.type(0) == kNumber)
_stack.value<Number>(0) = sin(_stack.value<Number>(0)); _stack.value<Number>(0) = sin(_stack.value<Number>(0));
else if (_stack.type(0) == cmd_complex) else if (_stack.type(0) == kComplex)
_stack.value<Complex>(0) = sin(_stack.value<Complex>(0)); _stack.value<Complex>(0) = sin(_stack.value<Complex>(0));
else else
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
/// @brief asin keyword implementation /// @brief asin keyword implementation
/// ///
void program::rpn_asin(void) { void program::rpn_asin(void) {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
if (_stack.type(0) == cmd_number) if (_stack.type(0) == kNumber)
_stack.value<Number>(0) = asin(_stack.value<Number>(0)); _stack.value<Number>(0) = asin(_stack.value<Number>(0));
else if (_stack.type(0) == cmd_complex) else if (_stack.type(0) == kComplex)
_stack.value<Complex>(0) = asin(_stack.value<Complex>(0)); _stack.value<Complex>(0) = asin(_stack.value<Complex>(0));
else else
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
/// @brief cos keyword implementation /// @brief cos keyword implementation
/// ///
void program::rpn_cos(void) { void program::rpn_cos(void) {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
if (_stack.type(0) == cmd_number) if (_stack.type(0) == kNumber)
_stack.value<Number>(0) = cos(_stack.value<Number>(0)); _stack.value<Number>(0) = cos(_stack.value<Number>(0));
else if (_stack.type(0) == cmd_complex) else if (_stack.type(0) == kComplex)
_stack.value<Complex>(0) = cos(_stack.value<Complex>(0)); _stack.value<Complex>(0) = cos(_stack.value<Complex>(0));
else else
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
/// @brief acos keyword implementation /// @brief acos keyword implementation
/// ///
void program::rpn_acos(void) { void program::rpn_acos(void) {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
if (_stack.type(0) == cmd_number) if (_stack.type(0) == kNumber)
_stack.value<Number>(0) = acos(_stack.value<Number>(0)); _stack.value<Number>(0) = acos(_stack.value<Number>(0));
else if (_stack.type(0) == cmd_complex) else if (_stack.type(0) == kComplex)
_stack.value<Complex>(0) = acos(_stack.value<Complex>(0)); _stack.value<Complex>(0) = acos(_stack.value<Complex>(0));
else else
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
/// @brief tan keyword implementation /// @brief tan keyword implementation
/// ///
void program::rpn_tan(void) { void program::rpn_tan(void) {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
if (_stack.type(0) == cmd_number) if (_stack.type(0) == kNumber)
_stack.value<Number>(0) = tan(_stack.value<Number>(0)); _stack.value<Number>(0) = tan(_stack.value<Number>(0));
else if (_stack.type(0) == cmd_complex) else if (_stack.type(0) == kComplex)
_stack.value<Complex>(0) = tan(_stack.value<Complex>(0)); _stack.value<Complex>(0) = tan(_stack.value<Complex>(0));
else else
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }
/// @brief atan keyword implementation /// @brief atan keyword implementation
/// ///
void program::rpn_atan(void) { void program::rpn_atan(void) {
MIN_ARGUMENTS(1); MIN_ARGUMENTS(1);
if (_stack.type(0) == cmd_number) if (_stack.type(0) == kNumber)
_stack.value<Number>(0) = atan(_stack.value<Number>(0)); _stack.value<Number>(0) = atan(_stack.value<Number>(0));
else if (_stack.type(0) == cmd_complex) else if (_stack.type(0) == kComplex)
_stack.value<Complex>(0) = atan(_stack.value<Complex>(0)); _stack.value<Complex>(0) = atan(_stack.value<Complex>(0));
else else
setErrorContext(ret_bad_operand_type); setErrorContext(kBadOperandType);
} }

View file

@ -32,7 +32,7 @@ class rpnstack : public deque<Object*> {
// access helpers // access helpers
// //
cmd_type_t type(int level) { ObjectType type(int level) {
// carefull: caller must ensure that level is correct // carefull: caller must ensure that level is correct
return at(level)->_type; return at(level)->_type;
} }