Handle errors through logger and error class in module builder
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
#include "ModuleBuilder.h"
|
#include "ModuleBuilder.h"
|
||||||
|
|
||||||
#include "Error.h"
|
#include "Error.h"
|
||||||
|
#include "Logger.h"
|
||||||
#include "Parser/ValueType.h"
|
#include "Parser/ValueType.h"
|
||||||
|
|
||||||
#include "Parser/Expression/ExpressionGrouping.h"
|
#include "Parser/Expression/ExpressionGrouping.h"
|
||||||
@@ -37,6 +38,13 @@ shared_ptr<llvm::Module> ModuleBuilder::getModule() {
|
|||||||
scopes.push(Scope());
|
scopes.push(Scope());
|
||||||
for (shared_ptr<Statement> &statement : statements)
|
for (shared_ptr<Statement> &statement : statements)
|
||||||
buildStatement(statement);
|
buildStatement(statement);
|
||||||
|
|
||||||
|
if (!errors.empty()) {
|
||||||
|
for (shared_ptr<Error> &error : errors)
|
||||||
|
Logger::print(error);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
return module;
|
return module;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +75,7 @@ void ModuleBuilder::buildStatement(shared_ptr<Statement> statement) {
|
|||||||
buildExpression(dynamic_pointer_cast<StatementExpression>(statement));
|
buildExpression(dynamic_pointer_cast<StatementExpression>(statement));
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
failWithMessage("Unexpected statement");
|
markError(0, 0, "Unexpected statement");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,7 +122,7 @@ void ModuleBuilder::buildFunctionDeclaration(shared_ptr<StatementFunction> state
|
|||||||
string errorMessage;
|
string errorMessage;
|
||||||
llvm::raw_string_ostream llvmErrorMessage(errorMessage);
|
llvm::raw_string_ostream llvmErrorMessage(errorMessage);
|
||||||
if (llvm::verifyFunction(*fun, &llvmErrorMessage))
|
if (llvm::verifyFunction(*fun, &llvmErrorMessage))
|
||||||
failWithMessage(errorMessage);
|
markError(0, 0, errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModuleBuilder::buildVarDeclaration(shared_ptr<StatementVariable> statement) {
|
void ModuleBuilder::buildVarDeclaration(shared_ptr<StatementVariable> statement) {
|
||||||
@@ -237,7 +245,8 @@ llvm::Value *ModuleBuilder::valueForExpression(shared_ptr<Expression> expression
|
|||||||
case ExpressionKind::CALL:
|
case ExpressionKind::CALL:
|
||||||
return valueForCall(dynamic_pointer_cast<ExpressionCall>(expression));
|
return valueForCall(dynamic_pointer_cast<ExpressionCall>(expression));
|
||||||
default:
|
default:
|
||||||
failWithMessage("Unexpected expression");
|
markError(0, 0, "Unexpected expression");
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,7 +284,8 @@ llvm::Value *ModuleBuilder::valueForBinary(shared_ptr<ExpressionBinary> expressi
|
|||||||
return valueForBinaryReal(expression->getOperation(), leftValue, rightValue);
|
return valueForBinaryReal(expression->getOperation(), leftValue, rightValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
failWithMessage("Unexpected operation");
|
markError(0, 0, "Unexpected operation");
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Value *ModuleBuilder::valueForBinaryBool(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue) {
|
llvm::Value *ModuleBuilder::valueForBinaryBool(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue) {
|
||||||
@@ -285,7 +295,8 @@ llvm::Value *ModuleBuilder::valueForBinaryBool(ExpressionBinaryOperation operati
|
|||||||
case ExpressionBinaryOperation::NOT_EQUAL:
|
case ExpressionBinaryOperation::NOT_EQUAL:
|
||||||
return builder->CreateICmpNE(leftValue, rightValue);
|
return builder->CreateICmpNE(leftValue, rightValue);
|
||||||
default:
|
default:
|
||||||
failWithMessage("Undefined operation for boolean operands");
|
markError(0, 0, "Unexpecgted operation for boolean operands");
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -417,8 +428,10 @@ llvm::Value *ModuleBuilder::valueForCall(shared_ptr<ExpressionCall> expression)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ModuleBuilder::setAlloca(string name, llvm::AllocaInst *alloca) {
|
bool ModuleBuilder::setAlloca(string name, llvm::AllocaInst *alloca) {
|
||||||
if (scopes.top().allocaMap[name] != nullptr)
|
if (scopes.top().allocaMap[name] != nullptr) {
|
||||||
|
markError(0, 0, format("Variable \"{}\" already defined", name));
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
scopes.top().allocaMap[name] = alloca;
|
scopes.top().allocaMap[name] = alloca;
|
||||||
return true;
|
return true;
|
||||||
@@ -434,12 +447,15 @@ llvm::AllocaInst* ModuleBuilder::getAlloca(string name) {
|
|||||||
scopes.pop();
|
scopes.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
markError(0, 0, format("Variable \"{}\" not defined in scope", name));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ModuleBuilder::setFun(string name, llvm::Function *fun) {
|
bool ModuleBuilder::setFun(string name, llvm::Function *fun) {
|
||||||
if (scopes.top().funMap[name] != nullptr)
|
if (scopes.top().funMap[name] != nullptr) {
|
||||||
|
markError(0, 0, format("Function \"{}\" already defined", name));
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
scopes.top().funMap[name] = fun;
|
scopes.top().funMap[name] = fun;
|
||||||
return true;
|
return true;
|
||||||
@@ -455,6 +471,7 @@ llvm::Function* ModuleBuilder::getFun(string name) {
|
|||||||
scopes.pop();
|
scopes.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
markError(0, 0, format("Function \"{}\" not defined in scope", name));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -471,11 +488,6 @@ llvm::Type *ModuleBuilder::typeForValueType(shared_ptr<ValueType> valueType) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModuleBuilder::failWithMessage(string message) {
|
|
||||||
cerr << "Error! Building module \"" << moduleName << "\" from \"" + sourceFileName + "\" failed:" << endl << message << endl;
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ModuleBuilder::markError(int line, int column, string message) {
|
void ModuleBuilder::markError(int line, int column, string message) {
|
||||||
errors.push_back(Error::builderError(line, column, message));
|
errors.push_back(Error::builderError(line, column, message));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,6 @@ private:
|
|||||||
llvm::Function *getFun(string name);
|
llvm::Function *getFun(string name);
|
||||||
|
|
||||||
llvm::Type *typeForValueType(shared_ptr<ValueType> valueType);
|
llvm::Type *typeForValueType(shared_ptr<ValueType> valueType);
|
||||||
void failWithMessage(string message);
|
|
||||||
|
|
||||||
void markError(int line, int column, string message);
|
void markError(int line, int column, string message);
|
||||||
|
|
||||||
|
|||||||
@@ -447,7 +447,8 @@ void Logger::print(shared_ptr<Error> error) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ErrorKind::BUILDER_ERROR: {
|
case ErrorKind::BUILDER_ERROR: {
|
||||||
message = "";
|
string errorMessage = error->getMessage() ? *(error->getMessage()) : "";
|
||||||
|
message = format("Error at line {}, column {}: {}", error->getLine(), error->getColumn(), errorMessage);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user