Cleaned up structure
This commit is contained in:
289
src/Parser/Expression.cpp
Normal file
289
src/Parser/Expression.cpp
Normal file
@@ -0,0 +1,289 @@
|
||||
#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> token, shared_ptr<Expression> left, shared_ptr<Expression> 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<Expression> ExpressionBinary::getLeft() {
|
||||
return left;
|
||||
}
|
||||
|
||||
shared_ptr<Expression> 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> 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:
|
||||
sint32Value = stoi(token->getLexme());
|
||||
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):
|
||||
Expression(ExpressionKind::GROUPING, expression->getValueType()), expression(expression) {
|
||||
}
|
||||
|
||||
shared_ptr<Expression> ExpressionGrouping::getExpression() {
|
||||
return expression;
|
||||
}
|
||||
|
||||
string ExpressionGrouping::toString(int indent) {
|
||||
return "( " + expression->toString(0) + " )";
|
||||
}
|
||||
|
||||
//
|
||||
// ExpressionIfElse
|
||||
ExpressionIfElse::ExpressionIfElse(shared_ptr<Expression> condition, shared_ptr<StatementBlock> thenBlock, shared_ptr<StatementBlock> 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<StatementExpression> thenStatementExpression = thenBlock->getStatementExpression();
|
||||
shared_ptr<Expression> thenExpression = thenStatementExpression != nullptr ? thenStatementExpression->getExpression() : nullptr;
|
||||
shared_ptr<StatementExpression> elseStatementExpression = elseBlock != nullptr ? elseBlock->getStatementExpression() : nullptr;
|
||||
shared_ptr<Expression> 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<Expression> ExpressionIfElse::getCondition() {
|
||||
return condition;
|
||||
}
|
||||
|
||||
shared_ptr<StatementBlock> ExpressionIfElse::getThenBlock() {
|
||||
return thenBlock;
|
||||
}
|
||||
|
||||
shared_ptr<StatementBlock> 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; ind<indent; ind++)
|
||||
value += " ";
|
||||
value += "ELSE:\n";
|
||||
value += elseBlock->toString(indent+1);
|
||||
}
|
||||
for (int ind=0; ind<indent; ind++)
|
||||
value += " ";
|
||||
value += ";";
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
//
|
||||
// ExpressionVar
|
||||
ExpressionVar::ExpressionVar(string name):
|
||||
Expression(ExpressionKind::VAR, ValueType::NONE), name(name) {
|
||||
}
|
||||
|
||||
string ExpressionVar::getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
string ExpressionVar::toString(int indent) {
|
||||
return "VAR(" + name + ")";
|
||||
}
|
||||
|
||||
//
|
||||
// Expression Call
|
||||
ExpressionCall::ExpressionCall(string name, vector<shared_ptr<Expression>> argumentExpressions):
|
||||
Expression(ExpressionKind::CALL, ValueType::NONE), name(name), argumentExpressions(argumentExpressions) {
|
||||
}
|
||||
|
||||
string ExpressionCall::getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
vector<shared_ptr<Expression>> ExpressionCall::getArgumentExpressions() {
|
||||
return argumentExpressions;
|
||||
}
|
||||
|
||||
string ExpressionCall::toString(int indent) {
|
||||
string value;
|
||||
|
||||
value += "CALL(" + name + "):";
|
||||
for (shared_ptr<Expression> &argumentExpression : argumentExpressions) {
|
||||
value += "\n";
|
||||
for (int ind=0; ind<indent+1; ind++)
|
||||
value += " ";
|
||||
value += argumentExpression->toString(indent+1) + ",";
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
//
|
||||
// ExpressionInvalid
|
||||
ExpressionInvalid::ExpressionInvalid(shared_ptr<Token> token):
|
||||
Expression(ExpressionKind::INVALID, ValueType::NONE), token(token) {
|
||||
}
|
||||
|
||||
shared_ptr<Token> ExpressionInvalid::getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
string ExpressionInvalid::toString(int indent) {
|
||||
return "Invalid token " + token->toString() + " at " + to_string(token->getLine()) + ":" + to_string(token->getColumn()) + "\n";
|
||||
}
|
||||
153
src/Parser/Expression.h
Normal file
153
src/Parser/Expression.h
Normal file
@@ -0,0 +1,153 @@
|
||||
#ifndef EXPRESSION_H
|
||||
#define EXPRESSION_H
|
||||
|
||||
#include "Lexer/Token.h"
|
||||
#include "Statement.h"
|
||||
#include "Types.h"
|
||||
|
||||
class StatementBlock;
|
||||
class StatementExpression;
|
||||
|
||||
using namespace std;
|
||||
|
||||
enum class ExpressionKind {
|
||||
LITERAL,
|
||||
GROUPING,
|
||||
BINARY,
|
||||
IF_ELSE,
|
||||
VAR,
|
||||
CALL,
|
||||
INVALID
|
||||
};
|
||||
|
||||
//
|
||||
// Expression
|
||||
class Expression {
|
||||
private:
|
||||
ExpressionKind kind;
|
||||
|
||||
protected:
|
||||
ValueType valueType;
|
||||
|
||||
public:
|
||||
Expression(ExpressionKind kind, ValueType valueType);
|
||||
ExpressionKind getKind();
|
||||
ValueType getValueType();
|
||||
bool isValid();
|
||||
virtual string toString(int indent);
|
||||
};
|
||||
|
||||
//
|
||||
// ExpressionLiteral
|
||||
class ExpressionLiteral: public Expression {
|
||||
private:
|
||||
bool boolValue;
|
||||
int32_t sint32Value;
|
||||
float real32Value;
|
||||
|
||||
public:
|
||||
ExpressionLiteral(shared_ptr<Token> token);
|
||||
bool getBoolValue();
|
||||
int32_t getSint32Value();
|
||||
float getReal32Value();
|
||||
string toString(int indent) override;
|
||||
};
|
||||
|
||||
//
|
||||
// ExpressionGrouping
|
||||
class ExpressionGrouping: public Expression {
|
||||
private:
|
||||
shared_ptr<Expression> expression;
|
||||
|
||||
public:
|
||||
ExpressionGrouping(shared_ptr<Expression> expression);
|
||||
shared_ptr<Expression> getExpression();
|
||||
string toString(int indent) override;
|
||||
};
|
||||
|
||||
//
|
||||
// ExpressionBinary
|
||||
class ExpressionBinary: public Expression {
|
||||
public:
|
||||
enum Operation {
|
||||
EQUAL,
|
||||
NOT_EQUAL,
|
||||
LESS,
|
||||
LESS_EQUAL,
|
||||
GREATER,
|
||||
GREATER_EQUAL,
|
||||
ADD,
|
||||
SUB,
|
||||
MUL,
|
||||
DIV,
|
||||
MOD
|
||||
};
|
||||
|
||||
private:
|
||||
Operation operation;
|
||||
shared_ptr<Expression> left;
|
||||
shared_ptr<Expression> right;
|
||||
|
||||
public:
|
||||
ExpressionBinary(shared_ptr<Token> token, shared_ptr<Expression> left, shared_ptr<Expression> right);
|
||||
Operation getOperation();
|
||||
shared_ptr<Expression> getLeft();
|
||||
shared_ptr<Expression> getRight();
|
||||
string toString(int indent) override;
|
||||
};
|
||||
|
||||
//
|
||||
// ExpressionIfElse
|
||||
class ExpressionIfElse: public Expression {
|
||||
private:
|
||||
shared_ptr<Expression> condition;
|
||||
shared_ptr<StatementBlock> thenBlock;
|
||||
shared_ptr<StatementBlock> elseBlock;
|
||||
|
||||
public:
|
||||
ExpressionIfElse(shared_ptr<Expression> condition, shared_ptr<StatementBlock> thenBlock, shared_ptr<StatementBlock> elseBlock);
|
||||
shared_ptr<Expression> getCondition();
|
||||
shared_ptr<StatementBlock> getThenBlock();
|
||||
shared_ptr<StatementBlock> getElseBlock();
|
||||
string toString(int indent) override;
|
||||
};
|
||||
|
||||
//
|
||||
// ExpressionVar
|
||||
class ExpressionVar: public Expression {
|
||||
private:
|
||||
string name;
|
||||
|
||||
public:
|
||||
ExpressionVar(string name);
|
||||
string getName();
|
||||
string toString(int indent) override;
|
||||
};
|
||||
|
||||
//
|
||||
// Expression Call
|
||||
class ExpressionCall: public Expression {
|
||||
private:
|
||||
string name;
|
||||
vector<shared_ptr<Expression>> argumentExpressions;
|
||||
|
||||
public:
|
||||
ExpressionCall(string name, vector<shared_ptr<Expression>> argumentExpressions);
|
||||
string getName();
|
||||
vector<shared_ptr<Expression>> getArgumentExpressions();
|
||||
string toString(int indent) override;
|
||||
};
|
||||
|
||||
//
|
||||
// ExpressionInvalid
|
||||
class ExpressionInvalid: public Expression {
|
||||
private:
|
||||
shared_ptr<Token> token;
|
||||
|
||||
public:
|
||||
ExpressionInvalid(shared_ptr<Token> token);
|
||||
shared_ptr<Token> getToken();
|
||||
string toString(int indent) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
512
src/Parser/Parser.cpp
Normal file
512
src/Parser/Parser.cpp
Normal file
@@ -0,0 +1,512 @@
|
||||
#include "Parser.h"
|
||||
|
||||
Parser::Parser(vector<shared_ptr<Token>> tokens): tokens(tokens) {
|
||||
}
|
||||
|
||||
vector<shared_ptr<Statement>> Parser::getStatements() {
|
||||
vector<shared_ptr<Statement>> statements;
|
||||
|
||||
while (!tryMatchingTokenKinds({TokenKind::END}, true, false)) {
|
||||
shared_ptr<Statement> statement = nextStatement();
|
||||
// Abort parsing if we got an error
|
||||
if (!statement->isValid()) {
|
||||
cerr << statement->toString(0);
|
||||
exit(1);
|
||||
}
|
||||
statements.push_back(statement);
|
||||
}
|
||||
|
||||
return statements;
|
||||
}
|
||||
|
||||
//
|
||||
// Statement
|
||||
//
|
||||
shared_ptr<Statement> Parser::nextStatement() {
|
||||
shared_ptr<Statement> statement;
|
||||
|
||||
statement = matchStatementFunctionDeclaration();
|
||||
if (statement != nullptr)
|
||||
return statement;
|
||||
|
||||
statement = matchStatementVarDeclaration();
|
||||
if (statement != nullptr)
|
||||
return statement;
|
||||
|
||||
statement = matchStatementReturn();
|
||||
if (statement != nullptr)
|
||||
return statement;
|
||||
|
||||
statement = matchStatementExpression();
|
||||
if (statement != nullptr)
|
||||
return statement;
|
||||
|
||||
statement = matchStatementMetaExternFunction();
|
||||
if (statement != nullptr)
|
||||
return statement;
|
||||
|
||||
return matchStatementInvalid("Unexpected token");
|
||||
}
|
||||
|
||||
shared_ptr<Statement> Parser::matchStatementFunctionDeclaration() {
|
||||
if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::FUNCTION}, true, false))
|
||||
return nullptr;
|
||||
|
||||
shared_ptr<Token> identifierToken = tokens.at(currentIndex);
|
||||
currentIndex++;
|
||||
currentIndex++; // skip fun
|
||||
|
||||
// Get arguments
|
||||
vector<pair<string, ValueType>> arguments;
|
||||
if (tryMatchingTokenKinds({TokenKind::COLON}, true, true)) {
|
||||
do {
|
||||
tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true); // skip new line
|
||||
if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::TYPE}, true, false))
|
||||
return matchStatementInvalid("Expected function argument");
|
||||
shared_ptr<Token> identifierToken = tokens.at(currentIndex);
|
||||
currentIndex++; // identifier
|
||||
shared_ptr<Token> typeToken = tokens.at(currentIndex);
|
||||
currentIndex++; // type
|
||||
optional<ValueType> argumentType = valueTypeForToken(typeToken);
|
||||
if (!argumentType)
|
||||
return matchStatementInvalid("Invalid argument type");
|
||||
|
||||
arguments.push_back(pair<string, ValueType>(identifierToken->getLexme(), *argumentType));
|
||||
} while (tryMatchingTokenKinds({TokenKind::COMMA}, true, true));
|
||||
}
|
||||
|
||||
// consume optional new line
|
||||
tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true);
|
||||
|
||||
// Return type
|
||||
ValueType returnType = ValueType::NONE;
|
||||
if (tryMatchingTokenKinds({TokenKind::RIGHT_ARROW}, true, true)) {
|
||||
shared_ptr<Token> typeToken = tokens.at(currentIndex);
|
||||
optional<ValueType> type = valueTypeForToken(typeToken);
|
||||
if (!type)
|
||||
return matchStatementInvalid("Expected return type");
|
||||
returnType = *type;
|
||||
|
||||
currentIndex++; // type
|
||||
|
||||
// consume new line
|
||||
if (!tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true))
|
||||
return matchStatementInvalid("Expected new line after function declaration");
|
||||
}
|
||||
|
||||
shared_ptr<Statement> statementBlock = matchStatementBlock({TokenKind::SEMICOLON}, true);
|
||||
if (statementBlock == nullptr)
|
||||
return matchStatementInvalid();
|
||||
else if (!statementBlock->isValid())
|
||||
return statementBlock;
|
||||
|
||||
if(!tryMatchingTokenKinds({TokenKind::NEW_LINE}, false, true))
|
||||
return matchStatementInvalid("Expected a new line after a function declaration");
|
||||
|
||||
return make_shared<StatementFunctionDeclaration>(identifierToken->getLexme(), arguments, returnType, dynamic_pointer_cast<StatementBlock>(statementBlock));
|
||||
}
|
||||
|
||||
shared_ptr<Statement> Parser::matchStatementVarDeclaration() {
|
||||
if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::TYPE}, true, false))
|
||||
return nullptr;
|
||||
|
||||
shared_ptr<Token> identifierToken = tokens.at(currentIndex);
|
||||
currentIndex++; // identifier
|
||||
shared_ptr<Token> valueTypeToken = tokens.at(currentIndex);
|
||||
|
||||
ValueType valueType;
|
||||
if (valueTypeToken->getLexme().compare("bool") == 0)
|
||||
valueType = ValueType::BOOL;
|
||||
else if (valueTypeToken->getLexme().compare("sint32") == 0)
|
||||
valueType = ValueType::SINT32;
|
||||
else if (valueTypeToken->getLexme().compare("real32") == 0)
|
||||
valueType = ValueType::REAL32;
|
||||
else
|
||||
return matchStatementInvalid("Invalid type");
|
||||
|
||||
currentIndex++; // type
|
||||
|
||||
// Expect left arrow
|
||||
if (!tryMatchingTokenKinds({TokenKind::LEFT_ARROW}, true, true))
|
||||
return matchStatementInvalid("Expected left arrow");
|
||||
|
||||
shared_ptr<Expression> expression = nextExpression();
|
||||
if (expression == nullptr || !expression->isValid())
|
||||
return matchStatementInvalid();
|
||||
|
||||
// Expect new line
|
||||
if (!tryMatchingTokenKinds({TokenKind::NEW_LINE}, false, true))
|
||||
return matchStatementInvalid("Expected a new line after variable declaration");
|
||||
|
||||
return make_shared<StatementVarDeclaration>(identifierToken->getLexme(), valueType, expression);
|
||||
}
|
||||
|
||||
shared_ptr<Statement> Parser::matchStatementBlock(vector<TokenKind> terminalTokenKinds, bool shouldConsumeTerminal) {
|
||||
vector<shared_ptr<Statement>> statements;
|
||||
|
||||
bool hasNewLineTerminal = find(terminalTokenKinds.begin(), terminalTokenKinds.end(), TokenKind::NEW_LINE) != terminalTokenKinds.end();
|
||||
while (!tryMatchingTokenKinds(terminalTokenKinds, false, shouldConsumeTerminal)) {
|
||||
shared_ptr<Statement> statement = nextStatement();
|
||||
if (statement == nullptr)
|
||||
return matchStatementInvalid();
|
||||
else if (!statement->isValid())
|
||||
return statement;
|
||||
else
|
||||
statements.push_back(statement);
|
||||
|
||||
if (hasNewLineTerminal && tokens.at(currentIndex-1)->getKind() == TokenKind::NEW_LINE)
|
||||
currentIndex--;
|
||||
}
|
||||
|
||||
|
||||
return make_shared<StatementBlock>(statements);
|
||||
}
|
||||
|
||||
shared_ptr<Statement> Parser::matchStatementReturn() {
|
||||
if (!tryMatchingTokenKinds({TokenKind::RETURN}, true, true))
|
||||
return nullptr;
|
||||
|
||||
shared_ptr<Expression> expression = nextExpression();
|
||||
if (expression != nullptr && !expression->isValid())
|
||||
return matchStatementInvalid();
|
||||
|
||||
if (!tryMatchingTokenKinds({TokenKind::NEW_LINE, TokenKind::SEMICOLON}, false, false))
|
||||
return matchStatementInvalid();
|
||||
|
||||
tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true);
|
||||
|
||||
return make_shared<StatementReturn>(expression);
|
||||
}
|
||||
|
||||
shared_ptr<Statement> Parser::matchStatementExpression() {
|
||||
shared_ptr<Expression> expression = nextExpression();
|
||||
|
||||
if (expression == nullptr)
|
||||
return nullptr;
|
||||
else if (!expression->isValid())
|
||||
return make_shared<StatementInvalid>(tokens.at(currentIndex), expression->toString(0));
|
||||
|
||||
// Consume new line
|
||||
tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true);
|
||||
|
||||
return make_shared<StatementExpression>(expression);
|
||||
}
|
||||
|
||||
shared_ptr<Statement> Parser::matchStatementMetaExternFunction() {
|
||||
if (!tryMatchingTokenKinds({TokenKind::M_EXTERN, TokenKind::IDENTIFIER, TokenKind::FUNCTION}, true, false))
|
||||
return nullptr;
|
||||
|
||||
currentIndex++; // skip meta
|
||||
shared_ptr<Token> identifierToken = tokens.at(currentIndex);
|
||||
currentIndex++;
|
||||
currentIndex++; // skip fun
|
||||
|
||||
// Get arguments
|
||||
vector<pair<string, ValueType>> arguments;
|
||||
if (tryMatchingTokenKinds({TokenKind::COLON}, true, true)) {
|
||||
do {
|
||||
tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true); // skip new line
|
||||
if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::TYPE}, true, false))
|
||||
return matchStatementInvalid("Expected function argument");
|
||||
shared_ptr<Token> identifierToken = tokens.at(currentIndex);
|
||||
currentIndex++; // identifier
|
||||
shared_ptr<Token> typeToken = tokens.at(currentIndex);
|
||||
currentIndex++; // type
|
||||
optional<ValueType> argumentType = valueTypeForToken(typeToken);
|
||||
if (!argumentType)
|
||||
return matchStatementInvalid("Invalid argument type");
|
||||
|
||||
arguments.push_back(pair<string, ValueType>(identifierToken->getLexme(), *argumentType));
|
||||
} while (tryMatchingTokenKinds({TokenKind::COMMA}, true, true));
|
||||
}
|
||||
|
||||
// consume optional new line
|
||||
tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true);
|
||||
|
||||
// Return type
|
||||
ValueType returnType = ValueType::NONE;
|
||||
if (tryMatchingTokenKinds({TokenKind::RIGHT_ARROW}, true, true)) {
|
||||
shared_ptr<Token> typeToken = tokens.at(currentIndex);
|
||||
optional<ValueType> type = valueTypeForToken(typeToken);
|
||||
if (!type)
|
||||
return matchStatementInvalid("Expected return type");
|
||||
returnType = *type;
|
||||
|
||||
currentIndex++; // type
|
||||
|
||||
// consume new line
|
||||
if (!tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true))
|
||||
return matchStatementInvalid("Expected new line after function declaration");
|
||||
}
|
||||
|
||||
return make_shared<StatementMetaExternFunction>(identifierToken->getLexme(), arguments, returnType);
|
||||
}
|
||||
|
||||
shared_ptr<StatementInvalid> Parser::matchStatementInvalid(string message) {
|
||||
return make_shared<StatementInvalid>(tokens.at(currentIndex), message);
|
||||
}
|
||||
|
||||
//
|
||||
// Expression
|
||||
//
|
||||
shared_ptr<Expression> Parser::nextExpression() {
|
||||
shared_ptr<Expression> expression;
|
||||
|
||||
expression = matchEquality();
|
||||
if (expression != nullptr)
|
||||
return expression;
|
||||
|
||||
expression = matchExpressionIfElse();
|
||||
if (expression != nullptr)
|
||||
return expression;
|
||||
|
||||
expression = matchExpressionVar();
|
||||
if (expression != nullptr)
|
||||
return expression;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
shared_ptr<Expression> Parser::matchEquality() {
|
||||
shared_ptr<Expression> expression = matchComparison();
|
||||
if (expression == nullptr || !expression->isValid())
|
||||
return expression;
|
||||
|
||||
while (tryMatchingTokenKinds({Token::tokensEquality}, false, false))
|
||||
expression = matchExpressionBinary(expression);
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
||||
shared_ptr<Expression> Parser::matchComparison() {
|
||||
shared_ptr<Expression> expression = matchTerm();
|
||||
if (expression == nullptr || !expression->isValid())
|
||||
return expression;
|
||||
|
||||
while (tryMatchingTokenKinds({Token::tokensComparison}, false, false))
|
||||
expression = matchExpressionBinary(expression);
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
||||
shared_ptr<Expression> Parser::matchTerm() {
|
||||
shared_ptr<Expression> expression = matchFactor();
|
||||
if (expression == nullptr || !expression->isValid())
|
||||
return expression;
|
||||
|
||||
while (tryMatchingTokenKinds({Token::tokensTerm}, false, false))
|
||||
expression = matchExpressionBinary(expression);
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
||||
shared_ptr<Expression> Parser::matchFactor() {
|
||||
shared_ptr<Expression> expression = matchPrimary();
|
||||
if (expression == nullptr || !expression->isValid())
|
||||
return expression;
|
||||
|
||||
while (tokens.at(currentIndex)->isOfKind(Token::tokensFactor))
|
||||
expression = matchExpressionBinary(expression);
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
||||
shared_ptr<Expression> Parser::matchPrimary() {
|
||||
shared_ptr<Expression> expression;
|
||||
|
||||
expression = matchExpressionLiteral();
|
||||
if (expression != nullptr)
|
||||
return expression;
|
||||
|
||||
expression = matchExpressionCall();
|
||||
if (expression != nullptr)
|
||||
return expression;
|
||||
|
||||
expression = matchExpressionVar();
|
||||
if (expression != nullptr)
|
||||
return expression;
|
||||
|
||||
expression = matchExpressionGrouping();
|
||||
if (expression != nullptr)
|
||||
return expression;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
shared_ptr<Expression> Parser::matchExpressionLiteral() {
|
||||
shared_ptr<Token> token = tokens.at(currentIndex);
|
||||
|
||||
if (tryMatchingTokenKinds(Token::tokensLiteral, false, true))
|
||||
return make_shared<ExpressionLiteral>(token);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
shared_ptr<Expression> Parser::matchExpressionGrouping() {
|
||||
shared_ptr<Token> token = tokens.at(currentIndex);
|
||||
if (tryMatchingTokenKinds({TokenKind::LEFT_PAREN}, true, true)) {
|
||||
shared_ptr<Expression> expression = matchTerm();
|
||||
// has grouped expression failed?
|
||||
if (expression == nullptr) {
|
||||
return matchExpressionInvalid();
|
||||
} else if(!expression->isValid()) {
|
||||
return expression;
|
||||
} else if (tryMatchingTokenKinds({TokenKind::RIGHT_PAREN}, true, true)) {
|
||||
return make_shared<ExpressionGrouping>(expression);
|
||||
} else {
|
||||
return matchExpressionInvalid();
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
shared_ptr<Expression> Parser::matchExpressionBinary(shared_ptr<Expression> left) {
|
||||
shared_ptr<Token> token = tokens.at(currentIndex);
|
||||
shared_ptr<Expression> right;
|
||||
// What level of binary expression are we having?
|
||||
if (tryMatchingTokenKinds(Token::tokensEquality, false, true)) {
|
||||
right = matchComparison();
|
||||
} else if (tryMatchingTokenKinds(Token::tokensComparison, false, true)) {
|
||||
right = matchTerm();
|
||||
} else if (tryMatchingTokenKinds(Token::tokensTerm, false, true)) {
|
||||
right = matchFactor();
|
||||
} else if (tryMatchingTokenKinds(Token::tokensFactor, false, true)) {
|
||||
right = matchPrimary();
|
||||
}
|
||||
|
||||
if (right == nullptr) {
|
||||
return matchExpressionInvalid();
|
||||
} else if (!right->isValid()) {
|
||||
return right;
|
||||
} else {
|
||||
return make_shared<ExpressionBinary>(token, left, right);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
shared_ptr<Expression> Parser::matchExpressionIfElse() {
|
||||
// Try maching '?'
|
||||
shared_ptr<Token> token = tokens.at(currentIndex);
|
||||
|
||||
if (!tryMatchingTokenKinds({TokenKind::QUESTION}, true, true))
|
||||
return nullptr;
|
||||
|
||||
// Then get condition
|
||||
shared_ptr<Expression> condition = nextExpression();
|
||||
if (condition == nullptr)
|
||||
return matchExpressionInvalid();
|
||||
else if (!condition->isValid())
|
||||
return condition;
|
||||
|
||||
// Consume optional ':'
|
||||
tryMatchingTokenKinds({TokenKind::COLON}, true, true);
|
||||
// Consume optional new line
|
||||
tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true);
|
||||
|
||||
// Match then block
|
||||
shared_ptr<Statement> thenBlock = matchStatementBlock({TokenKind::COLON, TokenKind::SEMICOLON}, false);
|
||||
if (thenBlock == nullptr)
|
||||
return matchExpressionInvalid();
|
||||
else if (!thenBlock->isValid())
|
||||
return matchExpressionInvalid(); // FIXME
|
||||
|
||||
// Match else block. Then and else block are separated by ':'
|
||||
shared_ptr<Statement> elseBlock;
|
||||
if (tryMatchingTokenKinds({TokenKind::COLON}, true, true)) {
|
||||
bool isSingleLine = !tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true);
|
||||
vector<TokenKind> terminalTokens = {TokenKind::SEMICOLON, TokenKind::COMMA, TokenKind::RIGHT_PAREN};
|
||||
if (isSingleLine)
|
||||
terminalTokens.push_back(TokenKind::NEW_LINE);
|
||||
|
||||
elseBlock = matchStatementBlock(terminalTokens, false);
|
||||
if (elseBlock == nullptr)
|
||||
return matchExpressionInvalid();
|
||||
else if (!elseBlock->isValid())
|
||||
return matchExpressionInvalid(); // FIXME
|
||||
}
|
||||
tryMatchingTokenKinds({TokenKind::SEMICOLON}, true, true);
|
||||
|
||||
return make_shared<ExpressionIfElse>(condition, dynamic_pointer_cast<StatementBlock>(thenBlock), dynamic_pointer_cast<StatementBlock>(elseBlock));
|
||||
}
|
||||
|
||||
shared_ptr<Expression> Parser::matchExpressionVar() {
|
||||
shared_ptr<Token> token = tokens.at(currentIndex);
|
||||
|
||||
if (tryMatchingTokenKinds({TokenKind::IDENTIFIER}, true, true))
|
||||
return make_shared<ExpressionVar>(token->getLexme());
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
shared_ptr<Expression> Parser::matchExpressionCall() {
|
||||
if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::LEFT_PAREN}, true, false))
|
||||
return nullptr;
|
||||
|
||||
shared_ptr<Token> identifierToken = tokens.at(currentIndex);
|
||||
currentIndex++; // identifier
|
||||
currentIndex++; // left parenthesis
|
||||
|
||||
vector<shared_ptr<Expression>> argumentExpressions;
|
||||
do {
|
||||
tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true); // optional new line
|
||||
|
||||
shared_ptr<Expression> argumentExpression = nextExpression();
|
||||
if (argumentExpression == nullptr || !argumentExpression->isValid())
|
||||
return argumentExpression;
|
||||
argumentExpressions.push_back(argumentExpression);
|
||||
} while (tryMatchingTokenKinds({TokenKind::COMMA}, true, true));
|
||||
|
||||
tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true); // optional new line
|
||||
if (!tryMatchingTokenKinds({TokenKind::RIGHT_PAREN}, true, true))
|
||||
return matchExpressionInvalid();
|
||||
|
||||
return make_shared<ExpressionCall>(identifierToken->getLexme(), argumentExpressions);
|
||||
}
|
||||
|
||||
shared_ptr<ExpressionInvalid> Parser::matchExpressionInvalid() {
|
||||
return make_shared<ExpressionInvalid>(tokens.at(currentIndex));
|
||||
}
|
||||
|
||||
bool Parser::tryMatchingTokenKinds(vector<TokenKind> kinds, bool shouldMatchAll, bool shouldAdvance) {
|
||||
int requiredCount = shouldMatchAll ? kinds.size() : 1;
|
||||
if (currentIndex + requiredCount > tokens.size())
|
||||
return false;
|
||||
|
||||
if (shouldMatchAll) {
|
||||
for (int i=0; i<kinds.size(); i++) {
|
||||
if (kinds.at(i) != tokens.at(currentIndex + i)->getKind())
|
||||
return false;
|
||||
}
|
||||
|
||||
if (shouldAdvance)
|
||||
currentIndex += kinds.size();
|
||||
|
||||
return true;
|
||||
} else {
|
||||
for (int i=0; i<kinds.size(); i++) {
|
||||
if (kinds.at(i) == tokens.at(currentIndex)->getKind()) {
|
||||
if (shouldAdvance)
|
||||
currentIndex++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
optional<ValueType> Parser::valueTypeForToken(shared_ptr<Token> token) {
|
||||
if (token->getKind() != TokenKind::TYPE)
|
||||
return {};
|
||||
|
||||
if (token->getLexme().compare("bool") == 0)
|
||||
return ValueType::BOOL;
|
||||
else if (token->getLexme().compare("sint32") == 0)
|
||||
return ValueType::SINT32;
|
||||
else if (token->getLexme().compare("real32") == 0)
|
||||
return ValueType::REAL32;
|
||||
|
||||
return {};
|
||||
}
|
||||
51
src/Parser/Parser.h
Normal file
51
src/Parser/Parser.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#ifndef PARSER_H
|
||||
#define PARSER_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "Lexer/Token.h"
|
||||
#include "Expression.h"
|
||||
#include "Statement.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Parser {
|
||||
private:
|
||||
vector<shared_ptr<Token>> tokens;
|
||||
int currentIndex = 0;
|
||||
|
||||
shared_ptr<Statement> nextStatement();
|
||||
shared_ptr<Statement> matchStatementFunctionDeclaration();
|
||||
shared_ptr<Statement> matchStatementVarDeclaration();
|
||||
shared_ptr<Statement> matchStatementBlock(vector<TokenKind> terminalTokenKinds, bool shouldConsumeTerminal);
|
||||
shared_ptr<Statement> matchStatementReturn();
|
||||
shared_ptr<Statement> matchStatementExpression();
|
||||
|
||||
shared_ptr<Statement> matchStatementMetaExternFunction();
|
||||
|
||||
shared_ptr<StatementInvalid> matchStatementInvalid(string message = "");
|
||||
|
||||
shared_ptr<Expression> nextExpression();
|
||||
shared_ptr<Expression> matchEquality(); // =, !=
|
||||
shared_ptr<Expression> matchComparison(); // <, <=, >, >=
|
||||
shared_ptr<Expression> matchTerm(); // +, -
|
||||
shared_ptr<Expression> matchFactor(); // *, /, %
|
||||
shared_ptr<Expression> matchPrimary(); // integer, ()
|
||||
|
||||
shared_ptr<Expression> matchExpressionLiteral();
|
||||
shared_ptr<Expression> matchExpressionGrouping();
|
||||
shared_ptr<Expression> matchExpressionBinary(shared_ptr<Expression> left);
|
||||
shared_ptr<Expression> matchExpressionIfElse();
|
||||
shared_ptr<Expression> matchExpressionVar();
|
||||
shared_ptr<Expression> matchExpressionCall();
|
||||
shared_ptr<ExpressionInvalid> matchExpressionInvalid();
|
||||
|
||||
bool tryMatchingTokenKinds(vector<TokenKind> kinds, bool shouldMatchAll, bool shouldAdvance);
|
||||
optional<ValueType> valueTypeForToken(shared_ptr<Token> token);
|
||||
|
||||
public:
|
||||
Parser(vector<shared_ptr<Token>> tokens);
|
||||
vector<shared_ptr<Statement>> getStatements();
|
||||
};
|
||||
|
||||
#endif
|
||||
220
src/Parser/Statement.cpp
Normal file
220
src/Parser/Statement.cpp
Normal file
@@ -0,0 +1,220 @@
|
||||
#include "Statement.h"
|
||||
|
||||
string valueTypeToString(ValueType valueType) {
|
||||
switch (valueType) {
|
||||
case ValueType::NONE:
|
||||
return "NONE";
|
||||
case ValueType::BOOL:
|
||||
return "BOOL";
|
||||
case ValueType::SINT32:
|
||||
return "SINT32";
|
||||
case ValueType::REAL32:
|
||||
return "REAL32";
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Statement
|
||||
Statement::Statement(StatementKind kind): kind(kind) {
|
||||
}
|
||||
|
||||
StatementKind Statement::getKind() {
|
||||
return kind;
|
||||
}
|
||||
|
||||
bool Statement::isValid() {
|
||||
return kind != StatementKind::INVALID;
|
||||
}
|
||||
|
||||
string Statement::toString(int indent) {
|
||||
return "STATEMENT";
|
||||
}
|
||||
|
||||
//
|
||||
// StatementFunctionDeclaration
|
||||
StatementFunctionDeclaration::StatementFunctionDeclaration(string name, vector<pair<string, ValueType>> arguments, ValueType returnValueType, shared_ptr<StatementBlock> statementBlock):
|
||||
Statement(StatementKind::FUNCTION_DECLARATION), name(name), arguments(arguments), returnValueType(returnValueType), statementBlock(statementBlock) {
|
||||
}
|
||||
|
||||
string StatementFunctionDeclaration::getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
vector<pair<string, ValueType>> StatementFunctionDeclaration::getArguments() {
|
||||
return arguments;
|
||||
}
|
||||
|
||||
ValueType StatementFunctionDeclaration::getReturnValueType() {
|
||||
return returnValueType;
|
||||
}
|
||||
|
||||
shared_ptr<StatementBlock> StatementFunctionDeclaration::getStatementBlock() {
|
||||
return statementBlock;
|
||||
}
|
||||
|
||||
string StatementFunctionDeclaration::toString(int indent) {
|
||||
string value = "";
|
||||
for (int ind=0; ind<indent; ind++)
|
||||
value += " ";
|
||||
value += "FUNCTION(";
|
||||
value += valueTypeToString(returnValueType);
|
||||
value += ", " + name + "):\n";
|
||||
value += statementBlock->toString(indent+1);
|
||||
for (int ind=0; ind<indent; ind++)
|
||||
value += " ";
|
||||
value += ";";
|
||||
return value;
|
||||
}
|
||||
|
||||
//
|
||||
// StatementVarDeclaration
|
||||
StatementVarDeclaration::StatementVarDeclaration(string name, ValueType valueType, shared_ptr<Expression> expression):
|
||||
Statement(StatementKind::VAR_DECLARATION), name(name), valueType(valueType), expression(expression) {
|
||||
}
|
||||
|
||||
string StatementVarDeclaration::getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
ValueType StatementVarDeclaration::getValueType() {
|
||||
return valueType;
|
||||
}
|
||||
|
||||
shared_ptr<Expression> StatementVarDeclaration::getExpression() {
|
||||
return expression;
|
||||
}
|
||||
|
||||
string StatementVarDeclaration::toString(int indent) {
|
||||
string value;
|
||||
for (int ind=0; ind<indent; ind++)
|
||||
value += " ";
|
||||
value += name + "(";
|
||||
value += valueTypeToString(valueType);
|
||||
value += "):\n";
|
||||
for (int ind=0; ind<indent+1; ind++)
|
||||
value += " ";
|
||||
value += expression->toString(indent+1);
|
||||
value += "\n";
|
||||
return value;
|
||||
}
|
||||
|
||||
//
|
||||
// StatementBlock
|
||||
StatementBlock::StatementBlock(vector<shared_ptr<Statement>> statements):
|
||||
Statement(StatementKind::BLOCK), statements(statements) {
|
||||
if (!statements.empty() && statements.back()->getKind() == StatementKind::EXPRESSION) {
|
||||
statementExpression = dynamic_pointer_cast<StatementExpression>(statements.back());
|
||||
this->statements.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
vector<shared_ptr<Statement>> StatementBlock::getStatements() {
|
||||
return statements;
|
||||
}
|
||||
|
||||
shared_ptr<StatementExpression> StatementBlock::getStatementExpression() {
|
||||
return statementExpression;
|
||||
}
|
||||
|
||||
string StatementBlock::toString(int indent) {
|
||||
string value;
|
||||
for (int i=0; i<statements.size(); i++) {
|
||||
//for (int ind=0; ind<indent; ind++)
|
||||
// value += " ";
|
||||
value += statements.at(i)->toString(indent);
|
||||
}
|
||||
if (statementExpression != nullptr) {
|
||||
for (int ind=0; ind<indent; ind++)
|
||||
value += " ";
|
||||
value += "WRAP_UP:\n";
|
||||
value += statementExpression->toString(indent);
|
||||
}
|
||||
for (int ind=0; ind<indent; ind++)
|
||||
value += " ";
|
||||
value += "#\n";
|
||||
return value;
|
||||
}
|
||||
|
||||
//
|
||||
// StatementReturn
|
||||
StatementReturn::StatementReturn(shared_ptr<Expression> expression):
|
||||
Statement(StatementKind::RETURN), expression(expression) {
|
||||
}
|
||||
|
||||
shared_ptr<Expression> StatementReturn::getExpression() {
|
||||
return expression;
|
||||
}
|
||||
|
||||
string StatementReturn::toString(int indent) {
|
||||
string value;
|
||||
for (int ind=0; ind<indent; ind++)
|
||||
value += " ";
|
||||
value += "RETURN:\n";
|
||||
for (int ind=0; ind<indent+1; ind++)
|
||||
value += " ";
|
||||
value += expression->toString(indent+1);
|
||||
value += "\n";
|
||||
return value;
|
||||
}
|
||||
|
||||
//
|
||||
// StatementExpression
|
||||
StatementExpression::StatementExpression(shared_ptr<Expression> expression):
|
||||
Statement(StatementKind::EXPRESSION), expression(expression) {
|
||||
}
|
||||
|
||||
shared_ptr<Expression> StatementExpression::getExpression() {
|
||||
return expression;
|
||||
}
|
||||
|
||||
string StatementExpression::toString(int indent) {
|
||||
string value;
|
||||
for (int ind=0; ind<indent; ind++)
|
||||
value += " ";
|
||||
value += expression->toString(indent);
|
||||
value += "\n";
|
||||
return value;
|
||||
}
|
||||
|
||||
//
|
||||
// Statement @ Function
|
||||
StatementMetaExternFunction::StatementMetaExternFunction(string name, vector<pair<string, ValueType>> arguments, ValueType returnValueType):
|
||||
Statement(StatementKind::META_EXTERN_FUNCTION), name(name), arguments(arguments), returnValueType(returnValueType) {
|
||||
}
|
||||
|
||||
string StatementMetaExternFunction::getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
vector<pair<string, ValueType>> StatementMetaExternFunction::getArguments() {
|
||||
return arguments;
|
||||
}
|
||||
|
||||
ValueType StatementMetaExternFunction::getReturnValueType() {
|
||||
return returnValueType;
|
||||
}
|
||||
|
||||
string StatementMetaExternFunction::toString(int indent) {
|
||||
string value;
|
||||
for (int ind=0; ind<indent; ind++)
|
||||
value += " ";
|
||||
value += "EXTERN_FUN(";
|
||||
value += name + ", ";
|
||||
value += valueTypeToString(returnValueType);
|
||||
value += ")\n";
|
||||
return value;
|
||||
}
|
||||
|
||||
//
|
||||
// StatementInvalid
|
||||
StatementInvalid::StatementInvalid(shared_ptr<Token> token, string message):
|
||||
Statement(StatementKind::INVALID), token(token), message(message) {
|
||||
}
|
||||
|
||||
string StatementInvalid::toString(int indent) {
|
||||
return "Error for token " + token->toString() + " at " + to_string(token->getLine()) + ":" + to_string(token->getColumn()) + ": " + message + "\n";
|
||||
}
|
||||
|
||||
string StatementInvalid::getMessage() {
|
||||
return message;
|
||||
}
|
||||
143
src/Parser/Statement.h
Normal file
143
src/Parser/Statement.h
Normal file
@@ -0,0 +1,143 @@
|
||||
#ifndef STATEMENT_H
|
||||
#define STATEMENT_H
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "Lexer/Token.h"
|
||||
#include "Expression.h"
|
||||
#include "Types.h"
|
||||
|
||||
class Expression;
|
||||
class Statement;
|
||||
class StatementBlock;
|
||||
class StatementReturn;
|
||||
class StatementExpression;
|
||||
class StatementInvalid;
|
||||
|
||||
using namespace std;
|
||||
|
||||
enum class StatementKind {
|
||||
FUNCTION_DECLARATION,
|
||||
VAR_DECLARATION,
|
||||
BLOCK,
|
||||
RETURN,
|
||||
EXPRESSION,
|
||||
META_EXTERN_FUNCTION,
|
||||
INVALID
|
||||
};
|
||||
|
||||
//
|
||||
// Statement
|
||||
class Statement {
|
||||
private:
|
||||
StatementKind kind;
|
||||
|
||||
public:
|
||||
Statement(StatementKind kind);
|
||||
StatementKind getKind();
|
||||
bool isValid();
|
||||
virtual string toString(int indent);
|
||||
};
|
||||
|
||||
//
|
||||
// StatementFunctionDeclaration
|
||||
class StatementFunctionDeclaration: public Statement {
|
||||
private:
|
||||
string name;
|
||||
vector<pair<string, ValueType>> arguments;
|
||||
ValueType returnValueType;
|
||||
shared_ptr<StatementBlock> statementBlock;
|
||||
|
||||
public:
|
||||
StatementFunctionDeclaration(string name, vector<pair<string, ValueType>> arguments, ValueType returnValueType, shared_ptr<StatementBlock> statementBlock);
|
||||
string getName();
|
||||
vector<pair<string, ValueType>> getArguments();
|
||||
ValueType getReturnValueType();
|
||||
shared_ptr<StatementBlock> getStatementBlock();
|
||||
string toString(int indent) override;
|
||||
};
|
||||
|
||||
//
|
||||
// StatementVarDeclaration
|
||||
class StatementVarDeclaration: public Statement {
|
||||
private:
|
||||
string name;
|
||||
ValueType valueType;
|
||||
shared_ptr<Expression> expression;
|
||||
|
||||
public:
|
||||
StatementVarDeclaration(string name, ValueType valueType, shared_ptr<Expression> expression);
|
||||
string getName();
|
||||
ValueType getValueType();
|
||||
shared_ptr<Expression> getExpression();
|
||||
string toString(int indent) override;
|
||||
};
|
||||
|
||||
//
|
||||
// StatementBlock
|
||||
class StatementBlock: public Statement {
|
||||
private:
|
||||
vector<shared_ptr<Statement>> statements;
|
||||
shared_ptr<StatementExpression> statementExpression;
|
||||
|
||||
public:
|
||||
StatementBlock(vector<shared_ptr<Statement>> statements);
|
||||
vector<shared_ptr<Statement>> getStatements();
|
||||
shared_ptr<StatementExpression> getStatementExpression();
|
||||
string toString(int indent) override;
|
||||
};
|
||||
|
||||
//
|
||||
// StatementReturn
|
||||
class StatementReturn: public Statement {
|
||||
private:
|
||||
shared_ptr<Expression> expression;
|
||||
|
||||
public:
|
||||
StatementReturn(shared_ptr<Expression> expression);
|
||||
shared_ptr<Expression> getExpression();
|
||||
string toString(int indent) override;
|
||||
};
|
||||
|
||||
//
|
||||
// StatementExpression
|
||||
class StatementExpression: public Statement {
|
||||
private:
|
||||
shared_ptr<Expression> expression;
|
||||
|
||||
public:
|
||||
StatementExpression(shared_ptr<Expression> expression);
|
||||
shared_ptr<Expression> getExpression();
|
||||
string toString(int indent) override;
|
||||
};
|
||||
|
||||
//
|
||||
// Statement @ Extern Function
|
||||
class StatementMetaExternFunction: public Statement {
|
||||
private:
|
||||
string name;
|
||||
vector<pair<string, ValueType>> arguments;
|
||||
ValueType returnValueType;
|
||||
|
||||
public:
|
||||
StatementMetaExternFunction(string name, vector<pair<string, ValueType>> arguments, ValueType returnValueType);
|
||||
string getName();
|
||||
vector<pair<string, ValueType>> getArguments();
|
||||
ValueType getReturnValueType();
|
||||
string toString(int indent) override;
|
||||
};
|
||||
|
||||
//
|
||||
// StatementInvalid
|
||||
class StatementInvalid: public Statement {
|
||||
private:
|
||||
shared_ptr<Token> token;
|
||||
string message;
|
||||
|
||||
public:
|
||||
StatementInvalid(shared_ptr<Token> token, string message);
|
||||
string toString(int indent) override;
|
||||
string getMessage();
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user