Shader: Add support for error messages (WIP)
This commit is contained in:
committed by
Jérôme Leclercq
parent
f14b10baf4
commit
ebad7b5e8c
@@ -4,10 +4,18 @@
|
||||
|
||||
// no header guards
|
||||
|
||||
#if !defined(NAZARA_SHADERLANG_ERROR) && (!defined(NAZARA_SHADERLANG_LEXER_ERROR) || !defined(NAZARA_SHADERLANG_PARSER_ERROR) || !defined(NAZARA_SHADERLANG_COMPILER_ERROR))
|
||||
#if !defined(NAZARA_SHADERLANG_ERROR) && (!defined(NAZARA_SHADERLANG_LEXER_ERROR) || !defined(NAZARA_SHADERLANG_PARSER_ERROR) || !defined(NAZARA_SHADERLANG_COMPILER_ERROR) || !defined(NAZARA_SHADERLANG_AST_ERROR))
|
||||
#error You must define NAZARA_SHADERLANG_ERROR or NAZARA_SHADERLANG_LEXER_ERROR/NAZARA_SHADERLANG_PARSER_ERROR/NAZARA_SHADERLANG_COMPILER_ERROR before including this file
|
||||
#endif
|
||||
|
||||
#ifndef NAZARA_SHADERLANG_AST_ERROR
|
||||
#define NAZARA_SHADERLANG_AST_ERROR(...) NAZARA_SHADERLANG_ERROR(A, ...)
|
||||
#endif
|
||||
|
||||
#ifndef NAZARA_SHADERLANG_COMPILER_ERROR
|
||||
#define NAZARA_SHADERLANG_COMPILER_ERROR(...) NAZARA_SHADERLANG_ERROR(C, ...)
|
||||
#endif
|
||||
|
||||
#ifndef NAZARA_SHADERLANG_LEXER_ERROR
|
||||
#define NAZARA_SHADERLANG_LEXER_ERROR(...) NAZARA_SHADERLANG_ERROR(L, ...)
|
||||
#endif
|
||||
@@ -16,10 +24,6 @@
|
||||
#define NAZARA_SHADERLANG_PARSER_ERROR(...) NAZARA_SHADERLANG_ERROR(P, ...)
|
||||
#endif
|
||||
|
||||
#ifndef NAZARA_SHADERLANG_COMPILER_ERROR
|
||||
#define NAZARA_SHADERLANG_COMPILER_ERROR(...) NAZARA_SHADERLANG_COMPILER_ERROR(C, ...)
|
||||
#endif
|
||||
|
||||
// Lexer errors
|
||||
NAZARA_SHADERLANG_LEXER_ERROR(1, BadNumber, "bad number")
|
||||
NAZARA_SHADERLANG_LEXER_ERROR(2, NumberOutOfRange, "number is out of range")
|
||||
@@ -28,18 +32,33 @@ NAZARA_SHADERLANG_LEXER_ERROR(4, UnrecognizedChar, "unrecognized character")
|
||||
NAZARA_SHADERLANG_LEXER_ERROR(5, UnrecognizedToken, "unrecognized token")
|
||||
|
||||
// Parser errors
|
||||
NAZARA_SHADERLANG_PARSER_ERROR(1, AttributeError, "attribute error")
|
||||
NAZARA_SHADERLANG_PARSER_ERROR(2, ExpectedToken, "expected token")
|
||||
NAZARA_SHADERLANG_PARSER_ERROR(3, DuplicateIdentifier, "duplicate identifier")
|
||||
NAZARA_SHADERLANG_PARSER_ERROR(4, DuplicateModule, "duplicate module")
|
||||
NAZARA_SHADERLANG_PARSER_ERROR(5, ReservedKeyword, "reserved keyword")
|
||||
NAZARA_SHADERLANG_PARSER_ERROR(6, UnknownAttribute, "unknown attribute")
|
||||
NAZARA_SHADERLANG_PARSER_ERROR(7, UnknownType, "unknown type")
|
||||
NAZARA_SHADERLANG_PARSER_ERROR(8, UnexpectedToken, "unexpected token")
|
||||
NAZARA_SHADERLANG_PARSER_ERROR( 1, AttributeExpectString, "attribute {} requires a string parameter", ShaderAst::AttributeType)
|
||||
NAZARA_SHADERLANG_PARSER_ERROR( 2, AttributeInvalidParameter, "invalid parameter {} for attribute {}", std::string, ShaderAst::AttributeType)
|
||||
NAZARA_SHADERLANG_PARSER_ERROR( 3, AttributeMissingParameter, "attribute {} requires a parameter", ShaderAst::AttributeType)
|
||||
NAZARA_SHADERLANG_PARSER_ERROR( 4, AttributeMultipleUnique, "attribute {} can only be present once", ShaderAst::AttributeType)
|
||||
NAZARA_SHADERLANG_PARSER_ERROR( 5, AttributeParameterIdentifier, "attribute {} parameter can only be an identifier", ShaderAst::AttributeType)
|
||||
NAZARA_SHADERLANG_PARSER_ERROR( 6, ExpectedToken, "expected token {}, got {}", ShaderLang::TokenType, ShaderLang::TokenType)
|
||||
NAZARA_SHADERLANG_PARSER_ERROR( 7, DuplicateIdentifier, "duplicate identifier")
|
||||
NAZARA_SHADERLANG_PARSER_ERROR( 8, DuplicateModule, "duplicate module")
|
||||
NAZARA_SHADERLANG_PARSER_ERROR( 9, InvalidVersion, "\"{}\" is not a valid version", std::string)
|
||||
NAZARA_SHADERLANG_PARSER_ERROR(10, InvalidUuid, "\"{}\" is not a valid UUID", std::string)
|
||||
NAZARA_SHADERLANG_PARSER_ERROR(11, MissingAttribute, "missing attribute {}", ShaderAst::AttributeType)
|
||||
NAZARA_SHADERLANG_PARSER_ERROR(12, ReservedKeyword, "reserved keyword")
|
||||
NAZARA_SHADERLANG_PARSER_ERROR(13, UnknownAttribute, "unknown attribute")
|
||||
NAZARA_SHADERLANG_PARSER_ERROR(14, UnknownType, "unknown type")
|
||||
NAZARA_SHADERLANG_PARSER_ERROR(15, UnexpectedAttribute, "unexpected attribute {}", ShaderAst::AttributeType)
|
||||
NAZARA_SHADERLANG_PARSER_ERROR(16, UnexpectedEndOfFile, "unexpected end of file")
|
||||
NAZARA_SHADERLANG_PARSER_ERROR(17, UnexpectedToken, "unexpected token {}", ShaderLang::TokenType)
|
||||
|
||||
// Compiler errors
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(1, InvalidSwizzle, "invalid swizzle {}", std::string)
|
||||
|
||||
// AST errors
|
||||
NAZARA_SHADERLANG_AST_ERROR(1, AlreadyUsedIndex, "index {} is already used", std::size_t)
|
||||
NAZARA_SHADERLANG_AST_ERROR(2, InvalidIndex, "invalid index {}", std::size_t)
|
||||
|
||||
#undef NAZARA_SHADERLANG_ERROR
|
||||
#undef NAZARA_SHADERLANG_AST_ERROR
|
||||
#undef NAZARA_SHADERLANG_COMPILER_ERROR
|
||||
#undef NAZARA_SHADERLANG_LEXER_ERROR
|
||||
#undef NAZARA_SHADERLANG_PARSER_ERROR
|
||||
|
||||
127
include/Nazara/Shader/ShaderLangErrors.hpp
Normal file
127
include/Nazara/Shader/ShaderLangErrors.hpp
Normal file
@@ -0,0 +1,127 @@
|
||||
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Shader module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_SHADER_SHADERLANGERRORS_HPP
|
||||
#define NAZARA_SHADER_SHADERLANGERRORS_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Shader/Config.hpp>
|
||||
#include <Nazara/Shader/ShaderLangParser.hpp>
|
||||
#include <Nazara/Shader/Ast/Enums.hpp>
|
||||
#include <exception>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
namespace Nz::ShaderLang
|
||||
{
|
||||
struct SourceLocation
|
||||
{
|
||||
inline SourceLocation();
|
||||
inline SourceLocation(unsigned int line, unsigned int column, std::shared_ptr<const std::string> file);
|
||||
inline SourceLocation(unsigned int line, unsigned int startColumn, unsigned int endColumn, std::shared_ptr<const std::string> file);
|
||||
inline SourceLocation(unsigned int startLine, unsigned int endLine, unsigned int startColumn, unsigned int endColumn, std::shared_ptr<const std::string> file);
|
||||
|
||||
inline bool IsValid() const;
|
||||
|
||||
std::shared_ptr<const std::string> file; //< Since the same file will be used for every node, prevent holding X time the same path
|
||||
unsigned int endColumn;
|
||||
unsigned int endLine;
|
||||
unsigned int startColumn;
|
||||
unsigned int startLine;
|
||||
};
|
||||
|
||||
enum class ErrorCategory
|
||||
{
|
||||
Ast,
|
||||
Compilation,
|
||||
Lexing,
|
||||
Parsing,
|
||||
|
||||
Max = Parsing
|
||||
};
|
||||
|
||||
class Error : public std::exception
|
||||
{
|
||||
public:
|
||||
inline Error(SourceLocation sourceLocation, ErrorCategory errorCategory, unsigned int errorType) noexcept;
|
||||
Error(const Error&) = delete;
|
||||
Error(Error&&) = delete;
|
||||
~Error() = default;
|
||||
|
||||
inline ErrorCategory GetErrorCategory() const;
|
||||
const std::string& GetErrorMessage() const;
|
||||
inline unsigned int GetErrorType() const;
|
||||
inline const SourceLocation& GetSourceLocation() const;
|
||||
|
||||
const char* what() const noexcept override;
|
||||
|
||||
Error& operator=(const Error&) = delete;
|
||||
Error& operator=(Error&&) = delete;
|
||||
|
||||
protected:
|
||||
virtual std::string BuildErrorMessage() const = 0;
|
||||
|
||||
private:
|
||||
mutable std::string m_errorMessage;
|
||||
ErrorCategory m_errorCategory;
|
||||
SourceLocation m_sourceLocation;
|
||||
unsigned int m_errorType;
|
||||
};
|
||||
|
||||
class AstError : public Error
|
||||
{
|
||||
public:
|
||||
inline AstError(SourceLocation sourceLocation, unsigned int errorType) noexcept;
|
||||
};
|
||||
|
||||
class CompilationError : public Error
|
||||
{
|
||||
public:
|
||||
inline CompilationError(SourceLocation sourceLocation, unsigned int errorType) noexcept;
|
||||
};
|
||||
|
||||
class LexingError : public Error
|
||||
{
|
||||
public:
|
||||
inline LexingError(SourceLocation sourceLocation, unsigned int errorType) noexcept;
|
||||
};
|
||||
|
||||
class ParsingError : public Error
|
||||
{
|
||||
public:
|
||||
inline ParsingError(SourceLocation sourceLocation, unsigned int errorType) noexcept;
|
||||
};
|
||||
|
||||
#define NAZARA_SHADERLANG_NEWERRORTYPE(Prefix, BaseClass, ErrorType, ErrorName, ErrorString, ...) \
|
||||
class Prefix ## ErrorName ## Error : public BaseClass \
|
||||
{ \
|
||||
public: \
|
||||
template<typename... Args> Prefix ## ErrorName ## Error(SourceLocation sourceLocation, Args&&... args) : \
|
||||
BaseClass(std::move(sourceLocation), ErrorType), \
|
||||
m_parameters(std::forward<Args>(args)...) \
|
||||
{ \
|
||||
} \
|
||||
\
|
||||
private: \
|
||||
std::string BuildErrorMessage() const override; \
|
||||
\
|
||||
std::tuple<__VA_ARGS__> m_parameters; \
|
||||
};
|
||||
|
||||
#define NAZARA_SHADERLANG_AST_ERROR(ErrorType, ErrorName, ErrorString, ...) NAZARA_SHADERLANG_NEWERRORTYPE(Ast, AstError, ErrorType, ErrorName, ErrorString, __VA_ARGS__)
|
||||
#define NAZARA_SHADERLANG_LEXER_ERROR(ErrorType, ErrorName, ErrorString, ...) NAZARA_SHADERLANG_NEWERRORTYPE(Lexer, LexingError, ErrorType, ErrorName, ErrorString, __VA_ARGS__)
|
||||
#define NAZARA_SHADERLANG_PARSER_ERROR(ErrorType, ErrorName, ErrorString, ...) NAZARA_SHADERLANG_NEWERRORTYPE(Parser, ParsingError, ErrorType, ErrorName, ErrorString, __VA_ARGS__)
|
||||
#define NAZARA_SHADERLANG_COMPILER_ERROR(ErrorType, ErrorName, ErrorString, ...) NAZARA_SHADERLANG_NEWERRORTYPE(Compiler, CompilationError, ErrorType, ErrorName, ErrorString, __VA_ARGS__)
|
||||
|
||||
#include <Nazara/Shader/ShaderLangErrorList.hpp>
|
||||
|
||||
#undef NAZARA_SHADERLANG_NEWERRORTYPE
|
||||
}
|
||||
|
||||
#include <Nazara/Shader/ShaderLangErrors.inl>
|
||||
|
||||
#endif // NAZARA_SHADER_SHADERLANGERRORS_HPP
|
||||
94
include/Nazara/Shader/ShaderLangErrors.inl
Normal file
94
include/Nazara/Shader/ShaderLangErrors.inl
Normal file
@@ -0,0 +1,94 @@
|
||||
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Shader module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Shader/ShaderLangErrors.hpp>
|
||||
#include <Nazara/Shader/Debug.hpp>
|
||||
|
||||
namespace Nz::ShaderLang
|
||||
{
|
||||
inline SourceLocation::SourceLocation() :
|
||||
endColumn(0),
|
||||
endLine(0),
|
||||
startColumn(0),
|
||||
startLine(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline SourceLocation::SourceLocation(unsigned int Line, unsigned int Column, std::shared_ptr<const std::string> File) :
|
||||
file(std::move(File)),
|
||||
endColumn(Column),
|
||||
endLine(Line),
|
||||
startColumn(Column),
|
||||
startLine(Line)
|
||||
{
|
||||
}
|
||||
|
||||
inline SourceLocation::SourceLocation(unsigned int Line, unsigned int StartColumn, unsigned int EndColumn, std::shared_ptr<const std::string> File) :
|
||||
file(std::move(File)),
|
||||
endColumn(EndColumn),
|
||||
endLine(Line),
|
||||
startColumn(StartColumn),
|
||||
startLine(Line)
|
||||
{
|
||||
}
|
||||
|
||||
inline SourceLocation::SourceLocation(unsigned int StartLine, unsigned int EndLine, unsigned int StartColumn, unsigned int EndColumn, std::shared_ptr<const std::string> File) :
|
||||
file(std::move(File)),
|
||||
endColumn(EndColumn),
|
||||
endLine(EndLine),
|
||||
startColumn(StartColumn),
|
||||
startLine(StartLine)
|
||||
{
|
||||
}
|
||||
|
||||
inline bool SourceLocation::IsValid() const
|
||||
{
|
||||
return startLine != 0 && endLine != 0 && endColumn != 0 && startColumn != 0;
|
||||
}
|
||||
|
||||
inline Error::Error(SourceLocation sourceLocation, ErrorCategory errorCategory, unsigned int errorType) noexcept :
|
||||
m_errorCategory(errorCategory),
|
||||
m_sourceLocation(std::move(sourceLocation)),
|
||||
m_errorType(errorType)
|
||||
{
|
||||
}
|
||||
|
||||
inline ErrorCategory Error::GetErrorCategory() const
|
||||
{
|
||||
return m_errorCategory;
|
||||
}
|
||||
|
||||
inline unsigned int Error::GetErrorType() const
|
||||
{
|
||||
return m_errorType;
|
||||
}
|
||||
|
||||
inline const SourceLocation& Error::GetSourceLocation() const
|
||||
{
|
||||
return m_sourceLocation;
|
||||
}
|
||||
|
||||
|
||||
inline AstError::AstError(SourceLocation sourceLocation, unsigned int errorType) noexcept :
|
||||
Error(std::move(sourceLocation), ErrorCategory::Ast, errorType)
|
||||
{
|
||||
}
|
||||
|
||||
inline CompilationError::CompilationError(SourceLocation sourceLocation, unsigned int errorType) noexcept :
|
||||
Error(std::move(sourceLocation), ErrorCategory::Compilation, errorType)
|
||||
{
|
||||
}
|
||||
|
||||
inline ParsingError::ParsingError(SourceLocation sourceLocation, unsigned int errorType) noexcept :
|
||||
Error(std::move(sourceLocation), ErrorCategory::Parsing, errorType)
|
||||
{
|
||||
}
|
||||
|
||||
inline LexingError::LexingError(SourceLocation sourceLocation, unsigned int errorType) noexcept :
|
||||
Error(std::move(sourceLocation), ErrorCategory::Lexing, errorType)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Shader/DebugOff.hpp>
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Shader/Config.hpp>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
@@ -28,35 +29,11 @@ namespace Nz::ShaderLang
|
||||
unsigned int column;
|
||||
unsigned int line;
|
||||
TokenType type;
|
||||
std::shared_ptr<const std::string> file;
|
||||
std::variant<double, long long, std::string> data;
|
||||
};
|
||||
|
||||
class BadNumber : public std::exception
|
||||
{
|
||||
using exception::exception;
|
||||
};
|
||||
|
||||
class NumberOutOfRange : public std::exception
|
||||
{
|
||||
using exception::exception;
|
||||
};
|
||||
|
||||
class UnfinishedString : public std::exception
|
||||
{
|
||||
using exception::exception;
|
||||
};
|
||||
|
||||
class UnrecognizedChar : public std::exception
|
||||
{
|
||||
using exception::exception;
|
||||
};
|
||||
|
||||
class UnrecognizedToken : public std::exception
|
||||
{
|
||||
using exception::exception;
|
||||
};
|
||||
|
||||
NAZARA_SHADER_API std::vector<Token> Tokenize(const std::string_view& str);
|
||||
NAZARA_SHADER_API std::vector<Token> Tokenize(const std::string_view& str, const std::string& filePath = std::string{});
|
||||
NAZARA_SHADER_API const char* ToString(TokenType tokenType);
|
||||
NAZARA_SHADER_API std::string ToString(const std::vector<Token>& tokens, bool pretty = true);
|
||||
}
|
||||
|
||||
@@ -16,54 +16,6 @@
|
||||
|
||||
namespace Nz::ShaderLang
|
||||
{
|
||||
class AttributeError : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
using runtime_error::runtime_error;
|
||||
};
|
||||
|
||||
class ExpectedToken : public std::exception
|
||||
{
|
||||
public:
|
||||
using exception::exception;
|
||||
};
|
||||
|
||||
class DuplicateIdentifier : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
using runtime_error::runtime_error;
|
||||
};
|
||||
|
||||
class DuplicateModule : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
using runtime_error::runtime_error;
|
||||
};
|
||||
|
||||
class ReservedKeyword : public std::exception
|
||||
{
|
||||
public:
|
||||
using exception::exception;
|
||||
};
|
||||
|
||||
class UnknownAttribute : public std::exception
|
||||
{
|
||||
public:
|
||||
using exception::exception;
|
||||
};
|
||||
|
||||
class UnknownType : public std::exception
|
||||
{
|
||||
public:
|
||||
using exception::exception;
|
||||
};
|
||||
|
||||
class UnexpectedToken : public std::exception
|
||||
{
|
||||
public:
|
||||
using exception::exception;
|
||||
};
|
||||
|
||||
class NAZARA_SHADER_API Parser
|
||||
{
|
||||
public:
|
||||
@@ -142,7 +94,7 @@ namespace Nz::ShaderLang
|
||||
Context* m_context;
|
||||
};
|
||||
|
||||
inline ShaderAst::ModulePtr Parse(const std::string_view& source);
|
||||
inline ShaderAst::ModulePtr Parse(const std::string_view& source, const std::string& filePath = std::string{});
|
||||
inline ShaderAst::ModulePtr Parse(const std::vector<Token>& tokens);
|
||||
NAZARA_SHADER_API ShaderAst::ModulePtr ParseFromFile(const std::filesystem::path& sourcePath);
|
||||
}
|
||||
|
||||
@@ -12,9 +12,9 @@ namespace Nz::ShaderLang
|
||||
{
|
||||
}
|
||||
|
||||
inline ShaderAst::ModulePtr Parse(const std::string_view& source)
|
||||
inline ShaderAst::ModulePtr Parse(const std::string_view& source, const std::string& filePath)
|
||||
{
|
||||
return Parse(Tokenize(source));
|
||||
return Parse(Tokenize(source, filePath));
|
||||
}
|
||||
|
||||
inline ShaderAst::ModulePtr Parse(const std::vector<Token>& tokens)
|
||||
|
||||
Reference in New Issue
Block a user