Added 'zR' option and fixed bug related to registers
dc / build (push) Successful in 15s Details

This commit is contained in:
Marco Cetica 2024-03-25 16:27:28 +01:00
parent 5de860a089
commit 19ceac3e88
Signed by: marco
GPG Key ID: 45060A949E90D0FD
5 changed files with 69 additions and 6 deletions

8
man.md
View File

@ -367,6 +367,14 @@ The previous of the register becomes inaccessible, thus it follows the LIFO poli
Pop the value off the top of register _r_'s stack and push it onto the main stack. The previous value in register _r_'s stack, if any,
is now accessible via the **l**r command.
**c**`r`
Clear the register `r` from memory.
**z**`r`
Pushes the current register's stack depth: the number of objects on the register's stack before the execution of the **z**`r` command.
## Register(Array)
Arrays support random access through an index. You can store a value in an array and retrieve it later.

View File

@ -14,7 +14,8 @@
VAL.at(0) == '=' || VAL.at(0) == '!'))
#define REGISTER_COND(VAL) ((VAL.length() == 2) && \
(VAL.at(0) == 's' || VAL.at(0) == 'S' || \
VAL.at(0) == 'l' || VAL.at(0) == 'L'))
VAL.at(0) == 'l' || VAL.at(0) == 'L' || \
VAL.at(0) == 'c' || VAL.at(0) == 'z'))
#define ARRAY_COND(VAL) ((VAL.length() == 2) && \
(VAL.at(0) == ':' || VAL.at(0) == ';'))
@ -43,6 +44,8 @@ void Evaluate::init_environment() {
this->op_factory.emplace("e", MAKE_UNIQUE_PTR(Mathematics, OPType::E));
this->op_factory.emplace("@", MAKE_UNIQUE_PTR(Mathematics, OPType::RND));
this->op_factory.emplace("$", MAKE_UNIQUE_PTR(Mathematics, OPType::INT));
// Statistical operations
// Bitwise operations
this->op_factory.emplace("{", MAKE_UNIQUE_PTR(Bitwise, OPType::BAND));
this->op_factory.emplace("}", MAKE_UNIQUE_PTR(Bitwise, OPType::BOR));
@ -262,13 +265,17 @@ std::optional<std::string> Evaluate::parse_register_command(std::string token) {
auto reg_name = token.at(1);
auto head = this->stack.pop(true);
// if register's stack exist, overwrite top of the stack
// If register's stack exist, overwrite top of the stack
// Otherwise allocate a new instance of the register
auto it = this->regs.find(reg_name);
if(it != this->regs.end()) { // Register exist
auto head_idx = it->second.stack.size()-1;
it->second.stack[head_idx] = head;
// If register exists but stack is empty, push the first element
if(it->second.stack.empty()) {
it->second.stack.push(head);
} else {
auto head_idx = it->second.stack.size()-1;
it->second.stack[head_idx] = head;
}
} else { // Register does not exist
this->regs[reg_name] = dc::Register{
dc::Stack<std::string>(),
@ -322,7 +329,7 @@ std::optional<std::string> Evaluate::parse_register_command(std::string token) {
// Otherwise, pop an element from the register's stack and push it onto the main stack
auto value = this->regs[reg_name].stack.pop(true);
this->stack.push(value);
} else {
} else if(token.at(0) == 'l') {
// Otherwise retrieve the register name and push its value
// to the stack without altering the register's stack.
// If the register is empty, push '0' to the stack
@ -338,6 +345,17 @@ std::optional<std::string> Evaluate::parse_register_command(std::string token) {
// Otherwise, peek an element from the register's stack and push it onto the main stack
auto value = this->regs[reg_name].stack.pop(false);
this->stack.push(value);
} else if(token.at(0) == 'c') {
// Delete register from memory
auto reg_name = token.at(1);
this->regs.erase(reg_name);
} else if(token.at(0) == 'z') {
// Pushes register's stack size on main stack
auto reg_name = token.at(1);
auto size = std::to_string(this->regs[reg_name].stack.size());
this->stack.push(size);
} else {
return "Unmanaged error";
}
return std::nullopt;

View File

@ -14,6 +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, RND, INT,
// Statistical operations
PERM, COMB, SUMX, SUMXX, MEAN, SDEV, LREG,
// Bitwise operations
BAND, BOR, BNOT, BXOR, BSL, BSR,
// Stack operations

20
tests/test_creg Normal file
View File

@ -0,0 +1,20 @@
#!/bin/sh
utest() {
PROGRAM="$PWD/build/dc"
# Fill some values into the register
EXPECTED="1 2"
ACTUAL=$("$PROGRAM" -e '1 2 SA SA 2 0 :A lA p. 0 ;A p cA')
assert_eq "$EXPECTED" "$ACTUAL"
# Test whether the register stack is empty
EXPECTED="0"
ACTUAL=$("$PROGRAM" -e 'lA p')
assert_eq "$EXPECTED" "$ACTUAL"
# Test whether the register array is empty
EXPECTED="Register 'A' is undefined"
ACTUAL=$("$PROGRAM" -e '0 ;A' 2>&1) || true
assert_eq "$EXPECTED" "$ACTUAL"
}
# vim: ts=4 sw=4 softtabstop=4 expandtab:

15
tests/test_dreg Normal file
View File

@ -0,0 +1,15 @@
#!/bin/sh
utest() {
PROGRAM="$PWD/build/dc"
# Fill some values into the register
EXPECTED="4"
ACTUAL=$("$PROGRAM" -e '1 2 3 4 SA SA SA SA zA p')
assert_eq "$EXPECTED" "$ACTUAL"
# Test with empty register
EXPECTED="0"
ACTUAL=$("$PROGRAM" -e 'zA p')
assert_eq "$EXPECTED" "$ACTUAL"
}
# vim: ts=4 sw=4 softtabstop=4 expandtab: