mirror of
https://github.com/louisrubet/rpn
synced 2025-01-30 20:34:30 +01:00
First step: lexer, entries and number outputs with new libbf decimal
This commit is contained in:
parent
0c8bc70ab9
commit
2ff0a3db88
17 changed files with 122 additions and 115 deletions
9
.gitmodules
vendored
9
.gitmodules
vendored
|
@ -1,9 +1,6 @@
|
|||
[submodule "linenoise-ng"]
|
||||
path = linenoise-ng
|
||||
url = https://github.com/louisrubet/linenoise-ng.git
|
||||
[submodule "mpreal"]
|
||||
path = mpreal
|
||||
url = https://github.com/advanpix/mpreal
|
||||
[submodule "libbf"]
|
||||
path = libbf
|
||||
url = https://github.com/louisrubet/libbf
|
||||
[submodule "libbfdec-cpp"]
|
||||
path = libbfdec-cpp
|
||||
url = git@github.com:louisrubet/libbfdec-cpp.git
|
||||
|
|
|
@ -31,22 +31,14 @@ set(RPN_LICENSE "LGPLv3")
|
|||
set(RPN_LICENSE_FILE "${PROJECT_SOURCE_DIR}/LICENSE")
|
||||
set(RPN_DESCRIPTION_FILE "${PROJECT_SOURCE_DIR}/README.md")
|
||||
|
||||
# custom linenoise-ng
|
||||
if(NOT EXISTS "${PROJECT_SOURCE_DIR}/linenoise-ng/.git")
|
||||
execute_process(COMMAND git submodule init ${PROJECT_SOURCE_DIR}/linenoise-ng)
|
||||
execute_process(COMMAND git submodule update ${PROJECT_SOURCE_DIR}/linenoise-ng)
|
||||
execute_process(COMMAND git checkout v1.1.4-rpn WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/linenoise-ng)
|
||||
endif()
|
||||
|
||||
# custom mpreal
|
||||
if(NOT EXISTS "${PROJECT_SOURCE_DIR}/mpreal/.git")
|
||||
execute_process(COMMAND git submodule init ${PROJECT_SOURCE_DIR}/mpreal)
|
||||
execute_process(COMMAND git submodule update ${PROJECT_SOURCE_DIR}/mpreal)
|
||||
execute_process(COMMAND git checkout mpfrc++-3.6.9 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/mpreal)
|
||||
endif()
|
||||
add_subdirectory(libbfdec-cpp)
|
||||
|
||||
# includes
|
||||
include_directories(${PROJECT_SOURCE_DIR}/src ${PROJECT_SOURCE_DIR}/linenoise-ng/include ${PROJECT_SOURCE_DIR}/mpreal)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/src
|
||||
${PROJECT_SOURCE_DIR}/linenoise-ng/include
|
||||
${PROJECT_SOURCE_DIR}/libbfdec-cpp
|
||||
${PROJECT_SOURCE_DIR}/libbfdec-cpp/libbf
|
||||
${PROJECT_SOURCE_DIR}/libbfdec-cpp/quickjs-fake)
|
||||
|
||||
# src
|
||||
set(RPN_SRC_FILES
|
||||
|
@ -54,13 +46,13 @@ set(RPN_SRC_FILES
|
|||
${PROJECT_SOURCE_DIR}/src/program.cc
|
||||
${PROJECT_SOURCE_DIR}/src/main.cc
|
||||
${PROJECT_SOURCE_DIR}/src/object.cc
|
||||
${PROJECT_SOURCE_DIR}/src/mpreal-out.cc
|
||||
# ${PROJECT_SOURCE_DIR}/src/mpreal-out.cc
|
||||
${PROJECT_SOURCE_DIR}/src/lexer.cc
|
||||
${PROJECT_SOURCE_DIR}/src/input.cc
|
||||
${PROJECT_SOURCE_DIR}/src/rpn-branch.cc
|
||||
${PROJECT_SOURCE_DIR}/src/rpn-complex.cc
|
||||
# ${PROJECT_SOURCE_DIR}/src/rpn-branch.cc
|
||||
# ${PROJECT_SOURCE_DIR}/src/rpn-complex.cc
|
||||
${PROJECT_SOURCE_DIR}/src/rpn-general.cc
|
||||
${PROJECT_SOURCE_DIR}/src/rpn-logs.cc
|
||||
# ${PROJECT_SOURCE_DIR}/src/rpn-logs.cc
|
||||
${PROJECT_SOURCE_DIR}/src/rpn-program.cc
|
||||
${PROJECT_SOURCE_DIR}/src/rpn-real.cc
|
||||
${PROJECT_SOURCE_DIR}/src/rpn-stack.cc
|
||||
|
@ -69,7 +61,11 @@ set(RPN_SRC_FILES
|
|||
${PROJECT_SOURCE_DIR}/src/rpn-test.cc
|
||||
${PROJECT_SOURCE_DIR}/src/rpn-test-framework.cc
|
||||
${PROJECT_SOURCE_DIR}/src/rpn-time.cc
|
||||
${PROJECT_SOURCE_DIR}/src/rpn-trig.cc)
|
||||
# ${PROJECT_SOURCE_DIR}/src/rpn-trig.cc
|
||||
# ${PROJECT_SOURCE_DIR}/libbfdec-cpp/libbf/libbf.c
|
||||
# ${PROJECT_SOURCE_DIR}/libbfdec-cpp/libbf/cutils.c
|
||||
# ${PROJECT_SOURCE_DIR}/libbfdec-cpp/libbfdec++.cpp
|
||||
)
|
||||
|
||||
set(LINENOISE_NG_SRC_FILES
|
||||
${PROJECT_SOURCE_DIR}/linenoise-ng/src/ConvertUTF.cpp
|
||||
|
@ -77,16 +73,14 @@ set(LINENOISE_NG_SRC_FILES
|
|||
${PROJECT_SOURCE_DIR}/linenoise-ng/src/wcwidth.cpp)
|
||||
|
||||
# compiler options
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set_source_files_properties(${RPN_SRC_FILES} COMPILE_FLAGS "-Wall -Wextra -pedantic -Wno-missing-field-initializers")
|
||||
add_compile_options("$<$<CONFIG:DEBUG>:-O0;-g3;-ggdb>" "$<$<CONFIG:RELEASE>:-O3>")
|
||||
|
||||
add_compile_options("-std=c++20"
|
||||
"$<$<CONFIG:DEBUG>:-O0;-g3;-ggdb>"
|
||||
"$<$<CONFIG:RELEASE>:-O3>")
|
||||
|
||||
add_executable(rpn ${RPN_SRC_FILES} ${LINENOISE_NG_SRC_FILES})
|
||||
|
||||
target_link_libraries(rpn mpfr)
|
||||
target_link_libraries(rpn gmp)
|
||||
# executable
|
||||
add_executable(rpn ${RPN_SRC_FILES} ${LINENOISE_NG_SRC_FILES} ${LIBBF_SRC_FILES})
|
||||
target_link_libraries(rpn libbf)
|
||||
|
||||
# install
|
||||
install(TARGETS rpn DESTINATION bin)
|
||||
|
|
1
libbf
1
libbf
|
@ -1 +0,0 @@
|
|||
Subproject commit 19bd01375827e13bd7ded3c82b9a5f50cc3bf2f4
|
1
libbfdec-cpp
Submodule
1
libbfdec-cpp
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 1a1ce5a93ca57abb548066f67581e9137549aeb1
|
1
mpreal
1
mpreal
|
@ -1 +0,0 @@
|
|||
Subproject commit 269a03782fa0b87c20470976b88677266c5423ad
|
|
@ -45,8 +45,8 @@ bool Lexer::Analyse(const string& entry, map<string, ReservedWord>& keywords, ve
|
|||
}
|
||||
|
||||
void Lexer::Trim(string& s) {
|
||||
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) { return !std::isspace(ch); }));
|
||||
s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) { return !std::isspace(ch); }).base(), s.end());
|
||||
s.erase(s.begin(), std::ranges::find_if(s.begin(), s.end(), [](unsigned char ch) { return !std::isspace(ch); }));
|
||||
s.erase(std::ranges::find_if(s.rbegin(), s.rend(), [](unsigned char ch) { return !std::isspace(ch); }).base(), s.end());
|
||||
}
|
||||
|
||||
bool Lexer::ParseString(const string& entry, size_t idx, size_t& next_idx,
|
||||
|
@ -167,7 +167,7 @@ bool Lexer::GetNumberAt(const string& entry, size_t idx, size_t& next_idx, int&
|
|||
if (base < 2 || base > 62) return false;
|
||||
if (numberIdx != 0) token = token.substr(numberIdx);
|
||||
*r = new mpreal;
|
||||
if (mpfr_set_str((*r)->mpfr_ptr(), token.c_str(), base, mpreal::get_default_rnd()) == 0) {
|
||||
if (bfdec_atof(&(*r)->toBfdec(), token.c_str(), nullptr, (limb_t)Bfdec::get_default_prec(), (bf_flags_t)Bfdec::get_default_rnd()) == 0) {
|
||||
if (!positive) *(*r) = -*(*r);
|
||||
return true;
|
||||
} else {
|
||||
|
|
|
@ -3,8 +3,7 @@
|
|||
#ifndef SRC_LEXER_H_
|
||||
#define SRC_LEXER_H_
|
||||
|
||||
#include <mpreal.h>
|
||||
using mpfr::mpreal;
|
||||
#include <libbfdec++.h>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <cerrno>
|
||||
#include <csignal>
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
using std::cerr;
|
||||
|
||||
// internal includes
|
||||
|
@ -119,7 +120,7 @@ int main(int argc, char* argv[]) {
|
|||
}
|
||||
}
|
||||
|
||||
mpfr_free_cache();
|
||||
Bfdec::clear_cache();
|
||||
|
||||
if (ret != kOk) return EXIT_FAILURE;
|
||||
return EXIT_SUCCESS;
|
||||
|
|
|
@ -2,11 +2,15 @@
|
|||
|
||||
#include "object.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
// number statics
|
||||
Number::mode_enum Number::mode = Number::kDefaultMode;
|
||||
int Number::digits = kDefaultDecimalDigits;
|
||||
limb_t Number::digits = kDefaultDecimalDigits;
|
||||
|
||||
ostream& Number::ShowValue(ostream& out, const mpreal& value, mode_enum mode, int digits, int base) {
|
||||
ostream& Number::ShowValue(ostream& out, const Bfdec& value, mode_enum mode, int digits, int base) {
|
||||
return out << bfdec_ftoa(NULL, &value.toBfdec(), (limb_t)BF_PREC_INF, (bf_flags_t)(BF_RNDZ | BF_FTOA_FORMAT_FREE));
|
||||
#if 0
|
||||
stringstream format;
|
||||
switch (base) {
|
||||
case 10:
|
||||
|
@ -40,4 +44,5 @@ ostream& Number::ShowValue(ostream& out, const mpreal& value, mode_enum mode, in
|
|||
// base other than 2, 10, 16
|
||||
return MprealOutputNBase(out, base, value);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
33
src/object.h
33
src/object.h
|
@ -3,8 +3,7 @@
|
|||
#ifndef SRC_OBJECT_H_
|
||||
#define SRC_OBJECT_H_
|
||||
|
||||
#include <mpreal.h>
|
||||
using mpfr::mpreal;
|
||||
#include <libbfdec++.h>
|
||||
|
||||
#include <complex>
|
||||
#include <ostream>
|
||||
|
@ -12,8 +11,6 @@ using mpfr::mpreal;
|
|||
#include <string>
|
||||
using std::complex, std::ostream, std::string, std::stringstream;
|
||||
|
||||
#include "mpreal-out.h"
|
||||
|
||||
// definitions for objects
|
||||
///
|
||||
typedef enum {
|
||||
|
@ -81,12 +78,14 @@ union object_cb_t {
|
|||
///
|
||||
struct Number : Object {
|
||||
Number() : Object(kNumber), base(10) {}
|
||||
explicit Number(const mpreal& value__, int base__ = 10) : Object(kNumber), base(base__), value(value__) {}
|
||||
explicit Number(int value__, int base__ = 10) : Object(kNumber), base(base__), value(value__) {}
|
||||
explicit Number(const Bfdec& value__, int base__ = 10) : Object(kNumber), base(base__), value(value__) {}
|
||||
explicit Number(int64_t value__, int base__ = 10) : Object(kNumber), base(base__), value(value__) {}
|
||||
explicit Number(uint64_t value__, int base__ = 10) : Object(kNumber), base(base__), value(value__) {}
|
||||
explicit Number(bool value__, int base__ = 10) : Object(kNumber), base(base__), value(value__ ? 1 : 0) {}
|
||||
explicit Number(int value__, int base__ = 10) : Object(kNumber), base(base__), value(value__) {}
|
||||
|
||||
int base;
|
||||
mpreal value;
|
||||
Bfdec value;
|
||||
|
||||
virtual Object* Clone() { return new Number(value, base); }
|
||||
virtual string Name() { return string("number"); }
|
||||
|
@ -98,30 +97,30 @@ struct Number : Object {
|
|||
static constexpr mode_enum kDefaultMode = Number::kStd;
|
||||
|
||||
// precision
|
||||
static constexpr mpfr_prec_t kMpfrDefaultPrecBits = 128;
|
||||
static constexpr mp_prec_t kMpfrDefaultPrecBits = 128;
|
||||
static constexpr int kDefaultDecimalDigits = 38;
|
||||
static int digits;
|
||||
static limb_t digits;
|
||||
|
||||
// clang-format on
|
||||
static ostream& ShowValue(ostream& out, const mpreal& value, mode_enum mode, int digits, int base);
|
||||
static ostream& ShowValue(ostream& out, const Bfdec& value, mode_enum mode, int digits, int base);
|
||||
|
||||
static void* rpn_bf_realloc(void*, void* ptr, size_t size);
|
||||
static bf_context_t rpn_bf_ctx;
|
||||
};
|
||||
|
||||
/// @brief stack objects inheriting Object
|
||||
///
|
||||
struct Complex : Object {
|
||||
Complex() : Object(kComplex), re_base(10), im_base(10) {}
|
||||
explicit Complex(complex<mpreal>& value__, int re_base__ = 10, int im_base__ = 10)
|
||||
: Object(kComplex), re_base(re_base__), im_base(im_base__) {
|
||||
value = value__;
|
||||
}
|
||||
explicit Complex(mpreal& re__, mpreal& im__, int re_base__ = 10, int im_base__ = 10)
|
||||
explicit Complex(complex<Bfdec>& value__, int re_base__ = 10, int im_base__ = 10)
|
||||
: Object(kComplex), re_base(re_base__), im_base(im_base__), value(value__) {}
|
||||
explicit Complex(Bfdec& re__, Bfdec& im__, int re_base__ = 10, int im_base__ = 10)
|
||||
: Object(kComplex), re_base(re_base__), im_base(im_base__) {
|
||||
value.real(re__);
|
||||
value.imag(im__);
|
||||
}
|
||||
|
||||
int re_base, im_base;
|
||||
complex<mpreal> value;
|
||||
complex<Bfdec> value;
|
||||
|
||||
virtual Object* Clone() { return new Complex(value, re_base, im_base); }
|
||||
virtual string Name() { return string("complex"); }
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
// Copyright (c) 2014-2022 Louis Rubet
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
#include "program.h"
|
||||
|
||||
//< language reserved keywords (allowed types are kKeyword, kBranch or kUndef)
|
||||
|
@ -24,6 +27,7 @@ vector<Program::keyword_t> Program::keywords_ = {
|
|||
{kKeyword, "-", {.prog = &Program::RpnMinus}, "substraction"},
|
||||
{kKeyword, "*", {.prog = &Program::RpnMul}, "multiplication"},
|
||||
{kKeyword, "/", {.prog = &Program::RpnDiv}, "division"},
|
||||
#if 0
|
||||
{kKeyword, "inv", {.prog = &Program::RpnInv}, "inverse"},
|
||||
{kKeyword, "chs", {.prog = &Program::RpnNeg}, "negation"},
|
||||
{kKeyword, "neg", {.prog = &Program::RpnNeg}, ""},
|
||||
|
@ -136,7 +140,7 @@ vector<Program::keyword_t> Program::keywords_ = {
|
|||
{kBranch, "until", {.branch = &Program::RpnUntil}, "used with do"},
|
||||
{kBranch, "while", {.branch = &Program::RpnWhile}, "while <test-instruction> repeat <loop-instructions> end"},
|
||||
{kBranch, "repeat", {.branch = &Program::RpnRepeat}, "used with while"},
|
||||
|
||||
#endif
|
||||
// STORE
|
||||
{kUndef, "", {.prog = nullptr}, "\nSTORE"},
|
||||
{kKeyword, "sto", {.prog = &Program::RpnSto}, "store a variable. ex: 1 'name' sto"},
|
||||
|
@ -149,6 +153,7 @@ vector<Program::keyword_t> Program::keywords_ = {
|
|||
{kKeyword, "sto-", {.prog = &Program::RpnStosub}, "substract to a stored variable. ex: 1 'name' sto- 'name' 2 sto-"},
|
||||
{kKeyword, "sto*", {.prog = &Program::RpnStomul}, "multiply a stored variable. ex: 3 'name' sto* 'name' 2 sto*"},
|
||||
{kKeyword, "sto/", {.prog = &Program::RpnStodiv}, "divide a stored variable. ex: 3 'name' sto/ 'name' 2 sto/"},
|
||||
#if 0
|
||||
{kKeyword, "sneg", {.prog = &Program::RpnStoneg}, "negate a variable. ex: 'name' sneg"},
|
||||
{kKeyword, "sinv", {.prog = &Program::RpnStoinv}, "inverse a variable. ex: 1 'name' sinv"},
|
||||
|
||||
|
@ -195,6 +200,7 @@ vector<Program::keyword_t> Program::keywords_ = {
|
|||
{kKeyword, "time", {.prog = &Program::RpnTime}, "local time in ISO 8601 format"},
|
||||
{kKeyword, "date", {.prog = &Program::RpnDate}, "local date in ISO 8601 format"},
|
||||
{kKeyword, "ticks", {.prog = &Program::RpnTicks}, "local date and time in µs"}
|
||||
#endif
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
|
|
@ -10,8 +10,7 @@
|
|||
#include <vector>
|
||||
using namespace std;
|
||||
|
||||
#include <mpreal.h>
|
||||
using mpfr::mpreal;
|
||||
#include <libbfdec++.h>
|
||||
|
||||
// internal includes
|
||||
#include "lexer.h"
|
||||
|
|
|
@ -13,9 +13,9 @@ using std::cout, std::string, std::pair;
|
|||
#define ATTR_OFF "\33[0m"
|
||||
|
||||
#define MPFR_ROUND \
|
||||
{"nearest (even)", MPFR_RNDN}, {"toward zero", MPFR_RNDZ}, {"toward +inf", MPFR_RNDU}, {"toward -inf", MPFR_RNDD}, \
|
||||
{"away from zero", MPFR_RNDA}, {"faithful rounding", MPFR_RNDF}, { \
|
||||
"nearest (away from zero)", MPFR_RNDNA \
|
||||
{"nearest (even)", BF_RNDN}, {"toward zero", BF_RNDZ}, {"toward +inf", BF_RNDU}, {"toward -inf", BF_RNDD}, \
|
||||
{"away from zero", BF_RNDA}, {"faithful rounding", BF_RNDF}, { \
|
||||
"nearest (away from zero)", BF_RNDNA \
|
||||
}
|
||||
|
||||
static const char _description[] =
|
||||
|
@ -75,7 +75,7 @@ void Program::RpnHelp() {
|
|||
// bits precision, decimal digits and rounding mode
|
||||
cout << " with " << Number::digits << " digits after the decimal point" << endl;
|
||||
cout << "Current floating point precision is " << static_cast<int>(mpreal::get_default_prec()) << " bits" << endl;
|
||||
vector<pair<string, mpfr_rnd_t>> rnd{MPFR_ROUND};
|
||||
vector<pair<string, mp_rnd_t>> rnd{MPFR_ROUND};
|
||||
for (auto& rn : rnd)
|
||||
if (rn.second == mpreal::get_default_rnd()) {
|
||||
cout << "Current rounding mode is '" << rn.first << '\'' << endl;
|
||||
|
@ -190,14 +190,14 @@ void Program::RpnPrecision() {
|
|||
ARG_MUST_BE_OF_TYPE(0, kNumber);
|
||||
|
||||
// set precision
|
||||
mpfr_prec_t prec = static_cast<int>(stack_.value<Number>(0).toLong());
|
||||
if (prec >= MPFR_PREC_MIN && prec <= MPFR_PREC_MAX) {
|
||||
mp_prec_t prec = static_cast<int>(stack_.value<Number>(0).toLong());
|
||||
if (prec >= BF_PREC_MIN && prec <= BF_PREC_MAX) {
|
||||
mpreal::set_default_prec(prec);
|
||||
|
||||
// modify digits seen by user if std mode
|
||||
if (Number::mode == Number::kStd) {
|
||||
// calc max nb of digits user can see with the current bit precision
|
||||
Number::digits = mpfr::bits2digits(mpreal::get_default_prec());
|
||||
Number::digits = Bfdec::bits2digits(mpreal::get_default_prec());
|
||||
}
|
||||
stack_.pop();
|
||||
} else {
|
||||
|
@ -211,7 +211,7 @@ void Program::RpnRound() {
|
|||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, kString);
|
||||
|
||||
map<string, mpfr_rnd_t> matchRound{MPFR_ROUND};
|
||||
map<string, mp_rnd_t> matchRound{MPFR_ROUND};
|
||||
|
||||
auto found = matchRound.find(stack_.value<String>(0));
|
||||
if (found != matchRound.end())
|
||||
|
|
|
@ -12,16 +12,16 @@ void Program::RpnPlus() {
|
|||
} else if (stack_.type(0) == kNumber && stack_.type(1) == kNumber) {
|
||||
stack_.value<Number>(1) += stack_.value<Number>(0);
|
||||
stack_.pop();
|
||||
} else if (stack_.type(0) == kComplex && stack_.type(1) == kComplex) {
|
||||
stack_.value<Complex>(1) += stack_.value<Complex>(0);
|
||||
stack_.pop();
|
||||
} else if (stack_.type(0) == kNumber && stack_.type(1) == kComplex) {
|
||||
stack_.value<Complex>(1) += stack_.value<Number>(0);
|
||||
stack_.pop();
|
||||
} else if (stack_.type(0) == kComplex && stack_.type(1) == kNumber) {
|
||||
RpnSwap();
|
||||
stack_.value<Complex>(1) += stack_.value<Number>(0);
|
||||
stack_.pop();
|
||||
// } else if (stack_.type(0) == kComplex && stack_.type(1) == kComplex) {
|
||||
// stack_.value<Complex>(1) += stack_.value<Complex>(0);
|
||||
// stack_.pop();
|
||||
//} else if (stack_.type(0) == kNumber && stack_.type(1) == kComplex) {
|
||||
// stack_.value<Complex>(1) += stack_.value<Number>(0);
|
||||
// stack_.pop();
|
||||
//} else if (stack_.type(0) == kComplex && stack_.type(1) == kNumber) {
|
||||
// RpnSwap();
|
||||
// stack_.value<Complex>(1) += stack_.value<Number>(0);
|
||||
// stack_.pop();
|
||||
} else {
|
||||
ERROR_CONTEXT(kBadOperandType);
|
||||
}
|
||||
|
@ -34,16 +34,16 @@ void Program::RpnMinus() {
|
|||
if (stack_.type(0) == kNumber && stack_.type(1) == kNumber) {
|
||||
stack_.value<Number>(1) -= stack_.value<Number>(0);
|
||||
stack_.pop();
|
||||
} else if (stack_.type(0) == kComplex && stack_.type(1) == kComplex) {
|
||||
stack_.value<Complex>(1) -= stack_.value<Complex>(0);
|
||||
stack_.pop();
|
||||
} else if (stack_.type(0) == kNumber && stack_.type(1) == kComplex) {
|
||||
stack_.value<Complex>(1) -= stack_.value<Number>(0);
|
||||
stack_.pop();
|
||||
} else if (stack_.type(0) == kComplex && stack_.type(1) == kNumber) {
|
||||
RpnSwap();
|
||||
stack_.value<Complex>(1) = stack_.value<Number>(0) - stack_.value<Complex>(1);
|
||||
stack_.pop();
|
||||
//} else if (stack_.type(0) == kComplex && stack_.type(1) == kComplex) {
|
||||
// stack_.value<Complex>(1) -= stack_.value<Complex>(0);
|
||||
// stack_.pop();
|
||||
//} else if (stack_.type(0) == kNumber && stack_.type(1) == kComplex) {
|
||||
// stack_.value<Complex>(1) -= stack_.value<Number>(0);
|
||||
// stack_.pop();
|
||||
//} else if (stack_.type(0) == kComplex && stack_.type(1) == kNumber) {
|
||||
// RpnSwap();
|
||||
// stack_.value<Complex>(1) = stack_.value<Number>(0) - stack_.value<Complex>(1);
|
||||
// stack_.pop();
|
||||
} else {
|
||||
ERROR_CONTEXT(kBadOperandType);
|
||||
}
|
||||
|
@ -56,16 +56,16 @@ void Program::RpnMul() {
|
|||
if (stack_.type(0) == kNumber && stack_.type(1) == kNumber) {
|
||||
stack_.value<Number>(1) *= stack_.value<Number>(0);
|
||||
stack_.pop();
|
||||
} else if (stack_.type(0) == kComplex && stack_.type(1) == kComplex) {
|
||||
stack_.value<Complex>(1) *= stack_.value<Complex>(0);
|
||||
stack_.pop();
|
||||
} else if (stack_.type(0) == kNumber && stack_.type(1) == kComplex) {
|
||||
stack_.value<Complex>(1) *= stack_.value<Number>(0);
|
||||
stack_.pop();
|
||||
} else if (stack_.type(0) == kComplex && stack_.type(1) == kNumber) {
|
||||
RpnSwap();
|
||||
stack_.value<Complex>(1) *= stack_.value<Number>(0);
|
||||
stack_.pop();
|
||||
//} else if (stack_.type(0) == kComplex && stack_.type(1) == kComplex) {
|
||||
// stack_.value<Complex>(1) *= stack_.value<Complex>(0);
|
||||
// stack_.pop();
|
||||
//} else if (stack_.type(0) == kNumber && stack_.type(1) == kComplex) {
|
||||
// stack_.value<Complex>(1) *= stack_.value<Number>(0);
|
||||
// stack_.pop();
|
||||
//} else if (stack_.type(0) == kComplex && stack_.type(1) == kNumber) {
|
||||
// RpnSwap();
|
||||
// stack_.value<Complex>(1) *= stack_.value<Number>(0);
|
||||
// stack_.pop();
|
||||
} else {
|
||||
ERROR_CONTEXT(kBadOperandType);
|
||||
}
|
||||
|
@ -78,21 +78,22 @@ void Program::RpnDiv() {
|
|||
if (stack_.type(0) == kNumber && stack_.type(1) == kNumber) {
|
||||
stack_.value<Number>(1) /= stack_.value<Number>(0);
|
||||
stack_.pop();
|
||||
} else if (stack_.type(0) == kComplex && stack_.type(1) == kComplex) {
|
||||
stack_.value<Complex>(1) /= stack_.value<Complex>(0);
|
||||
stack_.pop();
|
||||
} else if (stack_.type(0) == kNumber && stack_.type(1) == kComplex) {
|
||||
stack_.value<Complex>(1) /= stack_.value<Number>(0);
|
||||
stack_.pop();
|
||||
} else if (stack_.type(0) == kComplex && stack_.type(1) == kNumber) {
|
||||
RpnSwap();
|
||||
stack_.value<Complex>(1) = stack_.value<Number>(0) / stack_.value<Complex>(1);
|
||||
stack_.pop();
|
||||
//} else if (stack_.type(0) == kComplex && stack_.type(1) == kComplex) {
|
||||
// stack_.value<Complex>(1) /= stack_.value<Complex>(0);
|
||||
// stack_.pop();
|
||||
//} else if (stack_.type(0) == kNumber && stack_.type(1) == kComplex) {
|
||||
// stack_.value<Complex>(1) /= stack_.value<Number>(0);
|
||||
// stack_.pop();
|
||||
//} else if (stack_.type(0) == kComplex && stack_.type(1) == kNumber) {
|
||||
// RpnSwap();
|
||||
// stack_.value<Complex>(1) = stack_.value<Number>(0) / stack_.value<Complex>(1);
|
||||
// stack_.pop();
|
||||
} else {
|
||||
ERROR_CONTEXT(kBadOperandType);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/// @brief neg keyword implementation
|
||||
///
|
||||
void Program::RpnNeg() {
|
||||
|
@ -122,7 +123,7 @@ void Program::RpnInv() {
|
|||
void Program::RpnPower() {
|
||||
MIN_ARGUMENTS(2);
|
||||
if (stack_.type(0) == kNumber && stack_.type(1) == kNumber) {
|
||||
if (stack_.value<Number>(1) >= 0) {
|
||||
if (stack_.value<Number>(1).gt0()) {
|
||||
stack_.value<Number>(1) = pow(stack_.value<Number>(1), stack_.value<Number>(0));
|
||||
stack_.pop();
|
||||
} else {
|
||||
|
@ -387,3 +388,4 @@ void Program::RpnMax() {
|
|||
stack_.value<Number>(0) = max(stack_.value<Number>(0), stack_.value<Number>(1));
|
||||
stack_.erase(1);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
// Copyright (c) 2014-2022 Louis Rubet
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
#include "input.h"
|
||||
#include "program.h"
|
||||
|
||||
|
@ -87,6 +90,7 @@ void Program::RpnStodiv(void) {
|
|||
RpnSto();
|
||||
}
|
||||
|
||||
#if 0
|
||||
/// @brief stosneg keyword implementation
|
||||
///
|
||||
void Program::RpnStoneg(void) {
|
||||
|
@ -118,6 +122,7 @@ void Program::RpnStoinv(void) {
|
|||
RpnSwap();
|
||||
RpnSto();
|
||||
}
|
||||
#endif
|
||||
|
||||
/// @brief rcl keyword implementation
|
||||
///
|
||||
|
|
|
@ -51,9 +51,9 @@ void Program::RpnNum() {
|
|||
MIN_ARGUMENTS(1);
|
||||
ARG_MUST_BE_OF_TYPE(0, kString);
|
||||
if (stack_.value<String>(0).size() > 0)
|
||||
stack_.push_front(new Number(stack_.value<String>(0)[0]));
|
||||
stack_.push_front(new Number((int64_t)stack_.value<String>(0)[0]));
|
||||
else
|
||||
stack_.push_front(new Number(0));
|
||||
stack_.push_front(new Number((int64_t)0));
|
||||
stack_.erase(1);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
// Copyright (c) 2014-2022 Louis Rubet
|
||||
|
||||
#include <string>
|
||||
using std::string;
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
#include "program.h"
|
||||
#include "version.h"
|
||||
|
|
Loading…
Add table
Reference in a new issue