Added grouping
This commit is contained in:
@@ -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:
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|||||||
@@ -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})) {
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
Reference in New Issue
Block a user