diff --git a/src/Expression.cpp b/src/Expression.cpp index 4eadd62..9b309dc 100644 --- a/src/Expression.cpp +++ b/src/Expression.cpp @@ -1,52 +1,26 @@ #include "Expression.h" -Expression::Expression(Kind kind, Token token, shared_ptr left, shared_ptr right): token(token) { - switch (kind) { - case LITERAL: - setupLiteral(token); - break; - case GROUPING: - setupGrouping(token, left); - break; - case BINARY: - setupBinary(token, left, right); - break; - case INVALID: - break; - } +Expression::Expression(Kind kind): + kind(kind) { } -void Expression::setupLiteral(Token token) { - bool isKindValid = token.isOfKind({Token::Kind::INTEGER}); - if (!isKindValid) - return; - - kind = LITERAL; - integer = stoi(token.getLexme()); +Expression::Kind Expression::getKind() { + return kind; } -void Expression::setupGrouping(Token token, shared_ptr expression) { - bool isKindValid = token.getKind() == Token::Kind::LEFT_PAREN; - bool isExpressionValid = expression != nullptr && expression->getKind() != Kind::INVALID; - - if (!isKindValid || !isExpressionValid) - return; - - kind = GROUPING; - left = expression; +bool Expression::isValid() { + return kind != Expression::Kind::INVALID; } -void Expression::setupBinary(Token token, shared_ptr left, shared_ptr right) { - bool isKindValid = token.isOfKind({Token::Kind::PLUS, Token::Kind::MINUS, Token::Kind::STAR, Token::Kind::SLASH, Token::Kind::PERCENT}); - bool isLeftValid = left != nullptr && left->getKind() != Kind::INVALID; - bool isRightValid = right != nullptr && right->getKind() != Kind::INVALID; +string Expression::toString() { + return "EXPRESSION"; +} - if (!isKindValid || !isLeftValid || !isRightValid) - return; - - kind = BINARY; - - switch (token.getKind()) { +// +// ExpressionBinary +ExpressionBinary::ExpressionBinary(shared_ptr token, shared_ptr left, shared_ptr right): + Expression(Expression::Kind::BINARY), left(left), right(right) { + switch (token->getKind()) { case Token::Kind::PLUS: operation = ADD; break; @@ -62,66 +36,77 @@ void Expression::setupBinary(Token token, shared_ptr left, shared_pt case Token::Kind::PERCENT: operation = MOD; break; - case Token::Kind::INVALID: - break; default: exit(1); } - - this->left = left; - this->right = right; } -Expression::Kind Expression::getKind() { - return kind; -} - -Token Expression::getToken() { - return token; -} - -int64_t Expression::getInteger() { - return integer; -} - -Expression::Operator Expression::getOperator() { +ExpressionBinary::Operation ExpressionBinary::getOperation() { return operation; } -shared_ptr Expression::getLeft() { +shared_ptr ExpressionBinary::getLeft() { return left; } -shared_ptr Expression::getRight() { +shared_ptr ExpressionBinary::getRight() { return right; } -bool Expression::isValid() { - return kind != Expression::Kind::INVALID; +string ExpressionBinary::toString() { + switch (operation) { + case ADD: + return "<+ " + left->toString() + " " + right->toString() + ">"; + case SUB: + return "<- " + left->toString() + " " + right->toString() + ">"; + case MUL: + return "<* " + left->toString() + " " + right->toString() + ">"; + case DIV: + return "toString() + " " + right->toString() + ">"; + case MOD: + return "<% " + left->toString() + " " + right->toString() + ">"; + } } -string Expression::toString() { - switch (kind) { - case LITERAL: - return to_string(integer); - case GROUPING: - return "<( " + left->toString() + " )>"; - case BINARY: - switch (operation) { - case ADD: - return "<+ " + left->toString() + " " + right->toString() + ">"; - case SUB: - return "<- " + left->toString() + " " + right->toString() + ">"; - case MUL: - return "<* " + left->toString() + " " + right->toString() + ">"; - case DIV: - return "toString() + " " + right->toString() + ">"; - case MOD: - return "<% " + left->toString() + " " + right->toString() + ">"; - case NONE: - return "NONE"; - } - case INVALID: - return "INVALID"; - } +// +// ExpressionLiteral +ExpressionLiteral::ExpressionLiteral(shared_ptr token): + Expression(Expression::Kind::LITERAL) { + integer = stoi(token->getLexme()); +} + +int64_t ExpressionLiteral::getInteger() { + return integer; +} + +string ExpressionLiteral::toString() { + return to_string(integer); +} + +// +// ExpressionGrouping +ExpressionGrouping::ExpressionGrouping(shared_ptr expression): + Expression(Expression::Kind::GROUPING), expression(expression) { +} + +shared_ptr ExpressionGrouping::getExpression() { + return expression; +} + +string ExpressionGrouping::toString() { + return "<( " + expression->toString() + " )>"; +} + +// +// ExpressionInvalid +ExpressionInvalid::ExpressionInvalid(shared_ptr token): + Expression(Expression::Kind::INVALID), token(token) { +} + +shared_ptr ExpressionInvalid::getToken() { + return token; +} + +string ExpressionInvalid::toString() { + return "Invalid token " + token->toString() + " at " + to_string(token->getLine()) + ":" + to_string(token->getColumn()) + "\n"; } \ No newline at end of file diff --git a/src/Expression.h b/src/Expression.h index cde03aa..e4547bc 100644 --- a/src/Expression.h +++ b/src/Expression.h @@ -14,37 +14,67 @@ public: INVALID }; - enum Operator { +private: + Kind kind; + +public: + Expression(Kind kind); + Kind getKind(); + bool isValid(); + virtual string toString(); +}; + +class ExpressionBinary: public Expression { +public: + enum Operation { ADD, SUB, MUL, DIV, - MOD, - NONE + MOD }; private: - Kind kind = INVALID; - Token token; - int64_t integer = 0; - Operator operation = NONE; - shared_ptr left = nullptr; - shared_ptr right = nullptr; - - void setupLiteral(Token token); - void setupGrouping(Token token, shared_ptr expression); - void setupBinary(Token token, shared_ptr left, shared_ptr right); + Operation operation; + shared_ptr left; + shared_ptr right; public: - Expression(Kind kind, Token token, shared_ptr left, shared_ptr right); - Kind getKind(); - Token getToken(); - int64_t getInteger(); - Operator getOperator(); + ExpressionBinary(shared_ptr token, shared_ptr left, shared_ptr right); + Operation getOperation(); shared_ptr getLeft(); shared_ptr getRight(); - bool isValid(); - string toString(); + string toString() override; +}; + +class ExpressionLiteral: public Expression { +private: + int64_t integer = 0; + +public: + ExpressionLiteral(shared_ptr token); + int64_t getInteger(); + string toString() override; +}; + +class ExpressionGrouping: public Expression { +private: + shared_ptr expression; + +public: + ExpressionGrouping(shared_ptr expression); + shared_ptr getExpression(); + string toString() override; +}; + +class ExpressionInvalid: public Expression { +private: + shared_ptr token; + +public: + ExpressionInvalid(shared_ptr token); + shared_ptr getToken(); + string toString() override; }; #endif \ No newline at end of file diff --git a/src/Parser.cpp b/src/Parser.cpp index 8cf23f0..600d848 100644 --- a/src/Parser.cpp +++ b/src/Parser.cpp @@ -123,7 +123,7 @@ shared_ptr Parser::matchStatementInvalid() { // Expression // shared_ptr Parser::nextExpression() { - return nullptr; + return matchExpressionInvalid(); } /*shared_ptr Parser::term() { @@ -207,6 +207,10 @@ shared_ptr Parser::matchBinary(shared_ptr left) { return make_shared(Expression::Kind::INVALID, token, nullptr, nullptr); }*/ +shared_ptr Parser::matchExpressionInvalid() { + return make_shared(tokens.at(currentIndex)); +} + bool Parser::matchesTokenKinds(vector kinds) { if (currentIndex + kinds.size() >= tokens.size()) return false; diff --git a/src/Parser.h b/src/Parser.h index 6749622..3675d09 100644 --- a/src/Parser.h +++ b/src/Parser.h @@ -29,6 +29,7 @@ private: shared_ptr matchInteger(); shared_ptr matchGrouping(); shared_ptr matchBinary(shared_ptr left);*/ + shared_ptr matchExpressionInvalid(); bool matchesTokenKinds(vector kinds);