Moved radix and precision commands to Stack class
dc / build (push) Failing after 46s
Details
dc / build (push) Failing after 46s
Details
This commit is contained in:
parent
505ed8b148
commit
b9235470e3
|
@ -1,7 +1,7 @@
|
|||
name: dc
|
||||
on:
|
||||
push:
|
||||
branches: [master, unit_testing]
|
||||
branches: [master, factory_parsing]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
|
|
101
src/eval.cpp
101
src/eval.cpp
|
@ -248,32 +248,38 @@ std::optional<std::string> Evaluate::eval() {
|
|||
return err;
|
||||
}
|
||||
} else if(val == "k") { // SET PRECISION
|
||||
err = fn_set_precision();
|
||||
auto op = std::make_unique<Stack>(OPType::SP);
|
||||
err = op->exec(this->stack, this->parameters, this->regs);
|
||||
if(err != std::nullopt) {
|
||||
return err;
|
||||
}
|
||||
} else if(val == "K") { // GET PRECISION
|
||||
err = fn_get_precision();
|
||||
auto op = std::make_unique<Stack>(OPType::GP);
|
||||
err = op->exec(this->stack, this->parameters, this->regs);
|
||||
if(err != std::nullopt) {
|
||||
return err;
|
||||
}
|
||||
} else if(val == "o") { // SET OUTPUT BASE
|
||||
err = fn_set_oradix();
|
||||
auto op = std::make_unique<Stack>(OPType::SOR);
|
||||
err = op->exec(this->stack, this->parameters, this->regs);
|
||||
if(err != std::nullopt) {
|
||||
return err;
|
||||
}
|
||||
} else if(val == "O") { // GET OUTPUT BASE
|
||||
err = fn_get_oradix();
|
||||
auto op = std::make_unique<Stack>(OPType::GOR);
|
||||
err = op->exec(this->stack, this->parameters, this->regs);
|
||||
if(err != std::nullopt) {
|
||||
return err;
|
||||
}
|
||||
} else if(val == "i") { // SET INPUT BASE
|
||||
err = fn_set_iradix();
|
||||
auto op = std::make_unique<Stack>(OPType::SIR);
|
||||
err = op->exec(this->stack, this->parameters, this->regs);
|
||||
if(err != std::nullopt) {
|
||||
return err;
|
||||
}
|
||||
} else if(val == "I") { // GET INPUT BASE
|
||||
err = fn_get_iradix();
|
||||
auto op = std::make_unique<Stack>(OPType::GIR);
|
||||
err = op->exec(this->stack, this->parameters, this->regs);
|
||||
if(err != std::nullopt) {
|
||||
return err;
|
||||
}
|
||||
|
@ -632,86 +638,3 @@ std::optional<std::string> Evaluate::parse_array_command(std::string val) {
|
|||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Evaluate::fn_set_precision() {
|
||||
// Check if stack has enough elements
|
||||
if(this->stack.empty()) {
|
||||
return "'k' requires one operand";
|
||||
}
|
||||
|
||||
// Check whether head is a non negative number
|
||||
auto head = this->stack.back();
|
||||
if(!is_num<int>(head) || std::stoi(head) < 0) {
|
||||
return "Precision must be a non-negative number";
|
||||
}
|
||||
|
||||
// Otherwise extract head of the stack and use it
|
||||
// to set precision parameter
|
||||
this->stack.pop_back();
|
||||
this->parameters.precision = std::stoi(head);
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Evaluate::fn_get_precision() {
|
||||
this->stack.push_back(std::to_string(this->parameters.precision));
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Evaluate::fn_set_oradix() {
|
||||
// Check if stack has enough elements
|
||||
if(this->stack.empty()) {
|
||||
return "'o' requires one operand";
|
||||
}
|
||||
|
||||
// Check whether the head is a number
|
||||
auto head = this->stack.back();
|
||||
if(!is_num<int>(head)) {
|
||||
return "'o' requires numeric values only";
|
||||
}
|
||||
|
||||
// Otherwise convert it to int
|
||||
auto oradix = std::stoi(head);
|
||||
switch(oradix) {
|
||||
case 2: this->parameters.oradix = radix_base::BIN; break;
|
||||
case 8: this->parameters.oradix = radix_base::OCT; break;
|
||||
case 10: this->parameters.oradix = radix_base::DEC; break;
|
||||
case 16: this->parameters.oradix = radix_base::HEX; break;
|
||||
default: return "'o' accepts either BIN, OCT, DEC or HEX bases";
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Evaluate::fn_get_oradix() {
|
||||
this->stack.push_back(std::to_string(static_cast<int>(this->parameters.oradix)));
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Evaluate::fn_set_iradix() {
|
||||
// Check if stack has enough elements
|
||||
if(this->stack.empty()) {
|
||||
return "'i' requires one operand";
|
||||
}
|
||||
|
||||
// Check whether head is a number within the range 2-16
|
||||
auto head = this->stack.back();
|
||||
if(!is_num<double>(head) || std::stoi(head) < 2 || std::stoi(head) > 16) {
|
||||
return "Input base must be a number within the range 2-16(inclusive)";
|
||||
}
|
||||
|
||||
// Otherwise extract head of the stack and use it
|
||||
// to set input base
|
||||
this->stack.pop_back();
|
||||
this->parameters.iradix = std::stoi(head);
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Evaluate::fn_get_iradix() {
|
||||
this->stack.push_back(std::to_string(this->parameters.iradix));
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
|
|
@ -25,12 +25,7 @@ private:
|
|||
std::optional<std::string> parse_register_command(std::string val);
|
||||
std::optional<std::string> parse_array_command(std::string val);
|
||||
std::optional<std::string> parse_base_n(const std::string& val);
|
||||
std::optional<std::string> fn_set_precision();
|
||||
std::optional<std::string> fn_get_precision();
|
||||
std::optional<std::string> fn_set_oradix();
|
||||
std::optional<std::string> fn_get_oradix();
|
||||
std::optional<std::string> fn_set_iradix();
|
||||
std::optional<std::string> fn_get_iradix();
|
||||
|
||||
void init_op_factory();
|
||||
|
||||
using op_factory_t = std::function<std::unique_ptr<IOperation>()>;
|
||||
|
|
|
@ -14,7 +14,8 @@ enum class OPType {
|
|||
ADD, SUB, MUL, DIV, MOD, DIV_MOD, MOD_EXP, EXP,
|
||||
SQRT, SIN, COS, TAN, ASIN, ACOS, ATAN, FACT, PI, E,
|
||||
// Stack operations
|
||||
PCG, P, PBB, PBH, PBO, CLR, PH, SO, DP, PS, CH, CS,
|
||||
PCG, P, PBB, PBH, PBO, CLR, PH, SO, DP, PS, CH, CS,
|
||||
SP, GP, SOR, GOR, SIR, GIR,
|
||||
// Macro operations
|
||||
EX, CMP, RI
|
||||
};
|
||||
|
|
101
src/stack.cpp
101
src/stack.cpp
|
@ -24,12 +24,18 @@ std::optional<std::string> Stack::exec(dc_stack_t &stack, Parameters ¶meters
|
|||
case OPType::PBO: err = print_oradix(radix_base::OCT); break;
|
||||
case OPType::PBH: err = print_oradix(radix_base::HEX); break;
|
||||
case OPType::CLR: stack.clear(); break;
|
||||
case OPType::PH: fn_pop_head(stack); break;
|
||||
case OPType::SO: fn_swap_xy(stack); break;
|
||||
case OPType::DP: fn_dup_head(stack); break;
|
||||
case OPType::PS: fn_print_stack(stack, parameters); break;
|
||||
case OPType::CH: fn_head_size(stack); break;
|
||||
case OPType::CS: fn_stack_size(stack); break;
|
||||
case OPType::PH: err = fn_pop_head(stack); break;
|
||||
case OPType::SO: err = fn_swap_xy(stack); break;
|
||||
case OPType::DP: err = fn_dup_head(stack); break;
|
||||
case OPType::PS: err = fn_print_stack(stack, parameters); break;
|
||||
case OPType::CH: err = fn_head_size(stack); break;
|
||||
case OPType::CS: err = fn_stack_size(stack); break;
|
||||
case OPType::SP: err = fn_set_precision(stack, parameters); break;
|
||||
case OPType::GP: err = fn_get_precision(stack, parameters); break;
|
||||
case OPType::SOR: err = fn_set_oradix(stack, parameters); break;
|
||||
case OPType::GOR: err = fn_get_oradix(stack, parameters); break;
|
||||
case OPType::SIR: err = fn_set_iradix(stack, parameters); break;
|
||||
case OPType::GIR: err = fn_get_iradix(stack, parameters); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
|
@ -186,6 +192,89 @@ std::optional<std::string> Stack::fn_stack_size(dc_stack_t &stack) {
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Stack::fn_set_precision(dc_stack_t &stack, Parameters ¶meters) {
|
||||
// Check if stack has enough elements
|
||||
if(stack.empty()) {
|
||||
return "'k' requires one operand";
|
||||
}
|
||||
|
||||
// Check whether head is a non-negative number
|
||||
auto head = stack.back();
|
||||
if(!is_num<int>(head) || std::stoi(head) < 0) {
|
||||
return "Precision must be a non-negative number";
|
||||
}
|
||||
|
||||
// Otherwise extract head of the stack and use it
|
||||
// to set precision parameter
|
||||
stack.pop_back();
|
||||
parameters.precision = std::stoi(head);
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Stack::fn_get_precision(dc_stack_t &stack, Parameters ¶meters) {
|
||||
stack.push_back(std::to_string(parameters.precision));
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Stack::fn_set_oradix(dc_stack_t &stack, Parameters ¶meters) {
|
||||
// Check if stack has enough elements
|
||||
if(stack.empty()) {
|
||||
return "'o' requires one operand";
|
||||
}
|
||||
|
||||
// Check whether the head is a number
|
||||
auto head = stack.back();
|
||||
if(!is_num<int>(head)) {
|
||||
return "'o' requires numeric values only";
|
||||
}
|
||||
|
||||
// Otherwise convert it to int
|
||||
auto oradix = std::stoi(head);
|
||||
switch(oradix) {
|
||||
case 2: parameters.oradix = radix_base::BIN; break;
|
||||
case 8: parameters.oradix = radix_base::OCT; break;
|
||||
case 10: parameters.oradix = radix_base::DEC; break;
|
||||
case 16: parameters.oradix = radix_base::HEX; break;
|
||||
default: return "'o' accepts either BIN, OCT, DEC or HEX bases";
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Stack::fn_get_oradix(dc_stack_t &stack, Parameters ¶meters) {
|
||||
stack.push_back(std::to_string(static_cast<int>(parameters.oradix)));
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Stack::fn_set_iradix(dc_stack_t &stack, Parameters ¶meters) {
|
||||
// Check if stack has enough elements
|
||||
if(stack.empty()) {
|
||||
return "'i' requires one operand";
|
||||
}
|
||||
|
||||
// Check whether head is a number within the range 2-16
|
||||
auto head = stack.back();
|
||||
if(!is_num<double>(head) || std::stoi(head) < 2 || std::stoi(head) > 16) {
|
||||
return "Input base must be a number within the range 2-16(inclusive)";
|
||||
}
|
||||
|
||||
// Otherwise extract head of the stack and use it
|
||||
// to set input base
|
||||
stack.pop_back();
|
||||
parameters.iradix = std::stoi(head);
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Stack::fn_get_iradix(dc_stack_t &stack, Parameters ¶meters) {
|
||||
stack.push_back(std::to_string(parameters.iradix));
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
constexpr std::string Stack::to_bin(auto num) {
|
||||
if(num == 0) {
|
||||
return "0";
|
||||
|
|
|
@ -15,6 +15,12 @@ private:
|
|||
std::optional<std::string> fn_print_stack(dc_stack_t &stack, Parameters ¶meters);
|
||||
static std::optional<std::string> fn_head_size(dc_stack_t &stack);
|
||||
static std::optional<std::string> fn_stack_size(dc_stack_t &stack);
|
||||
static std::optional<std::string> fn_set_precision(dc_stack_t &stack, Parameters ¶meters);
|
||||
static std::optional<std::string> fn_get_precision(dc_stack_t &stack, Parameters ¶meters);
|
||||
static std::optional<std::string> fn_set_oradix(dc_stack_t &stack, Parameters ¶meters);
|
||||
static std::optional<std::string> fn_get_oradix(dc_stack_t &stack, Parameters ¶meters);
|
||||
static std::optional<std::string> fn_set_iradix(dc_stack_t &stack, Parameters ¶meters);
|
||||
static std::optional<std::string> fn_get_iradix(dc_stack_t &stack, Parameters ¶meters);
|
||||
constexpr std::string to_bin(auto num);
|
||||
|
||||
OPType op_type;
|
||||
|
|
Loading…
Reference in New Issue