First step: lexer, entries and number outputs with new libbf decimal

This commit is contained in:
Louis Rubet 2024-01-21 18:14:46 +01:00
parent 0c8bc70ab9
commit 2ff0a3db88
17 changed files with 122 additions and 115 deletions

9
.gitmodules vendored
View file

@ -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

View file

@ -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 +0,0 @@
Subproject commit 19bd01375827e13bd7ded3c82b9a5f50cc3bf2f4

1
libbfdec-cpp Submodule

@ -0,0 +1 @@
Subproject commit 1a1ce5a93ca57abb548066f67581e9137549aeb1

1
mpreal

@ -1 +0,0 @@
Subproject commit 269a03782fa0b87c20470976b88677266c5423ad

View file

@ -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 {

View file

@ -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>

View file

@ -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;

View file

@ -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
}

View file

@ -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"); }

View file

@ -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

View file

@ -10,8 +10,7 @@
#include <vector>
using namespace std;
#include <mpreal.h>
using mpfr::mpreal;
#include <libbfdec++.h>
// internal includes
#include "lexer.h"

View file

@ -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())

View file

@ -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

View file

@ -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
///

View file

@ -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);
}

View file

@ -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"