summaryrefslogtreecommitdiffstats
path: root/source/slang/syntax.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2017-11-01 13:16:26 -0400
committerYong He <yonghe@outlook.com>2017-11-01 13:16:26 -0400
commit134354c68768c0e3530c02678e12cb02f5646e8a (patch)
tree20a9ae10db6790ddc5032315b85efd94fc672cff /source/slang/syntax.cpp
parentb623864fe609e6912cdd2e350aa70cf7e441e1d3 (diff)
Adding support for associated types.
Diffstat (limited to 'source/slang/syntax.cpp')
-rw-r--r--source/slang/syntax.cpp118
1 files changed, 113 insertions, 5 deletions
diff --git a/source/slang/syntax.cpp b/source/slang/syntax.cpp
index 97f3cfb15..fd7fc0e14 100644
--- a/source/slang/syntax.cpp
+++ b/source/slang/syntax.cpp
@@ -959,15 +959,60 @@ void Type::accept(IValVisitor* visitor, void* extra)
RefPtr<Val> AssocTypeDeclRefType::SubstituteImpl(Substitutions* subst, int* ioDiff)
{
- auto parentType = this->GetDeclRef().GetParent().SubstituteImpl(subst, ioDiff);
- if (auto aggDeclRef = parentType.As<AggTypeDecl>())
+ if (!sourceType)
+ return this;
+ if (auto parentDeclRefType = sourceType->As<DeclRefType>())
{
- Decl* targetTypeDecl = nullptr;
- if (aggDeclRef.getDecl()->memberDictionary.TryGetValue(this->GetDeclRef().decl->getName(), targetTypeDecl))
+ auto parentDeclRef = parentDeclRefType->declRef;
+ DeclRef<AggTypeDecl> newParentDeclRef = parentDeclRef.As<AggTypeDecl>();
+ // search for a substitution that might apply to us
+ for (auto s = subst; s; s = s->outer.Ptr())
{
- return DeclRefType::Create(this->session, DeclRef<Decl>(targetTypeDecl, parentType.substitutions));
+ // the generic decl associated with the substitution list must be
+ // the generic decl that declared this parameter
+ auto genericDecl = s->genericDecl;
+ if (genericDecl != parentDeclRef.getDecl()->ParentDecl)
+ continue;
+ int index = 0;
+ for (auto m : genericDecl->Members)
+ {
+ if (m.Ptr() == parentDeclRef.getDecl())
+ {
+ // We've found it, so return the corresponding specialization argument
+ (*ioDiff)++;
+ if (auto declRef = s->args[index].As<DeclRefType>())
+ {
+ newParentDeclRef = (*declRef).declRef.As<AggTypeDecl>();
+ goto searchEnd;
+ }
+ }
+ else if (auto typeParam = m.As<GenericTypeParamDecl>())
+ {
+ index++;
+ }
+ else if (auto valParam = m.As<GenericValueParamDecl>())
+ {
+ index++;
+ }
+ else
+ {
+ }
+ }
+ }
+ searchEnd:
+ if (newParentDeclRef)
+ {
+ Decl* targetTypeDecl = nullptr;
+ if (newParentDeclRef.getDecl()->memberDictionary.TryGetValue(this->GetDeclRef().decl->getName(), targetTypeDecl))
+ {
+ if (auto typeDefDecl = targetTypeDecl->As<TypeDefDecl>())
+ return GetType(DeclRef<TypeDefDecl>(typeDefDecl, subst));
+ else
+ return DeclRefType::Create(this->getSession(), DeclRef<Decl>(targetTypeDecl, subst));
+ }
}
}
+
return this;
}
@@ -981,6 +1026,69 @@ void Type::accept(IValVisitor* visitor, void* extra)
return this;
}
+ // GenericConstraintDeclRefType
+
+ String GenericConstraintDeclRefType::ToString()
+ {
+ // TODO: what is appropriate here?
+ return "<GenericConstraintType>";
+ }
+
+ bool GenericConstraintDeclRefType::EqualsImpl(Type * type)
+ {
+ if (auto other = type->As<GenericConstraintDeclRefType>())
+ {
+ return supType->Equals(other->supType) && subType->Equals(other->subType);
+ }
+ return false;
+ }
+
+ RefPtr<Val> GenericConstraintDeclRefType::SubstituteImpl(Substitutions* subst, int* ioDiff)
+ {
+ auto genParamDecl = subType.As<DeclRefType>()->declRef.As<GenericTypeParamDecl>();
+ // search for a substitution that might apply to us
+ for (auto s = subst; s; s = s->outer.Ptr())
+ {
+ // the generic decl associated with the substitution list must be
+ // the generic decl that declared this parameter
+ auto genericDecl = s->genericDecl;
+ if (genericDecl != genParamDecl.getDecl()->ParentDecl)
+ continue;
+ int index = 0;
+ for (auto m : genericDecl->Members)
+ {
+ if (m.Ptr() == genParamDecl.getDecl())
+ {
+ // We've found it, so return the corresponding specialization argument
+ (*ioDiff)++;
+ return s->args[index];
+ }
+ else if (auto typeParam = m.As<GenericTypeParamDecl>())
+ {
+ index++;
+ }
+ else if (auto valParam = m.As<GenericValueParamDecl>())
+ {
+ index++;
+ }
+ else
+ {
+ }
+ }
+ }
+ return this;
+ }
+
+ int GenericConstraintDeclRefType::GetHashCode()
+ {
+ return combineHash(subType.GetHashCode(), supType.GetHashCode());
+ }
+
+ Type* GenericConstraintDeclRefType::CreateCanonicalType()
+ {
+ return this;
+ }
+
// ArithmeticExpressionType
// VectorExpressionType