Updated expression

This commit is contained in:
Rafał Grodziński
2025-06-04 00:51:17 +09:00
parent 84c1e823cb
commit 3ad912011c
4 changed files with 127 additions and 107 deletions

View File

@@ -1,52 +1,26 @@
#include "Expression.h" #include "Expression.h"
Expression::Expression(Kind kind, Token token, shared_ptr<Expression> left, shared_ptr<Expression> right): token(token) { Expression::Expression(Kind kind):
switch (kind) { kind(kind) {
case LITERAL:
setupLiteral(token);
break;
case GROUPING:
setupGrouping(token, left);
break;
case BINARY:
setupBinary(token, left, right);
break;
case INVALID:
break;
}
} }
void Expression::setupLiteral(Token token) { Expression::Kind Expression::getKind() {
bool isKindValid = token.isOfKind({Token::Kind::INTEGER}); return kind;
if (!isKindValid)
return;
kind = LITERAL;
integer = stoi(token.getLexme());
} }
void Expression::setupGrouping(Token token, shared_ptr<Expression> expression) { bool Expression::isValid() {
bool isKindValid = token.getKind() == Token::Kind::LEFT_PAREN; return kind != Expression::Kind::INVALID;
bool isExpressionValid = expression != nullptr && expression->getKind() != Kind::INVALID;
if (!isKindValid || !isExpressionValid)
return;
kind = GROUPING;
left = expression;
} }
void Expression::setupBinary(Token token, shared_ptr<Expression> left, shared_ptr<Expression> right) { string Expression::toString() {
bool isKindValid = token.isOfKind({Token::Kind::PLUS, Token::Kind::MINUS, Token::Kind::STAR, Token::Kind::SLASH, Token::Kind::PERCENT}); return "EXPRESSION";
bool isLeftValid = left != nullptr && left->getKind() != Kind::INVALID; }
bool isRightValid = right != nullptr && right->getKind() != Kind::INVALID;
if (!isKindValid || !isLeftValid || !isRightValid) //
return; // ExpressionBinary
ExpressionBinary::ExpressionBinary(shared_ptr<Token> token, shared_ptr<Expression> left, shared_ptr<Expression> right):
kind = BINARY; Expression(Expression::Kind::BINARY), left(left), right(right) {
switch (token->getKind()) {
switch (token.getKind()) {
case Token::Kind::PLUS: case Token::Kind::PLUS:
operation = ADD; operation = ADD;
break; break;
@@ -62,66 +36,77 @@ void Expression::setupBinary(Token token, shared_ptr<Expression> left, shared_pt
case Token::Kind::PERCENT: case Token::Kind::PERCENT:
operation = MOD; operation = MOD;
break; break;
case Token::Kind::INVALID:
break;
default: default:
exit(1); exit(1);
} }
this->left = left;
this->right = right;
} }
Expression::Kind Expression::getKind() { ExpressionBinary::Operation ExpressionBinary::getOperation() {
return kind;
}
Token Expression::getToken() {
return token;
}
int64_t Expression::getInteger() {
return integer;
}
Expression::Operator Expression::getOperator() {
return operation; return operation;
} }
shared_ptr<Expression> Expression::getLeft() { shared_ptr<Expression> ExpressionBinary::getLeft() {
return left; return left;
} }
shared_ptr<Expression> Expression::getRight() { shared_ptr<Expression> ExpressionBinary::getRight() {
return right; return right;
} }
bool Expression::isValid() { string ExpressionBinary::toString() {
return kind != Expression::Kind::INVALID; 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 "</ " + left->toString() + " " + right->toString() + ">";
case MOD:
return "<% " + left->toString() + " " + right->toString() + ">";
}
} }
string Expression::toString() { //
switch (kind) { // ExpressionLiteral
case LITERAL: ExpressionLiteral::ExpressionLiteral(shared_ptr<Token> token):
return to_string(integer); Expression(Expression::Kind::LITERAL) {
case GROUPING: integer = stoi(token->getLexme());
return "<( " + left->toString() + " )>"; }
case BINARY:
switch (operation) { int64_t ExpressionLiteral::getInteger() {
case ADD: return integer;
return "<+ " + left->toString() + " " + right->toString() + ">"; }
case SUB:
return "<- " + left->toString() + " " + right->toString() + ">"; string ExpressionLiteral::toString() {
case MUL: return to_string(integer);
return "<* " + left->toString() + " " + right->toString() + ">"; }
case DIV:
return "</ " + left->toString() + " " + right->toString() + ">"; //
case MOD: // ExpressionGrouping
return "<% " + left->toString() + " " + right->toString() + ">"; ExpressionGrouping::ExpressionGrouping(shared_ptr<Expression> expression):
case NONE: Expression(Expression::Kind::GROUPING), expression(expression) {
return "NONE"; }
}
case INVALID: shared_ptr<Expression> ExpressionGrouping::getExpression() {
return "INVALID"; return expression;
} }
string ExpressionGrouping::toString() {
return "<( " + expression->toString() + " )>";
}
//
// ExpressionInvalid
ExpressionInvalid::ExpressionInvalid(shared_ptr<Token> token):
Expression(Expression::Kind::INVALID), token(token) {
}
shared_ptr<Token> ExpressionInvalid::getToken() {
return token;
}
string ExpressionInvalid::toString() {
return "Invalid token " + token->toString() + " at " + to_string(token->getLine()) + ":" + to_string(token->getColumn()) + "\n";
} }

