diff --git a/src/Expression.cpp b/src/Expression.cpp index 36f5872..5895b7b 100644 --- a/src/Expression.cpp +++ b/src/Expression.cpp @@ -7,6 +7,8 @@ Expression::Expression(Kind kind, Token token, shared_ptr left, shar case LITERAL: setupLiteral(token); break; + case GROUPING: + setupGrouping(token, left); case BINARY: setupBinary(token, left, right); break; @@ -24,6 +26,17 @@ void Expression::setupLiteral(Token token) { integer = stoi(token.getLexme()); } +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; +} + void Expression::setupBinary(Token token, shared_ptr left, shared_ptr right) { 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; @@ -90,6 +103,8 @@ std::string Expression::toString() { switch (kind) { case LITERAL: return to_string(integer); + case GROUPING: + return "<( " + left->toString() + " )>"; case BINARY: switch (operation) { case ADD: diff --git a/src/Expression.h b/src/Expression.h index bbb0e5a..d93ecc3 100644 --- a/src/Expression.h +++ b/src/Expression.h @@ -9,6 +9,7 @@ class Expression { public: enum Kind { LITERAL, + GROUPING, BINARY, INVALID }; @@ -30,6 +31,7 @@ private: 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); public: diff --git a/src/ModuleBuilder.cpp b/src/ModuleBuilder.cpp index 5f23237..09f7919 100644 --- a/src/ModuleBuilder.cpp +++ b/src/ModuleBuilder.cpp @@ -16,6 +16,8 @@ llvm::Value *ModuleBuilder::valueForExpression(shared_ptr expression switch (expression->getKind()) { case Expression::Kind::LITERAL: return llvm::ConstantInt::get(int32Type, expression->getInteger(), true); + case Expression::Kind::GROUPING: + return valueForExpression(expression->getLeft()); case Expression::Kind::BINARY: llvm::Value *leftValue = valueForExpression(expression->getLeft()); llvm::Value *rightValue = valueForExpression(expression->getRight()); diff --git a/src/Parser.cpp b/src/Parser.cpp index 3b7b487..928e0c5 100644 --- a/src/Parser.cpp +++ b/src/Parser.cpp @@ -33,7 +33,9 @@ shared_ptr Parser::primary() { do { if((expression = matchInteger()) != Expression::Invalid) break; - + + if((expression = matchGrouping()) != Expression::Invalid) + break; } while(false); return expression; @@ -49,6 +51,20 @@ shared_ptr Parser::matchInteger() { return Expression::Invalid; } +shared_ptr Parser::matchGrouping() { + Token token = tokens.at(currentIndex); + if (token.getKind() == Token::Kind::LEFT_PAREN) { + currentIndex++; + shared_ptr expression = term(); + if (tokens.at(currentIndex).getKind() == Token::Kind::RIGHT_PAREN) { + currentIndex++; + return make_shared(Expression::Kind::GROUPING, token, expression, nullptr); + } + } + + return Expression::Invalid; +} + shared_ptr Parser::matchBinary(shared_ptr left) { Token token = tokens.at(currentIndex); if (token.isOneOf({Token::Kind::PLUS, Token::Kind::MINUS, Token::Kind::STAR, Token::Kind::SLASH, Token::Kind::PERCENT})) { diff --git a/src/Parser.h b/src/Parser.h index 452d65e..f6172fe 100644 --- a/src/Parser.h +++ b/src/Parser.h @@ -17,6 +17,7 @@ private: shared_ptr primary(); shared_ptr matchInteger(); + shared_ptr matchGrouping(); shared_ptr matchBinary(shared_ptr left); public: diff --git a/src/Token.cpp b/src/Token.cpp index c1c4bd6..55dd160 100644 --- a/src/Token.cpp +++ b/src/Token.cpp @@ -43,7 +43,7 @@ std::string Token::toString() { case PERCENT: return "PERCENT"; case LEFT_PAREN: - return "LEFT_PARENT"; + return "LEFT_PAREN"; case RIGHT_PAREN: return "RIGHT_PAREN"; case DOT: