types in separate file
This commit is contained in:
@@ -1,19 +1,19 @@
|
||||
#include "Expression.h"
|
||||
|
||||
Expression::Expression(Kind kind, ValueType valueType):
|
||||
Expression::Expression(ExpressionKind kind, ValueType valueType):
|
||||
kind(kind), valueType(valueType) {
|
||||
}
|
||||
|
||||
Expression::Kind Expression::getKind() {
|
||||
ExpressionKind Expression::getKind() {
|
||||
return kind;
|
||||
}
|
||||
|
||||
Expression::ValueType Expression::getValueType() {
|
||||
ValueType Expression::getValueType() {
|
||||
return valueType;
|
||||
}
|
||||
|
||||
bool Expression::isValid() {
|
||||
return kind != Expression::Kind::INVALID;
|
||||
return kind != ExpressionKind::INVALID;
|
||||
}
|
||||
|
||||
string Expression::toString(int indent) {
|
||||
@@ -23,57 +23,57 @@ string Expression::toString(int indent) {
|
||||
//
|
||||
// ExpressionBinary
|
||||
ExpressionBinary::ExpressionBinary(shared_ptr<Token> token, shared_ptr<Expression> left, shared_ptr<Expression> right):
|
||||
Expression(Expression::Kind::BINARY, Expression::ValueType::VOID), left(left), right(right) {
|
||||
Expression(ExpressionKind::BINARY, ValueType::VOID), left(left), right(right) {
|
||||
// Types must match
|
||||
if (left->getValueType() != right->getValueType())
|
||||
exit(1);
|
||||
|
||||
// Booleans can only do = or !=
|
||||
if (valueType == Expression::ValueType::BOOL && (token->getKind() != Token::Kind::EQUAL || token->getKind() != Token::Kind::NOT_EQUAL))
|
||||
if (valueType == ValueType::BOOL && (token->getKind() != TokenKind::EQUAL || token->getKind() != TokenKind::NOT_EQUAL))
|
||||
exit(1);
|
||||
|
||||
switch (token->getKind()) {
|
||||
case Token::Kind::EQUAL:
|
||||
case TokenKind::EQUAL:
|
||||
operation = EQUAL;
|
||||
valueType = Expression::ValueType::BOOL;
|
||||
valueType = ValueType::BOOL;
|
||||
break;
|
||||
case Token::Kind::NOT_EQUAL:
|
||||
case TokenKind::NOT_EQUAL:
|
||||
operation = NOT_EQUAL;
|
||||
valueType = Expression::ValueType::BOOL;
|
||||
valueType = ValueType::BOOL;
|
||||
break;
|
||||
case Token::Kind::LESS:
|
||||
case TokenKind::LESS:
|
||||
operation = LESS;
|
||||
valueType = Expression::ValueType::BOOL;
|
||||
valueType = ValueType::BOOL;
|
||||
break;
|
||||
case Token::Kind::LESS_EQUAL:
|
||||
case TokenKind::LESS_EQUAL:
|
||||
operation = LESS_EQUAL;
|
||||
valueType = Expression::ValueType::BOOL;
|
||||
valueType = ValueType::BOOL;
|
||||
break;
|
||||
case Token::Kind::GREATER:
|
||||
case TokenKind::GREATER:
|
||||
operation = GREATER;
|
||||
valueType = Expression::ValueType::BOOL;
|
||||
valueType = ValueType::BOOL;
|
||||
break;
|
||||
case Token::Kind::GREATER_EQUAL:
|
||||
case TokenKind::GREATER_EQUAL:
|
||||
operation = GREATER_EQUAL;
|
||||
valueType = Expression::ValueType::BOOL;
|
||||
valueType = ValueType::BOOL;
|
||||
break;
|
||||
case Token::Kind::PLUS:
|
||||
case TokenKind::PLUS:
|
||||
operation = ADD;
|
||||
valueType = left->getValueType();
|
||||
break;
|
||||
case Token::Kind::MINUS:
|
||||
case TokenKind::MINUS:
|
||||
operation = SUB;
|
||||
valueType = left->getValueType();
|
||||
break;
|
||||
case Token::Kind::STAR:
|
||||
case TokenKind::STAR:
|
||||
operation = MUL;
|
||||
valueType = left->getValueType();
|
||||
break;
|
||||
case Token::Kind::SLASH:
|
||||
case TokenKind::SLASH:
|
||||
operation = DIV;
|
||||
valueType = left->getValueType();
|
||||
break;
|
||||
case Token::Kind::PERCENT:
|
||||
case TokenKind::PERCENT:
|
||||
operation = MOD;
|
||||
valueType = left->getValueType();
|
||||
break;
|
||||
@@ -124,19 +124,19 @@ string ExpressionBinary::toString(int indent) {
|
||||
//
|
||||
// ExpressionLiteral
|
||||
ExpressionLiteral::ExpressionLiteral(shared_ptr<Token> token):
|
||||
Expression(Expression::Kind::LITERAL, Expression::ValueType::VOID) {
|
||||
Expression(ExpressionKind::LITERAL, ValueType::VOID) {
|
||||
switch (token->getKind()) {
|
||||
case Token::Kind::BOOL:
|
||||
case TokenKind::BOOL:
|
||||
boolValue = token->getLexme().compare("true") == 0;
|
||||
valueType = Expression::ValueType::BOOL;
|
||||
valueType = ValueType::BOOL;
|
||||
break;
|
||||
case Token::Kind::INTEGER:
|
||||
case TokenKind::INTEGER:
|
||||
sint32Value = stoi(token->getLexme());
|
||||
valueType = Expression::ValueType::SINT32;
|
||||
valueType = ValueType::SINT32;
|
||||
break;
|
||||
case Token::Kind::REAL:
|
||||
case TokenKind::REAL:
|
||||
real32Value = stof(token->getLexme());
|
||||
valueType = Expression::ValueType::REAL32;
|
||||
valueType = ValueType::REAL32;
|
||||
break;
|
||||
default:
|
||||
exit(1);
|
||||
@@ -147,7 +147,7 @@ bool ExpressionLiteral::getBoolValue() {
|
||||
return boolValue;
|
||||
}
|
||||
|
||||
int32_t ExpressionLiteral::getSint32Value() {
|
||||
int32_t ExpressionLiteral::getSInt32Value() {
|
||||
return sint32Value;
|
||||
}
|
||||
|
||||
@@ -157,13 +157,13 @@ float ExpressionLiteral::getReal32Value() {
|
||||
|
||||
string ExpressionLiteral::toString(int indent) {
|
||||
switch (valueType) {
|
||||
case Expression::ValueType::VOID:
|
||||
case ValueType::VOID:
|
||||
return "VOID";
|
||||
case Expression::ValueType::BOOL:
|
||||
return to_string(boolValue);
|
||||
case Expression::ValueType::SINT32:
|
||||
case ValueType::BOOL:
|
||||
return boolValue ? "true" : "false";
|
||||
case ValueType::SINT32:
|
||||
return to_string(sint32Value);
|
||||
case Expression::ValueType::REAL32:
|
||||
case ValueType::REAL32:
|
||||
return to_string(real32Value);
|
||||
}
|
||||
}
|
||||
@@ -171,7 +171,7 @@ string ExpressionLiteral::toString(int indent) {
|
||||
//
|
||||
// ExpressionGrouping
|
||||
ExpressionGrouping::ExpressionGrouping(shared_ptr<Expression> expression):
|
||||
Expression(Expression::Kind::GROUPING, expression->getValueType()), expression(expression) {
|
||||
Expression(ExpressionKind::GROUPING, expression->getValueType()), expression(expression) {
|
||||
}
|
||||
|
||||
shared_ptr<Expression> ExpressionGrouping::getExpression() {
|
||||
@@ -185,9 +185,9 @@ string ExpressionGrouping::toString(int indent) {
|
||||
//
|
||||
// ExpressionIfElse
|
||||
ExpressionIfElse::ExpressionIfElse(shared_ptr<Expression> condition, shared_ptr<StatementBlock> thenBlock, shared_ptr<StatementBlock> elseBlock):
|
||||
Expression(Expression::Kind::IF_ELSE, Expression::ValueType::VOID), condition(condition), thenBlock(thenBlock), elseBlock(elseBlock) {
|
||||
Expression(ExpressionKind::IF_ELSE, ValueType::VOID), condition(condition), thenBlock(thenBlock), elseBlock(elseBlock) {
|
||||
// Condition must evaluate to bool
|
||||
if (condition->getValueType() != Expression::ValueType::BOOL)
|
||||
if (condition->getValueType() != ValueType::BOOL)
|
||||
exit(1);
|
||||
|
||||
// Return types must match
|
||||
@@ -199,7 +199,7 @@ ExpressionIfElse::ExpressionIfElse(shared_ptr<Expression> condition, shared_ptr<
|
||||
exit(1);
|
||||
|
||||
// get type or default to void
|
||||
valueType = thenExpression ? thenExpression->getValueType() : Expression::ValueType::VOID;
|
||||
valueType = thenExpression ? thenExpression->getValueType() : ValueType::VOID;
|
||||
}
|
||||
|
||||
shared_ptr<Expression> ExpressionIfElse::getCondition() {
|
||||
@@ -235,7 +235,7 @@ string ExpressionIfElse::toString(int indent) {
|
||||
//
|
||||
// ExpressionInvalid
|
||||
ExpressionInvalid::ExpressionInvalid(shared_ptr<Token> token):
|
||||
Expression(Expression::Kind::INVALID, Expression::ValueType::VOID), token(token) {
|
||||
Expression(ExpressionKind::INVALID, ValueType::VOID), token(token) {
|
||||
}
|
||||
|
||||
shared_ptr<Token> ExpressionInvalid::getToken() {
|
||||
|
||||
@@ -3,43 +3,32 @@
|
||||
|
||||
#include "Token.h"
|
||||
#include "Statement.h"
|
||||
#include "Types.h"
|
||||
|
||||
class StatementBlock;
|
||||
class StatementExpression;
|
||||
|
||||
using namespace std;
|
||||
|
||||
//
|
||||
// Expression
|
||||
class Expression {
|
||||
public:
|
||||
enum Kind {
|
||||
LITERAL,
|
||||
GROUPING,
|
||||
BINARY,
|
||||
IF_ELSE,
|
||||
INVALID
|
||||
};
|
||||
|
||||
enum ValueType {
|
||||
VOID,
|
||||
BOOL,
|
||||
SINT32,
|
||||
REAL32
|
||||
};
|
||||
|
||||
private:
|
||||
Kind kind;
|
||||
ExpressionKind kind;
|
||||
|
||||
protected:
|
||||
ValueType valueType;
|
||||
|
||||
public:
|
||||
Expression(Kind kind, ValueType valueType);
|
||||
Kind getKind();
|
||||
Expression(ExpressionKind kind, ValueType valueType);
|
||||
ExpressionKind getKind();
|
||||
ValueType getValueType();
|
||||
bool isValid();
|
||||
virtual string toString(int indent);
|
||||
};
|
||||
|
||||
//
|
||||
// ExpressionLiteral
|
||||
class ExpressionLiteral: public Expression {
|
||||
private:
|
||||
bool boolValue;
|
||||
@@ -49,11 +38,13 @@ private:
|
||||
public:
|
||||
ExpressionLiteral(shared_ptr<Token> token);
|
||||
bool getBoolValue();
|
||||
int32_t getSint32Value();
|
||||
int32_t getSInt32Value();
|
||||
float getReal32Value();
|
||||
string toString(int indent) override;
|
||||
};
|
||||
|
||||
//
|
||||
// ExpressionGrouping
|
||||
class ExpressionGrouping: public Expression {
|
||||
private:
|
||||
shared_ptr<Expression> expression;
|
||||
@@ -64,6 +55,8 @@ public:
|
||||
string toString(int indent) override;
|
||||
};
|
||||
|
||||
//
|
||||
// ExpressionBinary
|
||||
class ExpressionBinary: public Expression {
|
||||
public:
|
||||
enum Operation {
|
||||
@@ -93,6 +86,8 @@ public:
|
||||
string toString(int indent) override;
|
||||
};
|
||||
|
||||
//
|
||||
// ExpressionIfElse
|
||||
class ExpressionIfElse: public Expression {
|
||||
private:
|
||||
shared_ptr<Expression> condition;
|
||||
@@ -107,6 +102,8 @@ public:
|
||||
string toString(int indent) override;
|
||||
};
|
||||
|
||||
//
|
||||
// ExpressionInvalid
|
||||
class ExpressionInvalid: public Expression {
|
||||
private:
|
||||
shared_ptr<Token> token;
|
||||
|
||||
@@ -21,9 +21,9 @@ vector<shared_ptr<Token>> Lexer::getTokens() {
|
||||
}
|
||||
|
||||
// filter out multiple new lines
|
||||
if (tokens.empty() || token->getKind() != Token::Kind::NEW_LINE || tokens.back()->getKind() != token->getKind())
|
||||
if (tokens.empty() || token->getKind() != TokenKind::NEW_LINE || tokens.back()->getKind() != token->getKind())
|
||||
tokens.push_back(token);
|
||||
} while (token->getKind() != Token::Kind::END);
|
||||
} while (token->getKind() != TokenKind::END);
|
||||
return tokens;
|
||||
}
|
||||
|
||||
@@ -37,12 +37,12 @@ shared_ptr<Token> Lexer::nextToken() {
|
||||
shared_ptr<Token> token;
|
||||
|
||||
// ignore // comment
|
||||
token = match(Token::Kind::INVALID, "//", false);
|
||||
token = match(TokenKind::INVALID, "//", false);
|
||||
if (token) {
|
||||
currentIndex += 2;
|
||||
do {
|
||||
// new line
|
||||
token = match(Token::Kind::NEW_LINE, "\n", false);
|
||||
token = match(TokenKind::NEW_LINE, "\n", false);
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
|
||||
@@ -57,13 +57,13 @@ shared_ptr<Token> Lexer::nextToken() {
|
||||
}
|
||||
|
||||
// ignore /* */ comment
|
||||
token = match(Token::Kind::INVALID, "/*", false);
|
||||
token = match(TokenKind::INVALID, "/*", false);
|
||||
if (token) {
|
||||
shared_ptr<Token> newLineToken = nullptr; // we want to return the first new line we come accross
|
||||
int depth = 1; // so we can embed comments inside each other
|
||||
do {
|
||||
// new line
|
||||
token = match(Token::Kind::NEW_LINE, "\n", false);
|
||||
token = match(TokenKind::NEW_LINE, "\n", false);
|
||||
newLineToken = newLineToken ? newLineToken : token;
|
||||
if (token) {
|
||||
continue;;
|
||||
@@ -72,17 +72,17 @@ shared_ptr<Token> Lexer::nextToken() {
|
||||
// eof
|
||||
token = matchEnd();
|
||||
if (token)
|
||||
return make_shared<Token>(Token::Kind::INVALID, "", currentLine, currentColumn);
|
||||
return make_shared<Token>(TokenKind::INVALID, "", currentLine, currentColumn);
|
||||
|
||||
// go deeper
|
||||
token = match(Token::Kind::INVALID, "/*", false);
|
||||
token = match(TokenKind::INVALID, "/*", false);
|
||||
if (token) {
|
||||
depth++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// go back
|
||||
token = match(Token::Kind::INVALID, "*/", false);
|
||||
token = match(TokenKind::INVALID, "*/", false);
|
||||
if (token) {
|
||||
depth--;
|
||||
}
|
||||
@@ -100,90 +100,90 @@ shared_ptr<Token> Lexer::nextToken() {
|
||||
}
|
||||
|
||||
// arithmetic
|
||||
token = match(Token::Kind::PLUS, "+", false);
|
||||
token = match(TokenKind::PLUS, "+", false);
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
|
||||
token = match(Token::Kind::MINUS, "-", false);
|
||||
token = match(TokenKind::MINUS, "-", false);
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
|
||||
token = match(Token::Kind::STAR, "*", false);
|
||||
token = match(TokenKind::STAR, "*", false);
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
|
||||
token = match(Token::Kind::SLASH, "/", false);
|
||||
token = match(TokenKind::SLASH, "/", false);
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
|
||||
token = match(Token::Kind::PERCENT, "%", false);
|
||||
token = match(TokenKind::PERCENT, "%", false);
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
|
||||
// comparison
|
||||
token = match(Token::Kind::NOT_EQUAL, "!=", false);
|
||||
token = match(TokenKind::NOT_EQUAL, "!=", false);
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
|
||||
token = match(Token::Kind::EQUAL, "=", false);
|
||||
token = match(TokenKind::EQUAL, "=", false);
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
|
||||
token = match(Token::Kind::LESS_EQUAL, "<=", false);
|
||||
token = match(TokenKind::LESS_EQUAL, "<=", false);
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
|
||||
token = match(Token::Kind::LESS, "<", false);
|
||||
token = match(TokenKind::LESS, "<", false);
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
|
||||
token = match(Token::Kind::GREATER_EQUAL, ">=", false);
|
||||
token = match(TokenKind::GREATER_EQUAL, ">=", false);
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
|
||||
token = match(Token::Kind::GREATER, ">", false);
|
||||
token = match(TokenKind::GREATER, ">", false);
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
|
||||
// structural
|
||||
token = match(Token::Kind::LEFT_PAREN, "(", false);
|
||||
token = match(TokenKind::LEFT_PAREN, "(", false);
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
|
||||
token = match(Token::Kind::RIGHT_PAREN, ")", false);
|
||||
token = match(TokenKind::RIGHT_PAREN, ")", false);
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
|
||||
token = match(Token::Kind::COLON, ":", false);
|
||||
token = match(TokenKind::COLON, ":", false);
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
|
||||
token = match(Token::Kind::SEMICOLON, ";", false);
|
||||
token = match(TokenKind::SEMICOLON, ";", false);
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
|
||||
token = match(Token::Kind::QUESTION_QUESTION, "??", false);
|
||||
token = match(TokenKind::QUESTION_QUESTION, "??", false);
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
|
||||
token = match(Token::Kind::QUESTION, "?", false);
|
||||
token = match(TokenKind::QUESTION, "?", false);
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
|
||||
// keywords
|
||||
token = match(Token::Kind::FUNCTION, "fun", true);
|
||||
token = match(TokenKind::FUNCTION, "fun", true);
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
|
||||
token = match(Token::Kind::RETURN, "ret", true);
|
||||
token = match(TokenKind::RETURN, "ret", true);
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
|
||||
token = match(Token::Kind::BOOL, "true", true);
|
||||
token = match(TokenKind::BOOL, "true", true);
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
|
||||
token = match(Token::Kind::BOOL, "false", true);
|
||||
token = match(TokenKind::BOOL, "false", true);
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
|
||||
@@ -202,7 +202,7 @@ shared_ptr<Token> Lexer::nextToken() {
|
||||
return token;
|
||||
|
||||
// new line
|
||||
token = match(Token::Kind::NEW_LINE, "\n", false);
|
||||
token = match(TokenKind::NEW_LINE, "\n", false);
|
||||
if (token != nullptr)
|
||||
return token;
|
||||
|
||||
@@ -214,7 +214,7 @@ shared_ptr<Token> Lexer::nextToken() {
|
||||
return matchInvalid();
|
||||
}
|
||||
|
||||
shared_ptr<Token> Lexer::match(Token::Kind kind, string lexme, bool needsSeparator) {
|
||||
shared_ptr<Token> Lexer::match(TokenKind kind, string lexme, bool needsSeparator) {
|
||||
bool isMatching = source.compare(currentIndex, lexme.length(), lexme) == 0;
|
||||
bool isSeparatorSatisfied = !needsSeparator || isSeparator(currentIndex + lexme.length());
|
||||
|
||||
@@ -236,7 +236,7 @@ shared_ptr<Token> Lexer::matchInteger() {
|
||||
return nullptr;
|
||||
|
||||
string lexme = source.substr(currentIndex, nextIndex - currentIndex);
|
||||
shared_ptr<Token> token = make_shared<Token>(Token::Kind::INTEGER, lexme, currentLine, currentColumn);
|
||||
shared_ptr<Token> token = make_shared<Token>(TokenKind::INTEGER, lexme, currentLine, currentColumn);
|
||||
advanceWithToken(token);
|
||||
return token;
|
||||
}
|
||||
@@ -259,7 +259,7 @@ shared_ptr<Token> Lexer::matchReal() {
|
||||
return matchInvalid();
|
||||
|
||||
string lexme = source.substr(currentIndex, nextIndex - currentIndex);
|
||||
shared_ptr<Token> token = make_shared<Token>(Token::Kind::REAL, lexme, currentLine, currentColumn);
|
||||
shared_ptr<Token> token = make_shared<Token>(TokenKind::REAL, lexme, currentLine, currentColumn);
|
||||
advanceWithToken(token);
|
||||
return token;
|
||||
}
|
||||
@@ -274,20 +274,20 @@ shared_ptr<Token> Lexer::matchIdentifier() {
|
||||
return nullptr;
|
||||
|
||||
string lexme = source.substr(currentIndex, nextIndex - currentIndex);
|
||||
shared_ptr<Token> token = make_shared<Token>(Token::Kind::IDENTIFIER, lexme, currentLine, currentColumn);
|
||||
shared_ptr<Token> token = make_shared<Token>(TokenKind::IDENTIFIER, lexme, currentLine, currentColumn);
|
||||
advanceWithToken(token);
|
||||
return token;
|
||||
}
|
||||
|
||||
shared_ptr<Token> Lexer::matchEnd() {
|
||||
if (currentIndex >= source.length())
|
||||
return make_shared<Token>(Token::Kind::END, "", currentLine, currentColumn);
|
||||
return make_shared<Token>(TokenKind::END, "", currentLine, currentColumn);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
shared_ptr<Token> Lexer::matchInvalid() {
|
||||
return make_shared<Token>(Token::Kind::INVALID, source.substr(currentIndex, 1), currentLine, currentColumn);
|
||||
return make_shared<Token>(TokenKind::INVALID, source.substr(currentIndex, 1), currentLine, currentColumn);
|
||||
}
|
||||
|
||||
bool Lexer::isWhiteSpace(int index) {
|
||||
@@ -337,7 +337,7 @@ bool Lexer::isSeparator(int index) {
|
||||
}
|
||||
|
||||
void Lexer::advanceWithToken(shared_ptr<Token> token) {
|
||||
if (token->getKind() == Token::Kind::NEW_LINE) {
|
||||
if (token->getKind() == TokenKind::NEW_LINE) {
|
||||
currentLine++;
|
||||
currentColumn = 0;
|
||||
} else {
|
||||
|
||||
@@ -15,7 +15,7 @@ private:
|
||||
int currentColumn = 0;
|
||||
|
||||
shared_ptr<Token> nextToken();
|
||||
shared_ptr<Token> match(Token::Kind kind, string lexme, bool needsSeparator);
|
||||
shared_ptr<Token> match(TokenKind kind, string lexme, bool needsSeparator);
|
||||
shared_ptr<Token> matchInteger();
|
||||
shared_ptr<Token> matchReal();
|
||||
shared_ptr<Token> matchIdentifier();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "ModuleBuilder.h"
|
||||
|
||||
/*ModuleBuilder::ModuleBuilder(vector<shared_ptr<Statement>> statements): statements(statements) {
|
||||
ModuleBuilder::ModuleBuilder(vector<shared_ptr<Statement>> statements): statements(statements) {
|
||||
context = make_shared<llvm::LLVMContext>();
|
||||
module = make_shared<llvm::Module>("dummy", *context);
|
||||
builder = make_shared<llvm::IRBuilder<>>(*context);
|
||||
@@ -20,16 +20,16 @@ shared_ptr<llvm::Module> ModuleBuilder::getModule() {
|
||||
|
||||
void ModuleBuilder::buildStatement(shared_ptr<Statement> statement) {
|
||||
switch (statement->getKind()) {
|
||||
case Statement::Kind::FUNCTION_DECLARATION:
|
||||
case StatementKind::FUNCTION_DECLARATION:
|
||||
buildFunctionDeclaration(dynamic_pointer_cast<StatementFunctionDeclaration>(statement));
|
||||
break;
|
||||
case Statement::Kind::BLOCK:
|
||||
case StatementKind::BLOCK:
|
||||
buildBlock(dynamic_pointer_cast<StatementBlock>(statement));
|
||||
break;
|
||||
case Statement::Kind::RETURN:
|
||||
case StatementKind::RETURN:
|
||||
buildReturn(dynamic_pointer_cast<StatementReturn>(statement));
|
||||
break;
|
||||
case Statement::Kind::EXPRESSION:
|
||||
case StatementKind::EXPRESSION:
|
||||
buildExpression(dynamic_pointer_cast<StatementExpression>(statement));
|
||||
return;
|
||||
default:
|
||||
@@ -49,6 +49,8 @@ void ModuleBuilder::buildBlock(shared_ptr<StatementBlock> statement) {
|
||||
for (shared_ptr<Statement> &innerStatement : statement->getStatements()) {
|
||||
buildStatement(innerStatement);
|
||||
}
|
||||
if (statement->getStatementExpression() != nullptr)
|
||||
buildStatement(statement->getStatementExpression());
|
||||
}
|
||||
|
||||
void ModuleBuilder::buildReturn(shared_ptr<StatementReturn> statement) {
|
||||
@@ -66,13 +68,13 @@ void ModuleBuilder::buildExpression(shared_ptr<StatementExpression> statement) {
|
||||
|
||||
llvm::Value *ModuleBuilder::valueForExpression(shared_ptr<Expression> expression) {
|
||||
switch (expression->getKind()) {
|
||||
case Expression::Kind::LITERAL:
|
||||
case ExpressionKind::LITERAL:
|
||||
return valueForLiteral(dynamic_pointer_cast<ExpressionLiteral>(expression));
|
||||
case Expression::Kind::GROUPING:
|
||||
case ExpressionKind::GROUPING:
|
||||
return valueForExpression(dynamic_pointer_cast<ExpressionGrouping>(expression)->getExpression());
|
||||
case Expression::Kind::BINARY:
|
||||
case ExpressionKind::BINARY:
|
||||
return valueForBinary(dynamic_pointer_cast<ExpressionBinary>(expression));
|
||||
case Expression::Kind::IF_ELSE:
|
||||
case ExpressionKind::IF_ELSE:
|
||||
return valueForIfElse(dynamic_pointer_cast<ExpressionIfElse>(expression));
|
||||
default:
|
||||
exit(1);
|
||||
@@ -80,8 +82,16 @@ llvm::Value *ModuleBuilder::valueForExpression(shared_ptr<Expression> expression
|
||||
}
|
||||
|
||||
llvm::Value *ModuleBuilder::valueForLiteral(shared_ptr<ExpressionLiteral> expression) {
|
||||
//return llvm::ConstantInt::get(int32Type, expression->getInteger(), true);
|
||||
return llvm::ConstantInt::get(typeSInt32, expression->getSint32Value(), true);
|
||||
switch (expression->getValueType()) {
|
||||
case ValueType::VOID:
|
||||
return llvm::UndefValue::get(typeVoid);
|
||||
case ValueType::BOOL:
|
||||
return llvm::ConstantInt::get(typeBool, expression->getBoolValue(), true);
|
||||
case ValueType::SINT32:
|
||||
return llvm::ConstantInt::get(typeSInt32, expression->getSInt32Value(), true);
|
||||
case ValueType::REAL32:
|
||||
return llvm::ConstantInt::get(typeReal32, expression->getReal32Value(), true);
|
||||
}
|
||||
}
|
||||
|
||||
llvm::Value *ModuleBuilder::valueForGrouping(shared_ptr<ExpressionGrouping> expression) {
|
||||
@@ -89,6 +99,33 @@ llvm::Value *ModuleBuilder::valueForGrouping(shared_ptr<ExpressionGrouping> expr
|
||||
}
|
||||
|
||||
llvm::Value *ModuleBuilder::valueForBinary(shared_ptr<ExpressionBinary> expression) {
|
||||
switch (expression->getValueType()) {
|
||||
case ValueType::BOOL:
|
||||
return valueForBinaryBool(expression);
|
||||
case ValueType::SINT32:
|
||||
return valueForBinaryInteger(expression);
|
||||
case ValueType::REAL32:
|
||||
return valueForBinaryReal(expression);
|
||||
default:
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
llvm::Value *ModuleBuilder::valueForBinaryBool(shared_ptr<ExpressionBinary> expression) {
|
||||
llvm::Value *leftValue = valueForExpression(expression->getLeft());
|
||||
llvm::Value *rightValue = valueForExpression(expression->getRight());
|
||||
|
||||
switch (expression->getOperation()) {
|
||||
case ExpressionBinary::Operation::EQUAL:
|
||||
return builder->CreateICmpEQ(leftValue, rightValue);
|
||||
case ExpressionBinary::Operation::NOT_EQUAL:
|
||||
return builder->CreateICmpNE(leftValue, rightValue);
|
||||
default:
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
llvm::Value *ModuleBuilder::valueForBinaryInteger(shared_ptr<ExpressionBinary> expression) {
|
||||
llvm::Value *leftValue = valueForExpression(expression->getLeft());
|
||||
llvm::Value *rightValue = valueForExpression(expression->getRight());
|
||||
|
||||
@@ -118,40 +155,79 @@ llvm::Value *ModuleBuilder::valueForBinary(shared_ptr<ExpressionBinary> expressi
|
||||
}
|
||||
}
|
||||
|
||||
llvm::Value *ModuleBuilder::valueForBinaryReal(shared_ptr<ExpressionBinary> expression) {
|
||||
llvm::Value *leftValue = valueForExpression(expression->getLeft());
|
||||
llvm::Value *rightValue = valueForExpression(expression->getRight());
|
||||
|
||||
switch (expression->getOperation()) {
|
||||
case ExpressionBinary::Operation::EQUAL:
|
||||
return builder->CreateFCmpOEQ(leftValue, rightValue);
|
||||
case ExpressionBinary::Operation::NOT_EQUAL:
|
||||
return builder->CreateFCmpONE(leftValue, rightValue);
|
||||
case ExpressionBinary::Operation::LESS:
|
||||
return builder->CreateFCmpOLT(leftValue, rightValue);
|
||||
case ExpressionBinary::Operation::LESS_EQUAL:
|
||||
return builder->CreateFCmpOLE(leftValue, rightValue);
|
||||
case ExpressionBinary::Operation::GREATER:
|
||||
return builder->CreateFCmpOGT(leftValue, rightValue);
|
||||
case ExpressionBinary::Operation::GREATER_EQUAL:
|
||||
return builder->CreateFCmpOGE(leftValue, rightValue);
|
||||
case ExpressionBinary::Operation::ADD:
|
||||
return builder->CreateNSWAdd(leftValue, rightValue);
|
||||
case ExpressionBinary::Operation::SUB:
|
||||
return builder->CreateNSWSub(leftValue, rightValue);
|
||||
case ExpressionBinary::Operation::MUL:
|
||||
return builder->CreateNSWMul(leftValue, rightValue);
|
||||
case ExpressionBinary::Operation::DIV:
|
||||
return builder->CreateSDiv(leftValue, rightValue);
|
||||
case ExpressionBinary::Operation::MOD:
|
||||
return builder->CreateSRem(leftValue, rightValue);
|
||||
}
|
||||
}
|
||||
|
||||
llvm::Value *ModuleBuilder::valueForIfElse(shared_ptr<ExpressionIfElse> expression) {
|
||||
shared_ptr<ExpressionBinary> conditionExpression = dynamic_pointer_cast<ExpressionBinary>(expression->getCondition());
|
||||
shared_ptr<Expression> conditionExpression = expression->getCondition();
|
||||
|
||||
llvm::Function *fun = builder->GetInsertBlock()->getParent();
|
||||
llvm::Value *conditionValue = valueForBinary(conditionExpression);
|
||||
//llvm::Value *conditionValue = valueForBinary(conditionExpression);
|
||||
llvm::Value *conditionValue = valueForExpression(conditionExpression);
|
||||
|
||||
llvm::BasicBlock *thenBlock = llvm::BasicBlock::Create(*context, "thenBlock", fun);
|
||||
llvm::BasicBlock *elseBlock = llvm::BasicBlock::Create(*context, "elseBlock");
|
||||
llvm::BasicBlock *mergeBlock = llvm::BasicBlock::Create(*context, "mergeBlock");
|
||||
|
||||
int valuesCount = 1;
|
||||
builder->CreateCondBr(conditionValue, thenBlock, elseBlock);
|
||||
|
||||
// Then
|
||||
builder->SetInsertPoint(thenBlock);
|
||||
llvm::Value *thenValue = llvm::ConstantInt::get(typeSInt32, 11, true);
|
||||
llvm::Value *thenValue = valueForExpression(expression->getThenBlock()->getStatementExpression()->getExpression());
|
||||
buildStatement(expression->getThenBlock());
|
||||
//llvm::Value *thenValue = llvm::ConstantInt::get(typeSInt32, 11, true);
|
||||
//buildStatement(expression->getThenBlock());
|
||||
builder->CreateBr(mergeBlock);
|
||||
thenBlock = builder->GetInsertBlock();
|
||||
|
||||
// Else
|
||||
fun->insert(fun->end(), elseBlock);
|
||||
llvm::Value *elseValue = llvm::ConstantInt::get(typeSInt32, 22, true);
|
||||
//llvm::Value *elseValue = llvm::ConstantInt::get(typeSInt32, 22, true);
|
||||
builder->SetInsertPoint(elseBlock);
|
||||
if (expression->getElseBlock() != nullptr)
|
||||
llvm::Value *elseValue = nullptr;
|
||||
if (expression->getElseBlock() != nullptr) {
|
||||
valuesCount++;
|
||||
elseValue = valueForExpression(expression->getElseBlock()->getStatementExpression()->getExpression());
|
||||
buildStatement(expression->getElseBlock());
|
||||
}
|
||||
builder->CreateBr(mergeBlock);
|
||||
elseBlock = builder->GetInsertBlock();
|
||||
|
||||
// Merge
|
||||
fun->insert(fun->end(), mergeBlock);
|
||||
builder->SetInsertPoint(mergeBlock);
|
||||
llvm::PHINode *phi = builder->CreatePHI(typeSInt32, 2, "phii");
|
||||
llvm::PHINode *phi = builder->CreatePHI(typeForExpression(expression), valuesCount, "phii");
|
||||
phi->addIncoming(thenValue, thenBlock);
|
||||
phi->addIncoming(elseValue, elseBlock);
|
||||
if (elseValue != nullptr)
|
||||
phi->addIncoming(elseValue, elseBlock);
|
||||
|
||||
//return llvm::ConstantInt::get(int32Type, 42, true);
|
||||
return phi;
|
||||
@@ -159,13 +235,13 @@ llvm::Value *ModuleBuilder::valueForIfElse(shared_ptr<ExpressionIfElse> expressi
|
||||
|
||||
llvm::Type *ModuleBuilder::typeForExpression(shared_ptr<Expression> expression) {
|
||||
switch (expression->getValueType()) {
|
||||
case Expression::ValueType::VOID:
|
||||
case ValueType::VOID:
|
||||
return typeVoid;
|
||||
case Expression::ValueType::BOOL:
|
||||
case ValueType::BOOL:
|
||||
return typeBool;
|
||||
case Expression::ValueType::SINT32:
|
||||
case ValueType::SINT32:
|
||||
return typeSInt32;
|
||||
case Expression::ValueType::REAL32:
|
||||
case ValueType::REAL32:
|
||||
return typeReal32;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
using namespace std;
|
||||
|
||||
class ModuleBuilder {
|
||||
/*private:
|
||||
private:
|
||||
shared_ptr<llvm::LLVMContext> context;
|
||||
shared_ptr<llvm::Module> module;
|
||||
shared_ptr<llvm::IRBuilder<>> builder;
|
||||
@@ -35,13 +35,16 @@ class ModuleBuilder {
|
||||
llvm::Value *valueForLiteral(shared_ptr<ExpressionLiteral> expression);
|
||||
llvm::Value *valueForGrouping(shared_ptr<ExpressionGrouping> expression);
|
||||
llvm::Value *valueForBinary(shared_ptr<ExpressionBinary> expression);
|
||||
llvm::Value *valueForBinaryBool(shared_ptr<ExpressionBinary> expression);
|
||||
llvm::Value *valueForBinaryInteger(shared_ptr<ExpressionBinary> expression);
|
||||
llvm::Value *valueForBinaryReal(shared_ptr<ExpressionBinary> expression);
|
||||
llvm::Value *valueForIfElse(shared_ptr<ExpressionIfElse> expression);
|
||||
|
||||
llvm::Type *typeForExpression(shared_ptr<Expression> expression);
|
||||
|
||||
public:
|
||||
ModuleBuilder(vector<shared_ptr<Statement>> statements);
|
||||
shared_ptr<llvm::Module> getModule();*/
|
||||
shared_ptr<llvm::Module> getModule();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -6,7 +6,7 @@ Parser::Parser(vector<shared_ptr<Token>> tokens): tokens(tokens) {
|
||||
vector<shared_ptr<Statement>> Parser::getStatements() {
|
||||
vector<shared_ptr<Statement>> statements;
|
||||
|
||||
while (tokens.at(currentIndex)->getKind() != Token::Kind::END) {
|
||||
while (tokens.at(currentIndex)->getKind() != TokenKind::END) {
|
||||
shared_ptr<Statement> statement = nextStatement();
|
||||
// Abort parsing if we got an error
|
||||
if (!statement->isValid()) {
|
||||
@@ -41,7 +41,7 @@ shared_ptr<Statement> Parser::nextStatement() {
|
||||
}
|
||||
|
||||
shared_ptr<Statement> Parser::matchStatementFunctionDeclaration() {
|
||||
if (!matchesTokenKinds({Token::Kind::IDENTIFIER, Token::Kind::COLON, Token::Kind::FUNCTION}))
|
||||
if (!matchesTokenKinds({TokenKind::IDENTIFIER, TokenKind::COLON, TokenKind::FUNCTION}))
|
||||
return nullptr;
|
||||
|
||||
shared_ptr<Token> identifierToken = tokens.at(currentIndex);
|
||||
@@ -49,7 +49,7 @@ shared_ptr<Statement> Parser::matchStatementFunctionDeclaration() {
|
||||
currentIndex++; // skip colon
|
||||
currentIndex++; // skip fun
|
||||
|
||||
while (tokens.at(currentIndex)->getKind() != Token::Kind::NEW_LINE) {
|
||||
while (tokens.at(currentIndex)->getKind() != TokenKind::NEW_LINE) {
|
||||
currentIndex++;
|
||||
}
|
||||
currentIndex++; // new line
|
||||
@@ -59,13 +59,13 @@ shared_ptr<Statement> Parser::matchStatementFunctionDeclaration() {
|
||||
else if (!statementBlock->isValid())
|
||||
return statementBlock;
|
||||
else
|
||||
return make_shared<StatementFunctionDeclaration>(identifierToken->getLexme(), dynamic_pointer_cast<StatementBlock>(statementBlock));
|
||||
return make_shared<StatementFunctionDeclaration>(identifierToken->getLexme(), ValueType::SINT32, dynamic_pointer_cast<StatementBlock>(statementBlock));
|
||||
}
|
||||
|
||||
shared_ptr<Statement> Parser::matchStatementBlock() {
|
||||
vector<shared_ptr<Statement>> statements;
|
||||
|
||||
while (!tokens.at(currentIndex)->isOfKind({Token::Kind::SEMICOLON, Token::Kind::COLON})) {
|
||||
while (!tokens.at(currentIndex)->isOfKind({TokenKind::SEMICOLON, TokenKind::COLON})) {
|
||||
shared_ptr<Statement> statement = nextStatement();
|
||||
if (statement == nullptr)
|
||||
return matchStatementInvalid();
|
||||
@@ -76,17 +76,17 @@ shared_ptr<Statement> Parser::matchStatementBlock() {
|
||||
}
|
||||
currentIndex++; // consune ';' and ':'
|
||||
|
||||
if (!tokens.at(currentIndex)->isOfKind({Token::Kind::NEW_LINE, Token::Kind::END}))
|
||||
if (!tokens.at(currentIndex)->isOfKind({TokenKind::NEW_LINE, TokenKind::END}))
|
||||
return matchStatementInvalid();
|
||||
|
||||
if (tokens.at(currentIndex)->getKind() == Token::Kind::NEW_LINE)
|
||||
if (tokens.at(currentIndex)->getKind() == TokenKind::NEW_LINE)
|
||||
currentIndex++;
|
||||
|
||||
return make_shared<StatementBlock>(statements);
|
||||
}
|
||||
|
||||
shared_ptr<Statement> Parser::matchStatementReturn() {
|
||||
if (tokens.at(currentIndex)->getKind() != Token::Kind::RETURN)
|
||||
if (tokens.at(currentIndex)->getKind() != TokenKind::RETURN)
|
||||
return nullptr;
|
||||
|
||||
currentIndex++;
|
||||
@@ -95,7 +95,7 @@ shared_ptr<Statement> Parser::matchStatementReturn() {
|
||||
if (expression != nullptr && !expression->isValid())
|
||||
return matchStatementInvalid();
|
||||
|
||||
if (tokens.at(currentIndex)->getKind() != Token::Kind::NEW_LINE)
|
||||
if (tokens.at(currentIndex)->getKind() != TokenKind::NEW_LINE)
|
||||
return matchStatementInvalid();
|
||||
|
||||
currentIndex++; // new line
|
||||
@@ -112,7 +112,7 @@ shared_ptr<Statement> Parser::matchStatementExpression() {
|
||||
return make_shared<StatementInvalid>(tokens.at(currentIndex));
|
||||
|
||||
// Consume new line
|
||||
if (tokens.at(currentIndex)->getKind() == Token::Kind::NEW_LINE)
|
||||
if (tokens.at(currentIndex)->getKind() == TokenKind::NEW_LINE)
|
||||
currentIndex++;
|
||||
|
||||
return make_shared<StatementExpression>(expression);
|
||||
@@ -199,7 +199,7 @@ shared_ptr<Expression> Parser::matchPrimary() {
|
||||
|
||||
shared_ptr<Expression> Parser::matchExpressionLiteral() {
|
||||
shared_ptr<Token> token = tokens.at(currentIndex);
|
||||
if (token->isOfKind({Token::Kind::BOOL, Token::Kind::INTEGER, Token::Kind::REAL})) {
|
||||
if (token->isOfKind({TokenKind::BOOL, TokenKind::INTEGER, TokenKind::REAL})) {
|
||||
currentIndex++;
|
||||
return make_shared<ExpressionLiteral>(token);
|
||||
}
|
||||
@@ -209,7 +209,7 @@ shared_ptr<Expression> Parser::matchExpressionLiteral() {
|
||||
|
||||
shared_ptr<Expression> Parser::matchExpressionGrouping() {
|
||||
shared_ptr<Token> token = tokens.at(currentIndex);
|
||||
if (token->getKind() == Token::Kind::LEFT_PAREN) {
|
||||
if (token->getKind() == TokenKind::LEFT_PAREN) {
|
||||
currentIndex++;
|
||||
shared_ptr<Expression> expression = matchTerm();
|
||||
// has grouped expression failed?
|
||||
@@ -217,7 +217,7 @@ shared_ptr<Expression> Parser::matchExpressionGrouping() {
|
||||
return matchExpressionInvalid();
|
||||
} else if(!expression->isValid()) {
|
||||
return expression;
|
||||
} else if (tokens.at(currentIndex)->getKind() == Token::Kind::RIGHT_PAREN) {
|
||||
} else if (tokens.at(currentIndex)->getKind() == TokenKind::RIGHT_PAREN) {
|
||||
currentIndex++;
|
||||
return make_shared<ExpressionGrouping>(expression);
|
||||
} else {
|
||||
@@ -260,7 +260,7 @@ shared_ptr<Expression> Parser::matchExpressionBinary(shared_ptr<Expression> left
|
||||
shared_ptr<Expression> Parser::matchExpressionIfElse() {
|
||||
// Try maching '?'
|
||||
shared_ptr<Token> token = tokens.at(currentIndex);
|
||||
if (token->getKind() != Token::Kind::QUESTION)
|
||||
if (token->getKind() != TokenKind::QUESTION)
|
||||
return nullptr;
|
||||
currentIndex++;
|
||||
|
||||
@@ -272,9 +272,9 @@ shared_ptr<Expression> Parser::matchExpressionIfElse() {
|
||||
return condition;
|
||||
|
||||
// Match ':', '\n', or ':\n'
|
||||
if (matchesTokenKinds({Token::Kind::COLON, Token::Kind::NEW_LINE}))
|
||||
if (matchesTokenKinds({TokenKind::COLON, TokenKind::NEW_LINE}))
|
||||
currentIndex += 2;
|
||||
else if (tokens.at(currentIndex)->isOfKind({Token::Kind::COLON, Token::Kind::NEW_LINE}))
|
||||
else if (tokens.at(currentIndex)->isOfKind({TokenKind::COLON, TokenKind::NEW_LINE}))
|
||||
currentIndex++;
|
||||
else
|
||||
return matchExpressionInvalid();
|
||||
@@ -291,7 +291,7 @@ shared_ptr<Expression> Parser::matchExpressionIfElse() {
|
||||
|
||||
shared_ptr<Token> lastToken = tokens.at(currentIndex-2);
|
||||
// ':' marks else block
|
||||
if (lastToken->getKind() == Token::Kind::COLON) {
|
||||
if (lastToken->getKind() == TokenKind::COLON) {
|
||||
elseBlock = matchStatementBlock();
|
||||
if (elseBlock == nullptr)
|
||||
return matchExpressionInvalid();
|
||||
@@ -306,7 +306,7 @@ shared_ptr<ExpressionInvalid> Parser::matchExpressionInvalid() {
|
||||
return make_shared<ExpressionInvalid>(tokens.at(currentIndex));
|
||||
}
|
||||
|
||||
bool Parser::matchesTokenKinds(vector<Token::Kind> kinds) {
|
||||
bool Parser::matchesTokenKinds(vector<TokenKind> kinds) {
|
||||
if (currentIndex + kinds.size() >= tokens.size())
|
||||
return false;
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ private:
|
||||
shared_ptr<Expression> matchExpressionIfElse();
|
||||
shared_ptr<ExpressionInvalid> matchExpressionInvalid();
|
||||
|
||||
bool matchesTokenKinds(vector<Token::Kind> kinds);
|
||||
bool matchesTokenKinds(vector<TokenKind> kinds);
|
||||
|
||||
public:
|
||||
Parser(vector<shared_ptr<Token>> tokens);
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
|
||||
//
|
||||
// Statement
|
||||
Statement::Statement(Kind kind): kind(kind) {
|
||||
Statement::Statement(StatementKind kind): kind(kind) {
|
||||
}
|
||||
|
||||
Statement::Kind Statement::getKind() {
|
||||
StatementKind Statement::getKind() {
|
||||
return kind;
|
||||
}
|
||||
|
||||
bool Statement::isValid() {
|
||||
return kind != Statement::Kind::INVALID;
|
||||
return kind != StatementKind::INVALID;
|
||||
}
|
||||
|
||||
string Statement::toString(int indent) {
|
||||
@@ -19,14 +19,22 @@ string Statement::toString(int indent) {
|
||||
|
||||
//
|
||||
// StatementFunctionDeclaration
|
||||
StatementFunctionDeclaration::StatementFunctionDeclaration(string name, shared_ptr<StatementBlock> statementBlock):
|
||||
Statement(Statement::Kind::FUNCTION_DECLARATION), name(name), statementBlock(statementBlock) {
|
||||
StatementFunctionDeclaration::StatementFunctionDeclaration(string name, ValueType returnValueType, shared_ptr<StatementBlock> statementBlock):
|
||||
Statement(StatementKind::FUNCTION_DECLARATION), name(name), returnValueType(returnValueType), statementBlock(statementBlock) {
|
||||
}
|
||||
|
||||
string StatementFunctionDeclaration::getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
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++)
|
||||
@@ -39,15 +47,11 @@ string StatementFunctionDeclaration::toString(int indent) {
|
||||
return value;
|
||||
}
|
||||
|
||||
shared_ptr<StatementBlock> StatementFunctionDeclaration::getStatementBlock() {
|
||||
return statementBlock;
|
||||
}
|
||||
|
||||
//
|
||||
// StatementBlock
|
||||
StatementBlock::StatementBlock(vector<shared_ptr<Statement>> statements):
|
||||
Statement(Statement::Kind::BLOCK), statements(statements) {
|
||||
if (statements.back()->getKind() == Statement::Kind::EXPRESSION) {
|
||||
Statement(StatementKind::BLOCK), statements(statements) {
|
||||
if (statements.back()->getKind() == StatementKind::EXPRESSION) {
|
||||
statementExpression = dynamic_pointer_cast<StatementExpression>(statements.back());
|
||||
this->statements.pop_back();
|
||||
}
|
||||
@@ -83,8 +87,7 @@ string StatementBlock::toString(int indent) {
|
||||
//
|
||||
// StatementReturn
|
||||
StatementReturn::StatementReturn(shared_ptr<Expression> expression):
|
||||
Statement(Statement::Kind::RETURN), expression(expression) {
|
||||
|
||||
Statement(StatementKind::RETURN), expression(expression) {
|
||||
}
|
||||
|
||||
shared_ptr<Expression> StatementReturn::getExpression() {
|
||||
@@ -105,7 +108,7 @@ string StatementReturn::toString(int indent) {
|
||||
//
|
||||
// StatementExpression
|
||||
StatementExpression::StatementExpression(shared_ptr<Expression> expression):
|
||||
Statement(Statement::Kind::EXPRESSION), expression(expression) {
|
||||
Statement(StatementKind::EXPRESSION), expression(expression) {
|
||||
}
|
||||
|
||||
shared_ptr<Expression> StatementExpression::getExpression() {
|
||||
@@ -124,7 +127,7 @@ string StatementExpression::toString(int indent) {
|
||||
//
|
||||
// StatementInvalid
|
||||
StatementInvalid::StatementInvalid(shared_ptr<Token> token):
|
||||
Statement(Statement::Kind::INVALID), token(token) {
|
||||
Statement(StatementKind::INVALID), token(token) {
|
||||
}
|
||||
|
||||
string StatementInvalid::toString(int indent) {
|
||||
|
||||
@@ -5,35 +5,26 @@
|
||||
|
||||
#include "Token.h"
|
||||
#include "Expression.h"
|
||||
#include "Types.h"
|
||||
|
||||
class Expression;
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Statement;
|
||||
class StatementBlock;
|
||||
class StatementReturn;
|
||||
class StatementExpression;
|
||||
class StatementInvalid;
|
||||
|
||||
using namespace std;
|
||||
|
||||
//
|
||||
// Statement
|
||||
class Statement {
|
||||
public:
|
||||
enum Kind {
|
||||
FUNCTION_DECLARATION,
|
||||
BLOCK,
|
||||
RETURN,
|
||||
EXPRESSION,
|
||||
INVALID
|
||||
};
|
||||
|
||||
private:
|
||||
Kind kind;
|
||||
StatementKind kind;
|
||||
|
||||
public:
|
||||
Statement(Kind kind);
|
||||
Kind getKind();
|
||||
Statement(StatementKind kind);
|
||||
StatementKind getKind();
|
||||
bool isValid();
|
||||
virtual string toString(int indent);
|
||||
};
|
||||
@@ -43,11 +34,13 @@ public:
|
||||
class StatementFunctionDeclaration: public Statement {
|
||||
private:
|
||||
string name;
|
||||
ValueType returnValueType;
|
||||
shared_ptr<StatementBlock> statementBlock;
|
||||
|
||||
public:
|
||||
StatementFunctionDeclaration(string name, shared_ptr<StatementBlock> statementBlock);
|
||||
StatementFunctionDeclaration(string name, ValueType returnValueType, shared_ptr<StatementBlock> statementBlock);
|
||||
string getName();
|
||||
ValueType getReturnValueType();
|
||||
shared_ptr<StatementBlock> getStatementBlock();
|
||||
string toString(int indent) override;
|
||||
};
|
||||
|
||||
116
src/Token.cpp
116
src/Token.cpp
@@ -1,46 +1,46 @@
|
||||
#include "Token.h"
|
||||
|
||||
vector<Token::Kind> Token::tokensEquality = {
|
||||
Token::Kind::EQUAL,
|
||||
Token::Kind::NOT_EQUAL
|
||||
vector<TokenKind> Token::tokensEquality = {
|
||||
TokenKind::EQUAL,
|
||||
TokenKind::NOT_EQUAL
|
||||
};
|
||||
vector<Token::Kind> Token::tokensComparison = {
|
||||
Token::Kind::LESS,
|
||||
Token::Kind::LESS_EQUAL,
|
||||
Token::Kind::GREATER,
|
||||
Token::Kind::GREATER_EQUAL
|
||||
vector<TokenKind> Token::tokensComparison = {
|
||||
TokenKind::LESS,
|
||||
TokenKind::LESS_EQUAL,
|
||||
TokenKind::GREATER,
|
||||
TokenKind::GREATER_EQUAL
|
||||
};
|
||||
vector<Token::Kind> Token::tokensTerm = {
|
||||
Token::Kind::PLUS,
|
||||
Token::Kind::MINUS
|
||||
vector<TokenKind> Token::tokensTerm = {
|
||||
TokenKind::PLUS,
|
||||
TokenKind::MINUS
|
||||
};
|
||||
vector<Token::Kind> Token::tokensFactor = {
|
||||
Token::Kind::STAR,
|
||||
Token::Kind::SLASH,
|
||||
Token::Kind::PERCENT
|
||||
vector<TokenKind> Token::tokensFactor = {
|
||||
TokenKind::STAR,
|
||||
TokenKind::SLASH,
|
||||
TokenKind::PERCENT
|
||||
};
|
||||
vector<Token::Kind> Token::tokensBinary = {
|
||||
Token::Kind::EQUAL,
|
||||
Token::Kind::NOT_EQUAL,
|
||||
vector<TokenKind> Token::tokensBinary = {
|
||||
TokenKind::EQUAL,
|
||||
TokenKind::NOT_EQUAL,
|
||||
|
||||
Token::Kind::LESS,
|
||||
Token::Kind::LESS_EQUAL,
|
||||
Token::Kind::GREATER,
|
||||
Token::Kind::GREATER_EQUAL,
|
||||
TokenKind::LESS,
|
||||
TokenKind::LESS_EQUAL,
|
||||
TokenKind::GREATER,
|
||||
TokenKind::GREATER_EQUAL,
|
||||
|
||||
Token::Kind::PLUS,
|
||||
Token::Kind::MINUS,
|
||||
TokenKind::PLUS,
|
||||
TokenKind::MINUS,
|
||||
|
||||
Token::Kind::STAR,
|
||||
Token::Kind::SLASH,
|
||||
Token::Kind::PERCENT
|
||||
TokenKind::STAR,
|
||||
TokenKind::SLASH,
|
||||
TokenKind::PERCENT
|
||||
};
|
||||
|
||||
Token::Token(Kind kind, string lexme, int line, int column):
|
||||
Token::Token(TokenKind kind, string lexme, int line, int column):
|
||||
kind(kind), lexme(lexme), line(line), column(column) {
|
||||
}
|
||||
|
||||
Token::Kind Token::getKind() {
|
||||
TokenKind Token::getKind() {
|
||||
return kind;
|
||||
}
|
||||
|
||||
@@ -57,11 +57,11 @@ int Token::getColumn() {
|
||||
}
|
||||
|
||||
bool Token::isValid() {
|
||||
return kind != Token::Kind::INVALID;
|
||||
return kind != TokenKind::INVALID;
|
||||
}
|
||||
|
||||
bool Token::isOfKind(vector<Kind> kinds) {
|
||||
for (Kind &kind : kinds) {
|
||||
bool Token::isOfKind(vector<TokenKind> kinds) {
|
||||
for (TokenKind &kind : kinds) {
|
||||
if (kind == this->kind)
|
||||
return true;
|
||||
}
|
||||
@@ -71,62 +71,62 @@ bool Token::isOfKind(vector<Kind> kinds) {
|
||||
|
||||
string Token::toString() {
|
||||
switch (kind) {
|
||||
case PLUS:
|
||||
case TokenKind::PLUS:
|
||||
return "PLUS";
|
||||
case MINUS:
|
||||
case TokenKind::MINUS:
|
||||
return "MINUS";
|
||||
case STAR:
|
||||
case TokenKind::STAR:
|
||||
return "STAR";
|
||||
case SLASH:
|
||||
case TokenKind::SLASH:
|
||||
return "SLASH";
|
||||
case PERCENT:
|
||||
case TokenKind::PERCENT:
|
||||
return "PERCENT";
|
||||
|
||||
case EQUAL:
|
||||
case TokenKind::EQUAL:
|
||||
return "EQUAL";
|
||||
case NOT_EQUAL:
|
||||
case TokenKind::NOT_EQUAL:
|
||||
return "NOT_EQUAL";
|
||||
case LESS:
|
||||
case TokenKind::LESS:
|
||||
return "LESS";
|
||||
case LESS_EQUAL:
|
||||
case TokenKind::LESS_EQUAL:
|
||||
return "LESS_EQUAL";
|
||||
case GREATER:
|
||||
case TokenKind::GREATER:
|
||||
return "GREATER";
|
||||
case GREATER_EQUAL:
|
||||
case TokenKind::GREATER_EQUAL:
|
||||
return "GREATER_EQUAL";
|
||||
|
||||
case LEFT_PAREN:
|
||||
case TokenKind::LEFT_PAREN:
|
||||
return "LEFT_PAREN";
|
||||
case RIGHT_PAREN:
|
||||
case TokenKind::RIGHT_PAREN:
|
||||
return "RIGHT_PAREN";
|
||||
case COLON:
|
||||
case TokenKind::COLON:
|
||||
return "COLON";
|
||||
case SEMICOLON:
|
||||
case TokenKind::SEMICOLON:
|
||||
return "SEMICOLON";
|
||||
case QUESTION_QUESTION:
|
||||
case TokenKind::QUESTION_QUESTION:
|
||||
return "QUESTION_QUESTION";
|
||||
case QUESTION:
|
||||
case TokenKind::QUESTION:
|
||||
return "QUESTION";
|
||||
|
||||
case BOOL:
|
||||
case TokenKind::BOOL:
|
||||
return "BOOL(" + lexme + ")";
|
||||
case INTEGER:
|
||||
case TokenKind::INTEGER:
|
||||
return "INTEGER(" + lexme + ")";
|
||||
case REAL:
|
||||
case TokenKind::REAL:
|
||||
return "REAL(" + lexme + ")";
|
||||
case IDENTIFIER:
|
||||
case TokenKind::IDENTIFIER:
|
||||
return "IDENTIFIER(" + lexme + ")";
|
||||
|
||||
case FUNCTION:
|
||||
case TokenKind::FUNCTION:
|
||||
return "FUNCTION";
|
||||
case RETURN:
|
||||
case TokenKind::RETURN:
|
||||
return "RETURN";
|
||||
|
||||
case NEW_LINE:
|
||||
case TokenKind::NEW_LINE:
|
||||
return "NEW_LINE";
|
||||
case END:
|
||||
case TokenKind::END:
|
||||
return "END";
|
||||
case INVALID:
|
||||
case TokenKind::INVALID:
|
||||
return "INVALID";
|
||||
}
|
||||
}
|
||||
56
src/Token.h
56
src/Token.h
@@ -3,65 +3,31 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Token {
|
||||
public:
|
||||
enum Kind {
|
||||
PLUS,
|
||||
MINUS,
|
||||
STAR,
|
||||
SLASH,
|
||||
PERCENT,
|
||||
|
||||
EQUAL,
|
||||
NOT_EQUAL,
|
||||
LESS,
|
||||
LESS_EQUAL,
|
||||
GREATER,
|
||||
GREATER_EQUAL,
|
||||
|
||||
LEFT_PAREN,
|
||||
RIGHT_PAREN,
|
||||
COLON,
|
||||
SEMICOLON,
|
||||
QUESTION,
|
||||
QUESTION_QUESTION,
|
||||
|
||||
FUNCTION,
|
||||
RETURN,
|
||||
|
||||
BOOL,
|
||||
INTEGER,
|
||||
REAL,
|
||||
IDENTIFIER,
|
||||
|
||||
NEW_LINE,
|
||||
END,
|
||||
|
||||
INVALID
|
||||
};
|
||||
|
||||
private:
|
||||
Kind kind;
|
||||
TokenKind kind;
|
||||
string lexme;
|
||||
int line;
|
||||
int column;
|
||||
|
||||
public:
|
||||
static vector<Token::Kind> tokensEquality;
|
||||
static vector<Token::Kind> tokensComparison;
|
||||
static vector<Token::Kind> tokensTerm;
|
||||
static vector<Token::Kind> tokensFactor;
|
||||
static vector<Token::Kind> tokensBinary;
|
||||
static vector<TokenKind> tokensEquality;
|
||||
static vector<TokenKind> tokensComparison;
|
||||
static vector<TokenKind> tokensTerm;
|
||||
static vector<TokenKind> tokensFactor;
|
||||
static vector<TokenKind> tokensBinary;
|
||||
|
||||
Token(Kind kind, string lexme, int line, int column);
|
||||
Kind getKind();
|
||||
Token(TokenKind kind, string lexme, int line, int column);
|
||||
TokenKind getKind();
|
||||
string getLexme();
|
||||
int getLine();
|
||||
int getColumn();
|
||||
bool isValid();
|
||||
bool isOfKind(vector<Kind> kinds);
|
||||
bool isOfKind(vector<TokenKind> kinds);
|
||||
string toString();
|
||||
};
|
||||
|
||||
|
||||
62
src/Types.h
Normal file
62
src/Types.h
Normal file
@@ -0,0 +1,62 @@
|
||||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
|
||||
enum class TokenKind {
|
||||
PLUS,
|
||||
MINUS,
|
||||
STAR,
|
||||
SLASH,
|
||||
PERCENT,
|
||||
|
||||
EQUAL,
|
||||
NOT_EQUAL,
|
||||
LESS,
|
||||
LESS_EQUAL,
|
||||
GREATER,
|
||||
GREATER_EQUAL,
|
||||
|
||||
LEFT_PAREN,
|
||||
RIGHT_PAREN,
|
||||
COLON,
|
||||
SEMICOLON,
|
||||
QUESTION,
|
||||
QUESTION_QUESTION,
|
||||
|
||||
FUNCTION,
|
||||
RETURN,
|
||||
|
||||
BOOL,
|
||||
INTEGER,
|
||||
REAL,
|
||||
IDENTIFIER,
|
||||
|
||||
NEW_LINE,
|
||||
END,
|
||||
|
||||
INVALID
|
||||
};
|
||||
|
||||
enum class ExpressionKind {
|
||||
LITERAL,
|
||||
GROUPING,
|
||||
BINARY,
|
||||
IF_ELSE,
|
||||
INVALID
|
||||
};
|
||||
|
||||
enum class StatementKind {
|
||||
FUNCTION_DECLARATION,
|
||||
BLOCK,
|
||||
RETURN,
|
||||
EXPRESSION,
|
||||
INVALID
|
||||
};
|
||||
|
||||
enum class ValueType {
|
||||
VOID,
|
||||
BOOL,
|
||||
SINT32,
|
||||
REAL32
|
||||
};
|
||||
|
||||
#endif
|
||||
31
src/main.cpp
31
src/main.cpp
@@ -13,33 +13,33 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
std::string readFile(std::string fileName) {
|
||||
std::ifstream file(fileName.c_str(), std::ios::in | std::ios::binary | std::ios::ate);
|
||||
string readFile(string fileName) {
|
||||
ifstream file(fileName.c_str(), ios::in | ios::binary | ios::ate);
|
||||
if (!file.is_open()) {
|
||||
std::cerr << "Cannot open file " << fileName << std::endl;
|
||||
cerr << "Cannot open file " << fileName << endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
std::streamsize fileSize = file.tellg();
|
||||
file.seekg(0, std::ios::beg);
|
||||
std::vector<char> fileBytes(fileSize);
|
||||
streamsize fileSize = file.tellg();
|
||||
file.seekg(0, ios::beg);
|
||||
vector<char> fileBytes(fileSize);
|
||||
file.read(fileBytes.data(), fileSize);
|
||||
return std::string(fileBytes.data(), fileSize);
|
||||
return string(fileBytes.data(), fileSize);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc < 2) {
|
||||
std::cerr << "Need to provide a file name" << std::endl;
|
||||
cerr << "Need to provide a file name" << endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
std::string source = readFile(std::string(argv[1]));
|
||||
string source = readFile(string(argv[1]));
|
||||
Lexer lexer(source);
|
||||
std::vector<shared_ptr<Token>> tokens = lexer.getTokens();
|
||||
vector<shared_ptr<Token>> tokens = lexer.getTokens();
|
||||
for (int i=0; i<tokens.size(); i++) {
|
||||
std::cout << tokens.at(i)->toString();
|
||||
cout << tokens.at(i)->toString();
|
||||
if (i < tokens.size() - 1)
|
||||
std::cout << " ";
|
||||
cout << " ";
|
||||
}
|
||||
cout << endl << endl;
|
||||
|
||||
@@ -49,10 +49,11 @@ int main(int argc, char **argv) {
|
||||
cout << statement->toString(0);
|
||||
cout << endl;
|
||||
}
|
||||
cout << endl << endl;
|
||||
|
||||
//ModuleBuilder moduleBuilder(statements);
|
||||
//shared_ptr<llvm::Module> module = moduleBuilder.getModule();
|
||||
//module->print(llvm::outs(), nullptr);
|
||||
ModuleBuilder moduleBuilder(statements);
|
||||
shared_ptr<llvm::Module> module = moduleBuilder.getModule();
|
||||
module->print(llvm::outs(), nullptr);
|
||||
|
||||
//CodeGenerator codeGenerator(module);
|
||||
//codeGenerator.generateObjectFile("dummy.s");
|
||||
|
||||
Reference in New Issue
Block a user