Skip to content

Commit

Permalink
initial pol calc
Browse files Browse the repository at this point in the history
  • Loading branch information
visper committed Dec 19, 2019
1 parent e67a5dd commit 456cebe
Show file tree
Hide file tree
Showing 15 changed files with 618 additions and 6 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ project(dummy_cmake_project)
set(CMAKE_CXX_STANDARD 14)
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)

set(SOURCES project.cc)
set(SOURCES project.cc Parser.cpp Token.cpp Stack.cpp Calculator.cpp executor.cpp)
add_library(ProjectLib ${SOURCES})

add_executable(project main.cc)
add_executable(project main.cc Parser.cpp Token.cpp Stack.cpp Calculator.cpp executor.cpp)
target_link_libraries(project ProjectLib)

enable_testing()
Expand Down
49 changes: 49 additions & 0 deletions Calculator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include "Calculator.h"
#include <iostream>

Calculator::Calculator(Stack &stk) : stk_(stk)
{}

double Calculator::exe() {

std::vector<long double> numbers;
double rec = 0;
for(;;) {
int rc;
Token t = stk_.pop(rc);
if(t.is_number()) {
numbers.push_back(t.getNumber());
} else { //operation

long double result = numbers[0];
for(int i = 1; i < numbers.size(); ++i) {

switch (t.getOperand()) {
case TOper::ADD:
result += numbers[i];
break;
case TOper::SUB:
result -= numbers[i];
break;
case TOper::MUL:
result *= numbers[i];
break;
case TOper::DIV:
result /= numbers[i];
break;
default:
std::cout << "exe error" << std::endl;
break;
}
}
numbers.clear();
Token nt(true, TOper::NONE, result);
stk_.push(nt);
std::cout << result << std::endl;
rec = result;
}

if(!rc) break;
}
return rec;
}
16 changes: 16 additions & 0 deletions Calculator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#ifndef CALCULATOR_H
#define CALCULATOR_H

#include "Stack.h"

class Calculator
{
public:
Calculator(Stack &stk);
double exe();///TODO rename execute

private:
Stack stk_;
};

#endif // CALCULATOR_H
49 changes: 49 additions & 0 deletions Parser.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include "Parser.h"

#include <iostream> //just for test
#include <string>

Parser::Parser(const std::vector <std::string>& line)
: rawLines(line)
, currentPosition(0)
{}

void Parser::parse()
{
for(size_t i = 0; i < rawLines.size(); ++i) {
currentPosition = i+1;
//check for operator
///TODO: check Factory applicance
if(rawLines[i] == std::string("+")) {
Token t(TOper::ADD);
tokens.push_back(t);
} else if (rawLines[i] == std::string("-")) {
Token t(TOper::SUB);
tokens.push_back(t);
} else if (rawLines[i] == std::string("*")) {
Token t(TOper::MUL);
tokens.push_back(t);
} else if (rawLines[i] == std::string("/")) {
Token t(TOper::DIV);
tokens.push_back(t);
} else { //check for number
long double dd;
// try {
dd = std::stod (rawLines[i]);
//try to throw position also
// } catch (...) {
// std::cerr << "wrong data on " << i+1
// << " position" << std::endl;
// return;
// }

Token t(dd);
tokens.push_back(t);
}
}
}

const std::vector<Token> &Parser::getTokens()
{
return tokens;
}
20 changes: 20 additions & 0 deletions Parser.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef PARSER_H
#define PARSER_H

#include "Token.h"
#include <vector>

class Parser
{
public:
Parser(const std::vector <std::string>& line);
void parse();
const std::vector<Token>& getTokens();
size_t getPositionOfErrorInRawLine() const;
private:
std::vector<Token> tokens;
std::vector <std::string> rawLines;
size_t currentPosition;
};

#endif // PARSER_H
45 changes: 45 additions & 0 deletions Stack.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include "Stack.h"
#include <iostream>

Stack::Stack(const std::vector<Token>& t) : size(0) /*: size(t.size()) */ //init vector
{
//for(int i = size-1; i >= 0; --i) {
for(int i = t.size()-1; i >= 0; --i) {
push(t[i]);
}
}

Stack::~Stack()
{
size = 0;
stk.clear();
}

int Stack::getSize() const
{
return size;
}

void Stack::push(const Token& elem)
{
if ( stk.size() <= size ) { // here size must be added after compate
stk.push_back(elem);
++size;
} else
std::cout << "stack is full" << std::endl;
}

