Shader/ShaderLang: Add type inference for variable declaration

This commit is contained in:
Jérôme Leclercq 2021-04-14 17:56:33 +02:00
parent 0f15387c6c
commit b234134abc
6 changed files with 37 additions and 7 deletions

View File

@ -45,8 +45,8 @@ struct FragOut
[[entry(frag)]]
fn main(fragIn: VertOut) -> FragOut
{
let lightDir: vec3<f32> = vec3<f32>(0.0, -0.707, 0.707);
let lightFactor: f32 = dot(fragIn.normal, lightDir);
let lightDir = vec3<f32>(0.0, -0.707, 0.707);
let lightFactor = dot(fragIn.normal, lightDir);
let fragOut: FragOut;
fragOut.color = lightFactor * tex.Sample(fragIn.uv);

View File

@ -49,6 +49,7 @@ namespace Nz::ShaderAst
void Visit(DeclareExternalStatement& node) override;
void Visit(DeclareFunctionStatement& node) override;
void Visit(DeclareStructStatement& node) override;
void Visit(DeclareVariableStatement& node) override;
void Visit(ExpressionStatement& node) override;
void Visit(MultiStatement& node) override;

View File

@ -70,6 +70,7 @@ namespace Nz::ShaderBuilder
struct DeclareVariable
{
inline std::unique_ptr<ShaderAst::DeclareVariableStatement> operator()(std::string name, ShaderAst::ExpressionPtr initialValue) const;
inline std::unique_ptr<ShaderAst::DeclareVariableStatement> operator()(std::string name, ShaderAst::ExpressionType type, ShaderAst::ExpressionPtr initialValue = nullptr) const;
};

View File

@ -128,6 +128,15 @@ namespace Nz::ShaderBuilder
return declareStructNode;
}
inline std::unique_ptr<ShaderAst::DeclareVariableStatement> Nz::ShaderBuilder::Impl::DeclareVariable::operator()(std::string name, ShaderAst::ExpressionPtr initialValue) const
{
auto declareVariableNode = std::make_unique<ShaderAst::DeclareVariableStatement>();
declareVariableNode->varName = std::move(name);
declareVariableNode->initialExpression = std::move(initialValue);
return declareVariableNode;
}
inline std::unique_ptr<ShaderAst::DeclareVariableStatement> Nz::ShaderBuilder::Impl::DeclareVariable::operator()(std::string name, ShaderAst::ExpressionType type, ShaderAst::ExpressionPtr initialValue) const
{
auto declareVariableNode = std::make_unique<ShaderAst::DeclareVariableStatement>();

View File

@ -594,6 +594,21 @@ namespace Nz::ShaderAst
AstScopedVisitor::Visit(node);
}
void AstValidator::Visit(DeclareVariableStatement& node)
{
if (IsNoType(node.varType))
{
if (!node.initialExpression)
throw AstError{ "variable must either have a type or an initial value" };
node.initialExpression->Visit(*this);
node.varType = GetExpressionType(*node.initialExpression);
}
AstScopedVisitor::Visit(node);
}
void AstValidator::Visit(ExpressionStatement& node)
{
MandatoryExpr(node.expression);

View File

@ -637,15 +637,19 @@ namespace Nz::ShaderLang
std::string variableName = ParseIdentifierAsName();
RegisterVariable(variableName);
ShaderAst::ExpressionType variableType = ShaderAst::NoType{};
if (Peek().type == TokenType::Colon)
{
Expect(Advance(), TokenType::Colon);
Expect(Advance(), TokenType::Colon);
ShaderAst::ExpressionType variableType = ParseType();
variableType = ParseType();
}
ShaderAst::ExpressionPtr expression;
if (Peek().type == TokenType::Assign)
if (IsNoType(variableType) || Peek().type == TokenType::Assign)
{
Consume();
Expect(Advance(), TokenType::Assign);
expression = ParseExpression();
}