mirror of
https://github.com/PashaBibko/LX.git
synced 2026-04-04 01:49:05 +00:00
Refactored error handling
Now uses base error class which has an abstract function for overiding how it is displayed to the console.
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
#include <Parser.h>
|
||||
|
||||
#include <ThrowIf.h>
|
||||
|
||||
#include <LLVM.h>
|
||||
#include <Util.h>
|
||||
#include <AST.h>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include <Parser.h>
|
||||
|
||||
#include <ThrowIf.h>
|
||||
|
||||
#include <Util.h>
|
||||
#include <AST.h>
|
||||
|
||||
@@ -28,7 +30,7 @@ namespace LX
|
||||
// Generates the IR within the function by looping over the nodes //
|
||||
for (auto& node : funcAST.body)
|
||||
{
|
||||
ThrowIf<int>(IsValidTopLevelNode(node->m_Type) == false); // <- TODO: replace with actual error type
|
||||
ThrowIf<IRGenerationError>(IsValidTopLevelNode(node->m_Type) == false); // <- TODO: replace with actual error type
|
||||
node->GenIR(LLVM);
|
||||
}
|
||||
|
||||
@@ -39,7 +41,7 @@ namespace LX
|
||||
}
|
||||
|
||||
// Verifies the function works //
|
||||
ThrowIf<int>(llvm::verifyFunction(*func)); // <- TODO: Make error type
|
||||
ThrowIf<IRGenerationError>(llvm::verifyFunction(*func)); // <- TODO: Make error type
|
||||
}
|
||||
|
||||
// Turns an abstract binary tree into LLVM intermediate representation //
|
||||
@@ -55,8 +57,6 @@ namespace LX
|
||||
// Loops over the functions to generate their LLVM IR //
|
||||
for (auto& func : ast.functions)
|
||||
{
|
||||
std::cout << "\t|\t|- Generating function: " << func.name << "\n";
|
||||
|
||||
LLVM.scope = &func.scope; // Sets the current scope for the builder
|
||||
GenerateFunctionIR(func, LLVM);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <Parser.h>
|
||||
|
||||
#include <ThrowIf.h>
|
||||
#include <Util.h>
|
||||
#include <AST.h>
|
||||
|
||||
@@ -7,6 +8,9 @@
|
||||
|
||||
namespace LX
|
||||
{
|
||||
std::string* UnexpectedToken::s_Source = nullptr;
|
||||
std::filesystem::path* UnexpectedToken::s_SourceFile = nullptr;
|
||||
|
||||
// Util function for working out if a token is a two sided operator //
|
||||
static bool IsTwoSidedOperator(Token::TokenType t)
|
||||
{
|
||||
@@ -204,7 +208,7 @@ namespace LX
|
||||
FileAST TurnTokensIntoAbstractSyntaxTree(std::vector<Token>& tokens, std::ofstream* log)
|
||||
{
|
||||
// Logs the start of the parsing
|
||||
SafeLog(log, LOG_BREAK, "Started parsing tokens", LOG_BREAK);
|
||||
SafeLog(log, LOG_BREAK, "Started parsing tokens", LOG_BREAK);
|
||||
|
||||
// Creates the output storer and the parser //
|
||||
FileAST output;
|
||||
|
||||
78
Parser/src/ParserErrors.cpp
Normal file
78
Parser/src/ParserErrors.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
#include <Parser.h>
|
||||
|
||||
#include <Console.h>
|
||||
|
||||
#include <filesystem>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
namespace LX
|
||||
{
|
||||
void IRGenerationError::PrintToConsole() const
|
||||
{
|
||||
}
|
||||
|
||||
const char* IRGenerationError::ErrorType() const
|
||||
{
|
||||
return "IR Generation Error";
|
||||
}
|
||||
|
||||
UnexpectedToken::UnexpectedToken(Token::TokenType _expected, std::string _override, Token _got)
|
||||
: expected(_expected), override(_override), got(_got)
|
||||
{}
|
||||
|
||||
void UnexpectedToken::PrintToConsole() const
|
||||
{
|
||||
// Calculates the length of the line number in the console so it is formatted correctly //
|
||||
std::ostringstream oss;
|
||||
oss << std::setw(3) << got.line;
|
||||
size_t lineNumberWidthInConsole = std::max(oss.str().size(), (size_t)3);
|
||||
|
||||
// Gets the line of the error //
|
||||
std::string line = LX::GetLineAtIndexOf(*s_Source, got.index);
|
||||
|
||||
// Prints the error to the console with the relevant info //
|
||||
std::cout << "\n";
|
||||
LX::PrintStringAsColor("Error: ", LX::Color::LIGHT_RED);
|
||||
std::cout << "Incorrect syntax in ";
|
||||
LX::PrintStringAsColor(s_SourceFile->filename().string(), LX::Color::WHITE);
|
||||
std::cout << ", found ";
|
||||
LX::PrintStringAsColor(LX::ToString(got.type).c_str(), LX::Color::WHITE);
|
||||
std::cout << " expected: ";
|
||||
|
||||
// Allows the error to have a custom type that is printed to the console //
|
||||
if (expected == LX::Token::UNDEFINED) { LX::PrintStringAsColor(override.c_str(), LX::Color::WHITE); }
|
||||
else { LX::PrintStringAsColor(LX::ToString(expected).c_str(), LX::Color::WHITE); }
|
||||
std::cout << "\n";
|
||||
|
||||
// Prints the code with the error to the console //
|
||||
std::string errorSquiggle(got.length, '~');
|
||||
std::cout << "Line: " << std::setw(lineNumberWidthInConsole) << got.line << " | " << line << "\n";
|
||||
std::cout << " " << std::setw(lineNumberWidthInConsole) << "" << " | " << std::setw(got.column) << "";
|
||||
LX::PrintStringAsColor(errorSquiggle.c_str(), LX::Color::LIGHT_RED);
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
const char* UnexpectedToken::ErrorType() const
|
||||
{
|
||||
return "Unexpected Token";
|
||||
}
|
||||
|
||||
void Scope::VariableAlreadyExists::PrintToConsole() const
|
||||
{
|
||||
}
|
||||
|
||||
const char* Scope::VariableAlreadyExists::ErrorType() const
|
||||
{
|
||||
return "Variable Already Exists";
|
||||
}
|
||||
|
||||
void Scope::VariableDoesntExist::PrintToConsole() const
|
||||
{
|
||||
}
|
||||
|
||||
const char* Scope::VariableDoesntExist::ErrorType() const
|
||||
{
|
||||
return "Variable Doesn't exist";
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <Parser.h>
|
||||
|
||||
#include <ThrowIf.h>
|
||||
#include <Util.h>
|
||||
#include <AST.h>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user