types in separate file

This commit is contained in:
Rafał Grodziński
2025-06-08 10:52:38 +09:00
parent 54b6e6868b
commit 53c5e2c22e
14 changed files with 394 additions and 293 deletions

View File

@@ -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() {

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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();

View File

@@ -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;
} }
}*/ }

View File

@@ -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

View File

@@ -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;

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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;
}; };

View File

@@ -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";
} }
} }

View File

@@ -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
View 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

View File

@@ -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");