Shader: Add compiler and AST errors (WIP)
I'm so afraid to lose all this work
This commit is contained in:
committed by
Jérôme Leclercq
parent
52d0c5b0bc
commit
ac9e7207ac
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Shader/Config.hpp>
|
||||
#include <Nazara/Shader/ShaderLangSourceLocation.hpp>
|
||||
#include <Nazara/Shader/Ast/AstRecursiveVisitor.hpp>
|
||||
#include <vector>
|
||||
|
||||
@@ -41,12 +42,12 @@ namespace Nz::ShaderAst
|
||||
std::function<void(const DeclareStructStatement& structDecl)> onStructDeclaration;
|
||||
std::function<void(const DeclareVariableStatement& variableDecl)> onVariableDeclaration;
|
||||
|
||||
std::function<void(const std::string& name, std::size_t aliasIndex)> onAliasIndex;
|
||||
std::function<void(const std::string& name, std::size_t constIndex)> onConstIndex;
|
||||
std::function<void(const std::string& name, std::size_t funcIndex)> onFunctionIndex;
|
||||
std::function<void(const std::string& name, std::size_t optIndex)> onOptionIndex;
|
||||
std::function<void(const std::string& name, std::size_t structIndex)> onStructIndex;
|
||||
std::function<void(const std::string& name, std::size_t varIndex)> onVariableIndex;
|
||||
std::function<void(const std::string& name, std::size_t aliasIndex, const ShaderLang::SourceLocation& sourceLocation)> onAliasIndex;
|
||||
std::function<void(const std::string& name, std::size_t constIndex, const ShaderLang::SourceLocation& sourceLocation)> onConstIndex;
|
||||
std::function<void(const std::string& name, std::size_t funcIndex, const ShaderLang::SourceLocation& sourceLocation)> onFunctionIndex;
|
||||
std::function<void(const std::string& name, std::size_t optIndex, const ShaderLang::SourceLocation& sourceLocation)> onOptionIndex;
|
||||
std::function<void(const std::string& name, std::size_t structIndex, const ShaderLang::SourceLocation& sourceLocation)> onStructIndex;
|
||||
std::function<void(const std::string& name, std::size_t varIndex, const ShaderLang::SourceLocation& sourceLocation)> onVariableIndex;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
@@ -39,8 +39,6 @@ namespace Nz::ShaderAst
|
||||
SanitizeVisitor& operator=(const SanitizeVisitor&) = delete;
|
||||
SanitizeVisitor& operator=(SanitizeVisitor&&) = delete;
|
||||
|
||||
static UInt32 ToSwizzleIndex(char c);
|
||||
|
||||
struct Options
|
||||
{
|
||||
std::shared_ptr<ShaderModuleResolver> moduleResolver;
|
||||
@@ -113,13 +111,10 @@ namespace Nz::ShaderAst
|
||||
const IdentifierData* FindIdentifier(const Environment& environment, const std::string_view& identifierName) const;
|
||||
template<typename F> const IdentifierData* FindIdentifier(const Environment& environment, const std::string_view& identifierName, F&& functor) const;
|
||||
|
||||
ExpressionPtr HandleIdentifier(const IdentifierData* identifierData);
|
||||
|
||||
const ExpressionType* GetExpressionType(Expression& expr) const;
|
||||
const ExpressionType& GetExpressionTypeSecure(Expression& expr) const;
|
||||
|
||||
Expression& MandatoryExpr(const ExpressionPtr& node) const;
|
||||
Statement& MandatoryStatement(const StatementPtr& node) const;
|
||||
ExpressionPtr HandleIdentifier(const IdentifierData* identifierData, const ShaderLang::SourceLocation& sourceLocation);
|
||||
|
||||
void PushScope();
|
||||
void PopScope();
|
||||
@@ -136,34 +131,31 @@ namespace Nz::ShaderAst
|
||||
|
||||
void RegisterBuiltin();
|
||||
|
||||
std::size_t RegisterAlias(std::string name, std::optional<IdentifierData> aliasData, std::optional<std::size_t> index = {});
|
||||
std::size_t RegisterConstant(std::string name, std::optional<ConstantValue> value, std::optional<std::size_t> index = {});
|
||||
std::size_t RegisterFunction(std::string name, std::optional<FunctionData> funcData, std::optional<std::size_t> index = {});
|
||||
std::size_t RegisterAlias(std::string name, std::optional<IdentifierData> aliasData, std::optional<std::size_t> index, const ShaderLang::SourceLocation& sourceLocation);
|
||||
std::size_t RegisterConstant(std::string name, std::optional<ConstantValue> value, std::optional<std::size_t> index, const ShaderLang::SourceLocation& sourceLocation);
|
||||
std::size_t RegisterFunction(std::string name, std::optional<FunctionData> funcData, std::optional<std::size_t> index, const ShaderLang::SourceLocation& sourceLocation);
|
||||
std::size_t RegisterIntrinsic(std::string name, IntrinsicType type);
|
||||
std::size_t RegisterModule(std::string moduleIdentifier, std::size_t moduleIndex);
|
||||
std::size_t RegisterStruct(std::string name, std::optional<StructDescription*> description, std::optional<std::size_t> index = {});
|
||||
std::size_t RegisterType(std::string name, std::optional<ExpressionType> expressionType, std::optional<std::size_t> index = {});
|
||||
std::size_t RegisterType(std::string name, std::optional<PartialType> partialType, std::optional<std::size_t> index = {});
|
||||
std::size_t RegisterStruct(std::string name, std::optional<StructDescription*> description, std::optional<std::size_t> index, const ShaderLang::SourceLocation& sourceLocation);
|
||||
std::size_t RegisterType(std::string name, std::optional<ExpressionType> expressionType, std::optional<std::size_t> index, const ShaderLang::SourceLocation& sourceLocation);
|
||||
std::size_t RegisterType(std::string name, std::optional<PartialType> partialType, std::optional<std::size_t> index, const ShaderLang::SourceLocation& sourceLocation);
|
||||
void RegisterUnresolved(std::string name);
|
||||
std::size_t RegisterVariable(std::string name, std::optional<ExpressionType> type, std::optional<std::size_t> index = {});
|
||||
std::size_t RegisterVariable(std::string name, std::optional<ExpressionType> type, std::optional<std::size_t> index, const ShaderLang::SourceLocation& sourceLocation);
|
||||
|
||||
const IdentifierData* ResolveAliasIdentifier(const IdentifierData* identifier) const;
|
||||
const IdentifierData* ResolveAliasIdentifier(const IdentifierData* identifier, const ShaderLang::SourceLocation& sourceLocation) const;
|
||||
void ResolveFunctions();
|
||||
std::size_t ResolveStruct(const AliasType& aliasType);
|
||||
std::size_t ResolveStruct(const ExpressionType& exprType);
|
||||
std::size_t ResolveStruct(const IdentifierType& identifierType);
|
||||
std::size_t ResolveStruct(const StructType& structType);
|
||||
std::size_t ResolveStruct(const UniformType& uniformType);
|
||||
ExpressionType ResolveType(const ExpressionType& exprType, bool resolveAlias = false);
|
||||
std::optional<ExpressionType> ResolveTypeExpr(const ExpressionValue<ExpressionType>& exprTypeValue, bool resolveAlias = false);
|
||||
ExpressionType ResolveType(const ExpressionType& exprType, bool resolveAlias, const ShaderLang::SourceLocation& sourceLocation);
|
||||
std::optional<ExpressionType> ResolveTypeExpr(const ExpressionValue<ExpressionType>& exprTypeValue, bool resolveAlias, const ShaderLang::SourceLocation& sourceLocation);
|
||||
|
||||
void SanitizeIdentifier(std::string& identifier);
|
||||
MultiStatementPtr SanitizeInternal(MultiStatement& rootNode, std::string* error);
|
||||
|
||||
ValidationResult TypeMustMatch(const ExpressionPtr& left, const ExpressionPtr& right) const;
|
||||
void TypeMustMatch(const ExpressionType& left, const ExpressionType& right) const;
|
||||
|
||||
StatementPtr Unscope(StatementPtr node);
|
||||
ValidationResult TypeMustMatch(const ExpressionPtr& left, const ExpressionPtr& right, const ShaderLang::SourceLocation& sourceLocation);
|
||||
|
||||
ValidationResult Validate(DeclareAliasStatement& node);
|
||||
ValidationResult Validate(WhileStatement& node);
|
||||
@@ -178,7 +170,21 @@ namespace Nz::ShaderAst
|
||||
ValidationResult Validate(SwizzleExpression& node);
|
||||
ValidationResult Validate(UnaryExpression& node);
|
||||
ValidationResult Validate(VariableValueExpression& node);
|
||||
ExpressionType ValidateBinaryOp(BinaryType op, const ExpressionType& leftExprType, const ExpressionType& rightExprType);
|
||||
ExpressionType ValidateBinaryOp(BinaryType op, const ExpressionType& leftExprType, const ExpressionType& rightExprType, const ShaderLang::SourceLocation& sourceLocation);
|
||||
|
||||
template<std::size_t N> ValidationResult ValidateIntrinsicParamCount(IntrinsicExpression& node);
|
||||
ValidationResult ValidateIntrinsicParamMatchingType(IntrinsicExpression& node);
|
||||
template<std::size_t N, typename F> ValidationResult ValidateIntrinsicParameter(IntrinsicExpression& node, F&& func);
|
||||
template<std::size_t N, typename F> ValidationResult ValidateIntrinsicParameterType(IntrinsicExpression& node, F&& func);
|
||||
|
||||
static Expression& MandatoryExpr(const ExpressionPtr& node, const ShaderLang::SourceLocation& sourceLocation);
|
||||
static Statement& MandatoryStatement(const StatementPtr& node, const ShaderLang::SourceLocation& sourceLocation);
|
||||
|
||||
static void TypeMustMatch(const ExpressionType& left, const ExpressionType& right, const ShaderLang::SourceLocation& sourceLocation);
|
||||
|
||||
static StatementPtr Unscope(StatementPtr node);
|
||||
|
||||
static UInt32 ToSwizzleIndex(char c, const ShaderLang::SourceLocation& sourceLocation);
|
||||
|
||||
enum class IdentifierCategory
|
||||
{
|
||||
|
||||
@@ -51,11 +51,63 @@ 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)
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, BinaryIncompatibleTypes, "incompatibles types (<TODO> and <TODO>)")
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, BinaryUnsupported, "{} type (<TODO>) does not support this binary operation", std::string)
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, BranchOutsideOfFunction, "non-const branching statements can only exist inside a function")
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, CastIncompatibleTypes, "incompatibles types (<TODO> and <TODO>)")
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, CastComponentMismatch, "component count doesn't match required component count")
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, CircularImport, "circular import detected on {}", std::string)
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, ConditionExpectedBool, "expected a boolean value")
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, ConstMissingExpression, "const variables must have an expression")
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, ConstantExpectedValue, "expected a value")
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, ConstantExpressionRequired, "a constant expression is required in this context")
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, DepthWriteAttribute, "only fragment entry-points can have the depth_write attribute")
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, DiscardEarlyFragmentTests, "discard is not compatible with early fragment tests")
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, EarlyFragmentTestsAttribute, "only functions with entry(frag) attribute can have the early_fragments_tests attribute")
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, EntryFunctionParameter, "entry functions can either take one struct parameter or no parameter")
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, EntryPointAlreadyDefined, "the same entry type has been defined multiple times")
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, ExpectedFunction, "expected function expression")
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, ExpectedIntrinsicFunction, "expected intrinsic function expression")
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, ExtAlreadyDeclared, "external variable {} is already declared", std::string)
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, ExtTypeNotAllowed, "external variable {} is of wrong type: only uniform and sampler are allowed in external blocks", std::string)
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, ExtBindingAlreadyUsed, "binding (set={}, binding={}) is already in use", UInt32, UInt32)
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, ExtMissingBindingIndex, "external variable requires a binding index")
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, ForEachUnsupportedType, "for-each statements can only be called on array types, got <TODO>")
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, FunctionCallOutsideOfFunction, "function calls must happen inside a function")
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, FunctionDeclarationInsideFunction, "a function cannot be defined inside another function")
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, IdentifierAlreadyUsed, "identifier {} is already used", std::string)
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, IntrinsicExpectedParameterCount, "expected {} parameter(s)", unsigned int)
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, IntrinsicExpectedFloat, "expected scalar or vector floating-points")
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, IntrinsicExpectedType, "expected type <TODO> for parameter #{}, got <TODO>", unsigned int)
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, IntrinsicUnexpectedBoolean, "boolean parameters are not allowed")
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, IntrinsicUnmatchingParameterType, "all types must match")
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, InvalidScalarSwizzle, "invalid swizzle for scalar")
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, InvalidSwizzle, "invalid swizzle {}", std::string)
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, MissingOptionValue, "option {} requires a value (no default value set)", std::string)
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, PartialTypeExpect, "expected a {} type at #{}", std::string, unsigned int)
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, StructDeclarationInsideFunction, "structs must be declared outside of functions")
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, VarDeclarationMissingTypeAndValue, "variable must either have a type or an initial value")
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, VarDeclarationTypeUnmatching, "initial expression type (<TODO>) doesn't match specified type (<TODO>)")
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, UnexpectedAccessedType, "unexpected type (only struct and vectors can be indexed with identifiers)")
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, UnaryUnsupported, "type (<TODO>) does not support this unary operation", std::string)
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, UnmatchingTypes, "left expression type (<TODO>) doesn't match right expression type (<TODO>)")
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, UnknownField, "unknown field {}", std::string)
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, UnknownMethod, "unknown method {}", std::string)
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, UnknownIdentifier, "unknown identifier {}", std::string)
|
||||
NAZARA_SHADERLANG_COMPILER_ERROR(2, WhileUnrollNotSupported, "unroll(always) is not yet supported on while")
|
||||
|
||||
// AST errors
|
||||
NAZARA_SHADERLANG_AST_ERROR(1, AlreadyUsedIndex, "index {} is already used", std::size_t)
|
||||
NAZARA_SHADERLANG_AST_ERROR(2, AlreadyUsedIndexPreregister, "cannot preregister used index {} as its already used", std::size_t)
|
||||
NAZARA_SHADERLANG_AST_ERROR(2, EmptyIdentifier, "identifier cannot be empty")
|
||||
NAZARA_SHADERLANG_AST_ERROR(2, Internal, "internal error: {}", std::string)
|
||||
NAZARA_SHADERLANG_AST_ERROR(2, InvalidConstantIndex, "invalid constant index #{}", std::size_t)
|
||||
NAZARA_SHADERLANG_AST_ERROR(2, InvalidIndex, "invalid index {}", std::size_t)
|
||||
NAZARA_SHADERLANG_AST_ERROR(2, MissingExpression, "a mandatory expression is missing")
|
||||
NAZARA_SHADERLANG_AST_ERROR(2, MissingStatement, "a mandatory statement is missing")
|
||||
NAZARA_SHADERLANG_AST_ERROR(2, NoIdentifier, "at least one identifier is required")
|
||||
NAZARA_SHADERLANG_AST_ERROR(2, NoIndex, "at least one index is required")
|
||||
NAZARA_SHADERLANG_AST_ERROR(2, UnexpectedIdentifier, "unexpected identifier of type {}", std::string)
|
||||
|
||||
#undef NAZARA_SHADERLANG_ERROR
|
||||
#undef NAZARA_SHADERLANG_AST_ERROR
|
||||
|
||||
Reference in New Issue
Block a user