View File

@@ -14,37 +14,67 @@ public:
INVALID 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, ADD,
SUB, SUB,
MUL, MUL,
DIV, DIV,
MOD, MOD
NONE
}; };
private: private:
Kind kind = INVALID; Operation operation;
Token token; shared_ptr<Expression> left;
int64_t integer = 0; shared_ptr<Expression> right;
Operator operation = NONE;
shared_ptr<Expression> left = nullptr;
shared_ptr<Expression> right = nullptr;
void setupLiteral(Token token);
void setupGrouping(Token token, shared_ptr<Expression> expression);
void setupBinary(Token token, shared_ptr<Expression> left, shared_ptr<Expression> right);
public: public:
Expression(Kind kind, Token token, shared_ptr<Expression> left, shared_ptr<Expression> right); ExpressionBinary(shared_ptr<Token> token, shared_ptr<Expression> left, shared_ptr<Expression> right);
Kind getKind(); Operation getOperation();
Token getToken();
int64_t getInteger();
Operator getOperator();
shared_ptr<Expression> getLeft(); shared_ptr<Expression> getLeft();
shared_ptr<Expression> getRight(); shared_ptr<Expression> getRight();
bool isValid(); string toString() override;
string toString(); };
class ExpressionLiteral: public Expression {
private:
int64_t integer = 0;
public:
ExpressionLiteral(shared_ptr<Token> token);
int64_t getInteger();
string toString() override;
};
class ExpressionGrouping: public Expression {
private:
shared_ptr<Expression> expression;
public:
ExpressionGrouping(shared_ptr<Expression> expression);
shared_ptr<Expression> getExpression();
string toString() override;
};
class ExpressionInvalid: public Expression {
private:
shared_ptr<Token> token;
public:
ExpressionInvalid(shared_ptr<Token> token);
shared_ptr<Token> getToken();
string toString() override;
}; };
#endif #endif

View File

@@ -123,7 +123,7 @@ shared_ptr<StatementInvalid> Parser::matchStatementInvalid() {
// Expression // Expression
// //
shared_ptr<Expression> Parser::nextExpression() { shared_ptr<Expression> Parser::nextExpression() {
return nullptr; return matchExpressionInvalid();
} }
/*shared_ptr<Expression> Parser::term() { /*shared_ptr<Expression> Parser::term() {
@@ -207,6 +207,10 @@ shared_ptr<Expression> Parser::matchBinary(shared_ptr<Expression> left) {
return make_shared<Expression>(Expression::Kind::INVALID, token, nullptr, nullptr); return make_shared<Expression>(Expression::Kind::INVALID, token, nullptr, nullptr);
}*/ }*/
shared_ptr<ExpressionInvalid> Parser::matchExpressionInvalid() {
return make_shared<ExpressionInvalid>(tokens.at(currentIndex));
}
bool Parser::matchesTokenKinds(vector<Token::Kind> kinds) { bool Parser::matchesTokenKinds(vector<Token::Kind> kinds) {
if (currentIndex + kinds.size() >= tokens.size()) if (currentIndex + kinds.size() >= tokens.size())
return false; return false;

View File

@@ -29,6 +29,7 @@ private:
shared_ptr<Expression> matchInteger(); shared_ptr<Expression> matchInteger();
shared_ptr<Expression> matchGrouping(); shared_ptr<Expression> matchGrouping();
shared_ptr<Expression> matchBinary(shared_ptr<Expression> left);*/ shared_ptr<Expression> matchBinary(shared_ptr<Expression> left);*/
shared_ptr<ExpressionInvalid> matchExpressionInvalid();
bool matchesTokenKinds(vector<Token::Kind> kinds); bool matchesTokenKinds(vector<Token::Kind> kinds);