Token Stack::pop(int &rc)
{
rc = 1;
if ( stk.empty() ) {
std::cout << "stack is empty" << std::endl;
//return -EINVAL;
rc = 0;
} else {
Token temp = stk.back();
stk.pop_back();
--size;
return temp;
}
}
22 changes: 22 additions & 0 deletions Stack.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#ifndef STACK_H
#define STACK_H

#include <stdint.h>
#include <vector>
#include "Token.h"

///TODO:namespace
class Stack {
int size;
std::vector<Token> stk;
public:
///TODO: stack is stack. do adapter for stack with Token
Stack(const std::vector<Token>& t);
~Stack();
void push(const Token& elem);
Token pop(int &rc); ///TODO: think about another one interface
int getSize() const;
};


#endif // STACK_H
40 changes: 40 additions & 0 deletions Token.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include "Token.h"

Token::Token(const bool is_number, const TOper::Operand opr, const long double num)
: is_num(is_number)
{
if(is_num) {
d = num;
this->opr = TOper::NONE;
} else {
this->opr = opr;
d = 0; //default
}
}

Token::Token(const long double num)
: is_num(true)
, d(num)
, opr(TOper::NONE)
{}

Token::Token(const TOper::Operand opr)
: is_num(false)
, d(0)
, opr(opr)
{}

TOper::Operand Token::getOperand()
{
return opr;
}

long double Token::getNumber()
{
return d;
}

bool Token::is_number()
{
return is_num;
}
36 changes: 36 additions & 0 deletions Token.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#ifndef TOKEN_H
#define TOKEN_H

#include <string>

namespace TOper {

///TODO: rename
///TODO: enum class
enum Operand {
ADD,
SUB,
DIV,
MUL,
NONE
};

}

class Token
{
public:
///TODO: split to different constructors
Token(const bool is_number, const TOper::Operand opr, const long double num);
Token(const long double num);
Token(const TOper::Operand opr);
bool is_number();
TOper::Operand getOperand();
long double getNumber();
private:
long double d;
TOper::Operand opr;
bool is_num;
};

#endif // TOKEN_H
16 changes: 16 additions & 0 deletions executor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include "executor.h"

#include "Parser.h"
#include "Stack.h"
#include "Calculator.h"
#include "executor.h"

double execute(const std::vector <std::string>& src)
{
Parser p(src);
p.parse();
Stack stk(p.getTokens());
//std::cout << "test" << std::endl;
Calculator calc(stk);
return calc.exe();
}
9 changes: 9 additions & 0 deletions executor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef EXECUTOR_H
#define EXECUTOR_H

#include <vector>
#include <string>
///TODO: namespace wrrap
double execute(const std::vector <std::string>& src);

#endif // EXECUTOR_H
63 changes: 61 additions & 2 deletions main.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,64 @@
#include "project.h"

int main() {
return 0;
#include "executor.h"

#include <iostream>
#include <vector>
#include <string>
using namespace std; // test

/*
* The calculator input is double numbers, operators + - * /
* The maximum input line is 255
*
* */

static int show_usage()
{
std::cerr << "Usage: <option(s)> || <valid arguments>"
<< "Options:\n"
<< "\t-h,--help\t\tShow this help message\n"
<< "Valid arguments:\n"
<< "\tSpecify target string after program name\n"
<< "\tNumbers with point and operations + - / * with space separation"
<< std::endl;
return -1;
}

int main(int argc, char** argv) {

try {
if (argc < 2 /*|| argc >= 12*/) {
show_usage();
return 1;
}

std::vector <std::string> sources;
for (int i = 1; i < argc; ++i) {
std::string arg = argv[i];
if ((arg == "-h") || (arg == "--help")) {
show_usage();
return 0;
} else {
sources.push_back(arg);
}
}

execute(sources);
} catch (const std::invalid_argument& e) {
std::cout << "std::invalid_argument" << std::endl;
show_usage();
} catch (const std::out_of_range& e) {
std::cout << "std::out_of_range" << std::endl;
show_usage();
} catch (...) {
/*
If no conversion could be performed, an invalid_argument exception is thrown.
If the value read is out of the range of representable values by a double (in some library implementations, this includes underflows), an out_of_range exception is thrown.
*/

show_usage();
}

return 0;
}
Loading

0 comments on commit 456cebe

Please sign in to comment.