Compare commits
15 Commits
4604e3afa1
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 110a292529 | |||
| 000629b937 | |||
| f651fcdb4c | |||
| 93da1771f4 | |||
| 1ef2665418 | |||
| 9c090bc317 | |||
| 8dda608d07 | |||
| 78ada5fbd4 | |||
| 688f490ec1 | |||
| 6f6ea77e69 | |||
| d366d15de3 | |||
| 06cee99f91 | |||
| eb7e3391c2 | |||
| d4790dfc4e | |||
| dd7178167d |
@@ -0,0 +1,12 @@
|
|||||||
|
all:
|
||||||
|
cc command.cpp input_resolver.cpp main.cpp -lstdc++ -std=c++17 -O3 -L./ -lCalc -o calculator
|
||||||
|
|
||||||
|
libs:
|
||||||
|
cc -c -fPIC basecalc.cpp Operation.cpp special_calculator.cpp
|
||||||
|
cc -shared basecalc.o Operation.o special_calculator.o -o libCalc.so
|
||||||
|
|
||||||
|
compile:
|
||||||
|
cc *.cpp -O3 -c
|
||||||
|
|
||||||
|
debug:
|
||||||
|
cc *.cpp -g -std=c++17 -o calculator -lstdc++ -lm
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#include "Operation.h"
|
||||||
|
|
||||||
|
Operation::Operation(const OpType type, int a, int b):
|
||||||
|
type{type}, a{a}, b{b}
|
||||||
|
{
|
||||||
|
}
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
};
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
#include "basecalc.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
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:
|
||||||
|
if (op.b == 0)
|
||||||
|
{
|
||||||
|
std::cerr << "Invalid operation requested! Resetting the accumulator to 0\n";
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
result = op.a / op.b;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OpType::Modulo:
|
||||||
|
if (op.b == 0)
|
||||||
|
{
|
||||||
|
std::cerr << "Invalid operation requested! Resetting the accumulator to 0\n";
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
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;
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#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;
|
||||||
|
};
|
||||||
+27
@@ -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;
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
#include "input_resolver.h"
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#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, token[0], 0};
|
||||||
|
|
||||||
|
int next = stoi(token.substr(digitpos));
|
||||||
|
return {true, token[0], 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())
|
||||||
|
{
|
||||||
|
std::ostringstream os;
|
||||||
|
os << "invalid token "<< validation_result.incorrect_token();
|
||||||
|
throw std::runtime_error{os.str()};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool shouldQuit = token.find("q") != token.npos;
|
||||||
|
bool shouldPrint = token.find("p") != token.npos;
|
||||||
|
char operation = 0;
|
||||||
|
|
||||||
|
for (const char c: token)
|
||||||
|
{
|
||||||
|
static const std::string operators {"+-*/%$"};
|
||||||
|
if(operators.find(c) != operators.npos)
|
||||||
|
{
|
||||||
|
operation = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (operation == 0)
|
||||||
|
{
|
||||||
|
operation = '+';
|
||||||
|
}
|
||||||
|
|
||||||
|
return {shouldQuit, operation, validation_result.next_arg(), shouldPrint};
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "command.h"
|
||||||
|
Command resolveCommand();
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include "basecalc.h"
|
||||||
|
#include "special_calculator.h"
|
||||||
|
#include <memory>
|
||||||
|
#include "input_resolver.h"
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
std::unique_ptr<BaseCalculator> calc = std::make_unique<SpecialCalculator>();
|
||||||
|
|
||||||
|
std::cout << "Initializing calculator\n";
|
||||||
|
|
||||||
|
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<int>(*calc), command.getNextArg()});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '-':
|
||||||
|
{
|
||||||
|
calc->calculate({OpType::Subtraction, static_cast<int>(*calc), command.getNextArg()});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '*':
|
||||||
|
{
|
||||||
|
calc->calculate({OpType::Multiplication, static_cast<int>(*calc), command.getNextArg()});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '/':
|
||||||
|
{
|
||||||
|
calc->calculate({OpType::Division, static_cast<int>(*calc), command.getNextArg()});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '%':
|
||||||
|
{
|
||||||
|
calc->calculate({OpType::Modulo, static_cast<int>(*calc), command.getNextArg()});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '$':
|
||||||
|
{
|
||||||
|
calc->calculate({OpType::Special, static_cast<int>(*calc)});
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(command.shouldPrint())
|
||||||
|
std::cout << "Intermediary result: " << static_cast<int>(*calc) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Final output: " << static_cast<int>(*calc) << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#include "special_calculator.h"
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
int SpecialCalculator::special(int a)
|
||||||
|
{
|
||||||
|
return sqrt(a);
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "basecalc.h"
|
||||||
|
|
||||||
|
class SpecialCalculator: public BaseCalculator
|
||||||
|
{
|
||||||
|
int special(int a) override;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user