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