commit 01f094c49bb6a190ba4cff4af184bc0daf567285 Author: Alex Date: Wed Apr 1 22:17:05 2026 +0300 Initial commit diff --git a/Operation.cpp b/Operation.cpp new file mode 100644 index 0000000..b2c3447 --- /dev/null +++ b/Operation.cpp @@ -0,0 +1,6 @@ +#include "Operation.h" + +Operation::Operation(const OpType type, int a, int b): +type{type}, a{a}, b{b} +{ +} \ No newline at end of file diff --git a/Operation.h b/Operation.h new file mode 100644 index 0000000..efe6ccd --- /dev/null +++ b/Operation.h @@ -0,0 +1,15 @@ +enum class OpType +{ + Addition, Subtraction, Multiplication, Division, Modulo, Special +}; + +class Operation +{ + public: + int a; + int b; + OpType type; + + Operation(const OpType type, int a, int b = 0); + +}; \ No newline at end of file diff --git a/basecalc.cpp b/basecalc.cpp new file mode 100644 index 0000000..9fe6768 --- /dev/null +++ b/basecalc.cpp @@ -0,0 +1,54 @@ +#include "basecalc.h" + +BaseCalculator::~BaseCalculator() +{} + +int BaseCalculator::calculate(const Operation& op) +{ + switch(op.type) + { + case OpType::Addition: + result = op.a + op.b; + break; + + case OpType::Subtraction: + result = op.a - op.b; + break; + + case OpType::Multiplication: + result = op.a * op.b; + break; + + case OpType::Division: + result = op.a / op.b; + break; + + case OpType::Modulo: + result += op.a % op.b; + break; + + case OpType::Special: + result = special(op.a); + break; + + default: + result = 0; + } + return result; +} + +BaseCalculator::operator int() +{ + return result; +} + +int BaseCalculator::negate() +{ + result = -result; + return result; +} + +int BaseCalculator::special(int a) +{ + return a * a; +} diff --git a/basecalc.h b/basecalc.h new file mode 100644 index 0000000..a802ada --- /dev/null +++ b/basecalc.h @@ -0,0 +1,17 @@ +#include "Operation.h" +class BaseCalculator +{ + public: + + int calculate(const Operation& a); + + virtual ~BaseCalculator(); + + explicit operator int(); + + virtual int negate(); + virtual int special(int a); + + private: + int result = 0; +}; \ No newline at end of file diff --git a/command.cpp b/command.cpp new file mode 100644 index 0000000..0d4475c --- /dev/null +++ b/command.cpp @@ -0,0 +1,27 @@ +#include "command.h" + +Command::Command(bool shouldTerminate, char nextChar, int nextArg, bool shouldPrint): +m_shouldTerminate{shouldTerminate}, m_nextChar{nextChar}, m_nextArg{nextArg}, m_shouldPrint{shouldPrint} +{ + +} + +bool Command::shouldTerminate() const +{ + return m_shouldTerminate; +} + +char Command::getNextChar() +{ + return m_nextChar; +} + +int Command::getNextArg() +{ + return m_nextArg; +} + +bool Command::shouldPrint() const +{ + return m_shouldPrint; +} \ No newline at end of file diff --git a/command.h b/command.h new file mode 100644 index 0000000..a836c75 --- /dev/null +++ b/command.h @@ -0,0 +1,15 @@ +class Command +{ + public: + Command(bool shouldTerminate, char nextChar, int nextArg, bool shouldPrint); + bool shouldTerminate() const; + char getNextChar(); + int getNextArg(); + bool shouldPrint() const; + + private: + bool m_shouldTerminate; + char m_nextChar; + int m_nextArg; + bool m_shouldPrint; +}; \ No newline at end of file diff --git a/input_resolver.cpp b/input_resolver.cpp new file mode 100644 index 0000000..c7f6457 --- /dev/null +++ b/input_resolver.cpp @@ -0,0 +1,83 @@ +#include "input_resolver.h" +#include +#include + +#define delimiter " " + +struct ValidationResult +{ + bool ok() + { + return isItOk; + } + + char incorrect_token() + { + return in_t; + } + + int next_arg() + { + return nextArg; + } + + bool isItOk; + char in_t; + int nextArg; +}; + + +ValidationResult validate_token(const std::string &token) +{ + + static const std::string allowedTokens{"+-*/%$qp"}; + char incorrectToken; + size_t digitpos = -1, counter = 0; + + for (const char c: token) + { + if (allowedTokens.find(c) == allowedTokens.npos && !isdigit(c) && !isspace(c)) + return {false, c}; + + if (digitpos == -1 && isdigit(c)) + digitpos = counter; + + counter++; + } + + + if (digitpos == -1) + return {true, ' ', 0}; + + int next = stoi(token.substr(digitpos)); + return {true, ' ', next}; +} + +Command resolveCommand() +{ + std::string st; + getline(std::cin, st); + + std::string token = st.substr(0, st.find(delimiter)); + + auto validation_result = validate_token(token); + if (!validation_result.ok()) + { + throw std::runtime_error{"invalid token " + validation_result.incorrect_token()}; + } + + bool shouldQuit = token.find("q") != token.npos; + bool shouldPrint = token.find("p") != token.npos; + char operation; + + for (const char c: token) + { + static const std::string operators {"+-*/%"}; + if(operators.find(c) != operators.npos) + { + operation = c; + } + } + + return {shouldQuit, operation, validation_result.next_arg(), shouldPrint}; +} \ No newline at end of file diff --git a/input_resolver.h b/input_resolver.h new file mode 100644 index 0000000..3bbbbce --- /dev/null +++ b/input_resolver.h @@ -0,0 +1,2 @@ +#include "command.h" +Command resolveCommand(); \ No newline at end of file diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..b1b9359 --- /dev/null +++ b/main.cpp @@ -0,0 +1,68 @@ +#include +#include "basecalc.h" +#include +#include "input_resolver.h" + +int main() +{ + auto calc = std::make_unique(); + + std::cout << "Initializing calculator"; + + while (true) + { + std::cout << "What's your next input? (+,-,*,/,%,$,q,p)"; + auto command = resolveCommand(); + + if (command.shouldTerminate()) + { + break; + } + + switch(command.getNextChar()) + { + case '+': + { + calc->calculate({OpType::Addition, static_cast(*calc), command.getNextArg()}); + } + break; + + case '-': + { + calc->calculate({OpType::Subtraction, static_cast(*calc), command.getNextArg()}); + } + break; + + case '*': + { + calc->calculate({OpType::Multiplication, static_cast(*calc), command.getNextArg()}); + } + break; + + case '/': + { + calc->calculate({OpType::Division, static_cast(*calc), command.getNextArg()}); + } + break; + + case '%': + { + calc->calculate({OpType::Modulo, static_cast(*calc), command.getNextArg()}); + } + break; + + case '$': + { + calc->calculate({OpType::Special, static_cast(*calc)}); + } + + break; + } + + if(command.shouldPrint()) + std::cout << "Intermediary result: " << static_cast(*calc) << std::endl; + } + + std::cout << "Final output: " << static_cast(*calc) << std::endl; + return 0; +} \ No newline at end of file diff --git a/special_calculator.h b/special_calculator.h new file mode 100644 index 0000000..4bedb15 --- /dev/null +++ b/special_calculator.h @@ -0,0 +1,6 @@ +#include "basecalc.h" + +class SpecialCalculator: public BaseCalculator +{ + int special(int a) override; +}; \ No newline at end of file