mirror of
https://github.com/louisrubet/rpn
synced 2025-02-01 07:57:52 +01:00
struct and class names
This commit is contained in:
parent
2a980eb74d
commit
327229dda4
19 changed files with 586 additions and 585 deletions
|
@ -71,7 +71,7 @@ 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({kSymbol, .value = entry.substr(idx + 1, i - idx - 1), .autoEval = false});
|
elements.push_back({kSymbol, .value = entry.substr(idx + 1, i - idx - 1), .auto_eval = false});
|
||||||
next_idx = i + 1;
|
next_idx = i + 1;
|
||||||
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({kNumber, .re = r, .reBase = base});
|
elements.push_back({kNumber, .re = r, .re_base = base});
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
errors.push_back({entry.size(), "unterminated number"});
|
errors.push_back({entry.size(), "unterminated number"});
|
||||||
|
@ -197,13 +197,13 @@ bool Lexer::parseComplex(string& entry, size_t idx, size_t& next_idx, vector<Syn
|
||||||
vector<SynElement>& elements) {
|
vector<SynElement>& elements) {
|
||||||
mpreal* re = nullptr;
|
mpreal* re = nullptr;
|
||||||
mpreal* im = nullptr;
|
mpreal* im = nullptr;
|
||||||
int reBase, imBase = 10;
|
int re_base, im_base = 10;
|
||||||
if (idx + 1 == entry.size()) {
|
if (idx + 1 == entry.size()) {
|
||||||
elements.push_back({kSymbol, .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, re_base, &re, ',')) {
|
||||||
elements.push_back({kSymbol, .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
|
||||||
|
@ -218,14 +218,14 @@ bool Lexer::parseComplex(string& entry, size_t idx, size_t& next_idx, vector<Syn
|
||||||
return true; // complex format error, return a symbol
|
return true; // complex format error, return a symbol
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!getNumberAt(entry, i, next_idx, imBase, &im, ')')) {
|
if (!getNumberAt(entry, i, next_idx, im_base, &im, ')')) {
|
||||||
elements.push_back({kSymbol, .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({kComplex, .re = re, .im = im, .reBase = reBase, .imBase = imBase});
|
elements.push_back({kComplex, .re = re, .im = im, .re_base = re_base, .im_base = im_base});
|
||||||
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({kSymbol, .value = token, .autoEval = true});
|
elements.push_back({kSymbol, .value = token, .auto_eval = true});
|
||||||
next_idx = token.size() + idx;
|
next_idx = token.size() + idx;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,10 +23,10 @@ class Lexer {
|
||||||
string value;
|
string value;
|
||||||
mpreal* re;
|
mpreal* re;
|
||||||
mpreal* im;
|
mpreal* im;
|
||||||
int reBase;
|
int re_base;
|
||||||
int imBase;
|
int im_base;
|
||||||
program_fn_t fn;
|
program_fn_t fn;
|
||||||
bool autoEval;
|
bool auto_eval;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SynError {
|
struct SynError {
|
||||||
|
|
|
@ -3,5 +3,5 @@
|
||||||
#include "object.hpp"
|
#include "object.hpp"
|
||||||
|
|
||||||
// number statics
|
// number statics
|
||||||
Number::mode_enum Number::s_mode = Number::DEFAULT_MODE;
|
Number::mode_enum Number::mode = Number::DEFAULT_MODE;
|
||||||
int Number::s_digits = DEFAULT_DECIMAL_DIGITS;
|
int Number::digits = kDefaultDecimalDigits;
|
||||||
|
|
|
@ -6,14 +6,14 @@
|
||||||
#include <mpreal.h>
|
#include <mpreal.h>
|
||||||
using mpfr::mpreal;
|
using mpfr::mpreal;
|
||||||
|
|
||||||
#include <ostream>
|
|
||||||
#include <string>
|
|
||||||
#include <sstream>
|
|
||||||
#include <complex>
|
#include <complex>
|
||||||
|
#include <ostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
using std::complex;
|
||||||
using std::ostream;
|
using std::ostream;
|
||||||
using std::string;
|
using std::string;
|
||||||
using std::stringstream;
|
using std::stringstream;
|
||||||
using std::complex;
|
|
||||||
|
|
||||||
#include "mpreal-out.hpp"
|
#include "mpreal-out.hpp"
|
||||||
|
|
||||||
|
@ -83,25 +83,25 @@ struct Object {
|
||||||
///
|
///
|
||||||
struct Number : Object {
|
struct Number : Object {
|
||||||
Number() : Object(kNumber), base(10) {}
|
Number() : Object(kNumber), base(10) {}
|
||||||
explicit Number(const mpreal& value_, int base_ = 10) : Object(kNumber), 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(kNumber), 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;
|
||||||
|
|
||||||
virtual Object* clone() { return new Number(value, base); }
|
virtual Object* clone() { return new Number(value, base); }
|
||||||
virtual string name() { return string("number"); }
|
virtual string name() { return string("number"); }
|
||||||
virtual ostream& show(ostream& out) { return showValue(out, value, s_mode, s_digits, base); }
|
virtual ostream& show(ostream& out) { return showValue(out, value, mode, digits, base); }
|
||||||
|
|
||||||
// representation mode
|
// representation mode
|
||||||
typedef enum { kStd, kFix, kSci } mode_enum;
|
typedef enum { kStd, kFix, kSci } mode_enum;
|
||||||
static mode_enum s_mode;
|
static mode_enum mode;
|
||||||
static constexpr mode_enum DEFAULT_MODE = Number::kStd;
|
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 kMpfrDefaultPrecBits = 128;
|
||||||
static constexpr int DEFAULT_DECIMAL_DIGITS = 38;
|
static constexpr int kDefaultDecimalDigits = 38;
|
||||||
static int s_digits;
|
static int digits;
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static string _makeNumberFormat(mode_enum mode, int digits) {
|
static string _makeNumberFormat(mode_enum mode, int digits) {
|
||||||
|
@ -118,7 +118,7 @@ struct Number : Object {
|
||||||
|
|
||||||
static ostream& showValue(ostream& out, const mpreal& value, mode_enum mode, int digits, int base) {
|
static ostream& showValue(ostream& out, const mpreal& value, mode_enum mode, int digits, int base) {
|
||||||
if (base == 10)
|
if (base == 10)
|
||||||
return MprealOutput10Base(out, _makeNumberFormat(s_mode, s_digits), value);
|
return MprealOutput10Base(out, _makeNumberFormat(mode, digits), value);
|
||||||
else
|
else
|
||||||
return MprealOutputNBase(out, base, value);
|
return MprealOutputNBase(out, base, value);
|
||||||
}
|
}
|
||||||
|
@ -127,34 +127,34 @@ struct Number : Object {
|
||||||
/// @brief stack objects inheriting Object
|
/// @brief stack objects inheriting Object
|
||||||
///
|
///
|
||||||
struct Complex : Object {
|
struct Complex : Object {
|
||||||
Complex() : Object(kComplex), reBase(10), imBase(10) {}
|
Complex() : Object(kComplex), re_base(10), im_base(10) {}
|
||||||
explicit Complex(complex<mpreal>& value_, int reb = 10, int imb = 10)
|
explicit Complex(complex<mpreal>& value__, int re_base__ = 10, int im_base__ = 10)
|
||||||
: Object(kComplex), reBase(reb), imBase(imb) {
|
: Object(kComplex), re_base(re_base__), im_base(im_base__) {
|
||||||
value = value_;
|
value = value__;
|
||||||
}
|
}
|
||||||
explicit Complex(mpreal& re_, mpreal& im_, int reb = 10, int imb = 10)
|
explicit Complex(mpreal& re__, mpreal& im__, int re_base__ = 10, int im_base__ = 10)
|
||||||
: Object(kComplex), reBase(reb), imBase(imb) {
|
: Object(kComplex), re_base(re_base__), im_base(im_base__) {
|
||||||
value.real(re_);
|
value.real(re__);
|
||||||
value.imag(im_);
|
value.imag(im__);
|
||||||
}
|
}
|
||||||
|
|
||||||
int reBase, imBase;
|
int re_base, im_base;
|
||||||
complex<mpreal> value;
|
complex<mpreal> value;
|
||||||
|
|
||||||
virtual Object* clone() { return new Complex(value, reBase, imBase); }
|
virtual Object* clone() { return new Complex(value, re_base, im_base); }
|
||||||
virtual string name() { return string("complex"); }
|
virtual string name() { return string("complex"); }
|
||||||
virtual ostream& show(ostream& out) {
|
virtual ostream& show(ostream& out) {
|
||||||
out << '(';
|
out << '(';
|
||||||
Number::showValue(out, value.real(), Number::s_mode, Number::s_digits, reBase);
|
Number::showValue(out, value.real(), Number::mode, Number::digits, re_base);
|
||||||
out << ',';
|
out << ',';
|
||||||
Number::showValue(out, value.imag(), Number::s_mode, Number::s_digits, imBase);
|
Number::showValue(out, value.imag(), Number::mode, Number::digits, im_base);
|
||||||
return out << ')';
|
return out << ')';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct String : Object {
|
struct String : Object {
|
||||||
String() : Object(kString) {}
|
String() : Object(kString) {}
|
||||||
explicit String(const string& value_) : Object(kString), 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,7 +163,7 @@ struct String : Object {
|
||||||
|
|
||||||
struct Program : Object {
|
struct Program : Object {
|
||||||
Program() : Object(kProgram) {}
|
Program() : Object(kProgram) {}
|
||||||
explicit Program(const string& value_) : Object(kProgram), 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 << "»"; }
|
||||||
|
@ -171,19 +171,19 @@ struct Program : Object {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Symbol : Object {
|
struct Symbol : Object {
|
||||||
explicit Symbol(bool autoEval_ = true) : Object(kSymbol), autoEval(autoEval_) {}
|
explicit Symbol(bool auto_eval__ = true) : Object(kSymbol), auto_eval(auto_eval__) {}
|
||||||
explicit Symbol(const string& value_, bool autoEval_ = true)
|
explicit Symbol(const string& value__, bool auto_eval__ = true)
|
||||||
: Object(kSymbol), value(value_), autoEval(autoEval_) {}
|
: Object(kSymbol), value(value__), auto_eval(auto_eval__) {}
|
||||||
virtual Object* clone() { return new Symbol(value, autoEval); }
|
virtual Object* clone() { return new Symbol(value, auto_eval); }
|
||||||
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 << "'"; }
|
||||||
bool autoEval;
|
bool auto_eval;
|
||||||
string value;
|
string value;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Keyword : Object {
|
struct Keyword : Object {
|
||||||
Keyword() : Object(kKeyword) {}
|
Keyword() : Object(kKeyword) {}
|
||||||
explicit Keyword(program_fn_t fn_, const string& value_) : Object(kKeyword), 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,13 +192,13 @@ struct Keyword : Object {
|
||||||
|
|
||||||
struct Branch : Object {
|
struct Branch : Object {
|
||||||
Branch() : Object(kBranch) {}
|
Branch() : Object(kBranch) {}
|
||||||
explicit Branch(branch_fn_t fn_, const string& value_) : Object(kBranch) {
|
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);
|
||||||
arg3 = static_cast<size_t>(-1);
|
arg3 = static_cast<size_t>(-1);
|
||||||
arg_bool = 0;
|
arg_bool = 0;
|
||||||
value = value_;
|
value = value__;
|
||||||
}
|
}
|
||||||
explicit Branch(Branch& other) : Object(kBranch) {
|
explicit Branch(Branch& other) : Object(kBranch) {
|
||||||
fn = other.fn;
|
fn = other.fn;
|
||||||
|
@ -212,7 +212,7 @@ struct Branch : Object {
|
||||||
virtual string name() { return string("branch"); }
|
virtual string name() { return string("branch"); }
|
||||||
branch_fn_t fn;
|
branch_fn_t fn;
|
||||||
size_t arg1, arg2, arg3;
|
size_t arg1, arg2, arg3;
|
||||||
mpreal firstIndex, lastIndex;
|
mpreal first_index, last_index;
|
||||||
bool arg_bool;
|
bool arg_bool;
|
||||||
string value;
|
string value;
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include "program.hpp"
|
#include "program.hpp"
|
||||||
|
|
||||||
//< language reserved keywords (allowed types are kKeyword, kBranch or kUndef)
|
//< language reserved keywords (allowed types are kKeyword, kBranch or kUndef)
|
||||||
vector<program::keyword_t> program::_keywords{
|
vector<program::keyword_t> program::keywords_{
|
||||||
// GENERAL
|
// GENERAL
|
||||||
{kUndef, "", nullptr, "\nGENERAL"},
|
{kUndef, "", nullptr, "\nGENERAL"},
|
||||||
{kKeyword, "nop", &program::rpn_nop, "no operation"},
|
{kKeyword, "nop", &program::rpn_nop, "no operation"},
|
||||||
|
@ -207,7 +207,7 @@ vector<program::keyword_t> program::_keywords{
|
||||||
vector<string>& program::getAutocompletionWords() {
|
vector<string>& program::getAutocompletionWords() {
|
||||||
static vector<string> autocompletion_words;
|
static vector<string> autocompletion_words;
|
||||||
if (autocompletion_words.empty())
|
if (autocompletion_words.empty())
|
||||||
for (auto& kw : _keywords)
|
for (auto& kw : keywords_)
|
||||||
if (!kw.name.empty()) autocompletion_words.push_back(kw.name);
|
if (!kw.name.empty()) autocompletion_words.push_back(kw.name);
|
||||||
return autocompletion_words;
|
return autocompletion_words;
|
||||||
}
|
}
|
||||||
|
@ -221,15 +221,15 @@ RetValue program::run() {
|
||||||
RetValue ret = kOk;
|
RetValue ret = kOk;
|
||||||
ObjectType type;
|
ObjectType type;
|
||||||
|
|
||||||
_err = kOk;
|
err_ = kOk;
|
||||||
_err_context = "";
|
err_context_ = "";
|
||||||
|
|
||||||
// branches for 'if'
|
// branches for 'if'
|
||||||
ret = preprocess();
|
ret = preprocess();
|
||||||
if (ret != kOk) {
|
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();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,7 +248,7 @@ RetValue program::run() {
|
||||||
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 kOk:
|
case kOk:
|
||||||
break;
|
break;
|
||||||
|
@ -262,10 +262,10 @@ RetValue program::run() {
|
||||||
go_out = true;
|
go_out = true;
|
||||||
|
|
||||||
// test error: make rpn return EXIT_FAILURE
|
// test error: make rpn return EXIT_FAILURE
|
||||||
if (_err == kTestFailed) ret = kTestFailed;
|
if (err_ == kTestFailed) ret = kTestFailed;
|
||||||
|
|
||||||
// error: show it
|
// error: show it
|
||||||
if (show_error(_err, _err_context) == kDeadlyError)
|
if (show_error(err_, err_context_) == kDeadlyError)
|
||||||
// pb showing error -> go out software
|
// pb showing error -> go out software
|
||||||
ret = kGoodbye;
|
ret = kGoodbye;
|
||||||
break;
|
break;
|
||||||
|
@ -284,7 +284,7 @@ RetValue program::run() {
|
||||||
i++; // meaning 'next command'
|
i++; // meaning 'next command'
|
||||||
break;
|
break;
|
||||||
case kRtError: // 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;
|
||||||
default:
|
default:
|
||||||
|
@ -297,7 +297,7 @@ RetValue program::run() {
|
||||||
default:
|
default:
|
||||||
// not a command, but a stack entry, manage it
|
// not a command, but a stack entry, manage it
|
||||||
// copy the program stack entry to the running stack
|
// copy the program stack entry to the running stack
|
||||||
_stack.push_front(o->clone());
|
stack_.push_front(o->clone());
|
||||||
i++;
|
i++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -305,7 +305,7 @@ RetValue program::run() {
|
||||||
|
|
||||||
// free allocated
|
// free allocated
|
||||||
for (Object* o : *this) delete o;
|
for (Object* o : *this) delete o;
|
||||||
_local_heap.clear();
|
local_heap_.clear();
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -571,7 +571,7 @@ RetValue program::parse(string& entry) {
|
||||||
|
|
||||||
// prepare map for finding reserved keywords
|
// prepare map for finding reserved keywords
|
||||||
if (keywords_map.empty())
|
if (keywords_map.empty())
|
||||||
for (auto& kw : _keywords)
|
for (auto& kw : keywords_)
|
||||||
if (!kw.name.empty()) keywords_map[kw.name] = {kw.type, kw.fn};
|
if (!kw.name.empty()) keywords_map[kw.name] = {kw.type, kw.fn};
|
||||||
|
|
||||||
// separate the entry string
|
// separate the entry string
|
||||||
|
@ -580,16 +580,16 @@ RetValue program::parse(string& entry) {
|
||||||
for (Lexer::SynElement& element : elements) {
|
for (Lexer::SynElement& element : elements) {
|
||||||
switch (element.type) {
|
switch (element.type) {
|
||||||
case kNumber:
|
case kNumber:
|
||||||
push_back(new Number(*element.re, element.reBase));
|
push_back(new Number(*element.re, element.re_base));
|
||||||
break;
|
break;
|
||||||
case kComplex:
|
case kComplex:
|
||||||
push_back(new Complex(*element.re, *element.im, element.reBase, element.imBase));
|
push_back(new Complex(*element.re, *element.im, element.re_base, element.im_base));
|
||||||
break;
|
break;
|
||||||
case kString:
|
case kString:
|
||||||
push_back(new String(element.value));
|
push_back(new String(element.value));
|
||||||
break;
|
break;
|
||||||
case kSymbol:
|
case kSymbol:
|
||||||
push_back(new Symbol(element.value, element.autoEval));
|
push_back(new Symbol(element.value, element.auto_eval));
|
||||||
break;
|
break;
|
||||||
case kProgram:
|
case kProgram:
|
||||||
push_back(new Program(element.value));
|
push_back(new Program(element.value));
|
||||||
|
@ -632,8 +632,8 @@ RetValue program::show_error() {
|
||||||
{kBadValue, "bad value"}, {kTestFailed, "test failed"}
|
{kBadValue, "bad value"}, {kTestFailed, "test failed"}
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
cerr << _err_context << ": error " << _err << ": " << errorStrings[_err] << endl;
|
cerr << err_context_ << ": error " << err_ << ": " << errorStrings[err_] << endl;
|
||||||
switch (_err) {
|
switch (err_) {
|
||||||
case kInternalError:
|
case kInternalError:
|
||||||
case kDeadlyError:
|
case kDeadlyError:
|
||||||
ret = kDeadlyError;
|
ret = kDeadlyError;
|
||||||
|
@ -652,8 +652,8 @@ RetValue program::show_error() {
|
||||||
///
|
///
|
||||||
RetValue program::show_error(RetValue 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;
|
||||||
return show_error();
|
return show_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -665,8 +665,8 @@ RetValue program::show_error(RetValue err, string& context) {
|
||||||
///
|
///
|
||||||
RetValue program::show_error(RetValue 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;
|
||||||
return show_error();
|
return show_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -678,8 +678,8 @@ RetValue program::show_error(RetValue err, const char* context) {
|
||||||
///
|
///
|
||||||
void program::show_syntax_error(const char* context) {
|
void program::show_syntax_error(const char* context) {
|
||||||
// record error
|
// record error
|
||||||
_err = kSyntaxError;
|
err_ = kSyntaxError;
|
||||||
_err_context = context;
|
err_context_ = context;
|
||||||
(void)show_error();
|
(void)show_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -687,7 +687,7 @@ void program::show_syntax_error(const char* context) {
|
||||||
///
|
///
|
||||||
/// @return RetValue see this type
|
/// @return RetValue see this type
|
||||||
///
|
///
|
||||||
RetValue 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
|
||||||
|
@ -695,12 +695,12 @@ RetValue program::get_err(void) { return _err; }
|
||||||
/// @param show_separator whether to show a stack level prefix or not
|
/// @param show_separator whether to show a stack level prefix or not
|
||||||
///
|
///
|
||||||
void program::show_stack(bool show_separator) {
|
void program::show_stack(bool show_separator) {
|
||||||
if (_stack.size() == 1) {
|
if (stack_.size() == 1) {
|
||||||
cout << _stack[0] << endl;
|
cout << stack_[0] << endl;
|
||||||
} else {
|
} else {
|
||||||
for (int i = _stack.size() - 1; i >= 0; i--) {
|
for (int i = stack_.size() - 1; i >= 0; i--) {
|
||||||
if (show_separator) cout << i + 1 << "> ";
|
if (show_separator) cout << i + 1 << "> ";
|
||||||
cout << _stack[i] << endl;
|
cout << stack_[i] << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -709,9 +709,9 @@ void program::show_stack(bool show_separator) {
|
||||||
///
|
///
|
||||||
void program::apply_default() {
|
void program::apply_default() {
|
||||||
// default float precision, float mode
|
// default float precision, float mode
|
||||||
Number::s_mode = Number::DEFAULT_MODE;
|
Number::mode = Number::DEFAULT_MODE;
|
||||||
Number::s_digits = Number::DEFAULT_DECIMAL_DIGITS;
|
Number::digits = Number::kDefaultDecimalDigits;
|
||||||
mpreal::set_default_prec(Number::MPFR_DEFAULT_PREC_BITS);
|
mpreal::set_default_prec(Number::kMpfrDefaultPrecBits);
|
||||||
|
|
||||||
static mp_rnd_t def_rnd = mpreal::get_default_rnd();
|
static mp_rnd_t def_rnd = mpreal::get_default_rnd();
|
||||||
mpreal::set_default_rnd(def_rnd);
|
mpreal::set_default_rnd(def_rnd);
|
||||||
|
|
|
@ -21,9 +21,10 @@ using mpfr::mpreal;
|
||||||
//< program class: the class containing a string parser, all the programs keywords, a stack for running the program
|
//< program class: the class containing a string parser, all the programs keywords, a stack for running the program
|
||||||
class program : public deque<Object*>, public Lexer {
|
class program : public deque<Object*>, public Lexer {
|
||||||
public:
|
public:
|
||||||
program(rpnstack& stk, heap& hp, program* parent = nullptr) : _stack(stk), _heap(hp), _parent(parent) {}
|
program(rpnstack& stack__, heap& heap__, program* parent__ = nullptr)
|
||||||
|
: stack_(stack__), heap_(heap__), parent_(parent__) {}
|
||||||
virtual ~program() {
|
virtual ~program() {
|
||||||
_local_heap.clear();
|
local_heap_.clear();
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,20 +51,20 @@ class program : public deque<Object*>, public Lexer {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// current error and its context
|
// current error and its context
|
||||||
RetValue _err;
|
RetValue err_;
|
||||||
string _err_context;
|
string err_context_;
|
||||||
|
|
||||||
// global stack holding results for user
|
// global stack holding results for user
|
||||||
rpnstack& _stack;
|
rpnstack& stack_;
|
||||||
|
|
||||||
// global heap (sto, rcl)
|
// global heap (sto, rcl)
|
||||||
heap& _heap;
|
heap& heap_;
|
||||||
|
|
||||||
// local heap for local loop variables (for..next)
|
// local heap for local loop variables (for..next)
|
||||||
heap _local_heap;
|
heap local_heap_;
|
||||||
|
|
||||||
// parent prog for inheriting heaps
|
// parent prog for inheriting heaps
|
||||||
program* _parent;
|
program* parent_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// keywords
|
// keywords
|
||||||
|
@ -73,7 +74,7 @@ class program : public deque<Object*>, public Lexer {
|
||||||
program_fn_t fn;
|
program_fn_t fn;
|
||||||
string comment;
|
string comment;
|
||||||
};
|
};
|
||||||
static vector<keyword_t> _keywords;
|
static vector<keyword_t> keywords_;
|
||||||
|
|
||||||
// keywords implementation
|
// keywords implementation
|
||||||
////
|
////
|
||||||
|
@ -252,38 +253,38 @@ class program : public deque<Object*>, public Lexer {
|
||||||
|
|
||||||
#define setErrorContext(err) \
|
#define setErrorContext(err) \
|
||||||
do { \
|
do { \
|
||||||
_err = (err); \
|
err_ = (err); \
|
||||||
_err_context = __FUNCTION__; \
|
err_context_ = __FUNCTION__; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define MIN_ARGUMENTS(num) \
|
#define MIN_ARGUMENTS(num) \
|
||||||
do { \
|
do { \
|
||||||
if ((num) >= 0 && _stack.size() < (num)) { \
|
if ((num) >= 0 && stack_.size() < (num)) { \
|
||||||
setErrorContext(kMissingOperand); \
|
setErrorContext(kMissingOperand); \
|
||||||
return; \
|
return; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#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(kMissingOperand); \
|
setErrorContext(kMissingOperand); \
|
||||||
return (ret); \
|
return (ret); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#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(kBadOperandType); \
|
setErrorContext(kBadOperandType); \
|
||||||
return; \
|
return; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#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(kBadOperandType); \
|
setErrorContext(kBadOperandType); \
|
||||||
return (ret); \
|
return (ret); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
|
@ -14,11 +14,11 @@ size_t program::rpn_if(Branch& myobj) {
|
||||||
MIN_ARGUMENTS_RET(1, kRtError);
|
MIN_ARGUMENTS_RET(1, kRtError);
|
||||||
ARG_MUST_BE_OF_TYPE_RET(0, kNumber, kRtError);
|
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 kStepOut;
|
return kStepOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,8 +89,8 @@ size_t program::rpn_end(Branch& myobj) {
|
||||||
ARG_MUST_BE_OF_TYPE_RET(0, kNumber, kRtError);
|
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 != kStepOut) {
|
} 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;
|
||||||
|
@ -136,10 +136,10 @@ void program::rpn_ift(void) {
|
||||||
|
|
||||||
// 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
|
||||||
if (_stack.value<Number>(1) != 0)
|
if (stack_.value<Number>(1) != 0)
|
||||||
_stack.erase(1);
|
stack_.erase(1);
|
||||||
else
|
else
|
||||||
_stack.erase(0, 2);
|
stack_.erase(0, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief ifte keyword (branch) implementation
|
/// @brief ifte keyword (branch) implementation
|
||||||
|
@ -154,12 +154,12 @@ void program::rpn_ifte(void) {
|
||||||
ARG_MUST_BE_OF_TYPE(2, kNumber);
|
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) {
|
||||||
_stack.erase(2);
|
stack_.erase(2);
|
||||||
_stack.pop();
|
stack_.pop();
|
||||||
} else {
|
} else {
|
||||||
_stack.erase(2);
|
stack_.erase(2);
|
||||||
_stack.erase(1);
|
stack_.erase(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,8 +190,8 @@ size_t program::rpn_repeat(Branch& myobj) {
|
||||||
|
|
||||||
// check arg
|
// check arg
|
||||||
// myobj.arg1 is end+1
|
// myobj.arg1 is end+1
|
||||||
if (_stack.value<Number>(0) == 0) ret = myobj.arg1;
|
if (stack_.value<Number>(0) == 0) ret = myobj.arg1;
|
||||||
_stack.pop();
|
stack_.pop();
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -211,12 +211,12 @@ size_t program::rpn_start(Branch& myobj) {
|
||||||
ARG_MUST_BE_OF_TYPE_RET(1, kNumber, kRtError);
|
ARG_MUST_BE_OF_TYPE_RET(1, kNumber, kRtError);
|
||||||
|
|
||||||
// loop boundaries
|
// loop boundaries
|
||||||
myobj.firstIndex = _stack.value<Number>(1);
|
myobj.first_index = stack_.value<Number>(1);
|
||||||
myobj.lastIndex = _stack.value<Number>(0);
|
myobj.last_index = stack_.value<Number>(0);
|
||||||
_stack.erase(0, 2);
|
stack_.erase(0, 2);
|
||||||
|
|
||||||
// test value
|
// test value
|
||||||
if (myobj.firstIndex > myobj.lastIndex)
|
if (myobj.first_index > myobj.last_index)
|
||||||
// last boundary lower than first boundary
|
// last boundary lower than first boundary
|
||||||
// -> next command shall be after 'next'
|
// -> next command shall be after 'next'
|
||||||
// arg2 holds index of 'next'
|
// arg2 holds index of 'next'
|
||||||
|
@ -247,27 +247,27 @@ size_t program::rpn_for(Branch& myobj) {
|
||||||
sym = reinterpret_cast<Symbol*>(at(myobj.arg1)); // arg1 = loop variable index
|
sym = reinterpret_cast<Symbol*>(at(myobj.arg1)); // arg1 = loop variable index
|
||||||
|
|
||||||
// loop boundaries
|
// loop boundaries
|
||||||
myobj.firstIndex = _stack.value<Number>(1);
|
myobj.first_index = stack_.value<Number>(1);
|
||||||
myobj.lastIndex = _stack.value<Number>(0);
|
myobj.last_index = stack_.value<Number>(0);
|
||||||
|
|
||||||
// test value
|
// test value
|
||||||
if (myobj.firstIndex > myobj.lastIndex) {
|
if (myobj.first_index > myobj.last_index) {
|
||||||
// last boundary lower than first boundary
|
// last boundary lower than first boundary
|
||||||
// -> next command shall be after 'next'
|
// -> next command shall be after 'next'
|
||||||
// arg2 holds index of 'next'
|
// arg2 holds index of 'next'
|
||||||
ret = myobj.arg2 + 1;
|
ret = myobj.arg2 + 1;
|
||||||
} else {
|
} else {
|
||||||
// store symbol with first value
|
// store symbol with first value
|
||||||
auto it = _local_heap.find(sym->value);
|
auto it = local_heap_.find(sym->value);
|
||||||
if (it != _local_heap.end()) {
|
if (it != local_heap_.end()) {
|
||||||
delete it->second;
|
delete it->second;
|
||||||
_local_heap.erase(it);
|
local_heap_.erase(it);
|
||||||
}
|
}
|
||||||
_local_heap[sym->value] = _stack.obj<Number>(1).clone();
|
local_heap_[sym->value] = stack_.obj<Number>(1).clone();
|
||||||
ret = myobj.arg1 + 1;
|
ret = myobj.arg1 + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
_stack.erase(0, 2);
|
stack_.erase(0, 2);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -281,7 +281,7 @@ size_t program::rpn_for(Branch& myobj) {
|
||||||
///
|
///
|
||||||
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
|
// first_index = current point in the loop
|
||||||
Branch* start_or_for;
|
Branch* start_or_for;
|
||||||
if (myobj.arg1 >= size() || at(myobj.arg1)->_type != kBranch) {
|
if (myobj.arg1 >= size() || at(myobj.arg1)->_type != kBranch) {
|
||||||
setErrorContext(kMissingOperand);
|
setErrorContext(kMissingOperand);
|
||||||
|
@ -290,12 +290,12 @@ size_t program::rpn_next(Branch& myobj) {
|
||||||
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) {
|
||||||
myobj.arg_bool = true;
|
myobj.arg_bool = true;
|
||||||
myobj.firstIndex = start_or_for->firstIndex;
|
myobj.first_index = start_or_for->first_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
// increment then test
|
// increment then test
|
||||||
// carefull: round toward minus infinity to avoid missing last boundary (because growing step)
|
// carefull: round toward minus infinity to avoid missing last boundary (because growing step)
|
||||||
mpfr_add(myobj.firstIndex.mpfr_ptr(), myobj.firstIndex.mpfr_srcptr(), mpreal(1).mpfr_srcptr(), MPFR_RNDD);
|
mpfr_add(myobj.first_index.mpfr_ptr(), myobj.first_index.mpfr_srcptr(), mpreal(1).mpfr_srcptr(), MPFR_RNDD);
|
||||||
|
|
||||||
// for command: increment symbol too
|
// for command: increment symbol too
|
||||||
if (start_or_for->arg1 != -1) {
|
if (start_or_for->arg1 != -1) {
|
||||||
|
@ -308,11 +308,11 @@ size_t program::rpn_next(Branch& myobj) {
|
||||||
var = reinterpret_cast<Symbol*>(at(start_or_for->arg1));
|
var = reinterpret_cast<Symbol*>(at(start_or_for->arg1));
|
||||||
|
|
||||||
// store symbol variable (asserted existing in the local heap)
|
// store symbol variable (asserted existing in the local heap)
|
||||||
reinterpret_cast<Number*>(_local_heap[var->value])->value = myobj.firstIndex;
|
reinterpret_cast<Number*>(local_heap_[var->value])->value = myobj.first_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
// test value
|
// test value
|
||||||
if (myobj.firstIndex > start_or_for->lastIndex) {
|
if (myobj.first_index > start_or_for->last_index) {
|
||||||
// end of loop
|
// end of loop
|
||||||
myobj.arg_bool = false; // init again next time
|
myobj.arg_bool = false; // init again next time
|
||||||
return kStepOut;
|
return kStepOut;
|
||||||
|
@ -337,15 +337,15 @@ size_t program::rpn_step(Branch& myobj) {
|
||||||
MIN_ARGUMENTS_RET(1, kRtError);
|
MIN_ARGUMENTS_RET(1, kRtError);
|
||||||
ARG_MUST_BE_OF_TYPE_RET(0, kNumber, kRtError);
|
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 = kStepOut;
|
ret = kStepOut;
|
||||||
} else {
|
} else {
|
||||||
// arg1 = loop variable index
|
// arg1 = loop variable index
|
||||||
// firstIndex = current count
|
// first_index = current count
|
||||||
Branch* start_or_for;
|
Branch* start_or_for;
|
||||||
if (myobj.arg1 >= size() || at(myobj.arg1)->_type != kBranch) {
|
if (myobj.arg1 >= size() || at(myobj.arg1)->_type != kBranch) {
|
||||||
setErrorContext(kMissingOperand);
|
setErrorContext(kMissingOperand);
|
||||||
|
@ -354,12 +354,12 @@ size_t program::rpn_step(Branch& myobj) {
|
||||||
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) {
|
||||||
myobj.arg_bool = true;
|
myobj.arg_bool = true;
|
||||||
myobj.firstIndex = start_or_for->firstIndex;
|
myobj.first_index = start_or_for->first_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
// increment then test
|
// increment then test
|
||||||
// carefull: round toward minus infinity to avoid missing last boundary (because growing step)
|
// carefull: round toward minus infinity to avoid missing last boundary (because growing step)
|
||||||
mpfr_add(myobj.firstIndex.mpfr_ptr(), myobj.firstIndex.mpfr_srcptr(), step.mpfr_srcptr(), MPFR_RNDD);
|
mpfr_add(myobj.first_index.mpfr_ptr(), myobj.first_index.mpfr_srcptr(), step.mpfr_srcptr(), MPFR_RNDD);
|
||||||
|
|
||||||
if (start_or_for->arg1 != -1) {
|
if (start_or_for->arg1 != -1) {
|
||||||
Object* obj;
|
Object* obj;
|
||||||
|
@ -372,11 +372,11 @@ size_t program::rpn_step(Branch& myobj) {
|
||||||
}
|
}
|
||||||
var = reinterpret_cast<Symbol*>(at(start_or_for->arg1));
|
var = reinterpret_cast<Symbol*>(at(start_or_for->arg1));
|
||||||
// increase symbol variable
|
// increase symbol variable
|
||||||
reinterpret_cast<Number*>(_local_heap[var->value])->value = myobj.firstIndex;
|
reinterpret_cast<Number*>(local_heap_[var->value])->value = myobj.first_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
// test loop value is out of range
|
// test loop value is out of range
|
||||||
if (myobj.firstIndex > start_or_for->lastIndex) {
|
if (myobj.first_index > start_or_for->last_index) {
|
||||||
// end of loop
|
// end of loop
|
||||||
myobj.arg_bool = false; // init again next time
|
myobj.arg_bool = false; // init again next time
|
||||||
ret = kStepOut;
|
ret = kStepOut;
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
void program::rpn_re() {
|
void program::rpn_re() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, kComplex);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief im keyword implementation
|
/// @brief im keyword implementation
|
||||||
|
@ -18,8 +18,8 @@ void program::rpn_re() {
|
||||||
void program::rpn_im() {
|
void program::rpn_im() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, kComplex);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief arg keyword implementation
|
/// @brief arg keyword implementation
|
||||||
|
@ -28,8 +28,8 @@ void program::rpn_im() {
|
||||||
void program::rpn_arg() {
|
void program::rpn_arg() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, kComplex);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief conj keyword implementation
|
/// @brief conj keyword implementation
|
||||||
|
@ -38,7 +38,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, kComplex);
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief r2c keyword implementation
|
/// @brief r2c keyword implementation
|
||||||
|
@ -48,8 +48,8 @@ void program::rpn_r2c() {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
||||||
ARG_MUST_BE_OF_TYPE(1, kNumber);
|
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).re_base, stack_.obj<Complex>(0).re_base));
|
||||||
_stack.erase(1, 2);
|
stack_.erase(1, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief c2r keyword implementation
|
/// @brief c2r keyword implementation
|
||||||
|
@ -58,9 +58,9 @@ void program::rpn_r2c() {
|
||||||
void program::rpn_c2r() {
|
void program::rpn_c2r() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, kComplex);
|
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).re_base));
|
||||||
_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).im_base));
|
||||||
_stack.erase(2);
|
stack_.erase(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief r2p keyword implementation
|
/// @brief r2p keyword implementation
|
||||||
|
@ -69,10 +69,10 @@ void program::rpn_c2r() {
|
||||||
void program::rpn_r2p() {
|
void program::rpn_r2p() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, kComplex);
|
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);
|
||||||
_stack.value<Complex>(0).imag(theta);
|
stack_.value<Complex>(0).imag(theta);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief p2r keyword implementation
|
/// @brief p2r keyword implementation
|
||||||
|
@ -81,5 +81,5 @@ void program::rpn_r2p() {
|
||||||
void program::rpn_p2r() {
|
void program::rpn_p2r() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, kComplex);
|
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)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ void program::rpn_help() {
|
||||||
|
|
||||||
// keywords
|
// keywords
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
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 == kUndef) cout << ATTR_BOLD;
|
if (kw.type == kUndef) cout << ATTR_BOLD;
|
||||||
|
@ -69,7 +69,7 @@ void program::rpn_help() {
|
||||||
|
|
||||||
// show mode
|
// show mode
|
||||||
cout << "Current float mode is ";
|
cout << "Current float mode is ";
|
||||||
switch (Number::s_mode) {
|
switch (Number::mode) {
|
||||||
case Number::kStd:
|
case Number::kStd:
|
||||||
cout << "'std'";
|
cout << "'std'";
|
||||||
break;
|
break;
|
||||||
|
@ -85,7 +85,7 @@ void program::rpn_help() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// bits precision, decimal digits and rounding mode
|
// bits precision, decimal digits and rounding mode
|
||||||
cout << " with " << Number::s_digits << " digits after the decimal point" << endl;
|
cout << " with " << Number::digits << " digits after the decimal point" << endl;
|
||||||
cout << "Current floating point precision is " << static_cast<int>(mpreal::get_default_prec()) << " bits" << endl;
|
cout << "Current floating point precision is " << static_cast<int>(mpreal::get_default_prec()) << " bits" << endl;
|
||||||
vector<pair<string, mpfr_rnd_t>> rnd{MPFR_ROUND};
|
vector<pair<string, mpfr_rnd_t>> rnd{MPFR_ROUND};
|
||||||
for (auto& rn : rnd)
|
for (auto& rn : rnd)
|
||||||
|
@ -110,13 +110,13 @@ void program::rpn_std() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
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::kStd;
|
Number::mode = Number::kStd;
|
||||||
Number::s_digits = digits;
|
Number::digits = digits;
|
||||||
_stack.pop();
|
stack_.pop();
|
||||||
} else {
|
} else {
|
||||||
setErrorContext(kOutOfRange);
|
setErrorContext(kOutOfRange);
|
||||||
}
|
}
|
||||||
|
@ -128,13 +128,13 @@ void program::rpn_fix() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
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::kFix;
|
Number::mode = Number::kFix;
|
||||||
Number::s_digits = digits;
|
Number::digits = digits;
|
||||||
_stack.pop();
|
stack_.pop();
|
||||||
} else {
|
} else {
|
||||||
setErrorContext(kOutOfRange);
|
setErrorContext(kOutOfRange);
|
||||||
}
|
}
|
||||||
|
@ -146,13 +146,13 @@ void program::rpn_sci() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
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::kSci;
|
Number::mode = Number::kSci;
|
||||||
Number::s_digits = digits;
|
Number::digits = digits;
|
||||||
_stack.pop();
|
stack_.pop();
|
||||||
} else {
|
} else {
|
||||||
setErrorContext(kOutOfRange);
|
setErrorContext(kOutOfRange);
|
||||||
}
|
}
|
||||||
|
@ -160,11 +160,11 @@ void program::rpn_sci() {
|
||||||
|
|
||||||
/// @brief _version keyword implementation
|
/// @brief _version keyword implementation
|
||||||
///
|
///
|
||||||
void program::rpn_version() { _stack.push_front(new String(RPN_VERSION)); }
|
void program::rpn_version() { stack_.push_front(new String(RPN_VERSION)); }
|
||||||
|
|
||||||
/// @brief _uname keyword implementation
|
/// @brief _uname keyword implementation
|
||||||
///
|
///
|
||||||
void program::rpn_uname() { _stack.push_front(new String(RPN_UNAME)); }
|
void program::rpn_uname() { stack_.push_front(new String(RPN_UNAME)); }
|
||||||
|
|
||||||
/// @brief history keyword implementation
|
/// @brief history keyword implementation
|
||||||
///
|
///
|
||||||
|
@ -183,8 +183,8 @@ void program::rpn_history() {
|
||||||
///
|
///
|
||||||
void program::rpn_type() {
|
void program::rpn_type() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
_stack.push(new String(_stack.at(0)->name()));
|
stack_.push(new String(stack_.at(0)->name()));
|
||||||
_stack.erase(1);
|
stack_.erase(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief default keyword implementation
|
/// @brief default keyword implementation
|
||||||
|
@ -198,16 +198,16 @@ void program::rpn_precision() {
|
||||||
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
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());
|
||||||
if (prec >= MPFR_PREC_MIN && prec <= MPFR_PREC_MAX) {
|
if (prec >= MPFR_PREC_MIN && prec <= MPFR_PREC_MAX) {
|
||||||
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::kStd) {
|
if (Number::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::digits = mpfr::bits2digits(mpreal::get_default_prec());
|
||||||
}
|
}
|
||||||
_stack.pop();
|
stack_.pop();
|
||||||
} else {
|
} else {
|
||||||
setErrorContext(kOutOfRange);
|
setErrorContext(kOutOfRange);
|
||||||
}
|
}
|
||||||
|
@ -221,10 +221,10 @@ void program::rpn_round() {
|
||||||
|
|
||||||
map<string, mpfr_rnd_t> matchRound{MPFR_ROUND};
|
map<string, mpfr_rnd_t> matchRound{MPFR_ROUND};
|
||||||
|
|
||||||
auto found = matchRound.find(_stack.value<String>(0));
|
auto found = matchRound.find(stack_.value<String>(0));
|
||||||
if (found != matchRound.end())
|
if (found != matchRound.end())
|
||||||
mpreal::set_default_rnd(found->second);
|
mpreal::set_default_rnd(found->second);
|
||||||
else
|
else
|
||||||
setErrorContext(kOutOfRange);
|
setErrorContext(kOutOfRange);
|
||||||
_stack.pop();
|
stack_.pop();
|
||||||
}
|
}
|
||||||
|
|
114
src/rpn-logs.cpp
114
src/rpn-logs.cpp
|
@ -4,16 +4,16 @@
|
||||||
|
|
||||||
/// @brief e keyword implementation
|
/// @brief e keyword implementation
|
||||||
///
|
///
|
||||||
void program::rpn_e(void) { _stack.push(new Number(mpfr::const_euler())); }
|
void program::rpn_e(void) { stack_.push(new Number(mpfr::const_euler())); }
|
||||||
|
|
||||||
/// @brief log10 keyword implementation
|
/// @brief log10 keyword implementation
|
||||||
///
|
///
|
||||||
void program::rpn_log10() {
|
void program::rpn_log10() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == kNumber)
|
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) == kComplex)
|
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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -22,10 +22,10 @@ void program::rpn_log10() {
|
||||||
///
|
///
|
||||||
void program::rpn_alog10() {
|
void program::rpn_alog10() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == kNumber)
|
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) == kComplex)
|
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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -34,10 +34,10 @@ void program::rpn_alog10() {
|
||||||
///
|
///
|
||||||
void program::rpn_log2() {
|
void program::rpn_log2() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == kNumber)
|
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) == kComplex)
|
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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -46,10 +46,10 @@ void program::rpn_log2() {
|
||||||
///
|
///
|
||||||
void program::rpn_alog2() {
|
void program::rpn_alog2() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == kNumber)
|
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) == kComplex)
|
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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -58,10 +58,10 @@ void program::rpn_alog2() {
|
||||||
///
|
///
|
||||||
void program::rpn_ln() {
|
void program::rpn_ln() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == kNumber)
|
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) == kComplex)
|
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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -70,10 +70,10 @@ void program::rpn_ln() {
|
||||||
///
|
///
|
||||||
void program::rpn_exp() {
|
void program::rpn_exp() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == kNumber)
|
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) == kComplex)
|
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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -82,10 +82,10 @@ void program::rpn_exp() {
|
||||||
///
|
///
|
||||||
void program::rpn_expm() {
|
void program::rpn_expm() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == kNumber)
|
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) == kComplex)
|
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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -94,10 +94,10 @@ void program::rpn_expm() {
|
||||||
///
|
///
|
||||||
void program::rpn_lnp1() {
|
void program::rpn_lnp1() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == kNumber)
|
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) == kComplex)
|
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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -106,10 +106,10 @@ void program::rpn_lnp1() {
|
||||||
///
|
///
|
||||||
void program::rpn_sinh() {
|
void program::rpn_sinh() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == kNumber)
|
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) == kComplex)
|
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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -118,10 +118,10 @@ void program::rpn_sinh() {
|
||||||
///
|
///
|
||||||
void program::rpn_asinh() {
|
void program::rpn_asinh() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == kNumber)
|
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) == kComplex)
|
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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -130,10 +130,10 @@ void program::rpn_asinh() {
|
||||||
///
|
///
|
||||||
void program::rpn_cosh() {
|
void program::rpn_cosh() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == kNumber)
|
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) == kComplex)
|
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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -142,10 +142,10 @@ void program::rpn_cosh() {
|
||||||
///
|
///
|
||||||
void program::rpn_acosh() {
|
void program::rpn_acosh() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == kNumber)
|
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) == kComplex)
|
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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -154,10 +154,10 @@ void program::rpn_acosh() {
|
||||||
///
|
///
|
||||||
void program::rpn_tanh() {
|
void program::rpn_tanh() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == kNumber)
|
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) == kComplex)
|
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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -166,10 +166,10 @@ void program::rpn_tanh() {
|
||||||
///
|
///
|
||||||
void program::rpn_atanh() {
|
void program::rpn_atanh() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == kNumber)
|
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) == kComplex)
|
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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,20 +11,20 @@
|
||||||
///
|
///
|
||||||
bool program::find_variable(string& variable, Object*& obj) {
|
bool program::find_variable(string& variable, Object*& obj) {
|
||||||
bool found = false;
|
bool found = false;
|
||||||
program* parent = _parent;
|
program* parent = parent_;
|
||||||
|
|
||||||
if (_local_heap.get(variable, obj)) {
|
if (local_heap_.get(variable, obj)) {
|
||||||
found = true;
|
found = true;
|
||||||
} else {
|
} else {
|
||||||
while (parent != nullptr) {
|
while (parent != nullptr) {
|
||||||
if (parent->_local_heap.get(variable, obj)) {
|
if (parent->local_heap_.get(variable, obj)) {
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
parent = parent->_parent;
|
parent = parent->parent_;
|
||||||
}
|
}
|
||||||
if (!found) {
|
if (!found) {
|
||||||
if (_heap.get(variable, obj)) found = true;
|
if (heap_.get(variable, obj)) found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,29 +38,29 @@ void program::rpn_eval(void) {
|
||||||
string prog_text;
|
string prog_text;
|
||||||
|
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == kSymbol) {
|
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));
|
||||||
_stack.pop();
|
stack_.pop();
|
||||||
|
|
||||||
// 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 == kProgram) {
|
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;
|
||||||
} else {
|
} else {
|
||||||
// else recall this variable (i.e. stack its content)
|
// else recall this variable (i.e. stack_ its content)
|
||||||
_stack.push_front(obj);
|
stack_.push_front(obj);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setErrorContext(kUnknownVariable);
|
setErrorContext(kUnknownVariable);
|
||||||
}
|
}
|
||||||
} else if (_stack.type(0) == kProgram) {
|
} 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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
|
@ -68,7 +68,7 @@ void program::rpn_eval(void) {
|
||||||
|
|
||||||
// run prog if any
|
// run prog if any
|
||||||
if (run_prog) {
|
if (run_prog) {
|
||||||
program prog(_stack, _heap, this);
|
program prog(stack_, heap_, this);
|
||||||
|
|
||||||
// make program from entry
|
// make program from entry
|
||||||
if (prog.parse(prog_text) == kOk) {
|
if (prog.parse(prog_text) == kOk) {
|
||||||
|
@ -105,7 +105,7 @@ int program::rpn_inprog(Branch& inprog_obj) {
|
||||||
} else {
|
} else {
|
||||||
// found something other than symbol
|
// found something other than symbol
|
||||||
setErrorContext(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
show_error(_err, context);
|
show_error(err_, context);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,33 +113,33 @@ int program::rpn_inprog(Branch& inprog_obj) {
|
||||||
// found 0 symbols
|
// found 0 symbols
|
||||||
if (count_symbols == 0) {
|
if (count_symbols == 0) {
|
||||||
setErrorContext(kSyntaxError);
|
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(kSyntaxError);
|
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(kMissingOperand);
|
setErrorContext(kMissingOperand);
|
||||||
show_error(_err, context);
|
show_error(err_, context);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// load variables
|
// load variables
|
||||||
for (unsigned int i = inprog_obj.arg1 + count_symbols; i > inprog_obj.arg1; i--) {
|
for (unsigned int i = inprog_obj.arg1 + count_symbols; i > inprog_obj.arg1; i--) {
|
||||||
_local_heap[reinterpret_cast<Symbol*>(at(i))->value] = _stack.at(0)->clone();
|
local_heap_[reinterpret_cast<Symbol*>(at(i))->value] = stack_.at(0)->clone();
|
||||||
_stack.pop();
|
stack_.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
// run the program
|
// run the program
|
||||||
string& entry = reinterpret_cast<Program*>(at(inprog_obj.arg1 + count_symbols + 1))->value;
|
string& entry = reinterpret_cast<Program*>(at(inprog_obj.arg1 + count_symbols + 1))->value;
|
||||||
program prog(_stack, _heap, this);
|
program prog(stack_, heap_, this);
|
||||||
|
|
||||||
// make the program from entry
|
// make the program from entry
|
||||||
if (prog.parse(entry) == kOk) {
|
if (prog.parse(entry) == kOk) {
|
||||||
|
|
278
src/rpn-real.cpp
278
src/rpn-real.cpp
|
@ -6,22 +6,22 @@
|
||||||
///
|
///
|
||||||
void program::rpn_plus() {
|
void program::rpn_plus() {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
if (_stack.type(0) == kString && _stack.type(1) == kString) {
|
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) == kNumber && _stack.type(1) == kNumber) {
|
} 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) == kComplex && _stack.type(1) == kComplex) {
|
} 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) == kNumber && _stack.type(1) == kComplex) {
|
} 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) == kComplex && _stack.type(1) == kNumber) {
|
} 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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -31,19 +31,19 @@ void program::rpn_plus() {
|
||||||
///
|
///
|
||||||
void program::rpn_minus() {
|
void program::rpn_minus() {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
if (_stack.type(0) == kNumber && _stack.type(1) == kNumber) {
|
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) == kComplex && _stack.type(1) == kComplex) {
|
} 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) == kNumber && _stack.type(1) == kComplex) {
|
} 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) == kComplex && _stack.type(1) == kNumber) {
|
} 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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -53,19 +53,19 @@ void program::rpn_minus() {
|
||||||
///
|
///
|
||||||
void program::rpn_mul() {
|
void program::rpn_mul() {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
if (_stack.type(0) == kNumber && _stack.type(1) == kNumber) {
|
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) == kComplex && _stack.type(1) == kComplex) {
|
} 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) == kNumber && _stack.type(1) == kComplex) {
|
} 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) == kComplex && _stack.type(1) == kNumber) {
|
} 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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -75,19 +75,19 @@ void program::rpn_mul() {
|
||||||
///
|
///
|
||||||
void program::rpn_div() {
|
void program::rpn_div() {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
if (_stack.type(0) == kNumber && _stack.type(1) == kNumber) {
|
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) == kComplex && _stack.type(1) == kComplex) {
|
} 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) == kNumber && _stack.type(1) == kComplex) {
|
} 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) == kComplex && _stack.type(1) == kNumber) {
|
} 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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -97,10 +97,10 @@ void program::rpn_div() {
|
||||||
///
|
///
|
||||||
void program::rpn_neg() {
|
void program::rpn_neg() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == kNumber)
|
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) == kComplex)
|
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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -109,10 +109,10 @@ void program::rpn_neg() {
|
||||||
///
|
///
|
||||||
void program::rpn_inv() {
|
void program::rpn_inv() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == kNumber)
|
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) == kComplex)
|
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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -121,26 +121,26 @@ void program::rpn_inv() {
|
||||||
///
|
///
|
||||||
void program::rpn_power() {
|
void program::rpn_power() {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
if (_stack.type(0) == kNumber && _stack.type(1) == kNumber) {
|
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();
|
||||||
} else {
|
} else {
|
||||||
mpreal zero;
|
mpreal zero;
|
||||||
_stack.push(new Complex(_stack.value<Number>(1), zero, _stack.obj<Number>(1).base));
|
stack_.push(new Complex(stack_.value<Number>(1), zero, stack_.obj<Number>(1).base));
|
||||||
_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) == kComplex && _stack.type(1) == kComplex) {
|
} 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) == kNumber && _stack.type(1) == kComplex) {
|
} 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) == kComplex && _stack.type(1) == kNumber) {
|
} 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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -150,19 +150,19 @@ void program::rpn_power() {
|
||||||
///
|
///
|
||||||
void program::rpn_squareroot() {
|
void program::rpn_squareroot() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == kNumber) {
|
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 {
|
||||||
// negative number -> square root is complex
|
// negative number -> square root is complex
|
||||||
mpreal zero;
|
mpreal zero;
|
||||||
_stack.push(new Complex(_stack.value<Number>(0), zero,
|
stack_.push(new Complex(stack_.value<Number>(0), zero,
|
||||||
_stack.obj<Number>(0).base)); // TODO(louis) manage new errors
|
stack_.obj<Number>(0).base)); // TODO(louis) manage new errors
|
||||||
_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) == kComplex) {
|
} 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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -172,11 +172,11 @@ void program::rpn_squareroot() {
|
||||||
///
|
///
|
||||||
void program::rpn_hex() {
|
void program::rpn_hex() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == kNumber) {
|
if (stack_.type(0) == kNumber) {
|
||||||
_stack.obj<Number>(0).base = 16;
|
stack_.obj<Number>(0).base = 16;
|
||||||
} else if (_stack.type(0) == kComplex) {
|
} else if (stack_.type(0) == kComplex) {
|
||||||
_stack.obj<Complex>(0).reBase = 16;
|
stack_.obj<Complex>(0).re_base = 16;
|
||||||
_stack.obj<Complex>(0).imBase = 16;
|
stack_.obj<Complex>(0).im_base = 16;
|
||||||
} else {
|
} else {
|
||||||
setErrorContext(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -186,11 +186,11 @@ void program::rpn_hex() {
|
||||||
///
|
///
|
||||||
void program::rpn_bin() {
|
void program::rpn_bin() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == kNumber) {
|
if (stack_.type(0) == kNumber) {
|
||||||
_stack.obj<Number>(0).base = 2;
|
stack_.obj<Number>(0).base = 2;
|
||||||
} else if (_stack.type(0) == kComplex) {
|
} else if (stack_.type(0) == kComplex) {
|
||||||
_stack.obj<Complex>(0).reBase = 2;
|
stack_.obj<Complex>(0).re_base = 2;
|
||||||
_stack.obj<Complex>(0).imBase = 2;
|
stack_.obj<Complex>(0).im_base = 2;
|
||||||
} else {
|
} else {
|
||||||
setErrorContext(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -200,11 +200,11 @@ void program::rpn_bin() {
|
||||||
///
|
///
|
||||||
void program::rpn_dec() {
|
void program::rpn_dec() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == kNumber) {
|
if (stack_.type(0) == kNumber) {
|
||||||
_stack.obj<Number>(0).base = 10;
|
stack_.obj<Number>(0).base = 10;
|
||||||
} else if (_stack.type(0) == kComplex) {
|
} else if (stack_.type(0) == kComplex) {
|
||||||
_stack.obj<Complex>(0).reBase = 10;
|
stack_.obj<Complex>(0).re_base = 10;
|
||||||
_stack.obj<Complex>(0).imBase = 10;
|
stack_.obj<Complex>(0).im_base = 10;
|
||||||
} else {
|
} else {
|
||||||
setErrorContext(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -214,15 +214,15 @@ void program::rpn_dec() {
|
||||||
///
|
///
|
||||||
void program::rpn_base() {
|
void program::rpn_base() {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
if (_stack.type(1) == kNumber || _stack.type(1) == kComplex) {
|
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) == kNumber) {
|
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).re_base = base;
|
||||||
_stack.obj<Complex>(0).imBase = base;
|
stack_.obj<Complex>(0).im_base = base;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setErrorContext(kOutOfRange);
|
setErrorContext(kOutOfRange);
|
||||||
|
@ -238,8 +238,8 @@ void program::rpn_purcent() {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
||||||
ARG_MUST_BE_OF_TYPE(1, kNumber);
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief %CH keyword implementation
|
/// @brief %CH keyword implementation
|
||||||
|
@ -248,18 +248,18 @@ void program::rpn_purcentCH() {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
||||||
ARG_MUST_BE_OF_TYPE(1, kNumber);
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief sq keyword implementation
|
/// @brief sq keyword implementation
|
||||||
///
|
///
|
||||||
void program::rpn_square() {
|
void program::rpn_square() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == kNumber)
|
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 == kComplex)
|
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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -270,19 +270,19 @@ void program::rpn_modulo() {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
||||||
ARG_MUST_BE_OF_TYPE(1, kNumber);
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief abs keyword implementation
|
/// @brief abs keyword implementation
|
||||||
///
|
///
|
||||||
void program::rpn_abs() {
|
void program::rpn_abs() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == kNumber) {
|
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) == kComplex) {
|
} 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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -294,17 +294,17 @@ void program::rpn_fact() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief sign keyword implementation
|
/// @brief sign keyword implementation
|
||||||
///
|
///
|
||||||
void program::rpn_sign() {
|
void program::rpn_sign() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == kNumber)
|
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 == kComplex)
|
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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -314,12 +314,12 @@ void program::rpn_sign() {
|
||||||
void program::rpn_mant() {
|
void program::rpn_mant() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
||||||
if (!isfinite(_stack.value<Number>(0))) {
|
if (!isfinite(stack_.value<Number>(0))) {
|
||||||
setErrorContext(kOutOfRange);
|
setErrorContext(kOutOfRange);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mp_exp_t exp;
|
mp_exp_t exp;
|
||||||
_stack.value<Number>(0) = frexp(_stack.value<Number>(0), &exp);
|
stack_.value<Number>(0) = frexp(stack_.value<Number>(0), &exp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief xpon keyword implementation
|
/// @brief xpon keyword implementation
|
||||||
|
@ -327,13 +327,13 @@ void program::rpn_mant() {
|
||||||
void program::rpn_xpon() {
|
void program::rpn_xpon() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
||||||
if (!isfinite(_stack.value<Number>(0))) {
|
if (!isfinite(stack_.value<Number>(0))) {
|
||||||
setErrorContext(kOutOfRange);
|
setErrorContext(kOutOfRange);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mp_exp_t exp;
|
mp_exp_t exp;
|
||||||
(void)frexp(_stack.value<Number>(0), &exp);
|
(void)frexp(stack_.value<Number>(0), &exp);
|
||||||
_stack.value<Number>(0) = exp;
|
stack_.value<Number>(0) = exp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief floor keyword implementation
|
/// @brief floor keyword implementation
|
||||||
|
@ -341,7 +341,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, kNumber);
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief ceil keyword implementation
|
/// @brief ceil keyword implementation
|
||||||
|
@ -349,7 +349,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, kNumber);
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief fp keyword implementation
|
/// @brief fp keyword implementation
|
||||||
|
@ -357,7 +357,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, kNumber);
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief ip keyword implementation
|
/// @brief ip keyword implementation
|
||||||
|
@ -365,7 +365,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, kNumber);
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief min keyword implementation
|
/// @brief min keyword implementation
|
||||||
|
@ -374,8 +374,8 @@ void program::rpn_min() {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
||||||
ARG_MUST_BE_OF_TYPE(1, kNumber);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief max keyword implementation
|
/// @brief max keyword implementation
|
||||||
|
@ -384,6 +384,6 @@ void program::rpn_max() {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
||||||
ARG_MUST_BE_OF_TYPE(1, kNumber);
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,23 +6,23 @@
|
||||||
///
|
///
|
||||||
void program::rpn_swap(void) {
|
void program::rpn_swap(void) {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
Object* tmp = _stack.front();
|
Object* tmp = stack_.front();
|
||||||
_stack.erase(0, 1, false);
|
stack_.erase(0, 1, false);
|
||||||
_stack.insert(_stack.begin() + 1, tmp);
|
stack_.insert(stack_.begin() + 1, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief drop keyword implementation
|
/// @brief drop keyword implementation
|
||||||
///
|
///
|
||||||
void program::rpn_drop(void) {
|
void program::rpn_drop(void) {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
_stack.pop();
|
stack_.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief drop2 keyword implementation
|
/// @brief drop2 keyword implementation
|
||||||
///
|
///
|
||||||
void program::rpn_drop2(void) {
|
void program::rpn_drop2(void) {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
_stack.erase(0, 2);
|
stack_.erase(0, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief dropn keyword implementation
|
/// @brief dropn keyword implementation
|
||||||
|
@ -31,20 +31,20 @@ void program::rpn_dropn(void) {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
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);
|
||||||
_stack.erase(0, args + 1);
|
stack_.erase(0, args + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief erase / del keyword implementation
|
/// @brief erase / del keyword implementation
|
||||||
///
|
///
|
||||||
void program::rpn_erase(void) { _stack.erase(0, _stack.size()); }
|
void program::rpn_erase(void) { stack_.erase(0, stack_.size()); }
|
||||||
|
|
||||||
/// @brief dup keyword implementation
|
/// @brief dup keyword implementation
|
||||||
///
|
///
|
||||||
void program::rpn_dup(void) {
|
void program::rpn_dup(void) {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
_stack.push_front(_stack.at(0)->clone());
|
stack_.push_front(stack_.at(0)->clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief dupn keyword implementation
|
/// @brief dupn keyword implementation
|
||||||
|
@ -53,19 +53,19 @@ void program::rpn_dupn(void) {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
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();
|
||||||
|
|
||||||
MIN_ARGUMENTS(args);
|
MIN_ARGUMENTS(args);
|
||||||
for (int i = 0; i < args; i++) _stack.push_front(_stack.at(args - 1)->clone());
|
for (int i = 0; i < args; i++) stack_.push_front(stack_.at(args - 1)->clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief dup2 keyword implementation
|
/// @brief dup2 keyword implementation
|
||||||
///
|
///
|
||||||
void program::rpn_dup2(void) {
|
void program::rpn_dup2(void) {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
_stack.push_front(_stack.at(1)->clone());
|
stack_.push_front(stack_.at(1)->clone());
|
||||||
_stack.push_front(_stack.at(1)->clone());
|
stack_.push_front(stack_.at(1)->clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief pick keyword implementation
|
/// @brief pick keyword implementation
|
||||||
|
@ -74,30 +74,30 @@ void program::rpn_pick(void) {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
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(kOutOfRange);
|
setErrorContext(kOutOfRange);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_stack.push_front(_stack.at(to_pick - 1)->clone());
|
stack_.push_front(stack_.at(to_pick - 1)->clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief rot keyword implementation
|
/// @brief rot keyword implementation
|
||||||
///
|
///
|
||||||
void program::rpn_rot(void) {
|
void program::rpn_rot(void) {
|
||||||
MIN_ARGUMENTS(3);
|
MIN_ARGUMENTS(3);
|
||||||
Object* tmp = _stack.at(2);
|
Object* tmp = stack_.at(2);
|
||||||
_stack.erase(2, 1, false);
|
stack_.erase(2, 1, false);
|
||||||
_stack.insert(_stack.begin(), tmp);
|
stack_.insert(stack_.begin(), tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief depth keyword implementation
|
/// @brief depth keyword implementation
|
||||||
///
|
///
|
||||||
void program::rpn_depth(void) { _stack.push_front(new Number(_stack.size())); }
|
void program::rpn_depth(void) { stack_.push_front(new Number(stack_.size())); }
|
||||||
|
|
||||||
/// @brief roll keyword implementation
|
/// @brief roll keyword implementation
|
||||||
///
|
///
|
||||||
|
@ -105,13 +105,13 @@ void program::rpn_roll(void) {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
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();
|
||||||
MIN_ARGUMENTS(args);
|
MIN_ARGUMENTS(args);
|
||||||
|
|
||||||
Object* tmp = _stack.at(args - 1);
|
Object* tmp = stack_.at(args - 1);
|
||||||
_stack.erase(args - 1, 1, false);
|
stack_.erase(args - 1, 1, false);
|
||||||
_stack.insert(_stack.begin(), tmp);
|
stack_.insert(stack_.begin(), tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief rolld keyword implementation
|
/// @brief rolld keyword implementation
|
||||||
|
@ -120,18 +120,18 @@ void program::rpn_rolld(void) {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
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();
|
||||||
MIN_ARGUMENTS(args);
|
MIN_ARGUMENTS(args);
|
||||||
|
|
||||||
Object* tmp = _stack.at(0);
|
Object* tmp = stack_.at(0);
|
||||||
_stack.erase(0, 1, false);
|
stack_.erase(0, 1, false);
|
||||||
_stack.insert(_stack.begin() + args - 1, tmp);
|
stack_.insert(stack_.begin() + args - 1, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief over keyword implementation
|
/// @brief over keyword implementation
|
||||||
///
|
///
|
||||||
void program::rpn_over(void) {
|
void program::rpn_over(void) {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
_stack.push_front(_stack.at(1)->clone());
|
stack_.push_front(stack_.at(1)->clone());
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,13 +10,13 @@ void program::rpn_sto(void) {
|
||||||
ARG_MUST_BE_OF_TYPE(0, kSymbol);
|
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));
|
||||||
if (it != _heap.end()) {
|
if (it != heap_.end()) {
|
||||||
delete it->second;
|
delete it->second;
|
||||||
_heap.erase(it);
|
heap_.erase(it);
|
||||||
}
|
}
|
||||||
_heap[_stack.value<String>(0)] = _stack.at(1)->clone();
|
heap_[stack_.value<String>(0)] = stack_.at(1)->clone();
|
||||||
_stack.erase(0, 2);
|
stack_.erase(0, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief sto+ keyword implementation
|
/// @brief sto+ keyword implementation
|
||||||
|
@ -24,7 +24,7 @@ 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, kSymbol);
|
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(kUnknownVariable);
|
setErrorContext(kUnknownVariable);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ 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, kSymbol);
|
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(kUnknownVariable);
|
setErrorContext(kUnknownVariable);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ 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, kSymbol);
|
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(kUnknownVariable);
|
setErrorContext(kUnknownVariable);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ 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, kSymbol);
|
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(kUnknownVariable);
|
setErrorContext(kUnknownVariable);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,7 @@ 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, kSymbol);
|
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(kUnknownVariable);
|
setErrorContext(kUnknownVariable);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -108,7 +108,7 @@ 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, kSymbol);
|
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(kUnknownVariable);
|
setErrorContext(kUnknownVariable);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -127,12 +127,12 @@ void program::rpn_rcl(void) {
|
||||||
|
|
||||||
// recall a variable
|
// recall a variable
|
||||||
Object* obj;
|
Object* obj;
|
||||||
string variable(_stack.value<Symbol>(0));
|
string variable(stack_.value<Symbol>(0));
|
||||||
|
|
||||||
// mind the order of heaps
|
// mind the order of heaps
|
||||||
if (find_variable(variable, obj)) {
|
if (find_variable(variable, obj)) {
|
||||||
(void)_stack.pop();
|
(void)stack_.pop();
|
||||||
_stack.push_front(obj->clone());
|
stack_.push_front(obj->clone());
|
||||||
} else {
|
} else {
|
||||||
setErrorContext(kUnknownVariable);
|
setErrorContext(kUnknownVariable);
|
||||||
}
|
}
|
||||||
|
@ -145,9 +145,9 @@ void program::rpn_edit(void) {
|
||||||
|
|
||||||
ostringstream st;
|
ostringstream st;
|
||||||
|
|
||||||
// re-write stack objet in a stream
|
// re-write stack_ objet in a stream
|
||||||
_stack.at(0)->show(st);
|
stack_.at(0)->show(st);
|
||||||
_stack.pop();
|
stack_.pop();
|
||||||
|
|
||||||
// set it as the linenoise line entry
|
// set it as the linenoise line entry
|
||||||
Input::preload(st.str().c_str());
|
Input::preload(st.str().c_str());
|
||||||
|
@ -158,19 +158,19 @@ void program::rpn_edit(void) {
|
||||||
/// @param symb the smlbol to recall and autoeval
|
/// @param symb the smlbol to recall and autoeval
|
||||||
///
|
///
|
||||||
void program::auto_rcl(Symbol* symb) {
|
void program::auto_rcl(Symbol* symb) {
|
||||||
if (symb->autoEval) {
|
if (symb->auto_eval) {
|
||||||
Object* obj;
|
Object* obj;
|
||||||
string variable(symb->value);
|
string variable(symb->value);
|
||||||
|
|
||||||
// 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 == kProgram) rpn_eval();
|
if (obj->_type == kProgram) rpn_eval();
|
||||||
} else {
|
} else {
|
||||||
_stack.push_front(symb->clone());
|
stack_.push_front(symb->clone());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_stack.push_front(symb->clone());
|
stack_.push_front(symb->clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,46 +180,46 @@ void program::rpn_purge(void) {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, kSymbol);
|
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(kUnknownVariable);
|
setErrorContext(kUnknownVariable);
|
||||||
}
|
}
|
||||||
_stack.pop();
|
stack_.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief vars keyword implementation
|
/// @brief vars keyword implementation
|
||||||
///
|
///
|
||||||
void program::rpn_vars(void) {
|
void program::rpn_vars(void) {
|
||||||
Object* obj;
|
Object* obj;
|
||||||
program* parent = _parent;
|
program* parent = parent_;
|
||||||
string name;
|
string name;
|
||||||
int index = 1;
|
int index = 1;
|
||||||
|
|
||||||
// heap variables
|
// heap variables
|
||||||
for (auto i : _heap) {
|
for (auto i : heap_) {
|
||||||
cout << "var " << index++ << ": name '" << i.first << "', type " << i.second->name() << ", value ";
|
cout << "var " << index++ << ": name '" << i.first << "', type " << i.second->name() << ", value ";
|
||||||
i.second->show(cout) << endl;
|
i.second->show(cout) << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// local variables
|
// local variables
|
||||||
for (auto i : _local_heap) {
|
for (auto i : local_heap_) {
|
||||||
cout << "var " << index++ << ": name '" << i.first << "', type " << i.second->name() << ", value ";
|
cout << "var " << index++ << ": name '" << i.first << "', type " << i.second->name() << ", value ";
|
||||||
i.second->show(cout) << endl;
|
i.second->show(cout) << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// parents local variables
|
// parents local variables
|
||||||
while (parent != nullptr) {
|
while (parent != nullptr) {
|
||||||
for (auto i : parent->_local_heap) {
|
for (auto i : parent->local_heap_) {
|
||||||
cout << "parent var " << index++ << ": name '" << i.first << "', type " << i.second->name() << ", value ";
|
cout << "parent var " << index++ << ": name '" << i.first << "', type " << i.second->name() << ", value ";
|
||||||
obj->show(cout) << endl;
|
obj->show(cout) << endl;
|
||||||
}
|
}
|
||||||
parent = parent->_parent;
|
parent = parent->parent_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief clusr keyword implementation
|
/// @brief clusr keyword implementation
|
||||||
///
|
///
|
||||||
void program::rpn_clusr(void) { _heap.clear(); }
|
void program::rpn_clusr(void) { heap_.clear(); }
|
||||||
|
|
|
@ -10,11 +10,11 @@ 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) != kString) {
|
if (stack_.type(0) != kString) {
|
||||||
stringstream ss;
|
stringstream ss;
|
||||||
ss << _stack.at(0);
|
ss << stack_.at(0);
|
||||||
_stack.pop();
|
stack_.pop();
|
||||||
_stack.push(new String(ss.str()));
|
stack_.push(new String(ss.str()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,11 +24,11 @@ void program::rpn_strout() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, kString);
|
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) == kOk)
|
if (prog.parse(entry) == kOk)
|
||||||
// run it
|
// run it
|
||||||
prog.run();
|
prog.run();
|
||||||
|
@ -39,10 +39,10 @@ void program::rpn_strout() {
|
||||||
void program::rpn_chr() {
|
void program::rpn_chr() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
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 = '.';
|
||||||
_stack.push_front(new String(string(1, the_chr)));
|
stack_.push_front(new String(string(1, the_chr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief num keyword implementation
|
/// @brief num keyword implementation
|
||||||
|
@ -50,11 +50,11 @@ void program::rpn_chr() {
|
||||||
void program::rpn_num() {
|
void program::rpn_num() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, kString);
|
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
|
||||||
_stack.push_front(new Number(0));
|
stack_.push_front(new Number(0));
|
||||||
_stack.erase(1);
|
stack_.erase(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief size keyword implementation
|
/// @brief size keyword implementation
|
||||||
|
@ -62,8 +62,8 @@ void program::rpn_num() {
|
||||||
void program::rpn_strsize() {
|
void program::rpn_strsize() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, kString);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief pos keyword implementation
|
/// @brief pos keyword implementation
|
||||||
|
@ -73,9 +73,9 @@ void program::rpn_strpos() {
|
||||||
ARG_MUST_BE_OF_TYPE(0, kString);
|
ARG_MUST_BE_OF_TYPE(0, kString);
|
||||||
ARG_MUST_BE_OF_TYPE(1, kString);
|
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);
|
||||||
_stack.push_front(new Number(pos));
|
stack_.push_front(new Number(pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief sub keyword implementation
|
/// @brief sub keyword implementation
|
||||||
|
@ -86,11 +86,11 @@ void program::rpn_strsub() {
|
||||||
ARG_MUST_BE_OF_TYPE(1, kNumber);
|
ARG_MUST_BE_OF_TYPE(1, kNumber);
|
||||||
ARG_MUST_BE_OF_TYPE(2, kString);
|
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;
|
||||||
first--;
|
first--;
|
||||||
|
|
||||||
if (first > _stack.value<String>(2).size()) first = len = 0;
|
if (first > stack_.value<String>(2).size()) first = len = 0;
|
||||||
_stack.push(new String(_stack.value<String>(2).substr(first, len)));
|
stack_.push(new String(stack_.value<String>(2).substr(first, len)));
|
||||||
_stack.erase(1, 3);
|
stack_.erase(1, 3);
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,16 +76,16 @@ void program::rpn_test() {
|
||||||
int total_steps = 0;
|
int total_steps = 0;
|
||||||
int total_steps_failed = 0;
|
int total_steps_failed = 0;
|
||||||
|
|
||||||
string test_filename = _stack.value<String>(0);
|
string test_filename = stack_.value<String>(0);
|
||||||
_stack.pop();
|
stack_.pop();
|
||||||
cout << endl << "rpn version is " << RPN_VERSION << endl;
|
cout << endl << "rpn version is " << RPN_VERSION << endl;
|
||||||
test(test_filename, total_tests, total_tests_failed, total_steps, total_steps_failed);
|
test(test_filename, total_tests, total_tests_failed, total_steps, total_steps_failed);
|
||||||
testShowResult("\nTotal", total_tests, total_tests_failed, total_steps, total_steps_failed);
|
testShowResult("\nTotal", total_tests, total_tests_failed, total_steps, total_steps_failed);
|
||||||
|
|
||||||
// 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 = kTestFailed;
|
err_ = kTestFailed;
|
||||||
_err_context = string("rpn version ") + RPN_VERSION + ", test file " + test_filename;
|
err_context_ = string("rpn version ") + RPN_VERSION + ", test file " + test_filename;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
116
src/rpn-test.cpp
116
src/rpn-test.cpp
|
@ -2,13 +2,13 @@
|
||||||
|
|
||||||
#include "program.hpp"
|
#include "program.hpp"
|
||||||
|
|
||||||
/// @brief compared 2 strings on top of the stack
|
/// @brief compared 2 strings on top of the stack_
|
||||||
///
|
///
|
||||||
/// @return 0 strings are equal
|
/// @return 0 strings are equal
|
||||||
/// @return !0 strings are not equal (see strcmp output)
|
/// @return !0 strings are not equal (see strcmp output)
|
||||||
///
|
///
|
||||||
static int CmpStringOnStackTop(rpnstack& stk) {
|
static int CmpStringOnStackTop(rpnstack& stk) {
|
||||||
// _stack should have 2 strings at level 1 and 2
|
// stack_ should have 2 strings at level 1 and 2
|
||||||
// this function removes these 2 entries
|
// this function removes these 2 entries
|
||||||
int res = stk.value<String>(1).compare(stk.value<String>(0));
|
int res = stk.value<String>(1).compare(stk.value<String>(0));
|
||||||
stk.erase(0, 2);
|
stk.erase(0, 2);
|
||||||
|
@ -19,12 +19,12 @@ 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) == kNumber && _stack.type(1) == kNumber) {
|
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) == kString && _stack.type(1) == kString) {
|
} 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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -34,12 +34,12 @@ 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) == kNumber && _stack.type(1) == kNumber) {
|
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) == kString && _stack.type(1) == kString) {
|
} 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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -50,12 +50,12 @@ 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) == kNumber && _stack.type(1) == kNumber) {
|
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) == kString && _stack.type(1) == kString) {
|
} 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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -65,12 +65,12 @@ 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) == kNumber && _stack.type(1) == kNumber) {
|
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) == kString && _stack.type(1) == kString) {
|
} 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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -80,15 +80,15 @@ 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) == kNumber && _stack.type(1) == kNumber) {
|
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) == kComplex && _stack.type(1) == kComplex) {
|
} 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) == kString && _stack.type(1) == kString) {
|
} 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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -98,15 +98,15 @@ 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) == kNumber && _stack.type(1) == kNumber) {
|
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) == kComplex && _stack.type(1) == kComplex) {
|
} 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) == kString && _stack.type(1) == kString) {
|
} 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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -118,11 +118,11 @@ void program::rpn_test_and(void) {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
||||||
ARG_MUST_BE_OF_TYPE(1, kNumber);
|
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
|
||||||
_stack.push(new Number(0));
|
stack_.push(new Number(0));
|
||||||
_stack.erase(1, 2);
|
stack_.erase(1, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief or keyword implementation
|
/// @brief or keyword implementation
|
||||||
|
@ -131,11 +131,11 @@ void program::rpn_test_or(void) {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
||||||
ARG_MUST_BE_OF_TYPE(1, kNumber);
|
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
|
||||||
_stack.push(new Number(0));
|
stack_.push(new Number(0));
|
||||||
_stack.erase(1, 2);
|
stack_.erase(1, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief xor keyword implementation
|
/// @brief xor keyword implementation
|
||||||
|
@ -144,11 +144,11 @@ void program::rpn_test_xor(void) {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
||||||
ARG_MUST_BE_OF_TYPE(1, kNumber);
|
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
|
||||||
_stack.push(new Number(0));
|
stack_.push(new Number(0));
|
||||||
_stack.erase(1, 2);
|
stack_.erase(1, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief not keyword implementation
|
/// @brief not keyword implementation
|
||||||
|
@ -157,8 +157,8 @@ void program::rpn_test_not(void) {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief test same implementation
|
/// @brief test same implementation
|
||||||
|
|
|
@ -22,8 +22,8 @@ void program::rpn_time() {
|
||||||
|
|
||||||
// push it
|
// push it
|
||||||
// division after push for real precision
|
// division after push for real precision
|
||||||
_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(kInternalError);
|
setErrorContext(kInternalError);
|
||||||
}
|
}
|
||||||
|
@ -48,8 +48,8 @@ void program::rpn_date() {
|
||||||
// push it
|
// push it
|
||||||
Number* num;
|
Number* num;
|
||||||
// division after push for real precision
|
// division after push for real precision
|
||||||
_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(kInternalError);
|
setErrorContext(kInternalError);
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ void program::rpn_ticks() {
|
||||||
if (tm != nullptr) {
|
if (tm != nullptr) {
|
||||||
// date in µs
|
// date in µs
|
||||||
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(kInternalError);
|
setErrorContext(kInternalError);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
/// @brief pi keyword implementation
|
/// @brief pi keyword implementation
|
||||||
///
|
///
|
||||||
void program::rpn_pi(void) {
|
void program::rpn_pi(void) {
|
||||||
_stack.push_front(new Number(mpfr::const_pi()));
|
stack_.push_front(new Number(mpfr::const_pi()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief d->r keyword implementation
|
/// @brief d->r keyword implementation
|
||||||
|
@ -13,8 +13,8 @@ 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, kNumber);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief r->d keyword implementation
|
/// @brief r->d keyword implementation
|
||||||
|
@ -22,18 +22,18 @@ 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, kNumber);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief sin keyword implementation
|
/// @brief sin keyword implementation
|
||||||
///
|
///
|
||||||
void program::rpn_sin(void) {
|
void program::rpn_sin(void) {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == kNumber)
|
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) == kComplex)
|
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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -42,10 +42,10 @@ void program::rpn_sin(void) {
|
||||||
///
|
///
|
||||||
void program::rpn_asin(void) {
|
void program::rpn_asin(void) {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == kNumber)
|
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) == kComplex)
|
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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -54,10 +54,10 @@ void program::rpn_asin(void) {
|
||||||
///
|
///
|
||||||
void program::rpn_cos(void) {
|
void program::rpn_cos(void) {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == kNumber)
|
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) == kComplex)
|
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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -66,10 +66,10 @@ void program::rpn_cos(void) {
|
||||||
///
|
///
|
||||||
void program::rpn_acos(void) {
|
void program::rpn_acos(void) {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == kNumber)
|
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) == kComplex)
|
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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -78,10 +78,10 @@ void program::rpn_acos(void) {
|
||||||
///
|
///
|
||||||
void program::rpn_tan(void) {
|
void program::rpn_tan(void) {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == kNumber)
|
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) == kComplex)
|
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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
@ -90,10 +90,10 @@ void program::rpn_tan(void) {
|
||||||
///
|
///
|
||||||
void program::rpn_atan(void) {
|
void program::rpn_atan(void) {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == kNumber)
|
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) == kComplex)
|
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(kBadOperandType);
|
setErrorContext(kBadOperandType);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue