#include "Expression.h" Expression::Expression(ExpressionKind kind, ValueType valueType): kind(kind), valueType(valueType) { } ExpressionKind Expression::getKind() { return kind; } ValueType Expression::getValueType() { return valueType; } bool Expression::isValid() { return kind != ExpressionKind::INVALID; } string Expression::toString(int indent) { return "EXPRESSION"; } // // ExpressionBinary ExpressionBinary::ExpressionBinary(shared_ptr token, shared_ptr left, shared_ptr right): Expression(ExpressionKind::BINARY, ValueType::NONE), left(left), right(right) { // Types must match if (left->getValueType() != right->getValueType()) exit(1); // Booleans can only do = or != if (valueType == ValueType::BOOL && (token->getKind() != TokenKind::EQUAL || token->getKind() != TokenKind::NOT_EQUAL)) exit(1); switch (token->getKind()) { case TokenKind::EQUAL: operation = EQUAL; valueType = ValueType::BOOL; break; case TokenKind::NOT_EQUAL: operation = NOT_EQUAL; valueType = ValueType::BOOL; break; case TokenKind::LESS: operation = LESS; valueType = ValueType::BOOL; break; case TokenKind::LESS_EQUAL: operation = LESS_EQUAL; valueType = ValueType::BOOL; break; case TokenKind::GREATER: operation = GREATER; valueType = ValueType::BOOL; break; case TokenKind::GREATER_EQUAL: operation = GREATER_EQUAL; valueType = ValueType::BOOL; break; case TokenKind::PLUS: operation = ADD; valueType = left->getValueType(); break; case TokenKind::MINUS: operation = SUB; valueType = left->getValueType(); break; case TokenKind::STAR: operation = MUL; valueType = left->getValueType(); break; case TokenKind::SLASH: operation = DIV; valueType = left->getValueType(); break; case TokenKind::PERCENT: operation = MOD; valueType = left->getValueType(); break; default: exit(1); } } ExpressionBinary::Operation ExpressionBinary::getOperation() { return operation; } shared_ptr ExpressionBinary::getLeft() { return left; } shared_ptr ExpressionBinary::getRight() { return right; } string ExpressionBinary::toString(int indent) { switch (operation) { case EQUAL: return "{= " + left->toString(0) + " " + right->toString(0) + "}"; case NOT_EQUAL: return "{!= " + left->toString(0) + " " + right->toString(0) + "}"; case LESS: return "{< " + left->toString(0) + " " + right->toString(0) + "}"; case LESS_EQUAL: return "{<= " + left->toString(0) + " " + right->toString(0) + "}"; case GREATER: return "{> " + left->toString(0) + " " + right->toString(0) + "}"; case GREATER_EQUAL: return "{<= " + left->toString(0) + " " + right->toString(0) + "}"; case ADD: return "{+ " + left->toString(0) + " " + right->toString(0) + "}"; case SUB: return "{- " + left->toString(0) + " " + right->toString(0) + "}"; case MUL: return "{* " + left->toString(0) + " " + right->toString(0) + "}"; case DIV: return "{/ " + left->toString(0) + " " + right->toString(0) + "}"; case MOD: return "{% " + left->toString(0) + " " + right->toString(0) + "}"; } } // // ExpressionLiteral ExpressionLiteral::ExpressionLiteral(shared_ptr token): Expression(ExpressionKind::LITERAL, ValueType::NONE) { switch (token->getKind()) { case TokenKind::BOOL: boolValue = token->getLexme().compare("true") == 0; valueType = ValueType::BOOL; break; case TokenKind::INTEGER_DEC: { string numString = token->getLexme(); erase(numString, '_'); sint32Value = stoi(numString, nullptr, 10); valueType = ValueType::SINT32; break; } case TokenKind::INTEGER_HEX: { string numString = token->getLexme(); erase(numString, '_'); sint32Value = stoi(numString, nullptr, 16); valueType = ValueType::SINT32; break; } case TokenKind::INTEGER_BIN: { string numString = token->getLexme(); erase(numString, '_'); numString = numString.substr(2, numString.size()-1); sint32Value = stoi(numString, nullptr, 2); valueType = ValueType::SINT32; break; } case TokenKind::REAL: real32Value = stof(token->getLexme()); valueType = ValueType::REAL32; break; default: exit(1); } } bool ExpressionLiteral::getBoolValue() { return boolValue; } int32_t ExpressionLiteral::getSint32Value() { return sint32Value; } float ExpressionLiteral::getReal32Value() { return real32Value; } string ExpressionLiteral::toString(int indent) { switch (valueType) { case ValueType::NONE: return "NONE"; case ValueType::BOOL: return boolValue ? "true" : "false"; case ValueType::SINT32: return to_string(sint32Value); case ValueType::REAL32: return to_string(real32Value); } } // // ExpressionGrouping ExpressionGrouping::ExpressionGrouping(shared_ptr expression): Expression(ExpressionKind::GROUPING, expression->getValueType()), expression(expression) { } shared_ptr ExpressionGrouping::getExpression() { return expression; } string ExpressionGrouping::toString(int indent) { return "( " + expression->toString(0) + " )"; } // // ExpressionIfElse ExpressionIfElse::ExpressionIfElse(shared_ptr condition, shared_ptr thenBlock, shared_ptr elseBlock): Expression(ExpressionKind::IF_ELSE, ValueType::NONE), condition(condition), thenBlock(thenBlock), elseBlock(elseBlock) { // Condition must evaluate to bool if (condition->getValueType() != ValueType::BOOL) exit(1); // Return types must match shared_ptr thenStatementExpression = thenBlock->getStatementExpression(); shared_ptr thenExpression = thenStatementExpression != nullptr ? thenStatementExpression->getExpression() : nullptr; shared_ptr elseStatementExpression = elseBlock != nullptr ? elseBlock->getStatementExpression() : nullptr; shared_ptr elseExpression = elseStatementExpression != nullptr ? elseStatementExpression->getExpression() : nullptr; if (thenExpression != nullptr && elseExpression != nullptr && thenExpression->getValueType() != elseExpression->getValueType()) exit(1); // get type or default to void valueType = thenExpression ? thenExpression->getValueType() : ValueType::NONE; } shared_ptr ExpressionIfElse::getCondition() { return condition; } shared_ptr ExpressionIfElse::getThenBlock() { return thenBlock; } shared_ptr ExpressionIfElse::getElseBlock() { return elseBlock; } string ExpressionIfElse::toString(int indent) { string value; value += "IF(" + condition->toString(0) + "):\n"; value += thenBlock->toString(indent+1); if (elseBlock != nullptr) { for (int ind=0; indtoString(indent+1); } for (int ind=0; ind> argumentExpressions): Expression(ExpressionKind::CALL, ValueType::NONE), name(name), argumentExpressions(argumentExpressions) { } string ExpressionCall::getName() { return name; } vector> ExpressionCall::getArgumentExpressions() { return argumentExpressions; } string ExpressionCall::toString(int indent) { string value; value += "CALL(" + name + "):"; for (shared_ptr &argumentExpression : argumentExpressions) { value += "\n"; for (int ind=0; indtoString(indent+1) + ","; } return value; } // // ExpressionInvalid ExpressionInvalid::ExpressionInvalid(shared_ptr token): Expression(ExpressionKind::INVALID, ValueType::NONE), token(token) { } shared_ptr ExpressionInvalid::getToken() { return token; } string ExpressionInvalid::toString(int indent) { return "Invalid token " + token->toString() + " at " + to_string(token->getLine()) + ":" + to_string(token->getColumn()) + "\n"; }