Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for named external block #51

Merged
merged 1 commit into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions include/NZSL/Ast/Compare.inl
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,9 @@
if (!Compare(lhs.variableId, rhs.variableId, params))
return false;

if (!Compare(lhs.prefix, rhs.prefix, params))
return false;

Check warning on line 528 in include/NZSL/Ast/Compare.inl

View check run for this annotation

Codecov / codecov/patch

include/NZSL/Ast/Compare.inl#L528

Added line #L528 was not covered by tests

return true;
}

Expand Down Expand Up @@ -609,6 +612,9 @@
if (!Compare(lhs.tag, rhs.tag, params))
return false;

if (!Compare(lhs.name, rhs.name, params))
return false;

Check warning on line 616 in include/NZSL/Ast/Compare.inl

View check run for this annotation

Codecov / codecov/patch

include/NZSL/Ast/Compare.inl#L616

Added line #L616 was not covered by tests

if (!Compare(lhs.externalVars, rhs.externalVars, params))
return false;

Expand Down
2 changes: 2 additions & 0 deletions include/NZSL/Ast/Nodes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ namespace nzsl::Ast
void Visit(ExpressionVisitor& visitor) override;

std::size_t variableId;
std::string prefix;
};

struct NZSL_API UnaryExpression : Expression
Expand Down Expand Up @@ -347,6 +348,7 @@ namespace nzsl::Ast
SourceLocation sourceLocation;
};

std::string name;
std::string tag;
std::vector<ExternalVar> externalVars;
ExpressionValue<std::uint32_t> bindingSet;
Expand Down
2 changes: 2 additions & 0 deletions include/NZSL/Ast/SanitizeVisitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ namespace nzsl::Ast
std::size_t RegisterIntrinsic(std::string name, IntrinsicType type);
std::size_t RegisterModule(std::string moduleIdentifier, std::size_t moduleIndex);
void RegisterReservedName(std::string name);
void RegisterExternalName(std::string name, const SourceLocation& sourceLocation);
std::size_t RegisterStruct(std::string name, std::optional<StructDescription*> description, std::optional<std::size_t> index, const SourceLocation& sourceLocation);
std::size_t RegisterType(std::string name, std::optional<ExpressionType> expressionType, std::optional<std::size_t> index, const SourceLocation& sourceLocation);
std::size_t RegisterType(std::string name, std::optional<PartialType> partialType, std::optional<std::size_t> index, const SourceLocation& sourceLocation);
Expand Down Expand Up @@ -207,6 +208,7 @@ namespace nzsl::Ast
{
Alias,
Constant,
External,
Function,
Intrinsic,
Module,
Expand Down
2 changes: 2 additions & 0 deletions src/NZSL/Ast/Cloner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ namespace nzsl::Ast
clone->autoBinding = Clone(node.autoBinding);
clone->bindingSet = Clone(node.bindingSet);
clone->tag = node.tag;
clone->name = node.name;

clone->externalVars.reserve(node.externalVars.size());
for (const auto& var : node.externalVars)
Expand Down Expand Up @@ -593,6 +594,7 @@ namespace nzsl::Ast
{
auto clone = std::make_unique<VariableValueExpression>();
clone->variableId = node.variableId;
clone->prefix = node.prefix;

clone->cachedExpressionType = node.cachedExpressionType;
clone->sourceLocation = node.sourceLocation;
Expand Down
2 changes: 1 addition & 1 deletion src/NZSL/Ast/ReflectVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ namespace nzsl::Ast
for (const auto& extVar : node.externalVars)
{
if (extVar.varIndex)
m_callbacks->onVariableIndex(extVar.name, *extVar.varIndex, extVar.sourceLocation);
m_callbacks->onVariableIndex(node.name + extVar.name, *extVar.varIndex, extVar.sourceLocation);
}
}

Expand Down
49 changes: 43 additions & 6 deletions src/NZSL/Ast/SanitizeVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -312,11 +312,12 @@

MandatoryExpr(node.expr, node.sourceLocation);

// Handle module access (TODO: Add namespace expression?)
// Handle module access and named external access (TODO: Add namespace expression?)
if (node.expr->GetType() == NodeType::IdentifierExpression && node.identifiers.size() == 1)
{
auto& identifierExpr = static_cast<IdentifierExpression&>(*node.expr);
const IdentifierData* identifierData = FindIdentifier(identifierExpr.identifier);

if (identifierData && identifierData->category == IdentifierCategory::Module)
{
std::size_t moduleIndex = m_context->moduleIndices.Retrieve(identifierData->index, node.sourceLocation);
Expand All @@ -331,6 +332,17 @@
return HandleIdentifier(identifierData, node.identifiers.front().sourceLocation);
}
}

if (identifierData && identifierData->category == IdentifierCategory::External)
{
identifierData = FindIdentifier(identifierExpr.identifier + node.identifiers.front().identifier);
if (identifierData)
{
auto variableValuePtr = HandleIdentifier(identifierData, node.identifiers.front().sourceLocation);
static_cast<VariableValueExpression*>(variableValuePtr.get())->prefix = identifierExpr.identifier;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really a fan of this one, and I'm not really sure how to tackle it correctly

return variableValuePtr;
}
}
}

