Added [] overload and namespace to dc's data structures
dc / build (push) Failing after 8s
Details
dc / build (push) Failing after 8s
Details
This commit is contained in:
parent
674d6deef6
commit
3c257a1fd1
|
@ -13,9 +13,8 @@ jobs:
|
|||
- name: Build dc
|
||||
run: |
|
||||
apt -y update && apt -y install cmake build-essential
|
||||
mkdir build && cd build
|
||||
cmake ..
|
||||
make
|
||||
cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug .
|
||||
cmake --build build
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
./utest.sh tests
|
||||
|
|
|
@ -12,9 +12,9 @@ jobs:
|
|||
uses: actions/checkout@main
|
||||
- name: Build dc
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
cmake ..
|
||||
make
|
||||
apt -y update && apt -y install cmake build-essential
|
||||
cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug .
|
||||
cmake --build build
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
./utest.sh tests
|
||||
|
|
10
README.md
10
README.md
|
@ -51,13 +51,13 @@ Some of the supported features are:
|
|||
And much more. You can find the complete manual [here](https://github.com/ice-bit/dc/blob/master/man.md).
|
||||
|
||||
## Installation
|
||||
`dc` is written in C++20 without using any additional dependency. In order to build it, install a recent version of CMake and issue
|
||||
the following command:
|
||||
`dc` is written in C++20 without using any additional dependency. In order to build it, install [CMake](https://cmake.org/), [Ninja](https://ninja-build.org/)
|
||||
and issue the following commands:
|
||||
```sh
|
||||
$> mkdir build && cd build
|
||||
$> cmake -DCMAKE_BUILD_TYPE=Release .. && make
|
||||
$> cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release .
|
||||
$> cmake --build build
|
||||
```
|
||||
A new statically-compiled binary called `dc` will be created in your local folder. To generate a man page from the `man.md` document,
|
||||
A new statically-compiled binary called `dc` will be created in the `build/` directory. To generate a man page from the `man.md` document,
|
||||
use the following command(note: needs pandoc):
|
||||
```sh
|
||||
$> pandoc man.md -s -t man > dc.1
|
||||
|
|
4
main.cpp
4
main.cpp
|
@ -9,6 +9,8 @@
|
|||
#include "src/eval.h"
|
||||
#include "src/macro.h" // for split static method
|
||||
|
||||
using namespace dc;
|
||||
|
||||
#define DC_VERSION "1.0.3"
|
||||
|
||||
void helper() {
|
||||
|
@ -27,7 +29,7 @@ int main(int argc, char **argv) {
|
|||
std::string stdin_expression;
|
||||
bool execute_expression = false;
|
||||
bool execute_file = false;
|
||||
DCStack<std::string> stack;
|
||||
Stack<std::string> stack;
|
||||
std::unordered_map<char, Register> regs;
|
||||
Parameters parameters = {
|
||||
.precision = 0,
|
||||
|
|
245
src/adt.cpp
245
src/adt.cpp
|
@ -4,128 +4,139 @@
|
|||
#define GET_Y this->stack.at(this->stack.size() - 2)
|
||||
#define GET_Z this->stack.at(this->stack.size() - 3)
|
||||
|
||||
/**
|
||||
* Add @value to the stack
|
||||
*/
|
||||
template<typename T>
|
||||
requires is_num_or_str<T>
|
||||
void DCStack<T>::push(T value) {
|
||||
this->stack.push_back(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the stack
|
||||
*/
|
||||
template<typename T>
|
||||
requires is_num_or_str<T>
|
||||
void DCStack<T>::clear() {
|
||||
if(!this->stack.empty()) {
|
||||
this->stack.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If @remove is true, pop head of the stack
|
||||
* otherwise return it without popping.
|
||||
* If stack is empty it causes undefined behavior
|
||||
*/
|
||||
template<typename T>
|
||||
requires is_num_or_str<T>
|
||||
T DCStack<T>::pop(bool remove) {
|
||||
T value = this->stack.back();
|
||||
|
||||
if(remove) {
|
||||
this->stack.pop_back();
|
||||
namespace dc {
|
||||
/**
|
||||
* Add @value to the stack
|
||||
*/
|
||||
template<typename T>
|
||||
requires is_num_or_str<T>
|
||||
void Stack<T>::push(T value) {
|
||||
this->stack.push_back(value);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a copy of head, 2nd and 3rd element
|
||||
* of the stack
|
||||
*/
|
||||
template<typename T>
|
||||
requires is_num_or_str<T>
|
||||
void DCStack<T>::copy_xyz() {
|
||||
if(this->stack.size() >= 1) {
|
||||
this->last_x = GET_X;
|
||||
/**
|
||||
* Clear the stack
|
||||
*/
|
||||
template<typename T>
|
||||
requires is_num_or_str<T>
|
||||
void Stack<T>::clear() {
|
||||
if(!this->stack.empty()) {
|
||||
this->stack.clear();
|
||||
}
|
||||
}
|
||||
|
||||
if(this->stack.size() >= 2) {
|
||||
this->last_y = GET_Y;
|
||||
/**
|
||||
* If @remove is true, pop head of the stack
|
||||
* otherwise return it without popping.
|
||||
* If stack is empty it causes undefined behavior
|
||||
*/
|
||||
template<typename T>
|
||||
requires is_num_or_str<T>
|
||||
T Stack<T>::pop(bool remove) {
|
||||
T value = this->stack.back();
|
||||
|
||||
if(remove) {
|
||||
this->stack.pop_back();
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
if(this->stack.size() >= 3) {
|
||||
this->last_z = GET_Z;
|
||||
/**
|
||||
* Make a copy of head, 2nd and 3rd element
|
||||
* of the stack
|
||||
*/
|
||||
template<typename T>
|
||||
requires is_num_or_str<T>
|
||||
void Stack<T>::copy_xyz() {
|
||||
if(this->stack.size() >= 1) {
|
||||
this->last_x = GET_X;
|
||||
}
|
||||
|
||||
if(this->stack.size() >= 2) {
|
||||
this->last_y = GET_Y;
|
||||
}
|
||||
|
||||
if(this->stack.size() >= 3) {
|
||||
this->last_z = GET_Z;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns last x of the stack
|
||||
* If stack is empty returns '0' or empty string
|
||||
*/
|
||||
template<typename T>
|
||||
requires is_num_or_str<T>
|
||||
T Stack<T>::get_last_x() {
|
||||
return this->last_x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns last y of the stack
|
||||
* If stack is empty returns '0' or empty string
|
||||
*/
|
||||
template<typename T>
|
||||
requires is_num_or_str<T>
|
||||
T Stack<T>::get_last_y() {
|
||||
return this->last_y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns last z of the stack
|
||||
* If stack is empty returns '0' or empty string
|
||||
*/
|
||||
template<typename T>
|
||||
requires is_num_or_str<T>
|
||||
T Stack<T>::get_last_z() {
|
||||
return this->last_z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads stack at @index
|
||||
*/
|
||||
template<typename T>
|
||||
requires is_num_or_str<T>
|
||||
T& Stack<T>::at(std::size_t index) {
|
||||
T &value = this->stack.at(index);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads stack at @index using '[]' syntax
|
||||
*/
|
||||
template<typename T>
|
||||
requires is_num_or_str<T>
|
||||
T& Stack<T>::operator[](std::size_t index) {
|
||||
return at(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns stack size
|
||||
*/
|
||||
template<typename T>
|
||||
requires is_num_or_str<T>
|
||||
std::size_t Stack<T>::size() {
|
||||
return this->stack.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if stack is empty
|
||||
* false otherwise
|
||||
*/
|
||||
template<typename T>
|
||||
requires is_num_or_str<T>
|
||||
bool Stack<T>::empty() {
|
||||
return this->stack.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a const reference to the stack
|
||||
*/
|
||||
template<typename T>
|
||||
requires is_num_or_str<T>
|
||||
const std::vector<T>& Stack<T>::get_ref() const {
|
||||
return this->stack;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns last x of the stack
|
||||
* If stack is empty returns '0' or empty string
|
||||
*/
|
||||
template<typename T>
|
||||
requires is_num_or_str<T>
|
||||
T DCStack<T>::get_last_x() {
|
||||
return this->last_x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns last y of the stack
|
||||
* If stack is empty returns '0' or empty string
|
||||
*/
|
||||
template<typename T>
|
||||
requires is_num_or_str<T>
|
||||
T DCStack<T>::get_last_y() {
|
||||
return this->last_y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns last z of the stack
|
||||
* If stack is empty returns '0' or empty string
|
||||
*/
|
||||
template<typename T>
|
||||
requires is_num_or_str<T>
|
||||
T DCStack<T>::get_last_z() {
|
||||
return this->last_z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads stack at @index
|
||||
*/
|
||||
template<typename T>
|
||||
requires is_num_or_str<T>
|
||||
T& DCStack<T>::at(size_t index) {
|
||||
T &value = this->stack.at(index);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns stack size
|
||||
*/
|
||||
template<typename T>
|
||||
requires is_num_or_str<T>
|
||||
size_t DCStack<T>::size() {
|
||||
return this->stack.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if stack is empty
|
||||
* false otherwise
|
||||
*/
|
||||
template<typename T>
|
||||
requires is_num_or_str<T>
|
||||
bool DCStack<T>::empty() {
|
||||
return this->stack.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a const reference to the stack
|
||||
*/
|
||||
template<typename T>
|
||||
requires is_num_or_str<T>
|
||||
const std::vector<T>& DCStack<T>::get_ref() const {
|
||||
return this->stack;
|
||||
}
|
||||
|
|
69
src/adt.h
69
src/adt.h
|
@ -4,40 +4,43 @@
|
|||
#include <cstdint>
|
||||
#include <unordered_map>
|
||||
|
||||
template<typename T>
|
||||
concept is_num_or_str = (std::is_arithmetic_v<T> || std::is_same_v<T, std::string>);
|
||||
namespace dc {
|
||||
template<typename T>
|
||||
concept is_num_or_str = (std::is_arithmetic_v<T> || std::is_same_v<T, std::string>);
|
||||
|
||||
template<typename T>
|
||||
requires is_num_or_str<T>
|
||||
class DCStack {
|
||||
public:
|
||||
void push(T value);
|
||||
void clear();
|
||||
void copy_xyz();
|
||||
T pop(bool remove);
|
||||
T get_last_x();
|
||||
T get_last_y();
|
||||
T get_last_z();
|
||||
T& at(size_t index);
|
||||
size_t size();
|
||||
bool empty();
|
||||
[[nodiscard]] const std::vector<T>& get_ref() const;
|
||||
template<typename T>
|
||||
requires is_num_or_str<T>
|
||||
class Stack {
|
||||
public:
|
||||
void push(T value);
|
||||
void clear();
|
||||
void copy_xyz();
|
||||
T pop(bool remove);
|
||||
T get_last_x();
|
||||
T get_last_y();
|
||||
T get_last_z();
|
||||
T& at(std::size_t index);
|
||||
T& operator[](std::size_t index);
|
||||
std::size_t size();
|
||||
bool empty();
|
||||
[[nodiscard]] const std::vector<T>& get_ref() const;
|
||||
|
||||
private:
|
||||
std::vector<T> stack;
|
||||
T last_x{};
|
||||
T last_y{};
|
||||
T last_z{};
|
||||
};
|
||||
private:
|
||||
std::vector<T> stack;
|
||||
T last_x{};
|
||||
T last_y{};
|
||||
T last_z{};
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
DCStack<std::string> stack;
|
||||
std::unordered_map<int, std::string> array;
|
||||
} Register;
|
||||
typedef struct {
|
||||
Stack<std::string> stack;
|
||||
std::unordered_map<int, std::string> array;
|
||||
} Register;
|
||||
|
||||
enum class radix_base : std::uint8_t { BIN = 2, OCT = 8, DEC = 10, HEX = 16 };
|
||||
typedef struct {
|
||||
unsigned int precision;
|
||||
unsigned short iradix;
|
||||
radix_base oradix;
|
||||
} Parameters;
|
||||
enum class radix_base : std::uint8_t { BIN = 2, OCT = 8, DEC = 10, HEX = 16 };
|
||||
typedef struct {
|
||||
unsigned int precision;
|
||||
unsigned short iradix;
|
||||
radix_base oradix;
|
||||
} Parameters;
|
||||
}
|
||||
|
|
16
src/eval.cpp
16
src/eval.cpp
|
@ -71,7 +71,7 @@ std::optional<std::string> Evaluate::eval() {
|
|||
// Set up environment
|
||||
init_environment();
|
||||
|
||||
for(size_t idx = 0; idx < this->expr.size(); idx++) {
|
||||
for(std::size_t idx = 0; idx < this->expr.size(); idx++) {
|
||||
std::optional<std::string> err = std::nullopt;
|
||||
auto token = this->expr.at(idx);
|
||||
|
||||
|
@ -123,7 +123,7 @@ std::optional<std::string> Evaluate::parse_base_n(const std::string& token) {
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Evaluate::parse_macro(size_t &idx) {
|
||||
std::optional<std::string> Evaluate::parse_macro(std::size_t &idx) {
|
||||
// A macro is any string surrounded by square brackets
|
||||
std::string dc_macro;
|
||||
bool closing_bracket = false;
|
||||
|
@ -250,8 +250,8 @@ std::optional<std::string> Evaluate::parse_register_command(std::string token) {
|
|||
// i.e., initialize a new instance of register 'reg_name'
|
||||
this->regs.erase(reg_name);
|
||||
this->regs.insert(
|
||||
std::make_pair(reg_name, Register{
|
||||
DCStack<std::string>(),
|
||||
std::make_pair(reg_name, dc::Register{
|
||||
dc::Stack<std::string>(),
|
||||
std::unordered_map<int, std::string>()
|
||||
})
|
||||
);
|
||||
|
@ -279,8 +279,8 @@ std::optional<std::string> Evaluate::parse_register_command(std::string token) {
|
|||
if(it != this->regs.end()) { // Register exists
|
||||
it->second.stack.push(head);
|
||||
} else { // Register doesn't exist
|
||||
this->regs[reg_name] = Register{
|
||||
DCStack<std::string>(),
|
||||
this->regs[reg_name] = dc::Register{
|
||||
dc::Stack<std::string>(),
|
||||
std::unordered_map<int, std::string>()
|
||||
};
|
||||
}
|
||||
|
@ -359,8 +359,8 @@ std::optional<std::string> Evaluate::parse_array_command(std::string token) {
|
|||
it->second.array.erase(idx);
|
||||
it->second.array.insert(std::pair<int, std::string>(idx, arr_val));
|
||||
} else { // Register doesn't exist
|
||||
this->regs[reg_name] = Register{
|
||||
DCStack<std::string>(),
|
||||
this->regs[reg_name] = dc::Register{
|
||||
dc::Stack<std::string>(),
|
||||
std::unordered_map<int, std::string>{{idx, arr_val}}
|
||||
};
|
||||
}
|
||||
|
|
14
src/eval.h
14
src/eval.h
|
@ -11,15 +11,15 @@
|
|||
|
||||
class Evaluate {
|
||||
public:
|
||||
Evaluate(const std::vector<std::string>& e, std::unordered_map<char, Register> &r,
|
||||
DCStack<std::string> &s, Parameters &p)
|
||||
Evaluate(const std::vector<std::string>& e, std::unordered_map<char, dc::Register> &r,
|
||||
dc::Stack<std::string> &s, dc::Parameters &p)
|
||||
: expr(e), regs(r), stack(s), parameters(p) {}
|
||||
Evaluate(std::unordered_map<char, Register> &r, DCStack<std::string> &s, Parameters &p)
|
||||
Evaluate(std::unordered_map<char, dc::Register> &r, dc::Stack<std::string> &s, dc::Parameters &p)
|
||||
: regs(r), stack(s), parameters(p) {}
|
||||
std::optional<std::string> eval();
|
||||
|
||||
private:
|
||||
std::optional<std::string> parse_macro(size_t &idx);
|
||||
std::optional<std::string> parse_macro(std::size_t &idx);
|
||||
std::optional<std::string> parse_macro_command(std::string token);
|
||||
std::optional<std::string> parse_register_command(std::string token);
|
||||
std::optional<std::string> parse_array_command(std::string token);
|
||||
|
@ -28,8 +28,8 @@ private:
|
|||
|
||||
using op_factory_t = std::function<std::unique_ptr<IOperation>()>;
|
||||
std::vector<std::string> expr;
|
||||
std::unordered_map<char, Register> ®s;
|
||||
std::unordered_map<char, dc::Register> ®s;
|
||||
std::unordered_map<std::string, op_factory_t> op_factory;
|
||||
DCStack<std::string> &stack;
|
||||
Parameters ¶meters;
|
||||
dc::Stack<std::string> &stack;
|
||||
dc::Parameters ¶meters;
|
||||
};
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include "macro.h"
|
||||
#include "is_num.h"
|
||||
|
||||
std::optional<std::string> Macro::exec(DCStack<std::string> &stack, Parameters ¶meters, std::unordered_map<char, Register> ®s) {
|
||||
std::optional<std::string> Macro::exec(dc::Stack<std::string> &stack, dc::Parameters ¶meters, std::unordered_map<char, dc::Register> ®s) {
|
||||
std::optional<std::string> err = std::nullopt;
|
||||
|
||||
switch(this->op_type) {
|
||||
|
@ -21,7 +21,7 @@ std::optional<std::string> Macro::exec(DCStack<std::string> &stack, Parameters &
|
|||
return err;
|
||||
}
|
||||
|
||||
std::optional<std::string> Macro::fn_execute(DCStack<std::string> &stack, Parameters ¶meters, std::unordered_map<char, Register> ®s) {
|
||||
std::optional<std::string> Macro::fn_execute(dc::Stack<std::string> &stack, dc::Parameters ¶meters, std::unordered_map<char, dc::Register> ®s) {
|
||||
// Check if stack has enough elements
|
||||
if(stack.empty()) {
|
||||
return "This operation does not work on empty stack";
|
||||
|
@ -45,7 +45,7 @@ std::optional<std::string> Macro::fn_execute(DCStack<std::string> &stack, Parame
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Macro::fn_evaluate_macro(DCStack<std::string> &stack, Parameters ¶meters, std::unordered_map<char, Register> ®s) {
|
||||
std::optional<std::string> Macro::fn_evaluate_macro(dc::Stack<std::string> &stack, dc::Parameters ¶meters, std::unordered_map<char, dc::Register> ®s) {
|
||||
// Check whether the main stack has enough elements
|
||||
if(stack.size() < 2) {
|
||||
return "This operation requires two elements";
|
||||
|
@ -146,7 +146,7 @@ std::optional<std::string> Macro::fn_evaluate_macro(DCStack<std::string> &stack,
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Macro::fn_read_input(DCStack<std::string> &stack, Parameters ¶meters, std::unordered_map<char, Register> ®s) {
|
||||
std::optional<std::string> Macro::fn_read_input(dc::Stack<std::string> &stack, dc::Parameters ¶meters, std::unordered_map<char, dc::Register> ®s) {
|
||||
// Read user input from stdin
|
||||
std::string user_input;
|
||||
|
||||
|
|
|
@ -10,13 +10,13 @@ class Macro : public IOperation {
|
|||
public:
|
||||
Macro(const OPType op_t, const Operator o, const char dc_r) : op_type(op_t), op(o), dc_register(dc_r) {}
|
||||
explicit Macro(const OPType op_t) : op_type(op_t) {}
|
||||
std::optional<std::string> exec(DCStack<std::string> &stack, Parameters ¶meters, std::unordered_map<char, Register> ®s) override;
|
||||
std::optional<std::string> exec(dc::Stack<std::string> &stack, dc::Parameters ¶meters, std::unordered_map<char, dc::Register> ®s) override;
|
||||
static std::vector<std::string> split(const std::string& str);
|
||||
|
||||
private:
|
||||
static std::optional<std::string> fn_execute(DCStack<std::string> &stack, Parameters ¶meters, std::unordered_map<char, Register> ®s);
|
||||
std::optional<std::string> fn_evaluate_macro(DCStack<std::string> &stack, Parameters ¶meters, std::unordered_map<char, Register> ®s);
|
||||
static std::optional<std::string> fn_read_input(DCStack<std::string> &stack, Parameters ¶meters, std::unordered_map<char, Register> ®s);
|
||||
static std::optional<std::string> fn_execute(dc::Stack<std::string> &stack, dc::Parameters ¶meters, std::unordered_map<char, dc::Register> ®s);
|
||||
std::optional<std::string> fn_evaluate_macro(dc::Stack<std::string> &stack, dc::Parameters ¶meters, std::unordered_map<char, dc::Register> ®s);
|
||||
static std::optional<std::string> fn_read_input(dc::Stack<std::string> &stack, dc::Parameters ¶meters, std::unordered_map<char, dc::Register> ®s);
|
||||
|
||||
OPType op_type;
|
||||
Operator op{};
|
||||
|
|
90
src/math.cpp
90
src/math.cpp
|
@ -6,7 +6,7 @@
|
|||
#include "math.h"
|
||||
#include "is_num.h"
|
||||
|
||||
std::optional<std::string> Math::exec(DCStack<std::string> &stack, Parameters ¶meters, __attribute__((unused)) std::unordered_map<char, Register> ®s) {
|
||||
std::optional<std::string> Math::exec(dc::Stack<std::string> &stack, dc::Parameters ¶meters, __attribute__((unused)) std::unordered_map<char, dc::Register> ®s) {
|
||||
std::optional<std::string> err = std::nullopt;
|
||||
|
||||
switch(this->op_type) {
|
||||
|
@ -34,7 +34,7 @@ std::optional<std::string> Math::exec(DCStack<std::string> &stack, Parameters &p
|
|||
return err;
|
||||
}
|
||||
|
||||
std::optional<std::string> Math::fn_add(DCStack<std::string> &stack, Parameters ¶meters) {
|
||||
std::optional<std::string> Math::fn_add(dc::Stack<std::string> &stack, dc::Parameters ¶meters) {
|
||||
// Check if stack has enough elements
|
||||
if(stack.size() < 2) {
|
||||
return "'+' requires two operands";
|
||||
|
@ -42,8 +42,8 @@ std::optional<std::string> Math::fn_add(DCStack<std::string> &stack, Parameters
|
|||
|
||||
// Extract two entries from the stack
|
||||
auto len = stack.size()-1;
|
||||
auto x = stack.at(len);
|
||||
auto y = stack.at(len-1);
|
||||
auto x = stack[len];
|
||||
auto y = stack[len-1];
|
||||
auto is_x_num = is_num<double>(x);
|
||||
auto is_y_num = is_num<double>(y);
|
||||
|
||||
|
@ -62,7 +62,7 @@ std::optional<std::string> Math::fn_add(DCStack<std::string> &stack, Parameters
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Math::fn_sub(DCStack<std::string> &stack, Parameters ¶meters) {
|
||||
std::optional<std::string> Math::fn_sub(dc::Stack<std::string> &stack, dc::Parameters ¶meters) {
|
||||
// Check if stack has enough elements
|
||||
if(stack.size() < 2) {
|
||||
return "'-' requires two operands";
|
||||
|
@ -70,8 +70,8 @@ std::optional<std::string> Math::fn_sub(DCStack<std::string> &stack, Parameters
|
|||
|
||||
// Extract two entries from the stack
|
||||
auto len = stack.size()-1;
|
||||
auto x = stack.at(len);
|
||||
auto y = stack.at(len-1);
|
||||
auto x = stack[len];
|
||||
auto y = stack[len-1];
|
||||
auto is_x_num = is_num<double>(x);
|
||||
auto is_y_num = is_num<double>(y);
|
||||
|
||||
|
@ -100,7 +100,7 @@ std::optional<std::string> Math::fn_sub(DCStack<std::string> &stack, Parameters
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Math::fn_mul(DCStack<std::string> &stack, Parameters ¶meters) {
|
||||
std::optional<std::string> Math::fn_mul(dc::Stack<std::string> &stack, dc::Parameters ¶meters) {
|
||||
// Check if stack has enough elements
|
||||
if(stack.size() < 2) {
|
||||
return "'*' requires two operands";
|
||||
|
@ -108,8 +108,8 @@ std::optional<std::string> Math::fn_mul(DCStack<std::string> &stack, Parameters
|
|||
|
||||
// Extract two entries from the stack
|
||||
auto len = stack.size()-1;
|
||||
auto x = stack.at(len);
|
||||
auto y = stack.at(len-1);
|
||||
auto x = stack[len];
|
||||
auto y = stack[len-1];
|
||||
auto is_x_num = is_num<double>(x);
|
||||
auto is_y_num = is_num<double>(y);
|
||||
|
||||
|
@ -128,7 +128,7 @@ std::optional<std::string> Math::fn_mul(DCStack<std::string> &stack, Parameters
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Math::fn_div(DCStack<std::string> &stack, Parameters ¶meters) {
|
||||
std::optional<std::string> Math::fn_div(dc::Stack<std::string> &stack, dc::Parameters ¶meters) {
|
||||
// Check if stack has enough elements
|
||||
if(stack.size() < 2) {
|
||||
return "'/' requires two operands";
|
||||
|
@ -136,8 +136,8 @@ std::optional<std::string> Math::fn_div(DCStack<std::string> &stack, Parameters
|
|||
|
||||
// Extract two entries from the stack
|
||||
auto len = stack.size()-1;
|
||||
auto x = stack.at(len);
|
||||
auto y = stack.at(len-1);
|
||||
auto x = stack[len];
|
||||
auto y = stack[len-1];
|
||||
auto is_x_num = is_num<double>(x);
|
||||
auto is_y_num = is_num<double>(y);
|
||||
|
||||
|
@ -161,7 +161,7 @@ std::optional<std::string> Math::fn_div(DCStack<std::string> &stack, Parameters
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Math::fn_mod(DCStack<std::string> &stack, Parameters ¶meters) {
|
||||
std::optional<std::string> Math::fn_mod(dc::Stack<std::string> &stack, dc::Parameters ¶meters) {
|
||||
// Check if stack has enough elements
|
||||
if(stack.size() < 2) {
|
||||
return "'%' requires two operands";
|
||||
|
@ -169,8 +169,8 @@ std::optional<std::string> Math::fn_mod(DCStack<std::string> &stack, Parameters
|
|||
|
||||
// Extract two entries from the stack
|
||||
auto len = stack.size()-1;
|
||||
auto x = stack.at(len);
|
||||
auto y = stack.at(len-1);
|
||||
auto x = stack[len];
|
||||
auto y = stack[len-1];
|
||||
auto is_x_num = is_num<double>(x);
|
||||
auto is_y_num = is_num<double>(y);
|
||||
|
||||
|
@ -194,7 +194,7 @@ std::optional<std::string> Math::fn_mod(DCStack<std::string> &stack, Parameters
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Math::fn_div_mod(DCStack<std::string> &stack, Parameters ¶meters) {
|
||||
std::optional<std::string> Math::fn_div_mod(dc::Stack<std::string> &stack, dc::Parameters ¶meters) {
|
||||
// Check if stack has enough elements
|
||||
if(stack.size() < 2) {
|
||||
return "'~' requires two operands";
|
||||
|
@ -202,8 +202,8 @@ std::optional<std::string> Math::fn_div_mod(DCStack<std::string> &stack, Paramet
|
|||
|
||||
// Extract two entries from the stack
|
||||
auto len = stack.size()-1;
|
||||
auto x = stack.at(len);
|
||||
auto y = stack.at(len-1);
|
||||
auto x = stack[len];
|
||||
auto y = stack[len-1];
|
||||
auto is_x_num = is_num<double>(x);
|
||||
auto is_y_num = is_num<double>(y);
|
||||
|
||||
|
@ -229,7 +229,7 @@ std::optional<std::string> Math::fn_div_mod(DCStack<std::string> &stack, Paramet
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Math::fn_mod_exp(DCStack<std::string> &stack, Parameters ¶meters) {
|
||||
std::optional<std::string> Math::fn_mod_exp(dc::Stack<std::string> &stack, dc::Parameters ¶meters) {
|
||||
// Check if stack has enough elements
|
||||
if(stack.size() < 3) {
|
||||
return "'|' requires three operands";
|
||||
|
@ -239,9 +239,9 @@ std::optional<std::string> Math::fn_mod_exp(DCStack<std::string> &stack, Paramet
|
|||
// The first one is the modulus(n), the second one
|
||||
// is the exponent(e) and the third one is the base(b)
|
||||
auto len = stack.size()-1;
|
||||
auto n = stack.at(len);
|
||||
auto e = stack.at(len-1);
|
||||
auto b = stack.at(len-2);
|
||||
auto n = stack[len];
|
||||
auto e = stack[len-1];
|
||||
auto b = stack[len-2];
|
||||
auto is_n_num = is_num<double>(n);
|
||||
auto is_e_num = is_num<double>(e);
|
||||
auto is_b_num = is_num<double>(b);
|
||||
|
@ -278,7 +278,7 @@ std::optional<std::string> Math::fn_mod_exp(DCStack<std::string> &stack, Paramet
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Math::fn_exp(DCStack<std::string> &stack, Parameters ¶meters) {
|
||||
std::optional<std::string> Math::fn_exp(dc::Stack<std::string> &stack, dc::Parameters ¶meters) {
|
||||
// Check if stack has enough elements
|
||||
if(stack.size() < 2) {
|
||||
return "'^' requires two operands";
|
||||
|
@ -286,8 +286,8 @@ std::optional<std::string> Math::fn_exp(DCStack<std::string> &stack, Parameters
|
|||
|
||||
// Extract two entries from the stack
|
||||
auto len = stack.size()-1;
|
||||
auto x = stack.at(len);
|
||||
auto y = stack.at(len-1);
|
||||
auto x = stack[len];
|
||||
auto y = stack[len-1];
|
||||
auto is_x_num = is_num<double>(x);
|
||||
auto is_y_num = is_num<double>(y);
|
||||
|
||||
|
@ -306,7 +306,7 @@ std::optional<std::string> Math::fn_exp(DCStack<std::string> &stack, Parameters
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Math::fn_sqrt(DCStack<std::string> &stack, Parameters ¶meters) {
|
||||
std::optional<std::string> Math::fn_sqrt(dc::Stack<std::string> &stack, dc::Parameters ¶meters) {
|
||||
// Check if stack has enough elements
|
||||
if(stack.empty()) {
|
||||
return "'v' requires one operand";
|
||||
|
@ -314,7 +314,7 @@ std::optional<std::string> Math::fn_sqrt(DCStack<std::string> &stack, Parameters
|
|||
|
||||
// Extract one entry from the stack
|
||||
auto len = stack.size()-1;
|
||||
auto x = stack.at(len);
|
||||
auto x = stack[len];
|
||||
auto is_x_num = is_num<double>(x);
|
||||
|
||||
// Check whether the entry is a number
|
||||
|
@ -335,7 +335,7 @@ std::optional<std::string> Math::fn_sqrt(DCStack<std::string> &stack, Parameters
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Math::fn_sin(DCStack<std::string> &stack, Parameters ¶meters) {
|
||||
std::optional<std::string> Math::fn_sin(dc::Stack<std::string> &stack, dc::Parameters ¶meters) {
|
||||
// Check if stack has enough elements
|
||||
if(stack.empty()) {
|
||||
return "'sin' requires one operand";
|
||||
|
@ -343,7 +343,7 @@ std::optional<std::string> Math::fn_sin(DCStack<std::string> &stack, Parameters
|
|||
|
||||
// Extract one entry from the stack
|
||||
auto len = stack.size()-1;
|
||||
auto x = stack.at(len);
|
||||
auto x = stack[len];
|
||||
auto is_x_num = is_num<double>(x);
|
||||
|
||||
// Check whether the entry is a number
|
||||
|
@ -360,7 +360,7 @@ std::optional<std::string> Math::fn_sin(DCStack<std::string> &stack, Parameters
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Math::fn_cos(DCStack<std::string> &stack, Parameters ¶meters) {
|
||||
std::optional<std::string> Math::fn_cos(dc::Stack<std::string> &stack, dc::Parameters ¶meters) {
|
||||
// Check if stack has enough elements
|
||||
if(stack.empty()) {
|
||||
return "'cos' requires one operand";
|
||||
|
@ -368,7 +368,7 @@ std::optional<std::string> Math::fn_cos(DCStack<std::string> &stack, Parameters
|
|||
|
||||
// Extract one entry from the stack
|
||||
auto len = stack.size()-1;
|
||||
auto x = stack.at(len);
|
||||
auto x = stack[len];
|
||||
auto is_x_num = is_num<double>(x);
|
||||
|
||||
// Check whether the entry is a number
|
||||
|
@ -385,7 +385,7 @@ std::optional<std::string> Math::fn_cos(DCStack<std::string> &stack, Parameters
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Math::fn_tan(DCStack<std::string> &stack, Parameters ¶meters) {
|
||||
std::optional<std::string> Math::fn_tan(dc::Stack<std::string> &stack, dc::Parameters ¶meters) {
|
||||
// Check if stack has enough elements
|
||||
if(stack.empty()) {
|
||||
return "'tan' requires one operand";
|
||||
|
@ -393,7 +393,7 @@ std::optional<std::string> Math::fn_tan(DCStack<std::string> &stack, Parameters
|
|||
|
||||
// Extract one entry from the stack
|
||||
auto len = stack.size()-1;
|
||||
auto x = stack.at(len);
|
||||
auto x = stack[len];
|
||||
auto is_x_num = is_num<double>(x);
|
||||
|
||||
// Check whether the entry is a number
|
||||
|
@ -410,7 +410,7 @@ std::optional<std::string> Math::fn_tan(DCStack<std::string> &stack, Parameters
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Math::fn_asin(DCStack<std::string> &stack, Parameters ¶meters) {
|
||||
std::optional<std::string> Math::fn_asin(dc::Stack<std::string> &stack, dc::Parameters ¶meters) {
|
||||
// Check if stack has enough elements
|
||||
if(stack.empty()) {
|
||||
return "'asin' requires one operand";
|
||||
|
@ -418,7 +418,7 @@ std::optional<std::string> Math::fn_asin(DCStack<std::string> &stack, Parameters
|
|||
|
||||
// Extract one entry from the stack
|
||||
auto len = stack.size()-1;
|
||||
auto x = stack.at(len);
|
||||
auto x = stack[len];
|
||||
auto is_x_num = is_num<double>(x);
|
||||
|
||||
// Check whether the entry is a number
|
||||
|
@ -435,7 +435,7 @@ std::optional<std::string> Math::fn_asin(DCStack<std::string> &stack, Parameters
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Math::fn_acos(DCStack<std::string> &stack, Parameters ¶meters) {
|
||||
std::optional<std::string> Math::fn_acos(dc::Stack<std::string> &stack, dc::Parameters ¶meters) {
|
||||
// Check if stack has enough elements
|
||||
if(stack.empty()) {
|
||||
return "'acos' requires one operand";
|
||||
|
@ -443,7 +443,7 @@ std::optional<std::string> Math::fn_acos(DCStack<std::string> &stack, Parameters
|
|||
|
||||
// Extract one entry from the stack
|
||||
auto len = stack.size()-1;
|
||||
auto x = stack.at(len);
|
||||
auto x = stack[len];
|
||||
auto is_x_num = is_num<double>(x);
|
||||
|
||||
// Check whether the entry is a number
|
||||
|
@ -460,7 +460,7 @@ std::optional<std::string> Math::fn_acos(DCStack<std::string> &stack, Parameters
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Math::fn_atan(DCStack<std::string> &stack, Parameters ¶meters) {
|
||||
std::optional<std::string> Math::fn_atan(dc::Stack<std::string> &stack, dc::Parameters ¶meters) {
|
||||
// Check if stack has enough elements
|
||||
if(stack.empty()) {
|
||||
return "'atan' requires one operand";
|
||||
|
@ -468,7 +468,7 @@ std::optional<std::string> Math::fn_atan(DCStack<std::string> &stack, Parameters
|
|||
|
||||
// Extract one entry from the stack
|
||||
auto len = stack.size()-1;
|
||||
auto x = stack.at(len);
|
||||
auto x = stack[len];
|
||||
auto is_x_num = is_num<double>(x);
|
||||
|
||||
// Check whether the entry is a number
|
||||
|
@ -485,7 +485,7 @@ std::optional<std::string> Math::fn_atan(DCStack<std::string> &stack, Parameters
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Math::fn_fact(DCStack<std::string> &stack, Parameters ¶meters) {
|
||||
std::optional<std::string> Math::fn_fact(dc::Stack<std::string> &stack, dc::Parameters ¶meters) {
|
||||
// Check if stack has enough elements
|
||||
if(stack.empty()) {
|
||||
return "'!' requires one operand";
|
||||
|
@ -493,7 +493,7 @@ std::optional<std::string> Math::fn_fact(DCStack<std::string> &stack, Parameters
|
|||
|
||||
// Extract one entry from the stack
|
||||
auto len = stack.size()-1;
|
||||
auto x = stack.at(len);
|
||||
auto x = stack[len];
|
||||
auto is_x_num = is_num<double>(x);
|
||||
|
||||
// Check whether the entry is a number
|
||||
|
@ -506,7 +506,7 @@ std::optional<std::string> Math::fn_fact(DCStack<std::string> &stack, Parameters
|
|||
factorial = 1;
|
||||
}
|
||||
|
||||
for(size_t i = 2; i <= (size_t)val; i++) {
|
||||
for(std::size_t i = 2; i <= (std::size_t)val; i++) {
|
||||
factorial *= i;
|
||||
}
|
||||
|
||||
|
@ -519,13 +519,13 @@ std::optional<std::string> Math::fn_fact(DCStack<std::string> &stack, Parameters
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Math::fn_pi(DCStack<std::string> &stack, Parameters ¶meters) {
|
||||
std::optional<std::string> Math::fn_pi(dc::Stack<std::string> &stack, dc::Parameters ¶meters) {
|
||||
stack.push(trim_digits(std::numbers::pi, parameters.precision));
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Math::fn_e(DCStack<std::string> &stack, Parameters ¶meters) {
|
||||
std::optional<std::string> Math::fn_e(dc::Stack<std::string> &stack, dc::Parameters ¶meters) {
|
||||
stack.push(trim_digits(std::numbers::e, parameters.precision));
|
||||
|
||||
return std::nullopt;
|
||||
|
|
38
src/math.h
38
src/math.h
|
@ -5,27 +5,27 @@
|
|||
class Math : public IOperation {
|
||||
public:
|
||||
explicit Math(const OPType op_t) : op_type(op_t) {}
|
||||
std::optional<std::string> exec(DCStack<std::string> &stack, Parameters ¶meters, std::unordered_map<char, Register> ®s) override;
|
||||
std::optional<std::string> exec(dc::Stack<std::string> &stack, dc::Parameters ¶meters, std::unordered_map<char, dc::Register> ®s) override;
|
||||
|
||||
private:
|
||||
static std::optional<std::string> fn_add(DCStack<std::string> &stack, Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_sub(DCStack<std::string> &stack, Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_mul(DCStack<std::string> &stack, Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_div(DCStack<std::string> &stack, Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_mod(DCStack<std::string> &stack, Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_div_mod(DCStack<std::string> &stack, Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_mod_exp(DCStack<std::string> &stack, Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_exp(DCStack<std::string> &stack, Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_sqrt(DCStack<std::string> &stack, Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_sin(DCStack<std::string> &stack, Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_cos(DCStack<std::string> &stack, Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_tan(DCStack<std::string> &stack, Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_asin(DCStack<std::string> &stack, Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_acos(DCStack<std::string> &stack, Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_atan(DCStack<std::string> &stack, Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_fact(DCStack<std::string> &stack, Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_pi(DCStack<std::string> &stack, Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_e(DCStack<std::string> &stack, Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_add(dc::Stack<std::string> &stack, dc::Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_sub(dc::Stack<std::string> &stack, dc::Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_mul(dc::Stack<std::string> &stack, dc::Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_div(dc::Stack<std::string> &stack, dc::Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_mod(dc::Stack<std::string> &stack, dc::Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_div_mod(dc::Stack<std::string> &stack, dc::Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_mod_exp(dc::Stack<std::string> &stack, dc::Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_exp(dc::Stack<std::string> &stack, dc::Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_sqrt(dc::Stack<std::string> &stack, dc::Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_sin(dc::Stack<std::string> &stack, dc::Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_cos(dc::Stack<std::string> &stack, dc::Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_tan(dc::Stack<std::string> &stack, dc::Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_asin(dc::Stack<std::string> &stack, dc::Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_acos(dc::Stack<std::string> &stack, dc::Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_atan(dc::Stack<std::string> &stack, dc::Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_fact(dc::Stack<std::string> &stack, dc::Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_pi(dc::Stack<std::string> &stack, dc::Parameters ¶meters) ;
|
||||
static std::optional<std::string> fn_e(dc::Stack<std::string> &stack, dc::Parameters ¶meters) ;
|
||||
static std::string trim_digits(double number, unsigned int precision);
|
||||
|
||||
OPType op_type;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
class IOperation {
|
||||
public:
|
||||
virtual std::optional<std::string> exec(DCStack<std::string> &stack, Parameters ¶meters, std::unordered_map<char, Register> ®s) = 0;
|
||||
virtual std::optional<std::string> exec(dc::Stack<std::string> &stack, dc::Parameters ¶meters, std::unordered_map<char, dc::Register> ®s) = 0;
|
||||
virtual ~IOperation() = default;
|
||||
};
|
||||
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
#include "stack.h"
|
||||
#include "is_num.h"
|
||||
|
||||
std::optional<std::string> Stack::exec(DCStack<std::string> &stack, Parameters ¶meters, __attribute__((unused)) std::unordered_map<char, Register> ®s) {
|
||||
std::optional<std::string> Stack::exec(dc::Stack<std::string> &stack, dc::Parameters ¶meters, __attribute__((unused)) std::unordered_map<char, dc::Register> ®s) {
|
||||
std::optional<std::string> err = std::nullopt;
|
||||
|
||||
auto print_oradix = [&stack, ¶meters, this](radix_base base) {
|
||||
auto print_oradix = [&stack, ¶meters, this](dc::radix_base base) {
|
||||
auto old_rdx = parameters.oradix;
|
||||
parameters.oradix = base;
|
||||
auto res = fn_print(stack, parameters, false);
|
||||
|
@ -21,9 +21,9 @@ std::optional<std::string> Stack::exec(DCStack<std::string> &stack, Parameters &
|
|||
switch(this->op_type) {
|
||||
case OPType::PCG: err = fn_print(stack, parameters, true); break;
|
||||
case OPType::P: err = fn_print(stack, parameters, false); break;
|
||||
case OPType::PBB: err = print_oradix(radix_base::BIN); break;
|
||||
case OPType::PBO: err = print_oradix(radix_base::OCT); break;
|
||||
case OPType::PBH: err = print_oradix(radix_base::HEX); break;
|
||||
case OPType::PBB: err = print_oradix(dc::radix_base::BIN); break;
|
||||
case OPType::PBO: err = print_oradix(dc::radix_base::OCT); break;
|
||||
case OPType::PBH: err = print_oradix(dc::radix_base::HEX); break;
|
||||
case OPType::CLR: stack.clear(); break;
|
||||
case OPType::PH: err = fn_pop_head(stack); break;
|
||||
case OPType::SO: err = fn_swap_xy(stack); break;
|
||||
|
@ -46,7 +46,7 @@ std::optional<std::string> Stack::exec(DCStack<std::string> &stack, Parameters &
|
|||
return err;
|
||||
}
|
||||
|
||||
std::optional<std::string> Stack::fn_print(DCStack<std::string> &stack, Parameters ¶meters, bool new_line) {
|
||||
std::optional<std::string> Stack::fn_print(dc::Stack<std::string> &stack, dc::Parameters ¶meters, bool new_line) {
|
||||
// Check if the stack is empty
|
||||
if(stack.empty()) {
|
||||
return "Cannot print empty stack";
|
||||
|
@ -58,7 +58,7 @@ std::optional<std::string> Stack::fn_print(DCStack<std::string> &stack, Paramete
|
|||
}
|
||||
|
||||
switch(parameters.oradix) {
|
||||
case radix_base::DEC: {
|
||||
case dc::radix_base::DEC: {
|
||||
if(new_line) {
|
||||
std::cout << stack.pop(false) << std::endl;
|
||||
} else {
|
||||
|
@ -66,17 +66,17 @@ std::optional<std::string> Stack::fn_print(DCStack<std::string> &stack, Paramete
|
|||
}
|
||||
break;
|
||||
}
|
||||
case radix_base::BIN: {
|
||||
case dc::radix_base::BIN: {
|
||||
auto head = std::stol(stack.pop(false));
|
||||
std::cout << to_bin(head) << 'b' << std::endl;
|
||||
break;
|
||||
}
|
||||
case radix_base::OCT: {
|
||||
case dc::radix_base::OCT: {
|
||||
auto head = std::stol(stack.pop(false));
|
||||
std::cout << std::oct << head << 'o' << std::dec << std::endl;
|
||||
break;
|
||||
}
|
||||
case radix_base::HEX: {
|
||||
case dc::radix_base::HEX: {
|
||||
auto head = std::stol(stack.pop(false));
|
||||
std::cout << std::hex << std::uppercase << head << 'h'
|
||||
<< std::dec << std::nouppercase << std::endl;
|
||||
|
@ -88,7 +88,7 @@ std::optional<std::string> Stack::fn_print(DCStack<std::string> &stack, Paramete
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Stack::fn_pop_head(DCStack<std::string> &stack) {
|
||||
std::optional<std::string> Stack::fn_pop_head(dc::Stack<std::string> &stack) {
|
||||
// Check if stack is empty
|
||||
if(stack.empty()) {
|
||||
return "'R' does not work on empty stack";
|
||||
|
@ -100,7 +100,7 @@ std::optional<std::string> Stack::fn_pop_head(DCStack<std::string> &stack) {
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Stack::fn_swap_xy(DCStack<std::string> &stack) {
|
||||
std::optional<std::string> Stack::fn_swap_xy(dc::Stack<std::string> &stack) {
|
||||
// Check if the stack has enough elements
|
||||
if(stack.size() < 2) {
|
||||
return "'r' requires two elements";
|
||||
|
@ -108,16 +108,16 @@ std::optional<std::string> Stack::fn_swap_xy(DCStack<std::string> &stack) {
|
|||
|
||||
// Swap top two elements
|
||||
auto len = stack.size()-1;
|
||||
auto x = stack.at(len);
|
||||
auto x = stack[len];
|
||||
|
||||
stack.copy_xyz();
|
||||
stack.at(len) = stack.at(len-1);
|
||||
stack.at(len-1) = x;
|
||||
stack[len] = stack[len-1];
|
||||
stack[len-1] = x;
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Stack::fn_dup_head(DCStack<std::string> &stack) {
|
||||
std::optional<std::string> Stack::fn_dup_head(dc::Stack<std::string> &stack) {
|
||||
// Check if the stack has enough elements
|
||||
if(stack.empty()) {
|
||||
return "'d' requires one element";
|
||||
|
@ -129,29 +129,29 @@ std::optional<std::string> Stack::fn_dup_head(DCStack<std::string> &stack) {
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Stack::fn_print_stack(DCStack<std::string> &stack, Parameters ¶meters) {
|
||||
std::optional<std::string> Stack::fn_print_stack(dc::Stack<std::string> &stack, dc::Parameters ¶meters) {
|
||||
const auto& const_ref = stack.get_ref();
|
||||
|
||||
switch(parameters.oradix) {
|
||||
case radix_base::DEC: {
|
||||
case dc::radix_base::DEC: {
|
||||
for(auto & it : std::ranges::reverse_view(const_ref)) {
|
||||
std::cout << it << std::endl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case radix_base::BIN: {
|
||||
case dc::radix_base::BIN: {
|
||||
for(auto & it : std::ranges::reverse_view(const_ref)) {
|
||||
std::cout << to_bin(std::stol(it)) << 'b' << std::endl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case radix_base::OCT: {
|
||||
case dc::radix_base::OCT: {
|
||||
for(auto & it : std::ranges::reverse_view(const_ref)) {
|
||||
std::cout << std::oct << std::stol(it) << 'o' << std::dec << std::endl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case radix_base::HEX: {
|
||||
case dc::radix_base::HEX: {
|
||||
for(auto & it : std::ranges::reverse_view(const_ref)) {
|
||||
std::cout << std::hex << std::uppercase << std::stol(it) << 'h'
|
||||
<< std::dec << std::nouppercase << std::endl;
|
||||
|
@ -163,7 +163,7 @@ std::optional<std::string> Stack::fn_print_stack(DCStack<std::string> &stack, Pa
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Stack::fn_head_size(DCStack<std::string> &stack) {
|
||||
std::optional<std::string> Stack::fn_head_size(dc::Stack<std::string> &stack) {
|
||||
// Check if the stack has enough elements
|
||||
if(stack.empty()) {
|
||||
return "'Z' does not work on empty stack";
|
||||
|
@ -179,7 +179,7 @@ std::optional<std::string> Stack::fn_head_size(DCStack<std::string> &stack) {
|
|||
stack.copy_xyz();
|
||||
stack.pop(true);
|
||||
|
||||
size_t len = 0;
|
||||
std::size_t len = 0;
|
||||
while(num > 0) {
|
||||
num /= 10;
|
||||
len++;
|
||||
|
@ -197,13 +197,13 @@ std::optional<std::string> Stack::fn_head_size(DCStack<std::string> &stack) {
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Stack::fn_stack_size(DCStack<std::string> &stack) {
|
||||
std::optional<std::string> Stack::fn_stack_size(dc::Stack<std::string> &stack) {
|
||||
stack.push(std::to_string(stack.size()));
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Stack::fn_set_precision(DCStack<std::string> &stack, Parameters ¶meters) {
|
||||
std::optional<std::string> Stack::fn_set_precision(dc::Stack<std::string> &stack, dc::Parameters ¶meters) {
|
||||
// Check if stack has enough elements
|
||||
if(stack.empty()) {
|
||||
return "'k' requires one operand";
|
||||
|
@ -224,13 +224,13 @@ std::optional<std::string> Stack::fn_set_precision(DCStack<std::string> &stack,
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Stack::fn_get_precision(DCStack<std::string> &stack, Parameters ¶meters) {
|
||||
std::optional<std::string> Stack::fn_get_precision(dc::Stack<std::string> &stack, dc::Parameters ¶meters) {
|
||||
stack.push(std::to_string(parameters.precision));
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Stack::fn_set_oradix(DCStack<std::string> &stack, Parameters ¶meters) {
|
||||
std::optional<std::string> Stack::fn_set_oradix(dc::Stack<std::string> &stack, dc::Parameters ¶meters) {
|
||||
// Check if stack has enough elements
|
||||
if(stack.empty()) {
|
||||
return "'o' requires one operand";
|
||||
|
@ -246,23 +246,23 @@ std::optional<std::string> Stack::fn_set_oradix(DCStack<std::string> &stack, Par
|
|||
// 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;
|
||||
case 2: parameters.oradix = dc::radix_base::BIN; break;
|
||||
case 8: parameters.oradix = dc::radix_base::OCT; break;
|
||||
case 10: parameters.oradix = dc::radix_base::DEC; break;
|
||||
case 16: parameters.oradix = dc::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(DCStack<std::string> &stack, Parameters ¶meters) {
|
||||
std::optional<std::string> Stack::fn_get_oradix(dc::Stack<std::string> &stack, dc::Parameters ¶meters) {
|
||||
stack.push(std::to_string(static_cast<int>(parameters.oradix)));
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Stack::fn_set_iradix(DCStack<std::string> &stack, Parameters ¶meters) {
|
||||
std::optional<std::string> Stack::fn_set_iradix(dc::Stack<std::string> &stack, dc::Parameters ¶meters) {
|
||||
// Check if stack has enough elements
|
||||
if(stack.empty()) {
|
||||
return "'i' requires one operand";
|
||||
|
@ -283,13 +283,13 @@ std::optional<std::string> Stack::fn_set_iradix(DCStack<std::string> &stack, Par
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Stack::fn_get_iradix(DCStack<std::string> &stack, Parameters ¶meters) {
|
||||
std::optional<std::string> Stack::fn_get_iradix(dc::Stack<std::string> &stack, dc::Parameters ¶meters) {
|
||||
stack.push(std::to_string(parameters.iradix));
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Stack::fn_get_lastx(DCStack<std::string> &stack) {
|
||||
std::optional<std::string> Stack::fn_get_lastx(dc::Stack<std::string> &stack) {
|
||||
// Retrieve last x from the stack and push it back
|
||||
auto last_x = stack.get_last_x();
|
||||
last_x.empty() ? stack.push("0") : stack.push(last_x);
|
||||
|
@ -297,7 +297,7 @@ std::optional<std::string> Stack::fn_get_lastx(DCStack<std::string> &stack) {
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Stack::fn_get_lasty(DCStack<std::string> &stack) {
|
||||
std::optional<std::string> Stack::fn_get_lasty(dc::Stack<std::string> &stack) {
|
||||
// Retrieve last y from the stack and push it back
|
||||
auto last_y = stack.get_last_y();
|
||||
last_y.empty() ? stack.push("0") : stack.push(last_y);
|
||||
|
@ -305,7 +305,7 @@ std::optional<std::string> Stack::fn_get_lasty(DCStack<std::string> &stack) {
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Stack::fn_get_lastz(DCStack<std::string> &stack) {
|
||||
std::optional<std::string> Stack::fn_get_lastz(dc::Stack<std::string> &stack) {
|
||||
// Retrieve last y from the stack and push it back
|
||||
auto last_z = stack.get_last_z();
|
||||
last_z.empty() ? stack.push("0") : stack.push(last_z);
|
||||
|
|
34
src/stack.h
34
src/stack.h
|
@ -5,25 +5,25 @@
|
|||
class Stack : public IOperation {
|
||||
public:
|
||||
explicit Stack(const OPType op_t) : op_type(op_t) {}
|
||||
std::optional<std::string> exec(DCStack<std::string> &stack, Parameters ¶meters, std::unordered_map<char, Register> ®s) override;
|
||||
std::optional<std::string> exec(dc::Stack<std::string> &stack, dc::Parameters ¶meters, std::unordered_map<char, dc::Register> ®s) override;
|
||||
|
||||
private:
|
||||
std::optional<std::string> fn_print(DCStack<std::string> &stack, Parameters ¶meters, bool new_line);
|
||||
static std::optional<std::string> fn_pop_head(DCStack<std::string> &stack);
|
||||
static std::optional<std::string> fn_swap_xy(DCStack<std::string> &stack);
|
||||
static std::optional<std::string> fn_dup_head(DCStack<std::string> &stack);
|
||||
std::optional<std::string> fn_print_stack(DCStack<std::string> &stack, Parameters ¶meters);
|
||||
static std::optional<std::string> fn_head_size(DCStack<std::string> &stack);
|
||||
static std::optional<std::string> fn_stack_size(DCStack<std::string> &stack);
|
||||
static std::optional<std::string> fn_set_precision(DCStack<std::string> &stack, Parameters ¶meters);
|
||||
static std::optional<std::string> fn_get_precision(DCStack<std::string> &stack, Parameters ¶meters);
|
||||
static std::optional<std::string> fn_set_oradix(DCStack<std::string> &stack, Parameters ¶meters);
|
||||
static std::optional<std::string> fn_get_oradix(DCStack<std::string> &stack, Parameters ¶meters);
|
||||
static std::optional<std::string> fn_set_iradix(DCStack<std::string> &stack, Parameters ¶meters);
|
||||
static std::optional<std::string> fn_get_iradix(DCStack<std::string> &stack, Parameters ¶meters);
|
||||
std::optional<std::string> fn_get_lastx(DCStack<std::string> &stack);
|
||||
std::optional<std::string> fn_get_lasty(DCStack<std::string> &stack);
|
||||
std::optional<std::string> fn_get_lastz(DCStack<std::string> &stack);
|
||||
std::optional<std::string> fn_print(dc::Stack<std::string> &stack, dc::Parameters ¶meters, bool new_line);
|
||||
static std::optional<std::string> fn_pop_head(dc::Stack<std::string> &stack);
|
||||
static std::optional<std::string> fn_swap_xy(dc::Stack<std::string> &stack);
|
||||
static std::optional<std::string> fn_dup_head(dc::Stack<std::string> &stack);
|
||||
std::optional<std::string> fn_print_stack(dc::Stack<std::string> &stack, dc::Parameters ¶meters);
|
||||
static std::optional<std::string> fn_head_size(dc::Stack<std::string> &stack);
|
||||
static std::optional<std::string> fn_stack_size(dc::Stack<std::string> &stack);
|
||||
static std::optional<std::string> fn_set_precision(dc::Stack<std::string> &stack, dc::Parameters ¶meters);
|
||||
static std::optional<std::string> fn_get_precision(dc::Stack<std::string> &stack, dc::Parameters ¶meters);
|
||||
static std::optional<std::string> fn_set_oradix(dc::Stack<std::string> &stack, dc::Parameters ¶meters);
|
||||
static std::optional<std::string> fn_get_oradix(dc::Stack<std::string> &stack, dc::Parameters ¶meters);
|
||||
static std::optional<std::string> fn_set_iradix(dc::Stack<std::string> &stack, dc::Parameters ¶meters);
|
||||
static std::optional<std::string> fn_get_iradix(dc::Stack<std::string> &stack, dc::Parameters ¶meters);
|
||||
std::optional<std::string> fn_get_lastx(dc::Stack<std::string> &stack);
|
||||
std::optional<std::string> fn_get_lasty(dc::Stack<std::string> &stack);
|
||||
std::optional<std::string> fn_get_lastz(dc::Stack<std::string> &stack);
|
||||
constexpr std::string to_bin(auto num);
|
||||
|
||||
OPType op_type;
|
||||
|
|
Loading…
Reference in New Issue