-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
618 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
Oops, something went wrong.