Added grouping

This commit is contained in:
Rafał Grodziński
2025-05-31 20:54:25 +09:00
parent c6f2156e3b
commit 2b78b5bf23
6 changed files with 38 additions and 2 deletions

View File

@@ -7,6 +7,8 @@ Expression::Expression(Kind kind, Token token, shared_ptr<Expression> left, shar
case LITERAL: case LITERAL:
setupLiteral(token); setupLiteral(token);
break; break;
case GROUPING:
setupGrouping(token, left);
case BINARY: case BINARY:
setupBinary(token, left, right); setupBinary(token, left, right);
break; break;
@@ -24,6 +26,17 @@ void Expression::setupLiteral(Token token) {
integer = stoi(token.getLexme()); integer = stoi(token.getLexme());
} }
void Expression::setupGrouping(Token token, shared_ptr<Expression> 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;
}
void Expression::setupBinary(Token token, shared_ptr<Expression> left, shared_ptr<Expression> right) { void Expression::setupBinary(Token token, shared_ptr<Expression> left, shared_ptr<Expression> right) {
bool isKindValid = token.isOneOf({Token::Kind::PLUS, Token::Kind::MINUS, Token::Kind::STAR, Token::Kind::SLASH, Token::Kind::PERCENT}); bool isKindValid = token.isOneOf({Token::Kind::PLUS, Token::Kind::MINUS, Token::Kind::STAR, Token::Kind::SLASH, Token::Kind::PERCENT});
bool isLeftValid = left != nullptr && left->getKind() != Kind::INVALID; bool isLeftValid = left != nullptr && left->getKind() != Kind::INVALID;
@@ -90,6 +103,8 @@ std::string Expression::toString() {
switch (kind) { switch (kind) {
case LITERAL: case LITERAL:
return to_string(integer); return to_string(integer);
case GROUPING:
return "<( " + left->toString() + " )>";
case BINARY: case BINARY:
switch (operation) { switch (operation) {
case ADD: case ADD:

View File

@@ -9,6 +9,7 @@ class Expression {
public: public:
enum Kind { enum Kind {
LITERAL, LITERAL,
GROUPING,
BINARY, BINARY,
INVALID INVALID
}; };
@@ -30,6 +31,7 @@ private:
shared_ptr<Expression> right = nullptr; shared_ptr<Expression> right = nullptr;
void setupLiteral(Token token); void setupLiteral(Token token);
void setupGrouping(Token token, shared_ptr<Expression> expression);
void setupBinary(Token token, shared_ptr<Expression> left, shared_ptr<Expression> right); void setupBinary(Token token, shared_ptr<Expression> left, shared_ptr<Expression> right);
public: public:

View File

@@ -16,6 +16,8 @@ llvm::Value *ModuleBuilder::valueForExpression(shared_ptr<Expression> expression
switch (expression->getKind()) { switch (expression->getKind()) {
case Expression::Kind::LITERAL: case Expression::Kind::LITERAL:
return llvm::ConstantInt::get(int32Type, expression->getInteger(), true); return llvm::ConstantInt::get(int32Type, expression->getInteger(), true);
case Expression::Kind::GROUPING:
return valueForExpression(expression->getLeft());
case Expression::Kind::BINARY: case Expression::Kind::BINARY:
llvm::Value *leftValue = valueForExpression(expression->getLeft()); llvm::Value *leftValue = valueForExpression(expression->getLeft());
llvm::Value *rightValue = valueForExpression(expression->getRight()); llvm::Value *rightValue = valueForExpression(expression->getRight());

View File

@@ -34,6 +34,8 @@ shared_ptr<Expression> Parser::primary() {
if((expression = matchInteger()) != Expression::Invalid) if((expression = matchInteger()) != Expression::Invalid)
break; break;
if((expression = matchGrouping()) != Expression::Invalid)
break;
} while(false); } while(false);
return expression; return expression;
@@ -49,6 +51,20 @@ shared_ptr<Expression> Parser::matchInteger() {
return Expression::Invalid; return Expression::Invalid;
} }
shared_ptr<Expression> Parser::matchGrouping() {
Token token = tokens.at(currentIndex);
if (token.getKind() == Token::Kind::LEFT_PAREN) {
currentIndex++;
shared_ptr<Expression> expression = term();
if (tokens.at(currentIndex).getKind() == Token::Kind::RIGHT_PAREN) {
currentIndex++;
return make_shared<Expression>(Expression::Kind::GROUPING, token, expression, nullptr);
}
}
return Expression::Invalid;
}
shared_ptr<Expression> Parser::matchBinary(shared_ptr<Expression> left) { shared_ptr<Expression> Parser::matchBinary(shared_ptr<Expression> left) {
Token token = tokens.at(currentIndex); Token token = tokens.at(currentIndex);
if (token.isOneOf({Token::Kind::PLUS, Token::Kind::MINUS, Token::Kind::STAR, Token::Kind::SLASH, Token::Kind::PERCENT})) { if (token.isOneOf({Token::Kind::PLUS, Token::Kind::MINUS, Token::Kind::STAR, Token::Kind::SLASH, Token::Kind::PERCENT})) {

View File

@@ -17,6 +17,7 @@ private:
shared_ptr<Expression> primary(); shared_ptr<Expression> primary();
shared_ptr<Expression> matchInteger(); shared_ptr<Expression> matchInteger();
shared_ptr<Expression> matchGrouping();
shared_ptr<Expression> matchBinary(shared_ptr<Expression> left); shared_ptr<Expression> matchBinary(shared_ptr<Expression> left);
public: public:

View File

@@ -43,7 +43,7 @@ std::string Token::toString() {
case PERCENT: case PERCENT:
return "PERCENT"; return "PERCENT";
case LEFT_PAREN: case LEFT_PAREN:
return "LEFT_PARENT"; return "LEFT_PAREN";
case RIGHT_PAREN: case RIGHT_PAREN:
return "RIGHT_PAREN"; return "RIGHT_PAREN";
case DOT: case DOT: