Compare commits

...

15 Commits

12 changed files with 344 additions and 0 deletions
+12
View File
@@ -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
+6
View File
@@ -0,0 +1,6 @@
#include "Operation.h"
Operation::Operation(const OpType type, int a, int b):
type{type}, a{a}, b{b}
{
}
+17
View File
@@ -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);
};
+67
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
+17
View File
@@ -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;
};
+91
View File
@@ -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};
}
+4
View File
@@ -0,0 +1,4 @@
#pragma once
#include "command.h"
Command resolveCommand();
+69
View File
@@ -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;
}
+7
View File
@@ -0,0 +1,7 @@
#include "special_calculator.h"
#include <cmath>
int SpecialCalculator::special(int a)
{
return sqrt(a);
}
+8
View File
@@ -0,0 +1,8 @@
#pragma once
#include "basecalc.h"
class SpecialCalculator: public BaseCalculator
{
int special(int a) override;
};