ExpressionPtr indexedExpr = CloneExpression(node.expr);
Expand Down Expand Up @@ -1464,27 +1476,36 @@
}
};

if (!clone->name.empty())
{
RegisterExternalName(clone->name, clone->sourceLocation);
}

bool hasUnresolved = false;
Nz::StackVector<std::size_t> autoBindingEntries = NazaraStackVector(std::size_t, clone->externalVars.size());
for (std::size_t i = 0; i < clone->externalVars.size(); ++i)
{
auto& extVar = clone->externalVars[i];

SanitizeIdentifier(extVar.name, IdentifierScope::ExternalVariable);

std::string fullName = clone->name + extVar.name;

Context::UsedExternalData usedBindingData;
usedBindingData.conditionalStatementIndex = m_context->currentConditionalIndex;

if (auto it = m_context->declaredExternalVar.find(extVar.name); it != m_context->declaredExternalVar.end())
if (auto it = m_context->declaredExternalVar.find(fullName); it != m_context->declaredExternalVar.end())
{
if (it->second.conditionalStatementIndex == m_context->currentConditionalIndex || usedBindingData.conditionalStatementIndex == m_context->currentConditionalIndex)
throw CompilerExtAlreadyDeclaredError{ extVar.sourceLocation, extVar.name };
}

m_context->declaredExternalVar.emplace(extVar.name, usedBindingData);
m_context->declaredExternalVar.emplace(fullName, usedBindingData);

std::optional<ExpressionType> resolvedType = ResolveTypeExpr(extVar.type, false, node.sourceLocation);
if (!resolvedType.has_value())
{
RegisterUnresolved(extVar.name);
RegisterUnresolved(fullName);
hasUnresolved = true;
continue;
}
Expand Down Expand Up @@ -1555,8 +1576,7 @@
}

extVar.type = std::move(resolvedType).value();
extVar.varIndex = RegisterVariable(extVar.name, std::move(varType), extVar.varIndex, extVar.sourceLocation);
SanitizeIdentifier(extVar.name, IdentifierScope::ExternalVariable);
extVar.varIndex = RegisterVariable(fullName, std::move(varType), extVar.varIndex, extVar.sourceLocation);
}

// Resolve auto-binding entries when explicit binding are known
Expand Down Expand Up @@ -2870,6 +2890,9 @@
return Clone(constantExpr); //< Turn ConstantExpression into ConstantValueExpression
}

case IdentifierCategory::External:

Check warning on line 2893 in src/NZSL/Ast/SanitizeVisitor.cpp

View check run for this annotation

Codecov / codecov/patch

src/NZSL/Ast/SanitizeVisitor.cpp#L2893

Added line #L2893 was not covered by tests
throw AstUnexpectedIdentifierError{ sourceLocation, "external" };

case IdentifierCategory::Function:
{
// Replace IdentifierExpression by FunctionExpression
Expand Down Expand Up @@ -3741,6 +3764,20 @@
});
}

void SanitizeVisitor::RegisterExternalName(std::string name, const SourceLocation& sourceLocation)
{
if (!IsIdentifierAvailable(name))
throw CompilerIdentifierAlreadyUsedError{ sourceLocation, name };

m_context->currentEnv->identifiersInScope.push_back({
std::move(name),
{
std::numeric_limits<std::size_t>::max(),
IdentifierCategory::External
}
});
}

