mirror of
https://github.com/louisrubet/rpn
synced 2025-02-07 08:45:48 +01:00
PascalCase classes, snake_case variables, (some) PAscalCase functions
This commit is contained in:
parent
e0665fc94f
commit
d0c7304ffd
26 changed files with 472 additions and 480 deletions
|
@ -15,7 +15,9 @@ Changelog
|
||||||
- static and global variables
|
- static and global variables
|
||||||
- common patterns (ex: no static maps or vectors)
|
- common patterns (ex: no static maps or vectors)
|
||||||
- classes (explicit)
|
- classes (explicit)
|
||||||
- naming: file names (.cc .h), types (PascalCase), variables (snake_case), members (trailing _), static const (camelCase begining with k), enum (enum class, values like static const)
|
- naming:
|
||||||
|
- file names (.cc .h), types (PascalCase), variables (snake_case), members (trailing _), static const (camelCase begining with k), enum (enum class, values like static const
|
||||||
|
- consistent comments (//), class comments, functions comments
|
||||||
- cpplint used with a CPPLINT.cfg removing some warnings
|
- cpplint used with a CPPLINT.cfg removing some warnings
|
||||||
- Test files are now markdown (.md) files, tests result are slightly changed
|
- Test files are now markdown (.md) files, tests result are slightly changed
|
||||||
- Delivery as flatpak and snap
|
- Delivery as flatpak and snap
|
||||||
|
|
|
@ -4,21 +4,22 @@
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
vector<string>* Input::_acWords = nullptr;
|
vector<string>* Input::_ac_list = nullptr;
|
||||||
|
|
||||||
Input::Input(string& entry, vector<string>& autocompletionWords, string prompt, string mlPrompt) : status(cont) {
|
Input::Input(string& entry, vector<string>& autocompletion_list, string prompt, string multiline_prompt)
|
||||||
|
: status(cont) {
|
||||||
char* c_entry = nullptr;
|
char* c_entry = nullptr;
|
||||||
bool multiline = false;
|
bool multiline = false;
|
||||||
int entry_len;
|
int entry_len;
|
||||||
|
|
||||||
_acWords = &autocompletionWords;
|
_ac_list = &autocompletion_list;
|
||||||
|
|
||||||
// linenoise for entry
|
// linenoise for entry
|
||||||
linenoiseSetCompletionCallback(entry_completion_generator);
|
linenoiseSetCompletionCallback(entry_completion_generator);
|
||||||
while (status == cont) {
|
while (status == cont) {
|
||||||
// get user entry
|
// get user entry
|
||||||
if (multiline)
|
if (multiline)
|
||||||
c_entry = linenoise(mlPrompt.c_str(), &entry_len);
|
c_entry = linenoise(multiline_prompt.c_str(), &entry_len);
|
||||||
else
|
else
|
||||||
c_entry = linenoise(prompt.c_str(), &entry_len);
|
c_entry = linenoise(prompt.c_str(), &entry_len);
|
||||||
|
|
||||||
|
@ -53,16 +54,16 @@ Input::Input(string& entry, vector<string>& autocompletionWords, string prompt,
|
||||||
/// @param lc the completion object to add strings with linenoiseAddCompletion()
|
/// @param lc the completion object to add strings with linenoiseAddCompletion()
|
||||||
///
|
///
|
||||||
void Input::entry_completion_generator(const char* text, linenoiseCompletions* lc) {
|
void Input::entry_completion_generator(const char* text, linenoiseCompletions* lc) {
|
||||||
if (Input::_acWords == nullptr || text == nullptr) return;
|
if (Input::_ac_list == nullptr || text == nullptr) return;
|
||||||
|
|
||||||
int text_len = strnlen(text, 6);
|
int text_len = strnlen(text, 6);
|
||||||
|
|
||||||
if (text_len == 0)
|
if (text_len == 0)
|
||||||
// propose all keywords
|
// propose all keywords
|
||||||
for (string& ac : *Input::_acWords) linenoiseAddCompletion(lc, ac.c_str());
|
for (string& ac : *Input::_ac_list) linenoiseAddCompletion(lc, ac.c_str());
|
||||||
else
|
else
|
||||||
// propose only keywords matching to text begining
|
// propose only keywords matching to text begining
|
||||||
for (string& ac : *Input::_acWords)
|
for (string& ac : *Input::_ac_list)
|
||||||
// compare list entry with text, return if match
|
// compare list entry with text, return if match
|
||||||
if (ac.compare(0, text_len, text) == 0) linenoiseAddCompletion(lc, ac.c_str());
|
if (ac.compare(0, text_len, text) == 0) linenoiseAddCompletion(lc, ac.c_str());
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,21 +6,21 @@
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
using std::vector;
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
using std::vector;
|
||||||
|
|
||||||
#include "linenoise.h"
|
#include "linenoise.h"
|
||||||
|
|
||||||
class Input {
|
class Input {
|
||||||
public:
|
public:
|
||||||
Input(string& entry, vector<string>& autocompletionWords, string prompt = "rpn> ", string mlPrompt = ">");
|
Input(string& entry, vector<string>& autocompletion_list, string prompt = "rpn> ", string multiline_prompt = ">");
|
||||||
enum { ok, cont, abort, ctrlc, error } status;
|
enum { ok, cont, abort, ctrlc, error } status;
|
||||||
|
|
||||||
static void preload(const char* preloadText);
|
static void preload(const char* preloadText);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void entry_completion_generator(const char* text, linenoiseCompletions* lc);
|
static void entry_completion_generator(const char* text, linenoiseCompletions* lc);
|
||||||
static vector<string>* _acWords;
|
static vector<string>* _ac_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SRC_INPUT_HPP_
|
#endif // SRC_INPUT_HPP_
|
||||||
|
|
|
@ -49,39 +49,39 @@ void Lexer::trim(string& s) {
|
||||||
s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) { return !std::isspace(ch); }).base(), s.end());
|
s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) { return !std::isspace(ch); }).base(), s.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Lexer::parseString(string& entry, size_t idx, size_t& nextIdx, vector<SynError>& errors,
|
bool Lexer::parseString(string& entry, size_t idx, size_t& next_idx, vector<SynError>& errors,
|
||||||
vector<SynElement>& elements) {
|
vector<SynElement>& elements) {
|
||||||
// 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] == '"') {
|
||||||
if (entry[i] - 1 != '\\') {
|
if (entry[i] - 1 != '\\') {
|
||||||
elements.push_back({cmd_string, .value = entry.substr(idx + 1, i - idx - 1)});
|
elements.push_back({cmd_string, .value = entry.substr(idx + 1, i - idx - 1)});
|
||||||
nextIdx = i + 1;
|
next_idx = i + 1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elements.push_back({cmd_string, .value = entry.substr(idx + 1, entry.size() - idx - 1)});
|
elements.push_back({cmd_string, .value = entry.substr(idx + 1, entry.size() - idx - 1)});
|
||||||
nextIdx = entry.size();
|
next_idx = entry.size();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Lexer::parseSymbol(string& entry, size_t idx, size_t& nextIdx, vector<SynError>& errors,
|
bool Lexer::parseSymbol(string& entry, size_t idx, size_t& next_idx, vector<SynError>& errors,
|
||||||
vector<SynElement>& elements) {
|
vector<SynElement>& elements) {
|
||||||
// here we are sure that entry[0] is at least '\''
|
// here we are sure that entry[0] is at least '\''
|
||||||
for (size_t i = idx + 1; i < entry.size(); i++) {
|
for (size_t i = idx + 1; i < entry.size(); i++) {
|
||||||
if (entry[i] == '\'') {
|
if (entry[i] == '\'') {
|
||||||
elements.push_back({cmd_symbol, .value = entry.substr(idx + 1, i - idx - 1), .autoEval = false});
|
elements.push_back({cmd_symbol, .value = entry.substr(idx + 1, i - idx - 1), .autoEval = false});
|
||||||
nextIdx = i + 1;
|
next_idx = i + 1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elements.push_back({cmd_symbol, .value = entry.substr(idx + 1, entry.size() - idx - 1)});
|
elements.push_back({cmd_symbol, .value = entry.substr(idx + 1, entry.size() - idx - 1)});
|
||||||
nextIdx = entry.size();
|
next_idx = entry.size();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Lexer::parseProgram(string& entry, size_t idx, size_t& nextIdx, vector<SynError>& errors,
|
bool Lexer::parseProgram(string& entry, size_t idx, size_t& next_idx, vector<SynError>& errors,
|
||||||
vector<SynElement>& elements) {
|
vector<SynElement>& elements) {
|
||||||
// here we are sure that entry is at least "<<"
|
// here we are sure that entry is at least "<<"
|
||||||
// find last ">>" or "»"
|
// find last ">>" or "»"
|
||||||
|
@ -94,7 +94,7 @@ bool Lexer::parseProgram(string& entry, size_t idx, size_t& nextIdx, vector<SynE
|
||||||
string prg = entry.substr(idx + 2, i - idx - 2);
|
string prg = entry.substr(idx + 2, i - idx - 2);
|
||||||
trim(prg);
|
trim(prg);
|
||||||
elements.push_back({cmd_program, .value = prg});
|
elements.push_back({cmd_program, .value = prg});
|
||||||
nextIdx = i + 2;
|
next_idx = i + 2;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
countNested--;
|
countNested--;
|
||||||
|
@ -104,24 +104,24 @@ bool Lexer::parseProgram(string& entry, size_t idx, size_t& nextIdx, vector<SynE
|
||||||
string prg = entry.substr(idx + 2, entry.size() - idx - 2);
|
string prg = entry.substr(idx + 2, entry.size() - idx - 2);
|
||||||
trim(prg);
|
trim(prg);
|
||||||
elements.push_back({cmd_program, .value = prg});
|
elements.push_back({cmd_program, .value = prg});
|
||||||
nextIdx = entry.size();
|
next_idx = entry.size();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Lexer::getBaseAt(string& entry, size_t& nextIdx, bool& positive) {
|
int Lexer::getBaseAt(string& entry, size_t& next_idx, bool& positive) {
|
||||||
// a regex could be "([+-])?((0[xX])|([0-9][0-9]?[bB]))"
|
// a regex could be "([+-])?((0[xX])|([0-9][0-9]?[bB]))"
|
||||||
// regex is not use because dramatically slow
|
// regex is not use because dramatically slow
|
||||||
// entry is scanned from idxStart, searching for [s]abc (sign and 3 first chars)
|
// entry is scanned from idxStart, searching for [s]abc (sign and 3 first chars)
|
||||||
size_t scan = 0;
|
size_t scan = 0;
|
||||||
nextIdx = 0;
|
next_idx = 0;
|
||||||
positive = true;
|
positive = true;
|
||||||
if (scan >= entry.size()) return 10;
|
if (scan >= entry.size()) return 10;
|
||||||
if (entry[scan] == '+') {
|
if (entry[scan] == '+') {
|
||||||
scan++;
|
scan++;
|
||||||
nextIdx = scan;
|
next_idx = scan;
|
||||||
} else if (entry[scan] == '-') {
|
} else if (entry[scan] == '-') {
|
||||||
scan++;
|
scan++;
|
||||||
nextIdx = scan;
|
next_idx = scan;
|
||||||
positive = false;
|
positive = false;
|
||||||
}
|
}
|
||||||
if (scan + 2 >= entry.size()) return 10;
|
if (scan + 2 >= entry.size()) return 10;
|
||||||
|
@ -131,38 +131,38 @@ int Lexer::getBaseAt(string& entry, size_t& nextIdx, bool& positive) {
|
||||||
if (scan + 2 < entry.size()) c = entry[scan + 2];
|
if (scan + 2 < entry.size()) c = entry[scan + 2];
|
||||||
if (a == '0') {
|
if (a == '0') {
|
||||||
if (b == 'x' || b == 'X') {
|
if (b == 'x' || b == 'X') {
|
||||||
nextIdx = scan + 2;
|
next_idx = scan + 2;
|
||||||
return 16;
|
return 16;
|
||||||
}
|
}
|
||||||
if (b == 'b' || b == 'B') {
|
if (b == 'b' || b == 'B') {
|
||||||
nextIdx = scan + 2;
|
next_idx = scan + 2;
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
} else if (isdigit(a)) {
|
} else if (isdigit(a)) {
|
||||||
if (b == 'b' || b == 'B') {
|
if (b == 'b' || b == 'B') {
|
||||||
nextIdx = scan + 2;
|
next_idx = scan + 2;
|
||||||
return static_cast<int>(a - '0');
|
return static_cast<int>(a - '0');
|
||||||
}
|
}
|
||||||
if (isdigit(b) && (c == 'b' || c == 'B')) {
|
if (isdigit(b) && (c == 'b' || c == 'B')) {
|
||||||
nextIdx = scan + 3;
|
next_idx = scan + 3;
|
||||||
return 10 * static_cast<int>(a - '0') + static_cast<int>(b - '0');
|
return 10 * static_cast<int>(a - '0') + static_cast<int>(b - '0');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 10;
|
return 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Lexer::getNumberAt(string& entry, size_t idx, size_t& nextIdx, int& base, mpreal** r, char delim) {
|
bool Lexer::getNumberAt(string& entry, size_t idx, size_t& next_idx, int& base, mpreal** r, char delim) {
|
||||||
stringstream ss;
|
stringstream ss;
|
||||||
int idxNumber = 0;
|
int idxNumber = 0;
|
||||||
string token;
|
string token;
|
||||||
bool positive = true;
|
bool positive = true;
|
||||||
|
|
||||||
nextIdx = idx;
|
next_idx = idx;
|
||||||
|
|
||||||
ss.str(entry.substr(idx));
|
ss.str(entry.substr(idx));
|
||||||
if (getline(ss, token, delim)) {
|
if (getline(ss, token, delim)) {
|
||||||
size_t numberIdx;
|
size_t numberIdx;
|
||||||
nextIdx = token.size() + idx + 1;
|
next_idx = token.size() + idx + 1;
|
||||||
trim(token);
|
trim(token);
|
||||||
base = getBaseAt(token, numberIdx, positive);
|
base = getBaseAt(token, numberIdx, positive);
|
||||||
if (base < 2 || base > 62) return false;
|
if (base < 2 || base > 62) return false;
|
||||||
|
@ -176,15 +176,15 @@ bool Lexer::getNumberAt(string& entry, size_t idx, size_t& nextIdx, int& base, m
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nextIdx = token.size() + idx + 1;
|
next_idx = token.size() + idx + 1;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Lexer::parseNumber(string& entry, size_t idx, size_t& nextIdx, vector<SynError>& errors,
|
bool Lexer::parseNumber(string& entry, size_t idx, size_t& next_idx, vector<SynError>& errors,
|
||||||
vector<SynElement>& elements) {
|
vector<SynElement>& elements) {
|
||||||
mpreal* r = nullptr;
|
mpreal* r = nullptr;
|
||||||
int base = 10;
|
int base = 10;
|
||||||
if (getNumberAt(entry, idx, nextIdx, base, &r)) {
|
if (getNumberAt(entry, idx, next_idx, base, &r)) {
|
||||||
elements.push_back({cmd_number, .re = r, .reBase = base});
|
elements.push_back({cmd_number, .re = r, .reBase = base});
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -193,44 +193,44 @@ bool Lexer::parseNumber(string& entry, size_t idx, size_t& nextIdx, vector<SynEr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Lexer::parseComplex(string& entry, size_t idx, size_t& nextIdx, vector<SynError>& errors,
|
bool Lexer::parseComplex(string& entry, size_t idx, size_t& next_idx, vector<SynError>& errors,
|
||||||
vector<SynElement>& elements) {
|
vector<SynElement>& elements) {
|
||||||
mpreal* re = nullptr;
|
mpreal* re = nullptr;
|
||||||
mpreal* im = nullptr;
|
mpreal* im = nullptr;
|
||||||
int reBase, imBase = 10;
|
int reBase, imBase = 10;
|
||||||
if (idx + 1 == entry.size()) {
|
if (idx + 1 == entry.size()) {
|
||||||
elements.push_back({cmd_symbol, .value = entry.substr(idx, entry.size() - idx)});
|
elements.push_back({cmd_symbol, .value = entry.substr(idx, entry.size() - idx)});
|
||||||
nextIdx = 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, nextIdx, reBase, &re, ',')) {
|
if (!getNumberAt(entry, idx + 1, next_idx, reBase, &re, ',')) {
|
||||||
elements.push_back({cmd_symbol, .value = entry.substr(idx, entry.size() - idx)});
|
elements.push_back({cmd_symbol, .value = entry.substr(idx, entry.size() - idx)});
|
||||||
nextIdx = entry.size();
|
next_idx = entry.size();
|
||||||
return true; // complex format error, return a symbol
|
return true; // complex format error, return a symbol
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t i = nextIdx;
|
size_t i = next_idx;
|
||||||
if (i >= entry.size()) {
|
if (i >= entry.size()) {
|
||||||
elements.push_back({cmd_symbol, .value = entry.substr(idx, entry.size() - idx)});
|
elements.push_back({cmd_symbol, .value = entry.substr(idx, entry.size() - idx)});
|
||||||
nextIdx = 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
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!getNumberAt(entry, i, nextIdx, imBase, &im, ')')) {
|
if (!getNumberAt(entry, i, next_idx, imBase, &im, ')')) {
|
||||||
elements.push_back({cmd_symbol, .value = entry.substr(idx, entry.size() - idx)});
|
elements.push_back({cmd_symbol, .value = entry.substr(idx, entry.size() - idx)});
|
||||||
nextIdx = entry.size();
|
next_idx = entry.size();
|
||||||
if (re != nullptr) delete re;
|
if (re != nullptr) delete re;
|
||||||
if (im != nullptr) delete im;
|
if (im != nullptr) delete im;
|
||||||
return true; // complex format error, return a symbol
|
return true; // complex format error, return a symbol
|
||||||
}
|
}
|
||||||
elements.push_back({cmd_complex, .re = re, .im = im, .reBase = reBase, .imBase = imBase});
|
elements.push_back({cmd_complex, .re = re, .im = im, .reBase = reBase, .imBase = imBase});
|
||||||
nextIdx++;
|
next_idx++;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Lexer::parseReserved(string& entry, size_t idx, size_t& nextIdx, vector<SynElement>& elements,
|
bool Lexer::parseReserved(string& entry, size_t idx, size_t& next_idx, vector<SynElement>& elements,
|
||||||
map<string, ReservedWord>& keywords) {
|
map<string, ReservedWord>& keywords) {
|
||||||
stringstream ss(entry.substr(idx));
|
stringstream ss(entry.substr(idx));
|
||||||
string token;
|
string token;
|
||||||
|
@ -239,17 +239,17 @@ bool Lexer::parseReserved(string& entry, size_t idx, size_t& nextIdx, vector<Syn
|
||||||
auto resa = keywords.find(token);
|
auto resa = keywords.find(token);
|
||||||
if (resa != keywords.end()) {
|
if (resa != keywords.end()) {
|
||||||
elements.push_back({resa->second.type, .value = token, .fn = resa->second.fn});
|
elements.push_back({resa->second.type, .value = token, .fn = resa->second.fn});
|
||||||
nextIdx = token.size() + idx;
|
next_idx = token.size() + idx;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Lexer::parseUnknown(string& entry, size_t idx, size_t& nextIdx, vector<SynElement>& elements) {
|
bool Lexer::parseUnknown(string& entry, size_t idx, size_t& next_idx, vector<SynElement>& elements) {
|
||||||
stringstream ss(entry.substr(idx));
|
stringstream ss(entry.substr(idx));
|
||||||
string token;
|
string token;
|
||||||
ss >> token;
|
ss >> token;
|
||||||
elements.push_back({cmd_symbol, .value = token, .autoEval = true});
|
elements.push_back({cmd_symbol, .value = token, .autoEval = true});
|
||||||
nextIdx = token.size() + idx;
|
next_idx = token.size() + idx;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,23 +53,23 @@ class Lexer {
|
||||||
vector<SynError>& errors);
|
vector<SynError>& errors);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool parseString(string& entry, size_t idx, size_t& nextIdx, vector<SynError>& errors,
|
bool parseString(string& entry, size_t idx, size_t& next_idx, vector<SynError>& errors,
|
||||||
vector<SynElement>& elements);
|
vector<SynElement>& elements);
|
||||||
bool parseSymbol(string& entry, size_t idx, size_t& nextIdx, vector<SynError>& errors,
|
bool parseSymbol(string& entry, size_t idx, size_t& next_idx, vector<SynError>& errors,
|
||||||
vector<SynElement>& elements);
|
vector<SynElement>& elements);
|
||||||
bool parseProgram(string& entry, size_t idx, size_t& nextIdx, vector<SynError>& errors,
|
bool parseProgram(string& entry, size_t idx, size_t& next_idx, vector<SynError>& errors,
|
||||||
vector<SynElement>& elements);
|
vector<SynElement>& elements);
|
||||||
bool parseNumber(string& entry, size_t idx, size_t& nextIdx, vector<SynError>& errors,
|
bool parseNumber(string& entry, size_t idx, size_t& next_idx, vector<SynError>& errors,
|
||||||
vector<SynElement>& elements);
|
vector<SynElement>& elements);
|
||||||
bool parseComplex(string& entry, size_t idx, size_t& nextIdx, vector<SynError>& errors,
|
bool parseComplex(string& entry, size_t idx, size_t& next_idx, vector<SynError>& errors,
|
||||||
vector<SynElement>& elements);
|
vector<SynElement>& elements);
|
||||||
bool parseReserved(string& entry, size_t idx, size_t& nextIdx, vector<SynElement>& elements,
|
bool parseReserved(string& entry, size_t idx, size_t& next_idx, vector<SynElement>& elements,
|
||||||
map<string, ReservedWord>& keywords);
|
map<string, ReservedWord>& keywords);
|
||||||
bool parseUnknown(string& entry, size_t idx, size_t& nextIdx, vector<SynElement>& elements);
|
bool parseUnknown(string& entry, size_t idx, size_t& next_idx, vector<SynElement>& elements);
|
||||||
|
|
||||||
void trim(string& s);
|
void trim(string& s);
|
||||||
int getBaseAt(string& entry, size_t& nextIdx, bool& positive);
|
int getBaseAt(string& entry, size_t& next_idx, bool& positive);
|
||||||
bool getNumberAt(string& entry, size_t idx, size_t& nextIdx, int& base, mpreal** r, char delim = ' ');
|
bool getNumberAt(string& entry, size_t idx, size_t& next_idx, int& base, mpreal** r, char delim = ' ');
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SRC_LEXER_HPP_
|
#endif // SRC_LEXER_HPP_
|
||||||
|
|
18
src/main.cpp
18
src/main.cpp
|
@ -14,7 +14,7 @@ using std::cerr;
|
||||||
|
|
||||||
/// @brief actions to be done at rpn exit
|
/// @brief actions to be done at rpn exit
|
||||||
///
|
///
|
||||||
static void exit_interactive_rpn() {
|
static void ExitInteractive() {
|
||||||
struct passwd* pw = getpwuid(getuid());
|
struct passwd* pw = getpwuid(getuid());
|
||||||
if (pw != nullptr) {
|
if (pw != nullptr) {
|
||||||
stringstream history_path;
|
stringstream history_path;
|
||||||
|
@ -34,7 +34,7 @@ static void exit_interactive_rpn() {
|
||||||
|
|
||||||
/// @brief actions to be done at rpn exit
|
/// @brief actions to be done at rpn exit
|
||||||
///
|
///
|
||||||
static void init_interactive_rpn() {
|
static void EnterInteractive() {
|
||||||
struct passwd* pw = getpwuid(getuid());
|
struct passwd* pw = getpwuid(getuid());
|
||||||
if (pw != nullptr) {
|
if (pw != nullptr) {
|
||||||
stringstream history_path;
|
stringstream history_path;
|
||||||
|
@ -52,16 +52,16 @@ static void init_interactive_rpn() {
|
||||||
/// @param siginfo signal info, see POSIX sigaction
|
/// @param siginfo signal info, see POSIX sigaction
|
||||||
/// @param context see POSIX sigaction
|
/// @param context see POSIX sigaction
|
||||||
///
|
///
|
||||||
static void ctrlc_handler(int sig, siginfo_t* siginfo, void* context) { exit_interactive_rpn(); }
|
static void CtrlHandler(int sig, siginfo_t* siginfo, void* context) { ExitInteractive(); }
|
||||||
|
|
||||||
/// @brief setup signals handlers to stop with honours
|
/// @brief setup signals handlers to stop with honours
|
||||||
///
|
///
|
||||||
/// @param prog the prog to catch the signals to, must be checked not nullptr by user
|
/// @param prog the prog to catch the signals to, must be checked not nullptr by user
|
||||||
///
|
///
|
||||||
static void catch_signals(program* prog) {
|
static void CatchSignals(program* prog) {
|
||||||
struct sigaction act = {0};
|
struct sigaction act = {0};
|
||||||
|
|
||||||
act.sa_sigaction = &ctrlc_handler;
|
act.sa_sigaction = &CtrlHandler;
|
||||||
act.sa_flags = SA_SIGINFO;
|
act.sa_flags = SA_SIGINFO;
|
||||||
if (sigaction(SIGINT, &act, nullptr) < 0)
|
if (sigaction(SIGINT, &act, nullptr) < 0)
|
||||||
cerr << "Warning, Ctrl-C cannot be caught [errno=" << errno << ' ' << strerror(errno) << "']" << endl;
|
cerr << "Warning, Ctrl-C cannot be caught [errno=" << errno << ' ' << strerror(errno) << "']" << endl;
|
||||||
|
@ -83,7 +83,7 @@ int main(int argc, char* argv[]) {
|
||||||
// run with interactive prompt
|
// run with interactive prompt
|
||||||
if (argc == 1) {
|
if (argc == 1) {
|
||||||
// init history
|
// init history
|
||||||
init_interactive_rpn();
|
EnterInteractive();
|
||||||
|
|
||||||
// entry loop
|
// entry loop
|
||||||
heap heap;
|
heap heap;
|
||||||
|
@ -96,7 +96,7 @@ int main(int argc, char* argv[]) {
|
||||||
switch (Input(entry, program::getAutocompletionWords()).status) {
|
switch (Input(entry, program::getAutocompletionWords()).status) {
|
||||||
case Input::ok:
|
case Input::ok:
|
||||||
// user could stop prog with CtrlC
|
// user could stop prog with CtrlC
|
||||||
catch_signals(&prog);
|
CatchSignals(&prog);
|
||||||
// run it
|
// run it
|
||||||
if (prog.parse(entry) == ret_ok && prog.run() == ret_good_bye)
|
if (prog.parse(entry) == ret_ok && prog.run() == ret_good_bye)
|
||||||
go_on = false;
|
go_on = false;
|
||||||
|
@ -112,7 +112,7 @@ int main(int argc, char* argv[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// manage history and exit
|
// manage history and exit
|
||||||
exit_interactive_rpn();
|
ExitInteractive();
|
||||||
} else { // run with cmd line arguments
|
} else { // run with cmd line arguments
|
||||||
heap heap;
|
heap heap;
|
||||||
rpnstack stack;
|
rpnstack stack;
|
||||||
|
@ -127,7 +127,7 @@ int main(int argc, char* argv[]) {
|
||||||
ret = prog.parse(entry);
|
ret = prog.parse(entry);
|
||||||
if (ret == ret_ok) {
|
if (ret == ret_ok) {
|
||||||
// user could stop prog with CtrlC
|
// user could stop prog with CtrlC
|
||||||
catch_signals(&prog);
|
CatchSignals(&prog);
|
||||||
|
|
||||||
// run it
|
// run it
|
||||||
ret = prog.run();
|
ret = prog.run();
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
#define MPFR_IS_POS(x) (MPFR_SIGN(x) > 0)
|
#define MPFR_IS_POS(x) (MPFR_SIGN(x) > 0)
|
||||||
#define MPFR_PREC(x) ((x)->_mpfr_prec)
|
#define MPFR_PREC(x) ((x)->_mpfr_prec)
|
||||||
|
|
||||||
ostream& mpreal_output10base(ostream& out, const string& fmt, const mpreal& value) {
|
ostream& MprealOutput10Base(ostream& out, const string& fmt, const mpreal& value) {
|
||||||
// cf std::ostream& mpreal::output(std::ostream& os) const
|
// cf std::ostream& mpreal::output(std::ostream& os) const
|
||||||
char* s = NULL;
|
char* s = NULL;
|
||||||
if (!(mpfr_asprintf(&s, fmt.c_str(), mpreal::get_default_rnd(), value.mpfr_srcptr()) < 0)) {
|
if (!(mpfr_asprintf(&s, fmt.c_str(), mpreal::get_default_rnd(), value.mpfr_srcptr()) < 0)) {
|
||||||
|
@ -195,7 +195,7 @@ ostream& _out_number(ostream& out, int base, const mpreal& value) {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ostream& mpreal_outputNbase(ostream& out, int base, const mpreal& value) {
|
ostream& MprealOutputNBase(ostream& out, int base, const mpreal& value) {
|
||||||
// see mpfr_vasprintf code
|
// see mpfr_vasprintf code
|
||||||
int digits = 0; // forced 0 digits after separator
|
int digits = 0; // forced 0 digits after separator
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ using mpfr::mpreal;
|
||||||
using std::string;
|
using std::string;
|
||||||
using std::ostream;
|
using std::ostream;
|
||||||
|
|
||||||
ostream& mpreal_output10base(ostream& out, const string& fmt, const mpreal& value);
|
ostream& MprealOutput10Base(ostream& out, const string& fmt, const mpreal& value);
|
||||||
ostream& mpreal_outputNbase(ostream& out, int base, const mpreal& value);
|
ostream& MprealOutputNBase(ostream& out, int base, const mpreal& value);
|
||||||
|
|
||||||
#endif // SRC_MPREAL_OUT_HPP_
|
#endif // SRC_MPREAL_OUT_HPP_
|
||||||
|
|
|
@ -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::s_mode = Number::DEFAULT_MODE;
|
||||||
int number::s_digits = DEFAULT_DECIMAL_DIGITS;
|
int Number::s_digits = DEFAULT_DECIMAL_DIGITS;
|
||||||
|
|
122
src/object.hpp
122
src/object.hpp
|
@ -44,60 +44,60 @@ typedef enum {
|
||||||
cmd_undef,
|
cmd_undef,
|
||||||
cmd_number, // floating point number
|
cmd_number, // floating point number
|
||||||
cmd_complex, // complex, couple of floating point numbers
|
cmd_complex, // complex, couple of floating point numbers
|
||||||
cmd_string, // string like "string"
|
cmd_string, // "string"
|
||||||
cmd_symbol, // symbol like 'symbol'
|
cmd_symbol, // 'symbol'
|
||||||
cmd_program, // program like << instructions >>
|
cmd_program, // << instructions >> «instructions»
|
||||||
cmd_keyword, // langage keyword
|
cmd_keyword, // langage (reserved) keyword
|
||||||
cmd_branch, // langage branch keyword
|
cmd_branch, // langage (reserved) branch keyword
|
||||||
cmd_max
|
cmd_max
|
||||||
} cmd_type_t;
|
} cmd_type_t;
|
||||||
|
|
||||||
class program;
|
class program;
|
||||||
class branch;
|
class Branch;
|
||||||
|
|
||||||
typedef void (program::*program_fn_t)(void);
|
typedef void (program::*program_fn_t)(void);
|
||||||
typedef size_t (program::*branch_fn_t)(branch&);
|
typedef size_t (program::*branch_fn_t)(Branch&);
|
||||||
|
|
||||||
/// @brief object - a generic stack object
|
/// @brief Object - a generic stack object
|
||||||
///
|
///
|
||||||
struct object {
|
struct Object {
|
||||||
explicit object(cmd_type_t type = cmd_undef) : _type(type) {}
|
explicit Object(cmd_type_t type = cmd_undef) : _type(type) {}
|
||||||
virtual ~object() {}
|
virtual ~Object() {}
|
||||||
cmd_type_t _type;
|
cmd_type_t _type;
|
||||||
virtual object* clone() {
|
virtual Object* clone() {
|
||||||
object* o = new object();
|
Object* o = new Object();
|
||||||
if (o != nullptr) *o = *this;
|
if (o != nullptr) *o = *this;
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual string name() { return string("object"); }
|
virtual string name() { return string("Object"); }
|
||||||
virtual ostream& show(ostream& out) {
|
virtual ostream& show(ostream& out) {
|
||||||
out << "(" << name() << " - unknown representation)";
|
out << "(" << name() << " - unknown representation)";
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
friend ostream& operator<<(ostream& os, object* o) { return o->show(os); }
|
friend ostream& operator<<(ostream& os, Object* o) { return o->show(os); }
|
||||||
|
|
||||||
unsigned int size() { return sizeof(*this); }
|
unsigned int size() { return sizeof(*this); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief stack objects derived from object
|
/// @brief stack objects derived from Object
|
||||||
///
|
///
|
||||||
struct number : object {
|
struct Number : Object {
|
||||||
number() : object(cmd_number), base(10) {}
|
Number() : Object(cmd_number), base(10) {}
|
||||||
explicit number(const mpreal& value_, int base_ = 10) : object(cmd_number), base(base_), value(value_) {}
|
explicit Number(const mpreal& value_, int base_ = 10) : Object(cmd_number), base(base_), value(value_) {}
|
||||||
explicit number(int value_, int base_ = 10) : object(cmd_number), base(base_), value(value_) {}
|
explicit Number(int value_, int base_ = 10) : Object(cmd_number), 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, s_mode, s_digits, base); }
|
||||||
|
|
||||||
// representation mode
|
// representation mode
|
||||||
typedef enum { std, fix, sci } mode_enum;
|
typedef enum { std, fix, sci } mode_enum;
|
||||||
static mode_enum s_mode;
|
static mode_enum s_mode;
|
||||||
static constexpr mode_enum DEFAULT_MODE = number::std;
|
static constexpr mode_enum DEFAULT_MODE = Number::std;
|
||||||
|
|
||||||
// precision
|
// precision
|
||||||
static constexpr mpfr_prec_t MPFR_DEFAULT_PREC_BITS = 128;
|
static constexpr mpfr_prec_t MPFR_DEFAULT_PREC_BITS = 128;
|
||||||
|
@ -119,22 +119,22 @@ 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 mpreal_output10base(out, _makeNumberFormat(s_mode, s_digits), value);
|
return MprealOutput10Base(out, _makeNumberFormat(s_mode, s_digits), value);
|
||||||
else
|
else
|
||||||
return mpreal_outputNbase(out, base, value);
|
return MprealOutputNBase(out, base, value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief stack objects derived from object
|
/// @brief stack objects inheriting Object
|
||||||
///
|
///
|
||||||
struct ocomplex : object {
|
struct Complex : Object {
|
||||||
ocomplex() : object(cmd_complex), reBase(10), imBase(10) {}
|
Complex() : Object(cmd_complex), reBase(10), imBase(10) {}
|
||||||
explicit ocomplex(complex<mpreal>& value_, int reb = 10, int imb = 10)
|
explicit Complex(complex<mpreal>& value_, int reb = 10, int imb = 10)
|
||||||
: object(cmd_complex), reBase(reb), imBase(imb) {
|
: Object(cmd_complex), reBase(reb), imBase(imb) {
|
||||||
value = value_;
|
value = value_;
|
||||||
}
|
}
|
||||||
explicit ocomplex(mpreal& re_, mpreal& im_, int reb = 10, int imb = 10)
|
explicit Complex(mpreal& re_, mpreal& im_, int reb = 10, int imb = 10)
|
||||||
: object(cmd_complex), reBase(reb), imBase(imb) {
|
: Object(cmd_complex), reBase(reb), imBase(imb) {
|
||||||
value.real(re_);
|
value.real(re_);
|
||||||
value.imag(im_);
|
value.imag(im_);
|
||||||
}
|
}
|
||||||
|
@ -142,68 +142,58 @@ struct ocomplex : object {
|
||||||
int reBase, imBase;
|
int reBase, imBase;
|
||||||
complex<mpreal> value;
|
complex<mpreal> value;
|
||||||
|
|
||||||
virtual object* clone() { return new ocomplex(value, reBase, imBase); }
|
virtual Object* clone() { return new Complex(value, reBase, imBase); }
|
||||||
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::s_mode, Number::s_digits, reBase);
|
||||||
out << ',';
|
out << ',';
|
||||||
number::showValue(out, value.imag(), number::s_mode, number::s_digits, imBase);
|
Number::showValue(out, value.imag(), Number::s_mode, Number::s_digits, imBase);
|
||||||
return out << ')';
|
return out << ')';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief object string
|
struct String : Object {
|
||||||
///
|
String() : Object(cmd_string) {}
|
||||||
struct ostring : object {
|
explicit String(const string& value_) : Object(cmd_string), value(value_) {}
|
||||||
ostring() : object(cmd_string) {}
|
virtual Object* clone() { return new String(value); }
|
||||||
explicit ostring(const string& value_) : object(cmd_string), value(value_) {}
|
|
||||||
virtual object* clone() { return new ostring(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 << "\""; }
|
||||||
string value;
|
string value;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief object program
|
struct Program : Object {
|
||||||
///
|
Program() : Object(cmd_program) {}
|
||||||
struct oprogram : object {
|
explicit Program(const string& value_) : Object(cmd_program), value(value_) {}
|
||||||
oprogram() : object(cmd_program) {}
|
virtual Object* clone() { return new Program(value); }
|
||||||
explicit oprogram(const string& value_) : object(cmd_program), value(value_) {}
|
|
||||||
virtual object* clone() { return new oprogram(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 << "»"; }
|
||||||
string value;
|
string value;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief object symbol
|
struct Symbol : Object {
|
||||||
///
|
explicit Symbol(bool autoEval_ = true) : Object(cmd_symbol), autoEval(autoEval_) {}
|
||||||
struct symbol : object {
|
explicit Symbol(const string& value_, bool autoEval_ = true)
|
||||||
explicit symbol(bool autoEval_ = true) : object(cmd_symbol), autoEval(autoEval_) {}
|
: Object(cmd_symbol), value(value_), autoEval(autoEval_) {}
|
||||||
explicit symbol(const string& value_, bool autoEval_ = true)
|
virtual Object* clone() { return new Symbol(value, autoEval); }
|
||||||
: object(cmd_symbol), value(value_), autoEval(autoEval_) {}
|
|
||||||
virtual object* clone() { return new symbol(value, autoEval); }
|
|
||||||
virtual string name() { return string("symbol"); }
|
virtual string name() { return string("symbol"); }
|
||||||
virtual ostream& show(ostream& out) { return out << "'" << value << "'"; }
|
virtual ostream& show(ostream& out) { return out << "'" << value << "'"; }
|
||||||
bool autoEval;
|
bool autoEval;
|
||||||
string value;
|
string value;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief object keyword
|
struct Keyword : Object {
|
||||||
///
|
Keyword() : Object(cmd_keyword) {}
|
||||||
struct keyword : object {
|
explicit Keyword(program_fn_t fn_, const string& value_) : Object(cmd_keyword), fn(fn_), value(value_) {}
|
||||||
keyword() : object(cmd_keyword) {}
|
virtual Object* clone() { return new Keyword(fn, value); }
|
||||||
explicit keyword(program_fn_t fn_, const string& value_) : object(cmd_keyword), fn(fn_), value(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;
|
||||||
string value;
|
string value;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief object branch
|
struct Branch : Object {
|
||||||
///
|
Branch() : Object(cmd_branch) {}
|
||||||
struct branch : object {
|
explicit Branch(branch_fn_t fn_, const string& value_) : Object(cmd_branch) {
|
||||||
branch() : object(cmd_branch) {}
|
|
||||||
explicit branch(branch_fn_t fn_, const string& value_) : object(cmd_branch) {
|
|
||||||
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);
|
||||||
|
@ -211,7 +201,7 @@ struct branch : object {
|
||||||
arg_bool = 0;
|
arg_bool = 0;
|
||||||
value = value_;
|
value = value_;
|
||||||
}
|
}
|
||||||
explicit branch(branch& other) : object(cmd_branch) {
|
explicit Branch(Branch& other) : Object(cmd_branch) {
|
||||||
fn = other.fn;
|
fn = other.fn;
|
||||||
arg1 = other.arg1;
|
arg1 = other.arg1;
|
||||||
arg2 = other.arg2;
|
arg2 = other.arg2;
|
||||||
|
@ -219,7 +209,7 @@ struct branch : object {
|
||||||
arg_bool = other.arg_bool;
|
arg_bool = other.arg_bool;
|
||||||
value = other.value;
|
value = other.value;
|
||||||
}
|
}
|
||||||
virtual object* clone() { return new branch(*this); }
|
virtual Object* clone() { return new Branch(*this); }
|
||||||
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;
|
||||||
|
|
|
@ -205,11 +205,11 @@ vector<program::keyword_t> program::_keywords{
|
||||||
|
|
||||||
/// autocompletion vector for linenoise autocompletion
|
/// autocompletion vector for linenoise autocompletion
|
||||||
vector<string>& program::getAutocompletionWords() {
|
vector<string>& program::getAutocompletionWords() {
|
||||||
static vector<string> autocompletionWords;
|
static vector<string> autocompletion_words;
|
||||||
if (autocompletionWords.empty())
|
if (autocompletion_words.empty())
|
||||||
for (auto& kw : _keywords)
|
for (auto& kw : _keywords)
|
||||||
if (!kw.name.empty()) autocompletionWords.push_back(kw.name);
|
if (!kw.name.empty()) autocompletion_words.push_back(kw.name);
|
||||||
return autocompletionWords;
|
return autocompletion_words;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief run a program on a stack and a heap
|
/// @brief run a program on a stack and a heap
|
||||||
|
@ -228,24 +228,24 @@ ret_value program::run() {
|
||||||
ret = preprocess();
|
ret = preprocess();
|
||||||
if (ret != ret_ok) {
|
if (ret != ret_ok) {
|
||||||
// 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
// iterate commands
|
// iterate commands
|
||||||
for (size_t i = 0; (go_out == false) && (i < size());) {
|
for (size_t i = 0; (go_out == false) && (i < size());) {
|
||||||
object* o = at(i);
|
Object* o = at(i);
|
||||||
switch (o->_type) {
|
switch (o->_type) {
|
||||||
// could be an auto-evaluated symbol
|
// could be an auto-evaluated symbol
|
||||||
case cmd_symbol:
|
case cmd_symbol:
|
||||||
auto_rcl(reinterpret_cast<symbol*>(o));
|
auto_rcl(reinterpret_cast<Symbol*>(o));
|
||||||
i++;
|
i++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// a keyword
|
// a keyword
|
||||||
case cmd_keyword: {
|
case cmd_keyword: {
|
||||||
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) {
|
||||||
|
@ -277,7 +277,7 @@ ret_value program::run() {
|
||||||
// a branch keyword
|
// a branch keyword
|
||||||
case cmd_branch: {
|
case cmd_branch: {
|
||||||
// call matching function
|
// call matching function
|
||||||
branch* b = reinterpret_cast<branch*>(o);
|
Branch* b = reinterpret_cast<Branch*>(o);
|
||||||
size_t next_cmd = (this->*(b->fn))(*b);
|
size_t next_cmd = (this->*(b->fn))(*b);
|
||||||
switch (next_cmd) {
|
switch (next_cmd) {
|
||||||
case step_out: // step out
|
case step_out: // step out
|
||||||
|
@ -304,7 +304,7 @@ ret_value 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;
|
||||||
|
@ -336,13 +336,13 @@ ret_value program::preprocess(void) {
|
||||||
vector<struct if_layout_t> vlayout;
|
vector<struct if_layout_t> vlayout;
|
||||||
int layout_index = -1;
|
int layout_index = -1;
|
||||||
// for start-end-step
|
// for start-end-step
|
||||||
vector<int> vstartindex;
|
vector<int> vstart_index;
|
||||||
|
|
||||||
// analyse if-then-else-end branches
|
// analyse if-then-else-end branches
|
||||||
// analyse start-{next, step} branches
|
// analyse start-{next, step} branches
|
||||||
for (size_t i = 0; i < size(); i++) {
|
for (size_t i = 0; i < size(); i++) {
|
||||||
if (at(i)->_type == cmd_branch) {
|
if (at(i)->_type == cmd_branch) {
|
||||||
branch* k = reinterpret_cast<branch*>(at(i));
|
Branch* k = reinterpret_cast<Branch*>(at(i));
|
||||||
if (k->value == "if") {
|
if (k->value == "if") {
|
||||||
if_layout_t layout;
|
if_layout_t layout;
|
||||||
layout.index_if_or_do_or_while = i;
|
layout.index_if_or_do_or_while = i;
|
||||||
|
@ -399,33 +399,33 @@ ret_value program::preprocess(void) {
|
||||||
vlayout[layout_index].index_else = i;
|
vlayout[layout_index].index_else = i;
|
||||||
k->arg1 = next; // fill branch1 (if was false) of 'else'
|
k->arg1 = next; // fill branch1 (if was false) of 'else'
|
||||||
k->arg3 = vlayout[layout_index].index_if_or_do_or_while;
|
k->arg3 = vlayout[layout_index].index_if_or_do_or_while;
|
||||||
reinterpret_cast<branch*>(at(vlayout[layout_index].index_then_or_unti_or_repeat))->arg2 =
|
reinterpret_cast<Branch*>(at(vlayout[layout_index].index_then_or_unti_or_repeat))->arg2 =
|
||||||
next; // fill branch2 (if was false) of 'then'
|
next; // fill branch2 (if was false) of 'then'
|
||||||
} else if (k->value == "start") {
|
} else if (k->value == "start") {
|
||||||
vstartindex.push_back(i);
|
vstart_index.push_back(i);
|
||||||
} else if (k->value == "for") {
|
} else if (k->value == "for") {
|
||||||
vstartindex.push_back(i);
|
vstart_index.push_back(i);
|
||||||
k->arg1 = i + 1; // arg1 points on symbol variable
|
k->arg1 = i + 1; // arg1 points on symbol variable
|
||||||
} else if (k->value == "next") {
|
} else if (k->value == "next") {
|
||||||
if (vstartindex.size() == 0) {
|
if (vstart_index.size() == 0) {
|
||||||
// error: show it
|
// error: show it
|
||||||
show_syntax_error("missing start or for before next");
|
show_syntax_error("missing start or for before next");
|
||||||
return ret_syntax;
|
return ret_syntax;
|
||||||
}
|
}
|
||||||
k->arg1 = vstartindex[vstartindex.size() - 1]; // 'next' arg1 = 'start' index
|
k->arg1 = vstart_index[vstart_index.size() - 1]; // 'next' arg1 = 'start' index
|
||||||
reinterpret_cast<branch*>(at(vstartindex[vstartindex.size() - 1]))->arg2 =
|
reinterpret_cast<Branch*>(at(vstart_index[vstart_index.size() - 1]))->arg2 =
|
||||||
i; // 'for' or 'start' arg2 = 'next' index
|
i; // 'for' or 'start' arg2 = 'next' index
|
||||||
vstartindex.pop_back();
|
vstart_index.pop_back();
|
||||||
} else if (k->value == "step") {
|
} else if (k->value == "step") {
|
||||||
if (vstartindex.size() == 0) {
|
if (vstart_index.size() == 0) {
|
||||||
// error: show it
|
// error: show it
|
||||||
show_syntax_error("missing start or for before step");
|
show_syntax_error("missing start or for before step");
|
||||||
return ret_syntax;
|
return ret_syntax;
|
||||||
}
|
}
|
||||||
k->arg1 = vstartindex[vstartindex.size() - 1]; // fill 'step' branch1 = 'start' index
|
k->arg1 = vstart_index[vstart_index.size() - 1]; // fill 'step' branch1 = 'start' index
|
||||||
reinterpret_cast<branch*>(at(vstartindex[vstartindex.size() - 1]))->arg2 =
|
reinterpret_cast<Branch*>(at(vstart_index[vstart_index.size() - 1]))->arg2 =
|
||||||
i; // 'for' or 'start' arg2 = 'next' index
|
i; // 'for' or 'start' arg2 = 'next' index
|
||||||
vstartindex.pop_back();
|
vstart_index.pop_back();
|
||||||
} else if (k->value == "->") {
|
} else if (k->value == "->") {
|
||||||
k->arg1 = i; // arg1 is '->' command index in program
|
k->arg1 = i; // arg1 is '->' command index in program
|
||||||
} else if (k->value == "do") {
|
} else if (k->value == "do") {
|
||||||
|
@ -515,8 +515,7 @@ ret_value program::preprocess(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// fill 'repeat' arg1 with 'end+1'
|
// fill 'repeat' arg1 with 'end+1'
|
||||||
reinterpret_cast<branch*>(at(vlayout[layout_index].index_then_or_unti_or_repeat))->arg1 =
|
reinterpret_cast<Branch*>(at(vlayout[layout_index].index_then_or_unti_or_repeat))->arg1 = i + 1;
|
||||||
i + 1;
|
|
||||||
layout_index--;
|
layout_index--;
|
||||||
} else {
|
} else {
|
||||||
// this end closes an if..then..(else)
|
// this end closes an if..then..(else)
|
||||||
|
@ -527,11 +526,11 @@ ret_value program::preprocess(void) {
|
||||||
}
|
}
|
||||||
if (vlayout[layout_index].index_else != -1) {
|
if (vlayout[layout_index].index_else != -1) {
|
||||||
// fill 'end' branch of 'else'
|
// fill 'end' branch of 'else'
|
||||||
reinterpret_cast<branch*>(at(vlayout[layout_index].index_else))->arg2 = i;
|
reinterpret_cast<Branch*>(at(vlayout[layout_index].index_else))->arg2 = i;
|
||||||
} else {
|
} else {
|
||||||
// fill 'end' branch of 'then'
|
// fill 'end' branch of 'then'
|
||||||
if (vlayout[layout_index].index_then_or_unti_or_repeat != -1) {
|
if (vlayout[layout_index].index_then_or_unti_or_repeat != -1) {
|
||||||
reinterpret_cast<branch*>(at(vlayout[layout_index].index_then_or_unti_or_repeat))
|
reinterpret_cast<Branch*>(at(vlayout[layout_index].index_then_or_unti_or_repeat))
|
||||||
->arg2 = i;
|
->arg2 = i;
|
||||||
} else {
|
} else {
|
||||||
// error: show it
|
// error: show it
|
||||||
|
@ -550,7 +549,7 @@ ret_value program::preprocess(void) {
|
||||||
show_syntax_error("missing end");
|
show_syntax_error("missing end");
|
||||||
return ret_syntax;
|
return ret_syntax;
|
||||||
}
|
}
|
||||||
if (vstartindex.size() > 0) {
|
if (vstart_index.size() > 0) {
|
||||||
// error: show it
|
// error: show it
|
||||||
show_syntax_error("missing next or step after for or start");
|
show_syntax_error("missing next or step after for or start");
|
||||||
return ret_syntax;
|
return ret_syntax;
|
||||||
|
@ -565,41 +564,41 @@ ret_value program::preprocess(void) {
|
||||||
/// @return ret_value see this type
|
/// @return ret_value see this type
|
||||||
///
|
///
|
||||||
ret_value program::parse(string& entry) {
|
ret_value program::parse(string& entry) {
|
||||||
static map<string, Lexer::ReservedWord> keywordsMap;
|
static map<string, Lexer::ReservedWord> keywords_map;
|
||||||
vector<Lexer::SynElement> elements;
|
vector<Lexer::SynElement> elements;
|
||||||
vector<Lexer::SynError> errors;
|
vector<Lexer::SynError> errors;
|
||||||
ret_value ret = ret_ok;
|
ret_value ret = ret_ok;
|
||||||
|
|
||||||
// prepare map for finding reserved keywords
|
// prepare map for finding reserved keywords
|
||||||
if (keywordsMap.empty())
|
if (keywords_map.empty())
|
||||||
for (auto& kw : _keywords)
|
for (auto& kw : _keywords)
|
||||||
if (!kw.name.empty()) keywordsMap[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
|
||||||
if (lexer(entry, keywordsMap, elements, errors)) {
|
if (lexer(entry, keywords_map, elements, errors)) {
|
||||||
// make objects from parsed elements
|
// make objects from parsed elements
|
||||||
for (Lexer::SynElement& element : elements) {
|
for (Lexer::SynElement& element : elements) {
|
||||||
switch (element.type) {
|
switch (element.type) {
|
||||||
case cmd_number:
|
case cmd_number:
|
||||||
push_back(new number(*element.re, element.reBase));
|
push_back(new Number(*element.re, element.reBase));
|
||||||
break;
|
break;
|
||||||
case cmd_complex:
|
case cmd_complex:
|
||||||
push_back(new ocomplex(*element.re, *element.im, element.reBase, element.imBase));
|
push_back(new Complex(*element.re, *element.im, element.reBase, element.imBase));
|
||||||
break;
|
break;
|
||||||
case cmd_string:
|
case cmd_string:
|
||||||
push_back(new ostring(element.value));
|
push_back(new String(element.value));
|
||||||
break;
|
break;
|
||||||
case cmd_symbol:
|
case cmd_symbol:
|
||||||
push_back(new symbol(element.value, element.autoEval));
|
push_back(new Symbol(element.value, element.autoEval));
|
||||||
break;
|
break;
|
||||||
case cmd_program:
|
case cmd_program:
|
||||||
push_back(new oprogram(element.value));
|
push_back(new Program(element.value));
|
||||||
break;
|
break;
|
||||||
case cmd_keyword:
|
case cmd_keyword:
|
||||||
push_back(new keyword(element.fn, element.value));
|
push_back(new Keyword(element.fn, element.value));
|
||||||
break;
|
break;
|
||||||
case cmd_branch:
|
case cmd_branch:
|
||||||
push_back(new branch((branch_fn_t)element.fn, element.value));
|
push_back(new Branch((branch_fn_t)element.fn, element.value));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
show_error(ret_unknown_err, "error creating program from entry");
|
show_error(ret_unknown_err, "error creating program from entry");
|
||||||
|
@ -708,9 +707,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::s_mode = Number::DEFAULT_MODE;
|
||||||
number::s_digits = number::DEFAULT_DECIMAL_DIGITS;
|
Number::s_digits = Number::DEFAULT_DECIMAL_DIGITS;
|
||||||
mpreal::set_default_prec(number::MPFR_DEFAULT_PREC_BITS);
|
mpreal::set_default_prec(Number::MPFR_DEFAULT_PREC_BITS);
|
||||||
|
|
||||||
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);
|
||||||
|
|
|
@ -19,7 +19,7 @@ using mpfr::mpreal;
|
||||||
#include "stack.hpp"
|
#include "stack.hpp"
|
||||||
|
|
||||||
//< 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& stk, heap& hp, program* parent = nullptr) : _stack(stk), _heap(hp), _parent(parent) {}
|
||||||
virtual ~program() {
|
virtual ~program() {
|
||||||
|
@ -79,20 +79,20 @@ class program : public deque<object*>, public Lexer {
|
||||||
////
|
////
|
||||||
|
|
||||||
// branch
|
// branch
|
||||||
size_t rpn_if(branch& myobj);
|
size_t rpn_if(Branch& myobj);
|
||||||
size_t rpn_then(branch& myobj);
|
size_t rpn_then(Branch& myobj);
|
||||||
size_t rpn_else(branch& myobj);
|
size_t rpn_else(Branch& myobj);
|
||||||
size_t rpn_end(branch& myobj);
|
size_t rpn_end(Branch& myobj);
|
||||||
size_t rpn_do(branch& myobj);
|
size_t rpn_do(Branch& myobj);
|
||||||
size_t rpn_until(branch& myobj);
|
size_t rpn_until(Branch& myobj);
|
||||||
void rpn_ift(void);
|
void rpn_ift(void);
|
||||||
void rpn_ifte(void);
|
void rpn_ifte(void);
|
||||||
size_t rpn_while(branch& myobj);
|
size_t rpn_while(Branch& myobj);
|
||||||
size_t rpn_repeat(branch& myobj);
|
size_t rpn_repeat(Branch& myobj);
|
||||||
size_t rpn_start(branch& myobj);
|
size_t rpn_start(Branch& myobj);
|
||||||
size_t rpn_for(branch& myobj);
|
size_t rpn_for(Branch& myobj);
|
||||||
size_t rpn_next(branch& myobj);
|
size_t rpn_next(Branch& myobj);
|
||||||
size_t rpn_step(branch& myobj);
|
size_t rpn_step(Branch& myobj);
|
||||||
enum { step_out = static_cast<size_t>(-1), runtime_error = static_cast<size_t>(-2) };
|
enum { step_out = static_cast<size_t>(-1), runtime_error = static_cast<size_t>(-2) };
|
||||||
|
|
||||||
// complex
|
// complex
|
||||||
|
@ -138,9 +138,9 @@ class program : public deque<object*>, public Lexer {
|
||||||
void rpn_atanh();
|
void rpn_atanh();
|
||||||
|
|
||||||
// program
|
// program
|
||||||
bool find_variable(string& variable, object*& obj);
|
bool find_variable(string& variable, Object*& obj);
|
||||||
void rpn_eval(void);
|
void rpn_eval(void);
|
||||||
int rpn_inprog(branch& myobj);
|
int rpn_inprog(Branch& inprog_obj);
|
||||||
|
|
||||||
// real
|
// real
|
||||||
void rpn_plus();
|
void rpn_plus();
|
||||||
|
@ -198,7 +198,7 @@ class program : public deque<object*>, public Lexer {
|
||||||
void rpn_stoinv(void);
|
void rpn_stoinv(void);
|
||||||
void rpn_rcl(void);
|
void rpn_rcl(void);
|
||||||
void rpn_edit(void);
|
void rpn_edit(void);
|
||||||
void auto_rcl(symbol* symb);
|
void auto_rcl(Symbol* symb);
|
||||||
void rpn_purge(void);
|
void rpn_purge(void);
|
||||||
void rpn_vars(void);
|
void rpn_vars(void);
|
||||||
void rpn_clusr(void);
|
void rpn_clusr(void);
|
||||||
|
|
|
@ -9,12 +9,12 @@
|
||||||
/// @return step_out next object to run in the current program is current + 1
|
/// @return step_out next object to run in the current program is current + 1
|
||||||
/// @return runtime_error something went wrong with preprocess, abort branch
|
/// @return runtime_error something went wrong with preprocess, abort branch
|
||||||
///
|
///
|
||||||
size_t program::rpn_if(branch& myobj) {
|
size_t program::rpn_if(Branch& myobj) {
|
||||||
// myobj.arg1 = 'if' condition evaluation value
|
// myobj.arg1 = 'if' condition evaluation value
|
||||||
MIN_ARGUMENTS_RET(1, runtime_error);
|
MIN_ARGUMENTS_RET(1, runtime_error);
|
||||||
ARG_MUST_BE_OF_TYPE_RET(0, cmd_number, runtime_error);
|
ARG_MUST_BE_OF_TYPE_RET(0, cmd_number, runtime_error);
|
||||||
|
|
||||||
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;
|
||||||
|
@ -27,20 +27,20 @@ size_t program::rpn_if(branch& myobj) {
|
||||||
/// @param myobj the current branch object
|
/// @param myobj the current branch object
|
||||||
/// @return size_t index of the next object to run in the current program
|
/// @return size_t index of the next object to run in the current program
|
||||||
/// @return step_out next object to run in the current program is current + 1
|
/// @return step_out next object to run in the current program is current + 1
|
||||||
/// @return runtime_error something went wrong with preprocess, abort branch
|
/// @return runtime_error something went wrong with preprocess, abort Branch
|
||||||
///
|
///
|
||||||
size_t program::rpn_then(branch& myobj) {
|
size_t program::rpn_then(Branch& myobj) {
|
||||||
// myobj.arg1 = index of then + 1
|
// myobj.arg1 = index of then + 1
|
||||||
// myobj.arg2 = index of else + 1 or end + 1
|
// myobj.arg2 = index of else + 1 or end + 1
|
||||||
// myobj.arg3 = index of if
|
// myobj.arg3 = index of if
|
||||||
// if condition is true -> arg1 (= jump to then + 1)
|
// if condition is true -> arg1 (= jump to then + 1)
|
||||||
// else -> arg2 (= jump to else + 1 or end + 1)
|
// else -> arg2 (= jump to else + 1 or end + 1)
|
||||||
branch* if_cmd;
|
Branch* if_cmd;
|
||||||
if (myobj.arg3 >= size() || at(myobj.arg3)->_type != cmd_branch) {
|
if (myobj.arg3 >= size() || at(myobj.arg3)->_type != cmd_branch) {
|
||||||
setErrorContext(ret_missing_operand);
|
setErrorContext(ret_missing_operand);
|
||||||
return runtime_error;
|
return runtime_error;
|
||||||
}
|
}
|
||||||
if_cmd = reinterpret_cast<branch*>(at(myobj.arg3));
|
if_cmd = reinterpret_cast<Branch*>(at(myobj.arg3));
|
||||||
if (if_cmd->arg1 == 1)
|
if (if_cmd->arg1 == 1)
|
||||||
return myobj.arg1;
|
return myobj.arg1;
|
||||||
else
|
else
|
||||||
|
@ -54,18 +54,18 @@ size_t program::rpn_then(branch& myobj) {
|
||||||
/// @return step_out next object to run in the current program is current + 1
|
/// @return step_out next object to run in the current program is current + 1
|
||||||
/// @return runtime_error something went wrong with preprocess, abort branch
|
/// @return runtime_error something went wrong with preprocess, abort branch
|
||||||
///
|
///
|
||||||
size_t program::rpn_else(branch& myobj) {
|
size_t program::rpn_else(Branch& myobj) {
|
||||||
// myobj.arg1 = index of else + 1
|
// myobj.arg1 = index of else + 1
|
||||||
// myobj.arg2 = index of end + 1
|
// myobj.arg2 = index of end + 1
|
||||||
// myobj.arg3 = index of if
|
// myobj.arg3 = index of if
|
||||||
// if condition was false -> arg1 (= jump to else + 1)
|
// if condition was false -> arg1 (= jump to else + 1)
|
||||||
// if condition was true -> arg2 (= jump to end + 1)
|
// if condition was true -> arg2 (= jump to end + 1)
|
||||||
branch* if_cmd;
|
Branch* if_cmd;
|
||||||
if (myobj.arg3 >= size() || at(myobj.arg3)->_type != cmd_branch) {
|
if (myobj.arg3 >= size() || at(myobj.arg3)->_type != cmd_branch) {
|
||||||
setErrorContext(ret_missing_operand);
|
setErrorContext(ret_missing_operand);
|
||||||
return runtime_error;
|
return runtime_error;
|
||||||
}
|
}
|
||||||
if_cmd = reinterpret_cast<branch*>(at(myobj.arg3));
|
if_cmd = reinterpret_cast<Branch*>(at(myobj.arg3));
|
||||||
if (if_cmd->arg1 == 1)
|
if (if_cmd->arg1 == 1)
|
||||||
return myobj.arg2;
|
return myobj.arg2;
|
||||||
else
|
else
|
||||||
|
@ -79,7 +79,7 @@ size_t program::rpn_else(branch& myobj) {
|
||||||
/// @return step_out next object to run in the current program is current + 1
|
/// @return step_out next object to run in the current program is current + 1
|
||||||
/// @return runtime_error something went wrong with preprocess, abort branch
|
/// @return runtime_error something went wrong with preprocess, abort branch
|
||||||
///
|
///
|
||||||
size_t program::rpn_end(branch& myobj) {
|
size_t program::rpn_end(Branch& myobj) {
|
||||||
size_t ret = step_out;
|
size_t ret = step_out;
|
||||||
|
|
||||||
// arg1 = index of do+1 in case of do..unti..end
|
// arg1 = index of do+1 in case of do..unti..end
|
||||||
|
@ -89,7 +89,7 @@ size_t program::rpn_end(branch& myobj) {
|
||||||
ARG_MUST_BE_OF_TYPE_RET(0, cmd_number, runtime_error);
|
ARG_MUST_BE_OF_TYPE_RET(0, cmd_number, runtime_error);
|
||||||
|
|
||||||
// check arg
|
// check arg
|
||||||
if (_stack.value<number>(0) == 0) ret = myobj.arg1;
|
if (_stack.value<Number>(0) == 0) ret = myobj.arg1;
|
||||||
_stack.pop();
|
_stack.pop();
|
||||||
} else if (myobj.arg2 != step_out) {
|
} else if (myobj.arg2 != step_out) {
|
||||||
// arg2 = index of while+1 in case of while..repeat..end
|
// arg2 = index of while+1 in case of while..repeat..end
|
||||||
|
@ -106,7 +106,7 @@ size_t program::rpn_end(branch& myobj) {
|
||||||
/// @return step_out next object to run in the current program is current + 1
|
/// @return step_out next object to run in the current program is current + 1
|
||||||
/// @return runtime_error something went wrong with preprocess, abort branch
|
/// @return runtime_error something went wrong with preprocess, abort branch
|
||||||
///
|
///
|
||||||
size_t program::rpn_do(branch& myobj) {
|
size_t program::rpn_do(Branch& myobj) {
|
||||||
// nothing
|
// nothing
|
||||||
return step_out;
|
return step_out;
|
||||||
}
|
}
|
||||||
|
@ -116,9 +116,9 @@ size_t program::rpn_do(branch& myobj) {
|
||||||
/// @param myobj the current branch object
|
/// @param myobj the current branch object
|
||||||
/// @return size_t index of the next object to run in the current program
|
/// @return size_t index of the next object to run in the current program
|
||||||
/// @return step_out next object to run in the current program is current + 1
|
/// @return step_out next object to run in the current program is current + 1
|
||||||
/// @return runtime_error something went wrong with preprocess, abort branch
|
/// @return runtime_error something went wrong with preprocess, abort Branch
|
||||||
///
|
///
|
||||||
size_t program::rpn_until(branch& myobj) {
|
size_t program::rpn_until(Branch& myobj) {
|
||||||
// nothing
|
// nothing
|
||||||
return step_out;
|
return step_out;
|
||||||
}
|
}
|
||||||
|
@ -135,8 +135,8 @@ void program::rpn_ift(void) {
|
||||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||||
|
|
||||||
// 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);
|
||||||
|
@ -154,7 +154,7 @@ void program::rpn_ifte(void) {
|
||||||
ARG_MUST_BE_OF_TYPE(2, cmd_number);
|
ARG_MUST_BE_OF_TYPE(2, cmd_number);
|
||||||
|
|
||||||
// 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 {
|
||||||
|
@ -170,7 +170,7 @@ void program::rpn_ifte(void) {
|
||||||
/// @return step_out next object to run in the current program is current + 1
|
/// @return step_out next object to run in the current program is current + 1
|
||||||
/// @return runtime_error something went wrong with preprocess, abort branch
|
/// @return runtime_error something went wrong with preprocess, abort branch
|
||||||
///
|
///
|
||||||
size_t program::rpn_while(branch& myobj) {
|
size_t program::rpn_while(Branch& myobj) {
|
||||||
// nothing
|
// nothing
|
||||||
return step_out;
|
return step_out;
|
||||||
}
|
}
|
||||||
|
@ -182,7 +182,7 @@ size_t program::rpn_while(branch& myobj) {
|
||||||
/// @return step_out next object to run in the current program is current + 1
|
/// @return step_out next object to run in the current program is current + 1
|
||||||
/// @return runtime_error something went wrong with preprocess, abort branch
|
/// @return runtime_error something went wrong with preprocess, abort branch
|
||||||
///
|
///
|
||||||
size_t program::rpn_repeat(branch& myobj) {
|
size_t program::rpn_repeat(Branch& myobj) {
|
||||||
size_t ret = step_out;
|
size_t ret = step_out;
|
||||||
|
|
||||||
MIN_ARGUMENTS_RET(1, runtime_error);
|
MIN_ARGUMENTS_RET(1, runtime_error);
|
||||||
|
@ -190,7 +190,7 @@ 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;
|
||||||
|
@ -203,7 +203,7 @@ size_t program::rpn_repeat(branch& myobj) {
|
||||||
/// @return step_out next object to run in the current program is current + 1
|
/// @return step_out next object to run in the current program is current + 1
|
||||||
/// @return runtime_error something went wrong with preprocess, abort branch
|
/// @return runtime_error something went wrong with preprocess, abort branch
|
||||||
///
|
///
|
||||||
size_t program::rpn_start(branch& myobj) {
|
size_t program::rpn_start(Branch& myobj) {
|
||||||
size_t ret = step_out;
|
size_t ret = step_out;
|
||||||
|
|
||||||
MIN_ARGUMENTS_RET(2, runtime_error);
|
MIN_ARGUMENTS_RET(2, runtime_error);
|
||||||
|
@ -211,8 +211,8 @@ size_t program::rpn_start(branch& myobj) {
|
||||||
ARG_MUST_BE_OF_TYPE_RET(1, cmd_number, runtime_error);
|
ARG_MUST_BE_OF_TYPE_RET(1, cmd_number, runtime_error);
|
||||||
|
|
||||||
// loop boundaries
|
// loop boundaries
|
||||||
myobj.firstIndex = _stack.value<number>(1);
|
myobj.firstIndex = _stack.value<Number>(1);
|
||||||
myobj.lastIndex = _stack.value<number>(0);
|
myobj.lastIndex = _stack.value<Number>(0);
|
||||||
_stack.erase(0, 2);
|
_stack.erase(0, 2);
|
||||||
|
|
||||||
// test value
|
// test value
|
||||||
|
@ -232,23 +232,23 @@ size_t program::rpn_start(branch& myobj) {
|
||||||
/// @return step_out next object to run in the current program is current + 1
|
/// @return step_out next object to run in the current program is current + 1
|
||||||
/// @return runtime_error something went wrong with preprocess, abort branch
|
/// @return runtime_error something went wrong with preprocess, abort branch
|
||||||
///
|
///
|
||||||
size_t program::rpn_for(branch& myobj) {
|
size_t program::rpn_for(Branch& myobj) {
|
||||||
size_t ret;
|
size_t ret;
|
||||||
|
|
||||||
MIN_ARGUMENTS_RET(2, runtime_error);
|
MIN_ARGUMENTS_RET(2, runtime_error);
|
||||||
ARG_MUST_BE_OF_TYPE_RET(0, cmd_number, runtime_error);
|
ARG_MUST_BE_OF_TYPE_RET(0, cmd_number, runtime_error);
|
||||||
ARG_MUST_BE_OF_TYPE_RET(1, cmd_number, runtime_error);
|
ARG_MUST_BE_OF_TYPE_RET(1, cmd_number, runtime_error);
|
||||||
|
|
||||||
symbol* sym;
|
Symbol* sym;
|
||||||
if (myobj.arg1 >= size() || at(myobj.arg1)->_type != cmd_symbol) {
|
if (myobj.arg1 >= size() || at(myobj.arg1)->_type != cmd_symbol) {
|
||||||
setErrorContext(ret_missing_operand);
|
setErrorContext(ret_missing_operand);
|
||||||
return runtime_error;
|
return runtime_error;
|
||||||
}
|
}
|
||||||
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.firstIndex = _stack.value<Number>(1);
|
||||||
myobj.lastIndex = _stack.value<number>(0);
|
myobj.lastIndex = _stack.value<Number>(0);
|
||||||
|
|
||||||
// test value
|
// test value
|
||||||
if (myobj.firstIndex > myobj.lastIndex) {
|
if (myobj.firstIndex > myobj.lastIndex) {
|
||||||
|
@ -263,7 +263,7 @@ size_t program::rpn_for(branch& myobj) {
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,15 +279,15 @@ size_t program::rpn_for(branch& myobj) {
|
||||||
/// @return step_out next object to run in the current program is current + 1
|
/// @return step_out next object to run in the current program is current + 1
|
||||||
/// @return runtime_error something went wrong with preprocess, abort branch
|
/// @return runtime_error something went wrong with preprocess, abort branch
|
||||||
///
|
///
|
||||||
size_t program::rpn_next(branch& myobj) {
|
size_t program::rpn_next(Branch& myobj) {
|
||||||
// arg1 = loop variable index
|
// arg1 = loop variable index
|
||||||
// firstIndex = current point in the loop
|
// firstIndex = current point in the loop
|
||||||
branch* start_or_for;
|
Branch* start_or_for;
|
||||||
if (myobj.arg1 >= size() || at(myobj.arg1)->_type != cmd_branch) {
|
if (myobj.arg1 >= size() || at(myobj.arg1)->_type != cmd_branch) {
|
||||||
setErrorContext(ret_missing_operand);
|
setErrorContext(ret_missing_operand);
|
||||||
return runtime_error;
|
return runtime_error;
|
||||||
}
|
}
|
||||||
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.firstIndex = start_or_for->firstIndex;
|
||||||
|
@ -299,16 +299,16 @@ size_t program::rpn_next(branch& myobj) {
|
||||||
|
|
||||||
// for command: increment symbol too
|
// for command: increment symbol too
|
||||||
if (start_or_for->arg1 != -1) {
|
if (start_or_for->arg1 != -1) {
|
||||||
object* obj;
|
Object* obj;
|
||||||
symbol* var;
|
Symbol* var;
|
||||||
if (start_or_for->arg1 >= size() || at(start_or_for->arg1)->_type != cmd_symbol) {
|
if (start_or_for->arg1 >= size() || at(start_or_for->arg1)->_type != cmd_symbol) {
|
||||||
setErrorContext(ret_missing_operand);
|
setErrorContext(ret_missing_operand);
|
||||||
return runtime_error;
|
return runtime_error;
|
||||||
}
|
}
|
||||||
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.firstIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
// test value
|
// test value
|
||||||
|
@ -332,12 +332,12 @@ size_t program::rpn_next(branch& myobj) {
|
||||||
/// @return step_out next object to run in the current program is current + 1
|
/// @return step_out next object to run in the current program is current + 1
|
||||||
/// @return runtime_error something went wrong with preprocess, abort branch
|
/// @return runtime_error something went wrong with preprocess, abort branch
|
||||||
///
|
///
|
||||||
size_t program::rpn_step(branch& myobj) {
|
size_t program::rpn_step(Branch& myobj) {
|
||||||
size_t ret;
|
size_t ret;
|
||||||
MIN_ARGUMENTS_RET(1, runtime_error);
|
MIN_ARGUMENTS_RET(1, runtime_error);
|
||||||
ARG_MUST_BE_OF_TYPE_RET(0, cmd_number, runtime_error);
|
ARG_MUST_BE_OF_TYPE_RET(0, cmd_number, runtime_error);
|
||||||
|
|
||||||
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
|
||||||
|
@ -346,12 +346,12 @@ size_t program::rpn_step(branch& myobj) {
|
||||||
} else {
|
} else {
|
||||||
// arg1 = loop variable index
|
// arg1 = loop variable index
|
||||||
// firstIndex = current count
|
// firstIndex = current count
|
||||||
branch* start_or_for;
|
Branch* start_or_for;
|
||||||
if (myobj.arg1 >= size() || at(myobj.arg1)->_type != cmd_branch) {
|
if (myobj.arg1 >= size() || at(myobj.arg1)->_type != cmd_branch) {
|
||||||
setErrorContext(ret_missing_operand);
|
setErrorContext(ret_missing_operand);
|
||||||
return runtime_error;
|
return runtime_error;
|
||||||
}
|
}
|
||||||
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.firstIndex = start_or_for->firstIndex;
|
||||||
|
@ -362,17 +362,17 @@ size_t program::rpn_step(branch& myobj) {
|
||||||
mpfr_add(myobj.firstIndex.mpfr_ptr(), myobj.firstIndex.mpfr_srcptr(), step.mpfr_srcptr(), MPFR_RNDD);
|
mpfr_add(myobj.firstIndex.mpfr_ptr(), myobj.firstIndex.mpfr_srcptr(), step.mpfr_srcptr(), MPFR_RNDD);
|
||||||
|
|
||||||
if (start_or_for->arg1 != -1) {
|
if (start_or_for->arg1 != -1) {
|
||||||
object* obj;
|
Object* obj;
|
||||||
symbol* var;
|
Symbol* var;
|
||||||
|
|
||||||
// for command: increment symbol too
|
// for command: increment symbol too
|
||||||
if (start_or_for->arg1 >= size() || at(start_or_for->arg1)->_type != cmd_symbol) {
|
if (start_or_for->arg1 >= size() || at(start_or_for->arg1)->_type != cmd_symbol) {
|
||||||
setErrorContext(ret_missing_operand);
|
setErrorContext(ret_missing_operand);
|
||||||
return runtime_error;
|
return runtime_error;
|
||||||
}
|
}
|
||||||
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.firstIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
// test loop value is out of range
|
// test loop value is out of range
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
void program::rpn_re() {
|
void program::rpn_re() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_complex);
|
ARG_MUST_BE_OF_TYPE(0, cmd_complex);
|
||||||
_stack.push_front(new number(real(_stack.value<ocomplex>(0))));
|
_stack.push_front(new Number(real(_stack.value<Complex>(0))));
|
||||||
_stack.erase(1);
|
_stack.erase(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ void program::rpn_re() {
|
||||||
void program::rpn_im() {
|
void program::rpn_im() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_complex);
|
ARG_MUST_BE_OF_TYPE(0, cmd_complex);
|
||||||
_stack.push_front(new number(imag(_stack.value<ocomplex>(0))));
|
_stack.push_front(new Number(imag(_stack.value<Complex>(0))));
|
||||||
_stack.erase(1);
|
_stack.erase(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ void program::rpn_im() {
|
||||||
void program::rpn_arg() {
|
void program::rpn_arg() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_complex);
|
ARG_MUST_BE_OF_TYPE(0, cmd_complex);
|
||||||
_stack.push_front(new number(arg(_stack.value<ocomplex>(0))));
|
_stack.push_front(new Number(arg(_stack.value<Complex>(0))));
|
||||||
_stack.erase(1);
|
_stack.erase(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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, cmd_complex);
|
ARG_MUST_BE_OF_TYPE(0, cmd_complex);
|
||||||
_stack.value<ocomplex>(0) = conj(_stack.value<ocomplex>(0));
|
_stack.value<Complex>(0) = conj(_stack.value<Complex>(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief r2c keyword implementation
|
/// @brief r2c keyword implementation
|
||||||
|
@ -48,7 +48,7 @@ void program::rpn_r2c() {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||||
_stack.push(new ocomplex(_stack.value<number>(1), _stack.value<number>(0), _stack.obj<ocomplex>(1).reBase, _stack.obj<ocomplex>(0).reBase));
|
_stack.push(new Complex(_stack.value<Number>(1), _stack.value<Number>(0), _stack.obj<Complex>(1).reBase, _stack.obj<Complex>(0).reBase));
|
||||||
_stack.erase(1, 2);
|
_stack.erase(1, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,8 +58,8 @@ void program::rpn_r2c() {
|
||||||
void program::rpn_c2r() {
|
void program::rpn_c2r() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_complex);
|
ARG_MUST_BE_OF_TYPE(0, cmd_complex);
|
||||||
_stack.push(new number(real(_stack.value<ocomplex>(0)), _stack.obj<ocomplex>(0).reBase));
|
_stack.push(new Number(real(_stack.value<Complex>(0)), _stack.obj<Complex>(0).reBase));
|
||||||
_stack.push(new number(imag(_stack.value<ocomplex>(1)), _stack.obj<ocomplex>(1).imBase));
|
_stack.push(new Number(imag(_stack.value<Complex>(1)), _stack.obj<Complex>(1).imBase));
|
||||||
_stack.erase(2);
|
_stack.erase(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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, cmd_complex);
|
ARG_MUST_BE_OF_TYPE(0, cmd_complex);
|
||||||
mpreal rho = abs(_stack.value<ocomplex>(0));
|
mpreal rho = abs(_stack.value<Complex>(0));
|
||||||
mpreal theta = arg(_stack.value<ocomplex>(0));
|
mpreal theta = arg(_stack.value<Complex>(0));
|
||||||
_stack.value<ocomplex>(0).real(rho);
|
_stack.value<Complex>(0).real(rho);
|
||||||
_stack.value<ocomplex>(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, cmd_complex);
|
ARG_MUST_BE_OF_TYPE(0, cmd_complex);
|
||||||
_stack.value<ocomplex>(0) = polar(abs(_stack.value<ocomplex>(0)), arg(_stack.value<ocomplex>(0)));
|
_stack.value<Complex>(0) = polar(abs(_stack.value<Complex>(0)), arg(_stack.value<Complex>(0)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,14 +69,14 @@ void program::rpn_help() {
|
||||||
|
|
||||||
// show mode
|
// show mode
|
||||||
cout << "Current float mode is ";
|
cout << "Current float mode is ";
|
||||||
switch (number::s_mode) {
|
switch (Number::s_mode) {
|
||||||
case number::std:
|
case Number::std:
|
||||||
cout << "'std'";
|
cout << "'std'";
|
||||||
break;
|
break;
|
||||||
case number::fix:
|
case Number::fix:
|
||||||
cout << "'fix'";
|
cout << "'fix'";
|
||||||
break;
|
break;
|
||||||
case number::sci:
|
case Number::sci:
|
||||||
cout << "'sci'";
|
cout << "'sci'";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -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::s_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,12 +110,12 @@ void program::rpn_std() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||||
|
|
||||||
int digits = static_cast<int>(_stack.value<number>(0).toLong());
|
int digits = static_cast<int>(_stack.value<Number>(0).toLong());
|
||||||
|
|
||||||
if (check_decimal_digits(digits)) {
|
if (check_decimal_digits(digits)) {
|
||||||
// set mode, decimal digits and print format
|
// set mode, decimal digits and print format
|
||||||
number::s_mode = number::std;
|
Number::s_mode = Number::std;
|
||||||
number::s_digits = digits;
|
Number::s_digits = digits;
|
||||||
_stack.pop();
|
_stack.pop();
|
||||||
} else {
|
} else {
|
||||||
setErrorContext(ret_out_of_range);
|
setErrorContext(ret_out_of_range);
|
||||||
|
@ -128,12 +128,12 @@ void program::rpn_fix() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||||
|
|
||||||
int digits = static_cast<int>(_stack.value<number>(0).toLong());
|
int digits = static_cast<int>(_stack.value<Number>(0).toLong());
|
||||||
|
|
||||||
if (check_decimal_digits(digits)) {
|
if (check_decimal_digits(digits)) {
|
||||||
// set mode, decimal digits and print format
|
// set mode, decimal digits and print format
|
||||||
number::s_mode = number::fix;
|
Number::s_mode = Number::fix;
|
||||||
number::s_digits = digits;
|
Number::s_digits = digits;
|
||||||
_stack.pop();
|
_stack.pop();
|
||||||
} else {
|
} else {
|
||||||
setErrorContext(ret_out_of_range);
|
setErrorContext(ret_out_of_range);
|
||||||
|
@ -146,12 +146,12 @@ void program::rpn_sci() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||||
|
|
||||||
int digits = static_cast<int>(_stack.value<number>(0).toLong());
|
int digits = static_cast<int>(_stack.value<Number>(0).toLong());
|
||||||
|
|
||||||
if (check_decimal_digits(digits)) {
|
if (check_decimal_digits(digits)) {
|
||||||
// set mode, decimal digits and print format
|
// set mode, decimal digits and print format
|
||||||
number::s_mode = number::sci;
|
Number::s_mode = Number::sci;
|
||||||
number::s_digits = digits;
|
Number::s_digits = digits;
|
||||||
_stack.pop();
|
_stack.pop();
|
||||||
} else {
|
} else {
|
||||||
setErrorContext(ret_out_of_range);
|
setErrorContext(ret_out_of_range);
|
||||||
|
@ -160,11 +160,11 @@ void program::rpn_sci() {
|
||||||
|
|
||||||
/// @brief _version keyword implementation
|
/// @brief _version keyword implementation
|
||||||
///
|
///
|
||||||
void program::rpn_version() { _stack.push_front(new ostring(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 ostring(RPN_UNAME)); }
|
void program::rpn_uname() { _stack.push_front(new String(RPN_UNAME)); }
|
||||||
|
|
||||||
/// @brief history keyword implementation
|
/// @brief history keyword implementation
|
||||||
///
|
///
|
||||||
|
@ -183,7 +183,7 @@ void program::rpn_history() {
|
||||||
///
|
///
|
||||||
void program::rpn_type() {
|
void program::rpn_type() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
_stack.push(new ostring(_stack.at(0)->name()));
|
_stack.push(new String(_stack.at(0)->name()));
|
||||||
_stack.erase(1);
|
_stack.erase(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,14 +198,14 @@ void program::rpn_precision() {
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||||
|
|
||||||
// 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::std) {
|
if (Number::s_mode == Number::std) {
|
||||||
// calc max nb of digits user can see with the current bit precision
|
// calc max nb of digits user can see with the current bit precision
|
||||||
number::s_digits = mpfr::bits2digits(mpreal::get_default_prec());
|
Number::s_digits = mpfr::bits2digits(mpreal::get_default_prec());
|
||||||
}
|
}
|
||||||
_stack.pop();
|
_stack.pop();
|
||||||
} else {
|
} else {
|
||||||
|
@ -221,7 +221,7 @@ 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<ostring>(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
|
||||||
|
|
|
@ -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) == cmd_number)
|
if (_stack.type(0) == cmd_number)
|
||||||
_stack.value<number>(0) = log10(_stack.value<number>(0));
|
_stack.value<Number>(0) = log10(_stack.value<Number>(0));
|
||||||
else if (_stack.type(0) == cmd_complex)
|
else if (_stack.type(0) == cmd_complex)
|
||||||
_stack.value<ocomplex>(0) = log10(_stack.value<ocomplex>(0));
|
_stack.value<Complex>(0) = log10(_stack.value<Complex>(0));
|
||||||
else
|
else
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
}
|
}
|
||||||
|
@ -23,9 +23,9 @@ void program::rpn_log10() {
|
||||||
void program::rpn_alog10() {
|
void program::rpn_alog10() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == cmd_number)
|
if (_stack.type(0) == cmd_number)
|
||||||
_stack.value<number>(0) = exp(log(mpreal(10)) * _stack.value<number>(0));
|
_stack.value<Number>(0) = exp(log(mpreal(10)) * _stack.value<Number>(0));
|
||||||
else if (_stack.type(0) == cmd_complex)
|
else if (_stack.type(0) == cmd_complex)
|
||||||
_stack.value<ocomplex>(0) = exp(log(mpreal(10)) * _stack.value<ocomplex>(0));
|
_stack.value<Complex>(0) = exp(log(mpreal(10)) * _stack.value<Complex>(0));
|
||||||
else
|
else
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
}
|
}
|
||||||
|
@ -35,9 +35,9 @@ void program::rpn_alog10() {
|
||||||
void program::rpn_log2() {
|
void program::rpn_log2() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == cmd_number)
|
if (_stack.type(0) == cmd_number)
|
||||||
_stack.value<number>(0) = log(_stack.value<number>(0)) / mpfr::const_log2();
|
_stack.value<Number>(0) = log(_stack.value<Number>(0)) / mpfr::const_log2();
|
||||||
else if (_stack.type(0) == cmd_complex)
|
else if (_stack.type(0) == cmd_complex)
|
||||||
_stack.value<ocomplex>(0) = log(_stack.value<ocomplex>(0)) / mpfr::const_log2();
|
_stack.value<Complex>(0) = log(_stack.value<Complex>(0)) / mpfr::const_log2();
|
||||||
else
|
else
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
}
|
}
|
||||||
|
@ -47,9 +47,9 @@ void program::rpn_log2() {
|
||||||
void program::rpn_alog2() {
|
void program::rpn_alog2() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == cmd_number)
|
if (_stack.type(0) == cmd_number)
|
||||||
_stack.value<number>(0) = exp(mpfr::const_log2() * _stack.value<number>(0));
|
_stack.value<Number>(0) = exp(mpfr::const_log2() * _stack.value<Number>(0));
|
||||||
else if (_stack.type(0) == cmd_complex)
|
else if (_stack.type(0) == cmd_complex)
|
||||||
_stack.value<ocomplex>(0) = exp(mpfr::const_log2() * _stack.value<ocomplex>(0));
|
_stack.value<Complex>(0) = exp(mpfr::const_log2() * _stack.value<Complex>(0));
|
||||||
else
|
else
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
}
|
}
|
||||||
|
@ -59,9 +59,9 @@ void program::rpn_alog2() {
|
||||||
void program::rpn_ln() {
|
void program::rpn_ln() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == cmd_number)
|
if (_stack.type(0) == cmd_number)
|
||||||
_stack.value<number>(0) = log(_stack.value<number>(0));
|
_stack.value<Number>(0) = log(_stack.value<Number>(0));
|
||||||
else if (_stack.type(0) == cmd_complex)
|
else if (_stack.type(0) == cmd_complex)
|
||||||
_stack.value<ocomplex>(0) = log(_stack.value<ocomplex>(0));
|
_stack.value<Complex>(0) = log(_stack.value<Complex>(0));
|
||||||
else
|
else
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
}
|
}
|
||||||
|
@ -71,9 +71,9 @@ void program::rpn_ln() {
|
||||||
void program::rpn_exp() {
|
void program::rpn_exp() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == cmd_number)
|
if (_stack.type(0) == cmd_number)
|
||||||
_stack.value<number>(0) = exp(_stack.value<number>(0));
|
_stack.value<Number>(0) = exp(_stack.value<Number>(0));
|
||||||
else if (_stack.type(0) == cmd_complex)
|
else if (_stack.type(0) == cmd_complex)
|
||||||
_stack.value<ocomplex>(0) = exp(_stack.value<ocomplex>(0));
|
_stack.value<Complex>(0) = exp(_stack.value<Complex>(0));
|
||||||
else
|
else
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
}
|
}
|
||||||
|
@ -83,9 +83,9 @@ void program::rpn_exp() {
|
||||||
void program::rpn_expm() {
|
void program::rpn_expm() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == cmd_number)
|
if (_stack.type(0) == cmd_number)
|
||||||
_stack.value<number>(0) = exp(_stack.value<number>(0)) - mpreal(1);
|
_stack.value<Number>(0) = exp(_stack.value<Number>(0)) - mpreal(1);
|
||||||
else if (_stack.type(0) == cmd_complex)
|
else if (_stack.type(0) == cmd_complex)
|
||||||
_stack.value<ocomplex>(0) = exp(_stack.value<ocomplex>(0)) - mpreal(1);
|
_stack.value<Complex>(0) = exp(_stack.value<Complex>(0)) - mpreal(1);
|
||||||
else
|
else
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
}
|
}
|
||||||
|
@ -95,9 +95,9 @@ void program::rpn_expm() {
|
||||||
void program::rpn_lnp1() {
|
void program::rpn_lnp1() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == cmd_number)
|
if (_stack.type(0) == cmd_number)
|
||||||
_stack.value<number>(0) = log(_stack.value<number>(0) + 1);
|
_stack.value<Number>(0) = log(_stack.value<Number>(0) + 1);
|
||||||
else if (_stack.type(0) == cmd_complex)
|
else if (_stack.type(0) == cmd_complex)
|
||||||
_stack.value<ocomplex>(0) = log(_stack.value<ocomplex>(0) + mpreal(1));
|
_stack.value<Complex>(0) = log(_stack.value<Complex>(0) + mpreal(1));
|
||||||
else
|
else
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
}
|
}
|
||||||
|
@ -107,9 +107,9 @@ void program::rpn_lnp1() {
|
||||||
void program::rpn_sinh() {
|
void program::rpn_sinh() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == cmd_number)
|
if (_stack.type(0) == cmd_number)
|
||||||
_stack.value<number>(0) = sinh(_stack.value<number>(0));
|
_stack.value<Number>(0) = sinh(_stack.value<Number>(0));
|
||||||
else if (_stack.type(0) == cmd_complex)
|
else if (_stack.type(0) == cmd_complex)
|
||||||
_stack.value<ocomplex>(0) = sinh(_stack.value<ocomplex>(0));
|
_stack.value<Complex>(0) = sinh(_stack.value<Complex>(0));
|
||||||
else
|
else
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
}
|
}
|
||||||
|
@ -119,9 +119,9 @@ void program::rpn_sinh() {
|
||||||
void program::rpn_asinh() {
|
void program::rpn_asinh() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == cmd_number)
|
if (_stack.type(0) == cmd_number)
|
||||||
_stack.value<number>(0) = asinh(_stack.value<number>(0));
|
_stack.value<Number>(0) = asinh(_stack.value<Number>(0));
|
||||||
else if (_stack.type(0) == cmd_complex)
|
else if (_stack.type(0) == cmd_complex)
|
||||||
_stack.value<ocomplex>(0) = asinh(_stack.value<ocomplex>(0));
|
_stack.value<Complex>(0) = asinh(_stack.value<Complex>(0));
|
||||||
else
|
else
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
}
|
}
|
||||||
|
@ -131,9 +131,9 @@ void program::rpn_asinh() {
|
||||||
void program::rpn_cosh() {
|
void program::rpn_cosh() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == cmd_number)
|
if (_stack.type(0) == cmd_number)
|
||||||
_stack.value<number>(0) = cosh(_stack.value<number>(0));
|
_stack.value<Number>(0) = cosh(_stack.value<Number>(0));
|
||||||
else if (_stack.type(0) == cmd_complex)
|
else if (_stack.type(0) == cmd_complex)
|
||||||
_stack.value<ocomplex>(0) = cosh(_stack.value<ocomplex>(0));
|
_stack.value<Complex>(0) = cosh(_stack.value<Complex>(0));
|
||||||
else
|
else
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
}
|
}
|
||||||
|
@ -143,9 +143,9 @@ void program::rpn_cosh() {
|
||||||
void program::rpn_acosh() {
|
void program::rpn_acosh() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == cmd_number)
|
if (_stack.type(0) == cmd_number)
|
||||||
_stack.value<number>(0) = acosh(_stack.value<number>(0));
|
_stack.value<Number>(0) = acosh(_stack.value<Number>(0));
|
||||||
else if (_stack.type(0) == cmd_complex)
|
else if (_stack.type(0) == cmd_complex)
|
||||||
_stack.value<ocomplex>(0) = acosh(_stack.value<ocomplex>(0));
|
_stack.value<Complex>(0) = acosh(_stack.value<Complex>(0));
|
||||||
else
|
else
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
}
|
}
|
||||||
|
@ -155,9 +155,9 @@ void program::rpn_acosh() {
|
||||||
void program::rpn_tanh() {
|
void program::rpn_tanh() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == cmd_number)
|
if (_stack.type(0) == cmd_number)
|
||||||
_stack.value<number>(0) = tanh(_stack.value<number>(0));
|
_stack.value<Number>(0) = tanh(_stack.value<Number>(0));
|
||||||
else if (_stack.type(0) == cmd_complex)
|
else if (_stack.type(0) == cmd_complex)
|
||||||
_stack.value<ocomplex>(0) = tanh(_stack.value<ocomplex>(0));
|
_stack.value<Complex>(0) = tanh(_stack.value<Complex>(0));
|
||||||
else
|
else
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
}
|
}
|
||||||
|
@ -167,9 +167,9 @@ void program::rpn_tanh() {
|
||||||
void program::rpn_atanh() {
|
void program::rpn_atanh() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == cmd_number)
|
if (_stack.type(0) == cmd_number)
|
||||||
_stack.value<number>(0) = atanh(_stack.value<number>(0));
|
_stack.value<Number>(0) = atanh(_stack.value<Number>(0));
|
||||||
else if (_stack.type(0) == cmd_complex)
|
else if (_stack.type(0) == cmd_complex)
|
||||||
_stack.value<ocomplex>(0) = atanh(_stack.value<ocomplex>(0));
|
_stack.value<Complex>(0) = atanh(_stack.value<Complex>(0));
|
||||||
else
|
else
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
/// @return true variable was found
|
/// @return true variable was found
|
||||||
/// @return false variable was not found
|
/// @return false variable was not found
|
||||||
///
|
///
|
||||||
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;
|
||||||
|
|
||||||
|
@ -40,14 +40,14 @@ void program::rpn_eval(void) {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == cmd_symbol) {
|
if (_stack.type(0) == cmd_symbol) {
|
||||||
// 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 == cmd_program) {
|
if (obj->_type == cmd_program) {
|
||||||
prog_text = _stack.value<oprogram>(0);
|
prog_text = _stack.value<Program>(0);
|
||||||
_stack.pop();
|
_stack.pop();
|
||||||
run_prog = true;
|
run_prog = true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -59,7 +59,7 @@ void program::rpn_eval(void) {
|
||||||
}
|
}
|
||||||
} else if (_stack.type(0) == cmd_program) {
|
} else if (_stack.type(0) == cmd_program) {
|
||||||
// eval a program
|
// eval a program
|
||||||
prog_text = _stack.value<oprogram>(0);
|
prog_text = _stack.value<Program>(0);
|
||||||
_stack.pop();
|
_stack.pop();
|
||||||
run_prog = true;
|
run_prog = true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -78,23 +78,23 @@ void program::rpn_eval(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief -> keyword (branch) implementation
|
/// @brief -> keyword (Branch) implementation
|
||||||
///
|
///
|
||||||
int program::rpn_inprog(branch& myobj) {
|
int program::rpn_inprog(Branch& inprog_obj) {
|
||||||
string context("->"); // for showing errors
|
string context("->"); // for showing errors
|
||||||
int count_symbols = 0;
|
int count_symbols = 0;
|
||||||
bool prog_found = false;
|
bool prog_found = false;
|
||||||
|
|
||||||
if (myobj.arg1 == -1) {
|
if (inprog_obj.arg1 == -1) {
|
||||||
setErrorContext(ret_unknown_err);
|
setErrorContext(ret_unknown_err);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// syntax must be
|
// syntax must be
|
||||||
// -> <auto evaluated symbol #1> ... <auto evaluated symbol #n> <oprogram>
|
// -> <auto evaluated symbol #1> ... <auto evaluated symbol #n> <program>
|
||||||
|
|
||||||
// find next oprogram object
|
// find next Program object
|
||||||
for (unsigned int i = myobj.arg1 + 1; i < size(); i++) {
|
for (unsigned int i = inprog_obj.arg1 + 1; i < size(); i++) {
|
||||||
// count symbol
|
// count symbol
|
||||||
if (at(i)->_type == cmd_symbol) {
|
if (at(i)->_type == cmd_symbol) {
|
||||||
count_symbols++;
|
count_symbols++;
|
||||||
|
@ -117,14 +117,14 @@ int program::rpn_inprog(branch& myobj) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// <oprogram> is missing
|
// <program> is missing
|
||||||
if (!prog_found) {
|
if (!prog_found) {
|
||||||
setErrorContext(ret_syntax);
|
setErrorContext(ret_syntax);
|
||||||
show_error(_err, context);
|
show_error(_err, context);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check symbols number vs stack size
|
// check symbols Number vs stack size
|
||||||
if (_stack.size() < count_symbols) {
|
if (_stack.size() < count_symbols) {
|
||||||
setErrorContext(ret_missing_operand);
|
setErrorContext(ret_missing_operand);
|
||||||
show_error(_err, context);
|
show_error(_err, context);
|
||||||
|
@ -132,13 +132,13 @@ int program::rpn_inprog(branch& myobj) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// load variables
|
// load variables
|
||||||
for (unsigned int i = myobj.arg1 + count_symbols; i > myobj.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<oprogram*>(at(myobj.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
|
||||||
|
@ -148,5 +148,5 @@ int program::rpn_inprog(branch& myobj) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// point on next command
|
// point on next command
|
||||||
return myobj.arg1 + count_symbols + 2;
|
return inprog_obj.arg1 + count_symbols + 2;
|
||||||
}
|
}
|
||||||
|
|
136
src/rpn-real.cpp
136
src/rpn-real.cpp
|
@ -7,20 +7,20 @@
|
||||||
void program::rpn_plus() {
|
void program::rpn_plus() {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
if (_stack.type(0) == cmd_string && _stack.type(1) == cmd_string) {
|
if (_stack.type(0) == cmd_string && _stack.type(1) == cmd_string) {
|
||||||
_stack.value<ostring>(1) += _stack.value<ostring>(0);
|
_stack.value<String>(1) += _stack.value<String>(0);
|
||||||
_stack.pop();
|
_stack.pop();
|
||||||
} else if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) {
|
} else if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) {
|
||||||
_stack.value<number>(1) += _stack.value<number>(0);
|
_stack.value<Number>(1) += _stack.value<Number>(0);
|
||||||
_stack.pop();
|
_stack.pop();
|
||||||
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_complex) {
|
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_complex) {
|
||||||
_stack.value<ocomplex>(1) += _stack.value<ocomplex>(0);
|
_stack.value<Complex>(1) += _stack.value<Complex>(0);
|
||||||
_stack.pop();
|
_stack.pop();
|
||||||
} else if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_complex) {
|
} else if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_complex) {
|
||||||
_stack.value<ocomplex>(1) += _stack.value<number>(0);
|
_stack.value<Complex>(1) += _stack.value<Number>(0);
|
||||||
_stack.pop();
|
_stack.pop();
|
||||||
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_number) {
|
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_number) {
|
||||||
rpn_swap();
|
rpn_swap();
|
||||||
_stack.value<ocomplex>(1) += _stack.value<number>(0);
|
_stack.value<Complex>(1) += _stack.value<Number>(0);
|
||||||
_stack.pop();
|
_stack.pop();
|
||||||
} else {
|
} else {
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
|
@ -32,17 +32,17 @@ void program::rpn_plus() {
|
||||||
void program::rpn_minus() {
|
void program::rpn_minus() {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) {
|
if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) {
|
||||||
_stack.value<number>(1) -= _stack.value<number>(0);
|
_stack.value<Number>(1) -= _stack.value<Number>(0);
|
||||||
_stack.pop();
|
_stack.pop();
|
||||||
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_complex) {
|
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_complex) {
|
||||||
_stack.value<ocomplex>(1) -= _stack.value<ocomplex>(0);
|
_stack.value<Complex>(1) -= _stack.value<Complex>(0);
|
||||||
_stack.pop();
|
_stack.pop();
|
||||||
} else if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_complex) {
|
} else if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_complex) {
|
||||||
_stack.value<ocomplex>(1) -= _stack.value<number>(0);
|
_stack.value<Complex>(1) -= _stack.value<Number>(0);
|
||||||
_stack.pop();
|
_stack.pop();
|
||||||
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_number) {
|
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_number) {
|
||||||
rpn_swap();
|
rpn_swap();
|
||||||
_stack.value<ocomplex>(1) = _stack.value<number>(0) - _stack.value<ocomplex>(1);
|
_stack.value<Complex>(1) = _stack.value<Number>(0) - _stack.value<Complex>(1);
|
||||||
_stack.pop();
|
_stack.pop();
|
||||||
} else {
|
} else {
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
|
@ -54,17 +54,17 @@ void program::rpn_minus() {
|
||||||
void program::rpn_mul() {
|
void program::rpn_mul() {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) {
|
if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) {
|
||||||
_stack.value<number>(1) *= _stack.value<number>(0);
|
_stack.value<Number>(1) *= _stack.value<Number>(0);
|
||||||
_stack.pop();
|
_stack.pop();
|
||||||
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_complex) {
|
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_complex) {
|
||||||
_stack.value<ocomplex>(1) *= _stack.value<ocomplex>(0);
|
_stack.value<Complex>(1) *= _stack.value<Complex>(0);
|
||||||
_stack.pop();
|
_stack.pop();
|
||||||
} else if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_complex) {
|
} else if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_complex) {
|
||||||
_stack.value<ocomplex>(1) *= _stack.value<number>(0);
|
_stack.value<Complex>(1) *= _stack.value<Number>(0);
|
||||||
_stack.pop();
|
_stack.pop();
|
||||||
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_number) {
|
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_number) {
|
||||||
rpn_swap();
|
rpn_swap();
|
||||||
_stack.value<ocomplex>(1) *= _stack.value<number>(0);
|
_stack.value<Complex>(1) *= _stack.value<Number>(0);
|
||||||
_stack.pop();
|
_stack.pop();
|
||||||
} else {
|
} else {
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
|
@ -76,17 +76,17 @@ void program::rpn_mul() {
|
||||||
void program::rpn_div() {
|
void program::rpn_div() {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) {
|
if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) {
|
||||||
_stack.value<number>(1) /= _stack.value<number>(0);
|
_stack.value<Number>(1) /= _stack.value<Number>(0);
|
||||||
_stack.pop();
|
_stack.pop();
|
||||||
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_complex) {
|
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_complex) {
|
||||||
_stack.value<ocomplex>(1) /= _stack.value<ocomplex>(0);
|
_stack.value<Complex>(1) /= _stack.value<Complex>(0);
|
||||||
_stack.pop();
|
_stack.pop();
|
||||||
} else if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_complex) {
|
} else if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_complex) {
|
||||||
_stack.value<ocomplex>(1) /= _stack.value<number>(0);
|
_stack.value<Complex>(1) /= _stack.value<Number>(0);
|
||||||
_stack.pop();
|
_stack.pop();
|
||||||
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_number) {
|
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_number) {
|
||||||
rpn_swap();
|
rpn_swap();
|
||||||
_stack.value<ocomplex>(1) = _stack.value<number>(0) / _stack.value<ocomplex>(1);
|
_stack.value<Complex>(1) = _stack.value<Number>(0) / _stack.value<Complex>(1);
|
||||||
_stack.pop();
|
_stack.pop();
|
||||||
} else {
|
} else {
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
|
@ -98,9 +98,9 @@ void program::rpn_div() {
|
||||||
void program::rpn_neg() {
|
void program::rpn_neg() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == cmd_number)
|
if (_stack.type(0) == cmd_number)
|
||||||
_stack.value<number>(0) = -_stack.value<number>(0);
|
_stack.value<Number>(0) = -_stack.value<Number>(0);
|
||||||
else if (_stack.type(0) == cmd_complex)
|
else if (_stack.type(0) == cmd_complex)
|
||||||
_stack.value<ocomplex>(0) = -_stack.value<ocomplex>(0);
|
_stack.value<Complex>(0) = -_stack.value<Complex>(0);
|
||||||
else
|
else
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
}
|
}
|
||||||
|
@ -110,9 +110,9 @@ void program::rpn_neg() {
|
||||||
void program::rpn_inv() {
|
void program::rpn_inv() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == cmd_number)
|
if (_stack.type(0) == cmd_number)
|
||||||
_stack.value<number>(0) = 1 / _stack.value<number>(0);
|
_stack.value<Number>(0) = 1 / _stack.value<Number>(0);
|
||||||
else if (_stack.type(0) == cmd_complex)
|
else if (_stack.type(0) == cmd_complex)
|
||||||
_stack.value<ocomplex>(0) = mpreal(1) / _stack.value<ocomplex>(0);
|
_stack.value<Complex>(0) = mpreal(1) / _stack.value<Complex>(0);
|
||||||
else
|
else
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
}
|
}
|
||||||
|
@ -122,24 +122,24 @@ void program::rpn_inv() {
|
||||||
void program::rpn_power() {
|
void program::rpn_power() {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) {
|
if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) {
|
||||||
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 ocomplex(_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<ocomplex>(0) = pow(_stack.value<ocomplex>(0), _stack.value<number>(1));
|
_stack.value<Complex>(0) = pow(_stack.value<Complex>(0), _stack.value<Number>(1));
|
||||||
_stack.erase(1, 2);
|
_stack.erase(1, 2);
|
||||||
}
|
}
|
||||||
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_complex) {
|
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_complex) {
|
||||||
_stack.value<ocomplex>(1) = pow(_stack.value<ocomplex>(1), _stack.value<ocomplex>(0));
|
_stack.value<Complex>(1) = pow(_stack.value<Complex>(1), _stack.value<Complex>(0));
|
||||||
_stack.pop();
|
_stack.pop();
|
||||||
} else if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_complex) {
|
} else if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_complex) {
|
||||||
_stack.value<ocomplex>(1) = pow(_stack.value<ocomplex>(1), _stack.value<number>(0));
|
_stack.value<Complex>(1) = pow(_stack.value<Complex>(1), _stack.value<Number>(0));
|
||||||
_stack.pop();
|
_stack.pop();
|
||||||
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_number) {
|
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_number) {
|
||||||
rpn_swap();
|
rpn_swap();
|
||||||
_stack.value<ocomplex>(1) = pow(_stack.value<number>(0), _stack.value<ocomplex>(1));
|
_stack.value<Complex>(1) = pow(_stack.value<Number>(0), _stack.value<Complex>(1));
|
||||||
_stack.pop();
|
_stack.pop();
|
||||||
} else {
|
} else {
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
|
@ -151,18 +151,18 @@ void program::rpn_power() {
|
||||||
void program::rpn_squareroot() {
|
void program::rpn_squareroot() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == cmd_number) {
|
if (_stack.type(0) == cmd_number) {
|
||||||
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 ocomplex(_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<ocomplex>(0) = sqrt(_stack.value<ocomplex>(0));
|
_stack.value<Complex>(0) = sqrt(_stack.value<Complex>(0));
|
||||||
_stack.erase(1);
|
_stack.erase(1);
|
||||||
}
|
}
|
||||||
} else if (_stack.type(0) == cmd_complex) {
|
} else if (_stack.type(0) == cmd_complex) {
|
||||||
_stack.value<ocomplex>(0) = sqrt(_stack.value<ocomplex>(0));
|
_stack.value<Complex>(0) = sqrt(_stack.value<Complex>(0));
|
||||||
} else {
|
} else {
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
}
|
}
|
||||||
|
@ -173,10 +173,10 @@ void program::rpn_squareroot() {
|
||||||
void program::rpn_hex() {
|
void program::rpn_hex() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == cmd_number) {
|
if (_stack.type(0) == cmd_number) {
|
||||||
_stack.obj<number>(0).base = 16;
|
_stack.obj<Number>(0).base = 16;
|
||||||
} else if (_stack.type(0) == cmd_complex) {
|
} else if (_stack.type(0) == cmd_complex) {
|
||||||
_stack.obj<ocomplex>(0).reBase = 16;
|
_stack.obj<Complex>(0).reBase = 16;
|
||||||
_stack.obj<ocomplex>(0).imBase = 16;
|
_stack.obj<Complex>(0).imBase = 16;
|
||||||
} else {
|
} else {
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
}
|
}
|
||||||
|
@ -187,10 +187,10 @@ void program::rpn_hex() {
|
||||||
void program::rpn_bin() {
|
void program::rpn_bin() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == cmd_number) {
|
if (_stack.type(0) == cmd_number) {
|
||||||
_stack.obj<number>(0).base = 2;
|
_stack.obj<Number>(0).base = 2;
|
||||||
} else if (_stack.type(0) == cmd_complex) {
|
} else if (_stack.type(0) == cmd_complex) {
|
||||||
_stack.obj<ocomplex>(0).reBase = 2;
|
_stack.obj<Complex>(0).reBase = 2;
|
||||||
_stack.obj<ocomplex>(0).imBase = 2;
|
_stack.obj<Complex>(0).imBase = 2;
|
||||||
} else {
|
} else {
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
}
|
}
|
||||||
|
@ -201,10 +201,10 @@ void program::rpn_bin() {
|
||||||
void program::rpn_dec() {
|
void program::rpn_dec() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == cmd_number) {
|
if (_stack.type(0) == cmd_number) {
|
||||||
_stack.obj<number>(0).base = 10;
|
_stack.obj<Number>(0).base = 10;
|
||||||
} else if (_stack.type(0) == cmd_complex) {
|
} else if (_stack.type(0) == cmd_complex) {
|
||||||
_stack.obj<ocomplex>(0).reBase = 10;
|
_stack.obj<Complex>(0).reBase = 10;
|
||||||
_stack.obj<ocomplex>(0).imBase = 10;
|
_stack.obj<Complex>(0).imBase = 10;
|
||||||
} else {
|
} else {
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
}
|
}
|
||||||
|
@ -215,14 +215,14 @@ void program::rpn_dec() {
|
||||||
void program::rpn_base() {
|
void program::rpn_base() {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
if (_stack.type(1) == cmd_number || _stack.type(1) == cmd_complex) {
|
if (_stack.type(1) == cmd_number || _stack.type(1) == cmd_complex) {
|
||||||
int base = static_cast<int>(_stack.value<number>(0).toLong());
|
int base = static_cast<int>(_stack.value<Number>(0).toLong());
|
||||||
_stack.pop();
|
_stack.pop();
|
||||||
if (base >= 2 && base <= 62) {
|
if (base >= 2 && base <= 62) {
|
||||||
if (_stack.type(0) == cmd_number) {
|
if (_stack.type(0) == cmd_number) {
|
||||||
_stack.obj<number>(0).base = base;
|
_stack.obj<Number>(0).base = base;
|
||||||
} else {
|
} else {
|
||||||
_stack.obj<ocomplex>(0).reBase = base;
|
_stack.obj<Complex>(0).reBase = base;
|
||||||
_stack.obj<ocomplex>(0).imBase = base;
|
_stack.obj<Complex>(0).imBase = base;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setErrorContext(ret_out_of_range);
|
setErrorContext(ret_out_of_range);
|
||||||
|
@ -238,7 +238,7 @@ void program::rpn_purcent() {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||||
_stack.value<number>(1) *= _stack.value<number>(0) / 100;
|
_stack.value<Number>(1) *= _stack.value<Number>(0) / 100;
|
||||||
_stack.pop();
|
_stack.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,7 +248,7 @@ void program::rpn_purcentCH() {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||||
_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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,9 +257,9 @@ void program::rpn_purcentCH() {
|
||||||
void program::rpn_square() {
|
void program::rpn_square() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == cmd_number)
|
if (_stack.type(0) == cmd_number)
|
||||||
_stack.value<number>(0) *= _stack.value<number>(0);
|
_stack.value<Number>(0) *= _stack.value<Number>(0);
|
||||||
else if (_stack.at(0)->_type == cmd_complex)
|
else if (_stack.at(0)->_type == cmd_complex)
|
||||||
_stack.value<ocomplex>(0) *= _stack.value<ocomplex>(0);
|
_stack.value<Complex>(0) *= _stack.value<Complex>(0);
|
||||||
else
|
else
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
}
|
}
|
||||||
|
@ -270,7 +270,7 @@ void program::rpn_modulo() {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||||
_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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,9 +279,9 @@ void program::rpn_modulo() {
|
||||||
void program::rpn_abs() {
|
void program::rpn_abs() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == cmd_number) {
|
if (_stack.type(0) == cmd_number) {
|
||||||
_stack.value<number>(0) = abs(_stack.value<number>(0));
|
_stack.value<Number>(0) = abs(_stack.value<Number>(0));
|
||||||
} else if (_stack.type(0) == cmd_complex) {
|
} else if (_stack.type(0) == cmd_complex) {
|
||||||
_stack.push(new number(abs(_stack.value<ocomplex>(0))));
|
_stack.push(new Number(abs(_stack.value<Complex>(0))));
|
||||||
_stack.erase(1);
|
_stack.erase(1);
|
||||||
} else {
|
} else {
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
|
@ -294,7 +294,7 @@ void program::rpn_fact() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||||
// 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
|
||||||
|
@ -302,9 +302,9 @@ void program::rpn_fact() {
|
||||||
void program::rpn_sign() {
|
void program::rpn_sign() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == cmd_number)
|
if (_stack.type(0) == cmd_number)
|
||||||
_stack.value<number>(0) = sgn(_stack.value<number>(0));
|
_stack.value<Number>(0) = sgn(_stack.value<Number>(0));
|
||||||
else if (_stack.at(0)->_type == cmd_complex)
|
else if (_stack.at(0)->_type == cmd_complex)
|
||||||
_stack.value<ocomplex>(0) = _stack.value<ocomplex>(0) / abs(_stack.value<ocomplex>(0));
|
_stack.value<Complex>(0) = _stack.value<Complex>(0) / abs(_stack.value<Complex>(0));
|
||||||
else
|
else
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
}
|
}
|
||||||
|
@ -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, cmd_number);
|
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||||
if (!isfinite(_stack.value<number>(0))) {
|
if (!isfinite(_stack.value<Number>(0))) {
|
||||||
setErrorContext(ret_out_of_range);
|
setErrorContext(ret_out_of_range);
|
||||||
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, cmd_number);
|
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||||
if (!isfinite(_stack.value<number>(0))) {
|
if (!isfinite(_stack.value<Number>(0))) {
|
||||||
setErrorContext(ret_out_of_range);
|
setErrorContext(ret_out_of_range);
|
||||||
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, cmd_number);
|
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||||
_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, cmd_number);
|
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||||
_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, cmd_number);
|
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||||
_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, cmd_number);
|
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||||
_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,7 +374,7 @@ void program::rpn_min() {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||||
_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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,6 +384,6 @@ void program::rpn_max() {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||||
_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,7 +6,7 @@
|
||||||
///
|
///
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ void program::rpn_dropn(void) {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ void program::rpn_dupn(void) {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||||
|
|
||||||
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);
|
||||||
|
@ -74,7 +74,7 @@ void program::rpn_pick(void) {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||||
|
|
||||||
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
|
||||||
|
@ -90,14 +90,14 @@ void program::rpn_pick(void) {
|
||||||
///
|
///
|
||||||
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,11 +105,11 @@ void program::rpn_roll(void) {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -120,11 +120,11 @@ void program::rpn_rolld(void) {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,12 +10,12 @@ void program::rpn_sto(void) {
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_symbol);
|
ARG_MUST_BE_OF_TYPE(0, cmd_symbol);
|
||||||
|
|
||||||
// store symbol with first value
|
// store symbol with first value
|
||||||
const auto it = _heap.find(_stack.value<ostring>(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<ostring>(0)] = _stack.at(1)->clone();
|
_heap[_stack.value<String>(0)] = _stack.at(1)->clone();
|
||||||
_stack.erase(0, 2);
|
_stack.erase(0, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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, cmd_symbol);
|
ARG_MUST_BE_OF_TYPE(0, cmd_symbol);
|
||||||
if (_heap.find(_stack.value<ostring>(0)) == _heap.end()) {
|
if (_heap.find(_stack.value<String>(0)) == _heap.end()) {
|
||||||
setErrorContext(ret_unknown_variable);
|
setErrorContext(ret_unknown_variable);
|
||||||
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, cmd_symbol);
|
ARG_MUST_BE_OF_TYPE(0, cmd_symbol);
|
||||||
if (_heap.find(_stack.value<ostring>(0)) == _heap.end()) {
|
if (_heap.find(_stack.value<String>(0)) == _heap.end()) {
|
||||||
setErrorContext(ret_unknown_variable);
|
setErrorContext(ret_unknown_variable);
|
||||||
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, cmd_symbol);
|
ARG_MUST_BE_OF_TYPE(0, cmd_symbol);
|
||||||
if (_heap.find(_stack.value<ostring>(0)) == _heap.end()) {
|
if (_heap.find(_stack.value<String>(0)) == _heap.end()) {
|
||||||
setErrorContext(ret_unknown_variable);
|
setErrorContext(ret_unknown_variable);
|
||||||
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, cmd_symbol);
|
ARG_MUST_BE_OF_TYPE(0, cmd_symbol);
|
||||||
if (_heap.find(_stack.value<ostring>(0)) == _heap.end()) {
|
if (_heap.find(_stack.value<String>(0)) == _heap.end()) {
|
||||||
setErrorContext(ret_unknown_variable);
|
setErrorContext(ret_unknown_variable);
|
||||||
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, cmd_symbol);
|
ARG_MUST_BE_OF_TYPE(0, cmd_symbol);
|
||||||
if (_heap.find(_stack.value<ostring>(0)) == _heap.end()) {
|
if (_heap.find(_stack.value<String>(0)) == _heap.end()) {
|
||||||
setErrorContext(ret_unknown_variable);
|
setErrorContext(ret_unknown_variable);
|
||||||
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, cmd_symbol);
|
ARG_MUST_BE_OF_TYPE(0, cmd_symbol);
|
||||||
if (_heap.find(_stack.value<ostring>(0)) == _heap.end()) {
|
if (_heap.find(_stack.value<String>(0)) == _heap.end()) {
|
||||||
setErrorContext(ret_unknown_variable);
|
setErrorContext(ret_unknown_variable);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -126,8 +126,8 @@ void program::rpn_rcl(void) {
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_symbol);
|
ARG_MUST_BE_OF_TYPE(0, cmd_symbol);
|
||||||
|
|
||||||
// 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)) {
|
||||||
|
@ -157,9 +157,9 @@ 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->autoEval) {
|
||||||
object* obj;
|
Object* obj;
|
||||||
string variable(symb->value);
|
string variable(symb->value);
|
||||||
|
|
||||||
// mind the order of heaps
|
// mind the order of heaps
|
||||||
|
@ -180,7 +180,7 @@ void program::rpn_purge(void) {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_symbol);
|
ARG_MUST_BE_OF_TYPE(0, cmd_symbol);
|
||||||
|
|
||||||
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);
|
||||||
|
@ -193,7 +193,7 @@ void program::rpn_purge(void) {
|
||||||
/// @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;
|
||||||
|
|
|
@ -14,7 +14,7 @@ void program::rpn_instr() {
|
||||||
stringstream ss;
|
stringstream ss;
|
||||||
ss << _stack.at(0);
|
ss << _stack.at(0);
|
||||||
_stack.pop();
|
_stack.pop();
|
||||||
_stack.push(new ostring(ss.str()));
|
_stack.push(new String(ss.str()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ void program::rpn_strout() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_string);
|
ARG_MUST_BE_OF_TYPE(0, cmd_string);
|
||||||
|
|
||||||
string entry(_stack.value<ostring>(0));
|
string entry(_stack.value<String>(0));
|
||||||
program prog(_stack, _heap);
|
program prog(_stack, _heap);
|
||||||
_stack.pop();
|
_stack.pop();
|
||||||
|
|
||||||
|
@ -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, cmd_number);
|
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||||
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 ostring(string(1, the_chr)));
|
_stack.push_front(new String(string(1, the_chr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief num keyword implementation
|
/// @brief num keyword implementation
|
||||||
|
@ -50,10 +50,10 @@ void program::rpn_chr() {
|
||||||
void program::rpn_num() {
|
void program::rpn_num() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_string);
|
ARG_MUST_BE_OF_TYPE(0, cmd_string);
|
||||||
if (_stack.value<ostring>(0).size() > 0)
|
if (_stack.value<String>(0).size() > 0)
|
||||||
_stack.push_front(new number(_stack.value<ostring>(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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ void program::rpn_num() {
|
||||||
void program::rpn_strsize() {
|
void program::rpn_strsize() {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_string);
|
ARG_MUST_BE_OF_TYPE(0, cmd_string);
|
||||||
_stack.push_front(new number(_stack.value<ostring>(0).size()));
|
_stack.push_front(new Number(_stack.value<String>(0).size()));
|
||||||
_stack.erase(1);
|
_stack.erase(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,9 +73,9 @@ void program::rpn_strpos() {
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_string);
|
ARG_MUST_BE_OF_TYPE(0, cmd_string);
|
||||||
ARG_MUST_BE_OF_TYPE(1, cmd_string);
|
ARG_MUST_BE_OF_TYPE(1, cmd_string);
|
||||||
|
|
||||||
size_t pos = _stack.value<ostring>(1).find(_stack.value<ostring>(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, cmd_number);
|
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||||
ARG_MUST_BE_OF_TYPE(2, cmd_string);
|
ARG_MUST_BE_OF_TYPE(2, cmd_string);
|
||||||
|
|
||||||
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<ostring>(2).size()) first = len = 0;
|
if (first > _stack.value<String>(2).size()) first = len = 0;
|
||||||
_stack.push(new ostring(_stack.value<ostring>(2).substr(first, len)));
|
_stack.push(new String(_stack.value<String>(2).substr(first, len)));
|
||||||
_stack.erase(1, 3);
|
_stack.erase(1, 3);
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,7 @@ 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<ostring>(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);
|
||||||
|
|
|
@ -7,10 +7,10 @@
|
||||||
/// @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 cmpStringsOnStackTop(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<ostring>(1).compare(stk.value<ostring>(0));
|
int res = stk.value<String>(1).compare(stk.value<String>(0));
|
||||||
stk.erase(0, 2);
|
stk.erase(0, 2);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -20,10 +20,10 @@ static int cmpStringsOnStackTop(rpnstack& stk) {
|
||||||
void program::rpn_sup(void) {
|
void program::rpn_sup(void) {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) {
|
if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) {
|
||||||
_stack.push_front(new number(_stack.value<number>(1) > _stack.value<number>(0)));
|
_stack.push_front(new Number(_stack.value<Number>(1) > _stack.value<Number>(0)));
|
||||||
_stack.erase(1, 2);
|
_stack.erase(1, 2);
|
||||||
} else if (_stack.type(0) == cmd_string && _stack.type(1) == cmd_string) {
|
} else if (_stack.type(0) == cmd_string && _stack.type(1) == cmd_string) {
|
||||||
_stack.push_front(new number(cmpStringsOnStackTop(_stack) == 1));
|
_stack.push_front(new Number(CmpStringOnStackTop(_stack) == 1));
|
||||||
_stack.erase(1, 2);
|
_stack.erase(1, 2);
|
||||||
} else {
|
} else {
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
|
@ -35,10 +35,10 @@ void program::rpn_sup(void) {
|
||||||
void program::rpn_sup_eq(void) {
|
void program::rpn_sup_eq(void) {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) {
|
if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) {
|
||||||
_stack.push_front(new number(_stack.value<number>(1) >= _stack.value<number>(0)));
|
_stack.push_front(new Number(_stack.value<Number>(1) >= _stack.value<Number>(0)));
|
||||||
_stack.erase(1, 2);
|
_stack.erase(1, 2);
|
||||||
} else if (_stack.type(0) == cmd_string && _stack.type(1) == cmd_string) {
|
} else if (_stack.type(0) == cmd_string && _stack.type(1) == cmd_string) {
|
||||||
_stack.push_front(new number(cmpStringsOnStackTop(_stack) != -1));
|
_stack.push_front(new Number(CmpStringOnStackTop(_stack) != -1));
|
||||||
_stack.erase(1, 2);
|
_stack.erase(1, 2);
|
||||||
} else {
|
} else {
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
|
@ -51,10 +51,10 @@ void program::rpn_inf(void) {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
|
|
||||||
if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) {
|
if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) {
|
||||||
_stack.push_front(new number(_stack.value<number>(1) < _stack.value<number>(0)));
|
_stack.push_front(new Number(_stack.value<Number>(1) < _stack.value<Number>(0)));
|
||||||
_stack.erase(1, 2);
|
_stack.erase(1, 2);
|
||||||
} else if (_stack.type(0) == cmd_string && _stack.type(1) == cmd_string) {
|
} else if (_stack.type(0) == cmd_string && _stack.type(1) == cmd_string) {
|
||||||
_stack.push_front(new number(cmpStringsOnStackTop(_stack) == -1));
|
_stack.push_front(new Number(CmpStringOnStackTop(_stack) == -1));
|
||||||
_stack.erase(1, 2);
|
_stack.erase(1, 2);
|
||||||
} else {
|
} else {
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
|
@ -66,10 +66,10 @@ void program::rpn_inf(void) {
|
||||||
void program::rpn_inf_eq(void) {
|
void program::rpn_inf_eq(void) {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) {
|
if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) {
|
||||||
_stack.push_front(new number(_stack.value<number>(1) <= _stack.value<number>(0)));
|
_stack.push_front(new Number(_stack.value<Number>(1) <= _stack.value<Number>(0)));
|
||||||
_stack.erase(1, 2);
|
_stack.erase(1, 2);
|
||||||
} else if (_stack.type(0) == cmd_string && _stack.type(1) == cmd_string) {
|
} else if (_stack.type(0) == cmd_string && _stack.type(1) == cmd_string) {
|
||||||
_stack.push_front(new number(cmpStringsOnStackTop(_stack) != 1));
|
_stack.push_front(new Number(CmpStringOnStackTop(_stack) != 1));
|
||||||
_stack.erase(1, 2);
|
_stack.erase(1, 2);
|
||||||
} else {
|
} else {
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
|
@ -81,13 +81,13 @@ void program::rpn_inf_eq(void) {
|
||||||
void program::rpn_diff(void) {
|
void program::rpn_diff(void) {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) {
|
if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) {
|
||||||
_stack.push_front(new number(_stack.value<number>(1) != _stack.value<number>(0)));
|
_stack.push_front(new Number(_stack.value<Number>(1) != _stack.value<Number>(0)));
|
||||||
_stack.erase(1, 2);
|
_stack.erase(1, 2);
|
||||||
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_complex) {
|
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_complex) {
|
||||||
_stack.push_front(new number(_stack.value<ocomplex>(1) != _stack.value<ocomplex>(0)));
|
_stack.push_front(new Number(_stack.value<Complex>(1) != _stack.value<Complex>(0)));
|
||||||
_stack.erase(1, 2);
|
_stack.erase(1, 2);
|
||||||
} else if (_stack.type(0) == cmd_string && _stack.type(1) == cmd_string) {
|
} else if (_stack.type(0) == cmd_string && _stack.type(1) == cmd_string) {
|
||||||
_stack.push_front(new number(cmpStringsOnStackTop(_stack) != 0));
|
_stack.push_front(new Number(CmpStringOnStackTop(_stack) != 0));
|
||||||
_stack.erase(1, 2);
|
_stack.erase(1, 2);
|
||||||
} else {
|
} else {
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
|
@ -99,13 +99,13 @@ void program::rpn_diff(void) {
|
||||||
void program::rpn_eq(void) {
|
void program::rpn_eq(void) {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) {
|
if (_stack.type(0) == cmd_number && _stack.type(1) == cmd_number) {
|
||||||
_stack.push_front(new number(_stack.value<number>(1) == _stack.value<number>(0)));
|
_stack.push_front(new Number(_stack.value<Number>(1) == _stack.value<Number>(0)));
|
||||||
_stack.erase(1, 2);
|
_stack.erase(1, 2);
|
||||||
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_complex) {
|
} else if (_stack.type(0) == cmd_complex && _stack.type(1) == cmd_complex) {
|
||||||
_stack.push_front(new number(_stack.value<ocomplex>(1) == _stack.value<ocomplex>(0)));
|
_stack.push_front(new Number(_stack.value<Complex>(1) == _stack.value<Complex>(0)));
|
||||||
_stack.erase(1, 2);
|
_stack.erase(1, 2);
|
||||||
} else if (_stack.type(0) == cmd_string && _stack.type(1) == cmd_string) {
|
} else if (_stack.type(0) == cmd_string && _stack.type(1) == cmd_string) {
|
||||||
_stack.push_front(new number(cmpStringsOnStackTop(_stack) == 0));
|
_stack.push_front(new Number(CmpStringOnStackTop(_stack) == 0));
|
||||||
_stack.erase(1, 2);
|
_stack.erase(1, 2);
|
||||||
} else {
|
} else {
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
|
@ -118,10 +118,10 @@ void program::rpn_test_and(void) {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,10 +131,10 @@ void program::rpn_test_or(void) {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,10 +144,10 @@ void program::rpn_test_xor(void) {
|
||||||
MIN_ARGUMENTS(2);
|
MIN_ARGUMENTS(2);
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||||
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
ARG_MUST_BE_OF_TYPE(1, cmd_number);
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ void program::rpn_test_not(void) {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||||
|
|
||||||
_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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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(ret_internal);
|
setErrorContext(ret_internal);
|
||||||
}
|
}
|
||||||
|
@ -46,10 +46,10 @@ void program::rpn_date() {
|
||||||
static_cast<double>(tm->tm_year + 1900);
|
static_cast<double>(tm->tm_year + 1900);
|
||||||
|
|
||||||
// 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(ret_internal);
|
setErrorContext(ret_internal);
|
||||||
}
|
}
|
||||||
|
@ -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(ret_internal);
|
setErrorContext(ret_internal);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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, cmd_number);
|
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||||
_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,8 +22,8 @@ void program::rpn_d2r(void) {
|
||||||
void program::rpn_r2d(void) {
|
void program::rpn_r2d(void) {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
ARG_MUST_BE_OF_TYPE(0, cmd_number);
|
||||||
_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
|
||||||
|
@ -31,9 +31,9 @@ void program::rpn_r2d(void) {
|
||||||
void program::rpn_sin(void) {
|
void program::rpn_sin(void) {
|
||||||
MIN_ARGUMENTS(1);
|
MIN_ARGUMENTS(1);
|
||||||
if (_stack.type(0) == cmd_number)
|
if (_stack.type(0) == cmd_number)
|
||||||
_stack.value<number>(0) = sin(_stack.value<number>(0));
|
_stack.value<Number>(0) = sin(_stack.value<Number>(0));
|
||||||
else if (_stack.type(0) == cmd_complex)
|
else if (_stack.type(0) == cmd_complex)
|
||||||
_stack.value<ocomplex>(0) = sin(_stack.value<ocomplex>(0));
|
_stack.value<Complex>(0) = sin(_stack.value<Complex>(0));
|
||||||
else
|
else
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
}
|
}
|
||||||
|
@ -43,9 +43,9 @@ 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) == cmd_number)
|
if (_stack.type(0) == cmd_number)
|
||||||
_stack.value<number>(0) = asin(_stack.value<number>(0));
|
_stack.value<Number>(0) = asin(_stack.value<Number>(0));
|
||||||
else if (_stack.type(0) == cmd_complex)
|
else if (_stack.type(0) == cmd_complex)
|
||||||
_stack.value<ocomplex>(0) = asin(_stack.value<ocomplex>(0));
|
_stack.value<Complex>(0) = asin(_stack.value<Complex>(0));
|
||||||
else
|
else
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
}
|
}
|
||||||
|
@ -55,9 +55,9 @@ 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) == cmd_number)
|
if (_stack.type(0) == cmd_number)
|
||||||
_stack.value<number>(0) = cos(_stack.value<number>(0));
|
_stack.value<Number>(0) = cos(_stack.value<Number>(0));
|
||||||
else if (_stack.type(0) == cmd_complex)
|
else if (_stack.type(0) == cmd_complex)
|
||||||
_stack.value<ocomplex>(0) = cos(_stack.value<ocomplex>(0));
|
_stack.value<Complex>(0) = cos(_stack.value<Complex>(0));
|
||||||
else
|
else
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
}
|
}
|
||||||
|
@ -67,9 +67,9 @@ 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) == cmd_number)
|
if (_stack.type(0) == cmd_number)
|
||||||
_stack.value<number>(0) = acos(_stack.value<number>(0));
|
_stack.value<Number>(0) = acos(_stack.value<Number>(0));
|
||||||
else if (_stack.type(0) == cmd_complex)
|
else if (_stack.type(0) == cmd_complex)
|
||||||
_stack.value<ocomplex>(0) = acos(_stack.value<ocomplex>(0));
|
_stack.value<Complex>(0) = acos(_stack.value<Complex>(0));
|
||||||
else
|
else
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
}
|
}
|
||||||
|
@ -79,9 +79,9 @@ 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) == cmd_number)
|
if (_stack.type(0) == cmd_number)
|
||||||
_stack.value<number>(0) = tan(_stack.value<number>(0));
|
_stack.value<Number>(0) = tan(_stack.value<Number>(0));
|
||||||
else if (_stack.type(0) == cmd_complex)
|
else if (_stack.type(0) == cmd_complex)
|
||||||
_stack.value<ocomplex>(0) = tan(_stack.value<ocomplex>(0));
|
_stack.value<Complex>(0) = tan(_stack.value<Complex>(0));
|
||||||
else
|
else
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
}
|
}
|
||||||
|
@ -91,9 +91,9 @@ 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) == cmd_number)
|
if (_stack.type(0) == cmd_number)
|
||||||
_stack.value<number>(0) = atan(_stack.value<number>(0));
|
_stack.value<Number>(0) = atan(_stack.value<Number>(0));
|
||||||
else if (_stack.type(0) == cmd_complex)
|
else if (_stack.type(0) == cmd_complex)
|
||||||
_stack.value<ocomplex>(0) = atan(_stack.value<ocomplex>(0));
|
_stack.value<Complex>(0) = atan(_stack.value<Complex>(0));
|
||||||
else
|
else
|
||||||
setErrorContext(ret_bad_operand_type);
|
setErrorContext(ret_bad_operand_type);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,18 +13,18 @@ using namespace std;
|
||||||
|
|
||||||
/// @brief stack object, parens of program, storing execution stack values or programs
|
/// @brief stack object, parens of program, storing execution stack values or programs
|
||||||
///
|
///
|
||||||
class rpnstack : public deque<object*> {
|
class rpnstack : public deque<Object*> {
|
||||||
public:
|
public:
|
||||||
rpnstack() {}
|
rpnstack() {}
|
||||||
virtual ~rpnstack() {
|
virtual ~rpnstack() {
|
||||||
for_each(begin(), end(), [](object* o) { delete o; });
|
for_each(begin(), end(), [](Object* o) { delete o; });
|
||||||
deque::erase(begin(), end());
|
deque::erase(begin(), end());
|
||||||
}
|
}
|
||||||
|
|
||||||
// stack manipulation
|
// stack manipulation
|
||||||
void erase(size_t first = 0, size_t nb = 1, bool del = true) {
|
void erase(size_t first = 0, size_t nb = 1, bool del = true) {
|
||||||
size_t last = std::min(first + nb, size());
|
size_t last = std::min(first + nb, size());
|
||||||
if (del) for_each(begin() + first, begin() + last, [](object* o) { delete o; });
|
if (del) for_each(begin() + first, begin() + last, [](Object* o) { delete o; });
|
||||||
deque::erase(begin() + first, begin() + last);
|
deque::erase(begin() + first, begin() + last);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,12 +49,12 @@ class rpnstack : public deque<object*> {
|
||||||
return static_cast<objectType*>(at(level))->value;
|
return static_cast<objectType*>(at(level))->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void push(object* o) { deque<object*>::push_front(o); }
|
void push(Object* o) { deque<Object*>::push_front(o); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief heap object, storing variables (=named object)
|
/// @brief heap object, storing variables (=named object)
|
||||||
///
|
///
|
||||||
class heap : public map<string, object*> {
|
class heap : public map<string, Object*> {
|
||||||
public:
|
public:
|
||||||
heap() {}
|
heap() {}
|
||||||
virtual ~heap() { clear(); }
|
virtual ~heap() { clear(); }
|
||||||
|
@ -64,7 +64,7 @@ class heap : public map<string, object*> {
|
||||||
map::erase(begin(), end());
|
map::erase(begin(), end());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get(const string name, object*& obj) {
|
bool get(const string name, Object*& obj) {
|
||||||
auto i = find(name);
|
auto i = find(name);
|
||||||
if (i != end()) {
|
if (i != end()) {
|
||||||
obj = i->second;
|
obj = i->second;
|
||||||
|
|
Loading…
Add table
Reference in a new issue