Added 'lastX', 'lastY', 'lastZ' operations and their tests
dc / build (push) Successful in 1m2s
Details
dc / build (push) Successful in 1m2s
Details
This commit is contained in:
parent
aebfec4fb3
commit
674d6deef6
25
README.md
25
README.md
|
@ -33,6 +33,7 @@ Some of the supported features are:
|
|||
- Swap order of top two elements(`r`);
|
||||
- Duplicate top element(`d`);
|
||||
- Dump the whole stack(`f`);
|
||||
- Last head, 2nd, 3rd element of the stack(`.x`, `.y`, `.z`);
|
||||
- Parameters:
|
||||
- Set precision(`k`);
|
||||
- Set input and output radix(`i` and `o`);
|
||||
|
@ -151,7 +152,15 @@ lA lB # Push 'A' and 'B' content onto the stack
|
|||
p # Print top element(output: 5)
|
||||
```
|
||||
|
||||
7. Print out numbers from 1 through user-defined upper bound:
|
||||
7. Recall last value of top three elements of the stack:
|
||||
```sh
|
||||
10 1 / # <- Wrong operation: division instead of sum
|
||||
.y # Call last value of y register
|
||||
.x # Call last value of x register
|
||||
+ p # Sum and print head(output: 11)
|
||||
```
|
||||
|
||||
8. Print out numbers from 1 through user-defined upper bound:
|
||||
```sh
|
||||
[ p 1 + d lN >L ] sL # Print numbers from 1 through 'N'
|
||||
|
||||
|
@ -160,20 +169,20 @@ p # Print top element(output: 5)
|
|||
c 1 lL x # Clear the stack, add lower bound, load and execute macro
|
||||
```
|
||||
|
||||
8. Sum the first 36 natural numbers(😈), i.e.,
|
||||
9. Sum the first 36 natural numbers(😈), i.e.,
|
||||
$$\sum_{i=1}^{37} i = 666$$
|
||||
```sh
|
||||
$> dc -e "36 [ d 1 - d 1 <F + ] d sF x p"
|
||||
```
|
||||
|
||||
5. Print the first 20 values of `n!`:
|
||||
10. Print the first 20 values of `n!`:
|
||||
```
|
||||
[ la 1 + d sa * p la 20 >y ] sy
|
||||
0 sa 1
|
||||
ly x
|
||||
```
|
||||
|
||||
9. Compute the factorial of a given number:
|
||||
11. Compute the factorial of a given number:
|
||||
```
|
||||
[ ln 1 - sn ln la * sa ln 1 !=f ] sf
|
||||
[ Enter value: ] P ? sn
|
||||
|
@ -182,7 +191,7 @@ lf x
|
|||
la p
|
||||
```
|
||||
|
||||
10. Compute the sum $8AB6F + B783E$ in base 16. Print the result in base 10 and in base 2:
|
||||
12. Compute the sum $8AB6F + B783E$ in base 16. Print the result in base 10 and in base 2:
|
||||
```
|
||||
16 i
|
||||
8AB6F B783E +
|
||||
|
@ -190,7 +199,7 @@ la p
|
|||
[ Result in base 2: ] P R pb
|
||||
```
|
||||
|
||||
11. Compute the Greatest Common Divisor(GCD) between two user-defined numbers `A` and `B`:
|
||||
13. Compute the Greatest Common Divisor(GCD) between two user-defined numbers `A` and `B`:
|
||||
```
|
||||
[ Enter A: ] P R ?
|
||||
[ Enter B: ] P R ?
|
||||
|
@ -198,7 +207,7 @@ la p
|
|||
[ GCD(A,B)= ] P R p
|
||||
```
|
||||
|
||||
12. Compute the Least Common Multiple(LCM) between two user-defined numbers `A` and `B`:
|
||||
14. Compute the Least Common Multiple(LCM) between two user-defined numbers `A` and `B`:
|
||||
```
|
||||
[ Enter A: ] P R ? d sA
|
||||
[ Enter B: ] P R ? d SA
|
||||
|
@ -207,7 +216,7 @@ LA lA * r /
|
|||
[ LCM(A,B)= ] P R p
|
||||
```
|
||||
|
||||
13. Find the roots of a quadratic equation of the form:
|
||||
15. Find the roots of a quadratic equation of the form:
|
||||
$$ax^2 + bx + c = 0$$
|
||||
|
||||
with $$a,b,c \in \mathbb{R}, a \neq 0$$
|
||||
|
|
19
man.md
19
man.md
|
@ -3,7 +3,7 @@ title: dc
|
|||
section: 1
|
||||
header: General Commands Manual
|
||||
footer: Marco Cetica
|
||||
date: November 28, 2023
|
||||
date: March 12, 2024
|
||||
---
|
||||
|
||||
|
||||
|
@ -91,7 +91,8 @@ register and the _value_ is a **private** instance of a stack and a **private**
|
|||
cannot operate directly on the auxiliary stacks or on the auxiliary arrays. In order to use a value stored on an auxiliary stack, you need to pop it
|
||||
and push it onto the main stack(see the register section).
|
||||
|
||||
Both the _main stack_ and the _auxiliary stack_ implement the same abstract data type, therefore any kind of data type supported by the main stack - as well as any other property or feature supported by the main stack - is also supported by the register's stack.
|
||||
Both the _main stack_ and the _auxiliary stack_ implement the same abstract data type, therefore any kind of data type supported by the main
|
||||
stack - as well as any other property or feature supported by the main stack - is also supported by the register's stack.
|
||||
|
||||
_Arrays_ are dynamic, homogeneous and private abstract data type associated with a register.
|
||||
The underlying data type of a dc array is a hashmap where the index is represented by
|
||||
|
@ -230,6 +231,20 @@ Reverses the order of the top two values of the stack. This can also be accompli
|
|||
|
||||
Pops the top-of-stack without printing it
|
||||
|
||||
**.x**
|
||||
|
||||
Retrieve the value that was last the top-of-stack *before execution of any operation*(stack, macro, arithmetical, etc.).
|
||||
This function can be used to quickly key back numbers when you are recovering from errors, such as typing in the wrong number
|
||||
or executing the wrong operation.
|
||||
|
||||
**.y**
|
||||
|
||||
Retrieve the value that was last the second-to-top of the stack *before execution of any operation*(stack, macro, arithmetical, etc.).
|
||||
|
||||
**.z**
|
||||
|
||||
Retrieve the value that was last the third-to-top of the stack *before execution of any operation*(stack, macro, arithmetical, etc.).
|
||||
|
||||
## Parameters
|
||||
**dc** has three parameters that control its operation: the *precision*, the *input radix* and the *output radix*.
|
||||
The precision specifies the number of fraction digits to keep in the result of most arithmetical operations. The
|
||||
|
|
61
src/adt.cpp
61
src/adt.cpp
|
@ -1,7 +1,11 @@
|
|||
#include "adt.h"
|
||||
|
||||
#define GET_X this->stack.back()
|
||||
#define GET_Y this->stack.at(this->stack.size() - 2)
|
||||
#define GET_Z this->stack.at(this->stack.size() - 3)
|
||||
|
||||
/**
|
||||
* Add new element to the stack
|
||||
* Add @value to the stack
|
||||
*/
|
||||
template<typename T>
|
||||
requires is_num_or_str<T>
|
||||
|
@ -36,8 +40,59 @@ T DCStack<T>::pop(bool remove) {
|
|||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read stack at index
|
||||
* 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;
|
||||
}
|
||||
|
||||
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 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>
|
||||
|
@ -73,4 +128,4 @@ template<typename T>
|
|||
requires is_num_or_str<T>
|
||||
const std::vector<T>& DCStack<T>::get_ref() const {
|
||||
return this->stack;
|
||||
}
|
||||
}
|
||||
|
|
11
src/adt.h
11
src/adt.h
|
@ -11,10 +11,13 @@ template<typename T>
|
|||
requires is_num_or_str<T>
|
||||
class DCStack {
|
||||
public:
|
||||
DCStack() = default;
|
||||
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();
|
||||
|
@ -22,9 +25,9 @@ public:
|
|||
|
||||
private:
|
||||
std::vector<T> stack;
|
||||
T last_x;
|
||||
T last_y;
|
||||
T last_z;
|
||||
T last_x{};
|
||||
T last_y{};
|
||||
T last_z{};
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -59,6 +59,9 @@ void Evaluate::init_environment() {
|
|||
this->op_factory.emplace("O", MAKE_UNIQUE_PTR(Stack, OPType::GOR));
|
||||
this->op_factory.emplace("i", MAKE_UNIQUE_PTR(Stack, OPType::SIR));
|
||||
this->op_factory.emplace("I", MAKE_UNIQUE_PTR(Stack, OPType::GIR));
|
||||
this->op_factory.emplace(".x", MAKE_UNIQUE_PTR(Stack, OPType::LX));
|
||||
this->op_factory.emplace(".y", MAKE_UNIQUE_PTR(Stack, OPType::LY));
|
||||
this->op_factory.emplace(".z", MAKE_UNIQUE_PTR(Stack, OPType::LZ));
|
||||
// Macro operations
|
||||
this->op_factory.emplace("x", MAKE_UNIQUE_PTR(Macro, OPType::EX));
|
||||
this->op_factory.emplace("?", MAKE_UNIQUE_PTR(Macro, OPType::RI));
|
||||
|
@ -239,6 +242,7 @@ std::optional<std::string> Evaluate::parse_register_command(std::string token) {
|
|||
|
||||
// Otherwise pop an element from main stack and store it into
|
||||
// the register's top-of-the-stack. Any previous value gets overwritten
|
||||
this->stack.copy_xyz();
|
||||
auto reg_name = token.at(1);
|
||||
auto head = this->stack.pop(true);
|
||||
|
||||
|
@ -265,6 +269,7 @@ std::optional<std::string> Evaluate::parse_register_command(std::string token) {
|
|||
return "This operation does not work on empty stack";
|
||||
}
|
||||
|
||||
this->stack.copy_xyz();
|
||||
auto reg_name = token.at(1);
|
||||
auto head = this->stack.pop(true);
|
||||
|
||||
|
@ -334,6 +339,7 @@ std::optional<std::string> Evaluate::parse_array_command(std::string token) {
|
|||
}
|
||||
|
||||
// Extract two elements from the main stack
|
||||
this->stack.copy_xyz();
|
||||
auto idx_str = this->stack.pop(true);
|
||||
auto arr_val = this->stack.pop(true);
|
||||
|
||||
|
@ -369,6 +375,7 @@ std::optional<std::string> Evaluate::parse_array_command(std::string token) {
|
|||
}
|
||||
|
||||
// Extract the index from the stack
|
||||
this->stack.copy_xyz();
|
||||
auto idx_str = this->stack.pop(true);
|
||||
|
||||
// Check if index is an integer
|
||||
|
|
|
@ -31,6 +31,7 @@ std::optional<std::string> Macro::fn_execute(DCStack<std::string> &stack, Parame
|
|||
// pop it and execute it as a macro
|
||||
auto head = stack.pop(false);
|
||||
if(!is_num<double>(head)) {
|
||||
stack.copy_xyz();
|
||||
stack.pop(true);
|
||||
std::vector<std::string> tokens = split(head);
|
||||
Evaluate evaluator(tokens, regs, stack, parameters);
|
||||
|
@ -56,6 +57,7 @@ std::optional<std::string> Macro::fn_evaluate_macro(DCStack<std::string> &stack,
|
|||
}
|
||||
|
||||
// Extract macro and top two values of the stack
|
||||
stack.copy_xyz();
|
||||
auto head_str = stack.pop(true);
|
||||
auto second_str = stack.pop(true);
|
||||
auto dc_macro = regs[this->dc_register].stack.pop(false);
|
||||
|
|
16
src/math.cpp
16
src/math.cpp
|
@ -49,6 +49,7 @@ std::optional<std::string> Math::fn_add(DCStack<std::string> &stack, Parameters
|
|||
|
||||
// Check whether both entries are numbers
|
||||
if(is_x_num && is_y_num) {
|
||||
stack.copy_xyz();
|
||||
auto lhs = std::stod(stack.pop(true));
|
||||
auto rhs = std::stod(stack.pop(true));
|
||||
|
||||
|
@ -76,6 +77,7 @@ std::optional<std::string> Math::fn_sub(DCStack<std::string> &stack, Parameters
|
|||
|
||||
// Check whether both entries are numbers
|
||||
if(is_x_num && is_y_num) {
|
||||
stack.copy_xyz();
|
||||
auto lhs = std::stod(stack.pop(true));
|
||||
auto rhs = std::stod(stack.pop(true));
|
||||
|
||||
|
@ -113,6 +115,7 @@ std::optional<std::string> Math::fn_mul(DCStack<std::string> &stack, Parameters
|
|||
|
||||
// Check whether both entries are numbers
|
||||
if(is_x_num && is_y_num) {
|
||||
stack.copy_xyz();
|
||||
auto lhs = std::stod(stack.pop(true));
|
||||
auto rhs = std::stod(stack.pop(true));
|
||||
|
||||
|
@ -140,6 +143,7 @@ std::optional<std::string> Math::fn_div(DCStack<std::string> &stack, Parameters
|
|||
|
||||
// Check whether both entries are numbers
|
||||
if(is_x_num && is_y_num) {
|
||||
stack.copy_xyz();
|
||||
auto divisor = std::stod(stack.pop(true));
|
||||
auto dividend = std::stod(stack.pop(true));
|
||||
|
||||
|
@ -172,6 +176,7 @@ std::optional<std::string> Math::fn_mod(DCStack<std::string> &stack, Parameters
|
|||
|
||||
// Check whether both entries are numbers
|
||||
if(is_x_num && is_y_num) {
|
||||
stack.copy_xyz();
|
||||
auto rhs = std::stod(stack.pop(true));
|
||||
auto lhs = std::stod(stack.pop(true));
|
||||
|
||||
|
@ -204,6 +209,7 @@ std::optional<std::string> Math::fn_div_mod(DCStack<std::string> &stack, Paramet
|
|||
|
||||
// Check whether both entries are numbers
|
||||
if(is_x_num && is_y_num) {
|
||||
stack.copy_xyz();
|
||||
auto divisor = std::stod(stack.pop(true));
|
||||
auto dividend = std::stod(stack.pop(true));
|
||||
|
||||
|
@ -243,6 +249,7 @@ std::optional<std::string> Math::fn_mod_exp(DCStack<std::string> &stack, Paramet
|
|||
// This functions computes
|
||||
// c ≡ b^e (mod n)
|
||||
if(is_n_num && is_e_num && is_b_num) {
|
||||
stack.copy_xyz();
|
||||
auto modulus = std::stoi(stack.pop(true));
|
||||
auto exponent = std::stoi(stack.pop(true));
|
||||
auto base = std::stoi(stack.pop(true));
|
||||
|
@ -286,6 +293,7 @@ std::optional<std::string> Math::fn_exp(DCStack<std::string> &stack, Parameters
|
|||
|
||||
// Check whether both entries are numbers
|
||||
if(is_x_num && is_y_num) {
|
||||
stack.copy_xyz();
|
||||
auto exp = std::stod(stack.pop(true));
|
||||
auto base = std::stod(stack.pop(true));
|
||||
|
||||
|
@ -311,6 +319,7 @@ std::optional<std::string> Math::fn_sqrt(DCStack<std::string> &stack, Parameters
|
|||
|
||||
// Check whether the entry is a number
|
||||
if(is_x_num) {
|
||||
stack.copy_xyz();
|
||||
auto val = std::stod(stack.pop(true));
|
||||
|
||||
if(val <= 0.0) {
|
||||
|
@ -339,6 +348,7 @@ std::optional<std::string> Math::fn_sin(DCStack<std::string> &stack, Parameters
|
|||
|
||||
// Check whether the entry is a number
|
||||
if(is_x_num) {
|
||||
stack.copy_xyz();
|
||||
auto val = std::stod(stack.pop(true));
|
||||
|
||||
// Push back the result as a string
|
||||
|
@ -363,6 +373,7 @@ std::optional<std::string> Math::fn_cos(DCStack<std::string> &stack, Parameters
|
|||
|
||||
// Check whether the entry is a number
|
||||
if(is_x_num) {
|
||||
stack.copy_xyz();
|
||||
auto val = std::stod(stack.pop(true));
|
||||
|
||||
// Push back the result as a string
|
||||
|
@ -387,6 +398,7 @@ std::optional<std::string> Math::fn_tan(DCStack<std::string> &stack, Parameters
|
|||
|
||||
// Check whether the entry is a number
|
||||
if(is_x_num) {
|
||||
stack.copy_xyz();
|
||||
auto val = std::stod(stack.pop(true));
|
||||
|
||||
// Push back the result as a string
|
||||
|
@ -411,6 +423,7 @@ std::optional<std::string> Math::fn_asin(DCStack<std::string> &stack, Parameters
|
|||
|
||||
// Check whether the entry is a number
|
||||
if(is_x_num) {
|
||||
stack.copy_xyz();
|
||||
auto val = std::stod(stack.pop(true));
|
||||
|
||||
// Push back the result as a string
|
||||
|
@ -435,6 +448,7 @@ std::optional<std::string> Math::fn_acos(DCStack<std::string> &stack, Parameters
|
|||
|
||||
// Check whether the entry is a number
|
||||
if(is_x_num) {
|
||||
stack.copy_xyz();
|
||||
auto val = std::stod(stack.pop(true));
|
||||
|
||||
// Push back the result as a string
|
||||
|
@ -459,6 +473,7 @@ std::optional<std::string> Math::fn_atan(DCStack<std::string> &stack, Parameters
|
|||
|
||||
// Check whether the entry is a number
|
||||
if(is_x_num) {
|
||||
stack.copy_xyz();
|
||||
auto val = std::stod(stack.pop(true));
|
||||
|
||||
// Push back the result as a string
|
||||
|
@ -483,6 +498,7 @@ std::optional<std::string> Math::fn_fact(DCStack<std::string> &stack, Parameters
|
|||
|
||||
// Check whether the entry is a number
|
||||
if(is_x_num) {
|
||||
stack.copy_xyz();
|
||||
unsigned long factorial = 1;
|
||||
auto val = std::stod(stack.pop(true));
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ enum class OPType {
|
|||
SQRT, SIN, COS, TAN, ASIN, ACOS, ATAN, FACT, PI, E,
|
||||
// Stack operations
|
||||
PCG, P, PBB, PBH, PBO, CLR, PH, SO, DP, PS, CH, CS,
|
||||
SP, GP, SOR, GOR, SIR, GIR,
|
||||
SP, GP, SOR, GOR, SIR, GIR, LX, LY, LZ,
|
||||
// Macro operations
|
||||
EX, CMP, RI
|
||||
};
|
||||
|
|
|
@ -37,6 +37,9 @@ std::optional<std::string> Stack::exec(DCStack<std::string> &stack, Parameters &
|
|||
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;
|
||||
case OPType::LX: err = fn_get_lastx(stack); break;
|
||||
case OPType::LY: err = fn_get_lasty(stack); break;
|
||||
case OPType::LZ: err = fn_get_lastz(stack); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
|
@ -91,6 +94,7 @@ std::optional<std::string> Stack::fn_pop_head(DCStack<std::string> &stack) {
|
|||
return "'R' does not work on empty stack";
|
||||
}
|
||||
|
||||
stack.copy_xyz();
|
||||
stack.pop(true);
|
||||
|
||||
return std::nullopt;
|
||||
|
@ -106,6 +110,7 @@ std::optional<std::string> Stack::fn_swap_xy(DCStack<std::string> &stack) {
|
|||
auto len = stack.size()-1;
|
||||
auto x = stack.at(len);
|
||||
|
||||
stack.copy_xyz();
|
||||
stack.at(len) = stack.at(len-1);
|
||||
stack.at(len-1) = x;
|
||||
|
||||
|
@ -170,6 +175,8 @@ std::optional<std::string> Stack::fn_head_size(DCStack<std::string> &stack) {
|
|||
// If it's an integer, count its digits
|
||||
if(is_num<int>(head)) {
|
||||
auto num = std::stoi(head);
|
||||
|
||||
stack.copy_xyz();
|
||||
stack.pop(true);
|
||||
|
||||
size_t len = 0;
|
||||
|
@ -181,6 +188,7 @@ std::optional<std::string> Stack::fn_head_size(DCStack<std::string> &stack) {
|
|||
stack.push(std::to_string(len));
|
||||
} else {
|
||||
// Otherwise, treat the value as a string and count its length
|
||||
stack.copy_xyz();
|
||||
stack.pop(true);
|
||||
head.erase(std::remove(head.begin(), head.end(), '.'), head.end());
|
||||
stack.push(std::to_string(head.length()));
|
||||
|
@ -209,6 +217,7 @@ std::optional<std::string> Stack::fn_set_precision(DCStack<std::string> &stack,
|
|||
|
||||
// Otherwise extract head of the stack and use it
|
||||
// to set precision parameter
|
||||
stack.copy_xyz();
|
||||
stack.pop(true);
|
||||
parameters.precision = std::stoi(head);
|
||||
|
||||
|
@ -228,7 +237,8 @@ std::optional<std::string> Stack::fn_set_oradix(DCStack<std::string> &stack, Par
|
|||
}
|
||||
|
||||
// Check whether the head is a number
|
||||
auto head = stack.pop(false);
|
||||
stack.copy_xyz();
|
||||
auto head = stack.pop(true);
|
||||
if(!is_num<int>(head)) {
|
||||
return "'o' requires numeric values only";
|
||||
}
|
||||
|
@ -266,6 +276,7 @@ std::optional<std::string> Stack::fn_set_iradix(DCStack<std::string> &stack, Par
|
|||
|
||||
// Otherwise extract head of the stack and use it
|
||||
// to set input base
|
||||
stack.copy_xyz();
|
||||
stack.pop(true);
|
||||
parameters.iradix = std::stoi(head);
|
||||
|
||||
|
@ -278,6 +289,30 @@ std::optional<std::string> Stack::fn_get_iradix(DCStack<std::string> &stack, Par
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Stack::fn_get_lastx(DCStack<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);
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Stack::fn_get_lasty(DCStack<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);
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> Stack::fn_get_lastz(DCStack<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);
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
constexpr std::string Stack::to_bin(auto num) {
|
||||
if(num == 0) {
|
||||
return "0";
|
||||
|
|
|
@ -21,6 +21,9 @@ private:
|
|||
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);
|
||||
constexpr std::string to_bin(auto num);
|
||||
|
||||
OPType op_type;
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
#!/bin/sh
|
||||
|
||||
utest() {
|
||||
PROGRAM="$PWD/build/dc"
|
||||
|
||||
# Test with arithmetical operations
|
||||
EXPECTED="4"
|
||||
ACTUAL=$("$PROGRAM" -e '5 4 + .x p')
|
||||
assert_eq "$EXPECTED" "$ACTUAL"
|
||||
|
||||
# Test with default value
|
||||
EXPECTED="0"
|
||||
ACTUAL=$("$PROGRAM" -e '.x p')
|
||||
assert_eq "$EXPECTED" "$ACTUAL"
|
||||
|
||||
# Test with macro opeartions
|
||||
EXPECTED="foo"
|
||||
ACTUAL=$("$PROGRAM" -e '[ foo ] sx .x p')
|
||||
assert_eq "$EXPECTED" "$ACTUAL"
|
||||
|
||||
# Test with stack operations
|
||||
EXPECTED="2"
|
||||
ACTUAL=$("$PROGRAM" -e '1 2 r .x p')
|
||||
assert_eq "$EXPECTED" "$ACTUAL"
|
||||
}
|
||||
# vim: ts=4 sw=4 softtabstop=4 expandtab:
|
|
@ -0,0 +1,26 @@
|
|||
#!/bin/sh
|
||||
|
||||
utest() {
|
||||
PROGRAM="$PWD/build/dc"
|
||||
|
||||
# Test with arithmetical operations
|
||||
EXPECTED="5"
|
||||
ACTUAL=$("$PROGRAM" -e '5 4 + .y p')
|
||||
assert_eq "$EXPECTED" "$ACTUAL"
|
||||
|
||||
# Test with default value
|
||||
EXPECTED="0"
|
||||
ACTUAL=$("$PROGRAM" -e '.y p')
|
||||
assert_eq "$EXPECTED" "$ACTUAL"
|
||||
|
||||
# Test with macro opeartions
|
||||
EXPECTED="6"
|
||||
ACTUAL=$("$PROGRAM" -e '6 [ foo ] sx sy .y p')
|
||||
assert_eq "$EXPECTED" "$ACTUAL"
|
||||
|
||||
# Test with stack operations
|
||||
EXPECTED="1"
|
||||
ACTUAL=$("$PROGRAM" -e '1 2 r .y p')
|
||||
assert_eq "$EXPECTED" "$ACTUAL"
|
||||
}
|
||||
# vim: ts=4 sw=4 softtabstop=4 expandtab:
|
|
@ -0,0 +1,26 @@
|
|||
#!/bin/sh
|
||||
|
||||
utest() {
|
||||
PROGRAM="$PWD/build/dc"
|
||||
|
||||
# Test with arithmetical operations
|
||||
EXPECTED="1"
|
||||
ACTUAL=$("$PROGRAM" -e '1 5 4 + + .z p')
|
||||
assert_eq "$EXPECTED" "$ACTUAL"
|
||||
|
||||
# Test with default value
|
||||
EXPECTED="0"
|
||||
ACTUAL=$("$PROGRAM" -e '.z p')
|
||||
assert_eq "$EXPECTED" "$ACTUAL"
|
||||
|
||||
# Test with macro opeartions
|
||||
EXPECTED="5"
|
||||
ACTUAL=$("$PROGRAM" -e '5 6 [ foo ] sx sy sz .z p')
|
||||
assert_eq "$EXPECTED" "$ACTUAL"
|
||||
|
||||
# Test with stack operations
|
||||
EXPECTED="10"
|
||||
ACTUAL=$("$PROGRAM" -e '10 1 2 R .z p')
|
||||
assert_eq "$EXPECTED" "$ACTUAL"
|
||||
}
|
||||
# vim: ts=4 sw=4 softtabstop=4 expandtab:
|
Loading…
Reference in New Issue