std::size_t SanitizeVisitor::RegisterStruct(std::string name, std::optional<StructDescription*> description, std::optional<std::size_t> index, const SourceLocation& sourceLocation)
{
bool unresolved = false;
Expand Down
2 changes: 1 addition & 1 deletion src/NZSL/GlslWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2270,7 +2270,7 @@ namespace nzsl
AppendComment("struct tag: " + structInfo.desc->tag);
}

std::string varName = externalVar.name + m_currentState->moduleSuffix;
std::string varName = node.name + externalVar.name + m_currentState->moduleSuffix;

// Layout handling
bool hasLayout = false;
Expand Down
13 changes: 12 additions & 1 deletion src/NZSL/LangWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1260,6 +1260,11 @@ namespace nzsl

void LangWriter::Visit(Ast::VariableValueExpression& node)
{
if (!node.prefix.empty())
{
Append(node.prefix, '.');
}

AppendIdentifier(m_currentState->variables, node.variableId);
}

Expand Down Expand Up @@ -1366,7 +1371,13 @@ namespace nzsl
void LangWriter::Visit(Ast::DeclareExternalStatement& node)
{
AppendAttributes(true, SetAttribute{ node.bindingSet }, AutoBindingAttribute{ node.autoBinding }, TagAttribute{ node.tag });
AppendLine("external");
Append("external");

if (!node.name.empty())
Append(" ", node.name);

AppendLine();

EnterScope();

bool first = true;
Expand Down
8 changes: 6 additions & 2 deletions src/NZSL/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -708,11 +708,15 @@ namespace nzsl
NAZARA_USE_ANONYMOUS_NAMESPACE

const Token& externalToken = Expect(Advance(), TokenType::External);
Expect(Advance(), TokenType::OpenCurlyBracket);


std::unique_ptr<Ast::DeclareExternalStatement> externalStatement = std::make_unique<Ast::DeclareExternalStatement>();
externalStatement->sourceLocation = externalToken.location;

if (const Token& peekToken = Peek(); peekToken.type == TokenType::Identifier)
externalStatement->name = ParseIdentifierAsName(nullptr);

Expect(Advance(), TokenType::OpenCurlyBracket);

Ast::ExpressionValue<bool> condition;

for (auto&& attribute : attributes)
Expand Down
2 changes: 1 addition & 1 deletion src/NZSL/SpirvWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ namespace nzsl
ExternalVar& extVarData = extVars[*extVar.varIndex];

SpirvConstantCache::Variable variable;
variable.debugName = extVar.name;
variable.debugName = node.name + extVar.name;

const Ast::ExpressionType& extVarType = extVar.type.GetResultingValue();

Expand Down
41 changes: 41 additions & 0 deletions tests/src/Tests/ErrorsTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,47 @@ fn main()
}
)"), "(28,19 -> 28): CFunctionCallUnmatchingParameterType error: function GetValue parameter #0 type mismatch (expected array[struct Inner, 3], got array[uniform[struct Inner], 3])");

CHECK_THROWS_WITH(Compile(R"(
[nzsl_version("1.0")]
module;

external Viewer
{
[tag("Color map")]
[binding(0)] tex: sampler2D[f32]
}

external Viewer
{
[tag("Color map")]
[binding(1)] tex2: sampler2D[f32]
}

[entry(frag)]
fn main()
{
let value = Viewer.tex.Sample(vec2[f32](0.0, 0.0));
}
)"), "(11,1 -> 8): CIdentifierAlreadyUsed error: identifier Viewer is already used");

CHECK_THROWS_WITH(Compile(R"(
[nzsl_version("1.0")]
module;

external Viewer
{
[tag("Color map")]
[binding(0)] tex: sampler2D[f32]
}

[entry(frag)]
fn main()
{
let Viewer = 0.0;
let value = Viewer.tex.Sample(vec2[f32](0.0, 0.0));
}
)"), "(14,2 -> 18): CIdentifierAlreadyUsed error: identifier Viewer is already used");

}

/************************************************************************/
Expand Down
Loading
Loading