summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYONGH\yongh <yonghe@outlook.com>2017-10-30 21:18:20 -0400
committerYONGH\yongh <yonghe@outlook.com>2017-10-30 21:18:20 -0400
commit84f381cc180b3176d6a58da4085ee8470f246922 (patch)
tree4c20475c42b33a1e719237c573106eaeb5698322
parent91ac1555d7838961c3b5c41d5af39c7a881f59eb (diff)
work in-progress, add parsing for assoc type decls and member type expressions
-rw-r--r--source/slang/decl-defs.h5
-rw-r--r--source/slang/parser.cpp38
-rw-r--r--source/slang/syntax.cpp27
-rw-r--r--source/slang/type-defs.h23
-rw-r--r--tests/compute/assoctype-simple.slang34
5 files changed, 124 insertions, 3 deletions
diff --git a/source/slang/decl-defs.h b/source/slang/decl-defs.h
index c96fe6d09..4021f5a38 100644
--- a/source/slang/decl-defs.h
+++ b/source/slang/decl-defs.h
@@ -122,6 +122,11 @@ SYNTAX_CLASS(TypeDefDecl, SimpleTypeDecl)
SYNTAX_FIELD(TypeExp, type)
END_SYNTAX_CLASS()
+// An 'assoctype' declaration
+SYNTAX_CLASS(AssocTypeDecl, SimpleTypeDecl)
+ SYNTAX_FIELD(TypeExp, constraint)
+END_SYNTAX_CLASS()
+
// A scope for local declarations (e.g., as part of a statement)
SIMPLE_SYNTAX_CLASS(ScopeDecl, ContainerDecl)
diff --git a/source/slang/parser.cpp b/source/slang/parser.cpp
index 322f403e6..554eebc18 100644
--- a/source/slang/parser.cpp
+++ b/source/slang/parser.cpp
@@ -544,6 +544,21 @@ namespace Slang
return typeDefDecl;
}
+ RefPtr<RefObject> ParseAssocType(Parser * parser, void *)
+ {
+ RefPtr<AssocTypeDecl> assocTypeDecl = new AssocTypeDecl();
+
+ auto nameToken = parser->ReadToken(TokenType::Identifier);
+ assocTypeDecl->nameAndLoc = NameLoc(nameToken);
+ assocTypeDecl->loc = nameToken.loc;
+ if (parser->LookAheadToken(TokenType::Colon))
+ {
+ auto type = parser->ParseTypeExp();
+ assocTypeDecl->constraint = type;
+ }
+ return assocTypeDecl;
+ }
+
// Add a modifier to a list of modifiers being built
static void AddModifier(RefPtr<Modifier>** ioModifierLink, RefPtr<Modifier> modifier)
{
@@ -1396,6 +1411,16 @@ namespace Slang
return genericApp;
}
+ static RefPtr<Expr> parseMemberType(Parser * parser, RefPtr<Expr> base)
+ {
+ RefPtr<MemberExpr> memberExpr = new MemberExpr();
+ parser->ReadToken(TokenType::Dot);
+ parser->FillPosition(memberExpr.Ptr());
+ memberExpr->BaseExpression = base;
+ memberExpr->name = expectIdentifier(parser).name;
+ return memberExpr;
+ }
+
// Parse option `[]` braces after a type expression, that indicate an array type
static RefPtr<Expr> parsePostfixTypeSuffix(
Parser* parser,
@@ -1452,9 +1477,16 @@ namespace Slang
RefPtr<Expr> typeExpr = basicType;
- if (parser->LookAheadToken(TokenType::OpLess))
+ while (parser->LookAheadToken(TokenType::OpLess) || parser->LookAheadToken(TokenType::Dot))
{
- typeExpr = parseGenericApp(parser, typeExpr);
+ if (parser->LookAheadToken(TokenType::OpLess))
+ {
+ typeExpr = parseGenericApp(parser, typeExpr);
+ }
+ else
+ {
+ typeExpr = parseMemberType(parser, typeExpr);
+ }
}
// GLSL allows `[]` directly in a type specifier
@@ -4029,8 +4061,8 @@ namespace Slang
// Add syntax for declaration keywords
#define DECL(KEYWORD, CALLBACK) \
addBuiltinSyntax<Decl>(session, scope, #KEYWORD, &CALLBACK)
-
DECL(typedef, ParseTypeDef);
+ DECL(assoctype, ParseAssocType);
DECL(cbuffer, parseHLSLCBufferDecl);
DECL(tbuffer, parseHLSLTBufferDecl);
DECL(__generic, ParseGenericDecl);
diff --git a/source/slang/syntax.cpp b/source/slang/syntax.cpp
index 6cf3fd7c9..165b2d132 100644
--- a/source/slang/syntax.cpp
+++ b/source/slang/syntax.cpp
@@ -940,6 +940,33 @@ void Type::accept(IValVisitor* visitor, void* extra)
return this;
}
+ // AssocTypeDeclRefType
+
+ String AssocTypeDeclRefType::ToString()
+ {
+ // TODO: what is appropriate here?
+ return "<AssocType>";
+ }
+
+ bool AssocTypeDeclRefType::EqualsImpl(Type * type)
+ {
+ if (auto assocTypeDeclRefType = type->As<AssocTypeDeclRefType>())
+ {
+ return declRef.Equals(assocTypeDeclRefType->declRef);
+ }
+ return false;
+ }
+
+ int AssocTypeDeclRefType::GetHashCode()
+ {
+ return declRef.GetHashCode();
+ }
+
+ Type* AssocTypeDeclRefType::CreateCanonicalType()
+ {
+ return this;
+ }
+
// ArithmeticExpressionType
// VectorExpressionType
diff --git a/source/slang/type-defs.h b/source/slang/type-defs.h
index 2010d07b4..7648e0b87 100644
--- a/source/slang/type-defs.h
+++ b/source/slang/type-defs.h
@@ -491,3 +491,26 @@ protected:
virtual Type* CreateCanonicalType() override;
)
END_SYNTAX_CLASS()
+
+// The "type" of an expression that references a asscoiated type decl (via 'assoctype' keyword).
+SYNTAX_CLASS(AssocTypeDeclRefType, Type)
+ DECL_FIELD(DeclRef<AssocTypeDecl>, declRef)
+ RAW(
+ AssocTypeDeclRefType()
+ {}
+ AssocTypeDeclRefType(
+ DeclRef<AssocTypeDecl> declRef)
+ : declRef(declRef)
+ {}
+
+
+ DeclRef<AssocTypeDecl> const& GetDeclRef() const { return declRef; }
+
+ virtual String ToString() override;
+
+ protected:
+ virtual bool EqualsImpl(Type * type) override;
+ virtual int GetHashCode() override;
+ virtual Type* CreateCanonicalType() override;
+ )
+END_SYNTAX_CLASS() \ No newline at end of file
diff --git a/tests/compute/assoctype-simple.slang b/tests/compute/assoctype-simple.slang
new file mode 100644
index 000000000..5a2c339a6
--- /dev/null
+++ b/tests/compute/assoctype-simple.slang
@@ -0,0 +1,34 @@
+//TEST(smoke,compute):COMPARE_COMPUTE:-xslang -use-ir
+//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):dxbinding(0),glbinding(0),out
+// Confirm that generics syntax can be used in user
+// code and generates valid output.
+
+RWStructuredBuffer<float> outputBuffer;
+
+interface ISimple
+{
+ assoctype T;
+ T add(T v0, T v1);
+}
+
+struct Simple : ISimple
+{
+ typedef float T;
+ T add(T v0, float v1)
+ {
+ return v0 + v1;
+ }
+};
+
+__generic<T:ISimple>
+T.T test(T simple, T.T v0, T.T v1)
+{
+ return simple.add(v0, v1);
+}
+
+[numthreads(4, 1, 1)]
+void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
+{
+ float outVal = test<Simple>(Simple(), 2.0, 1.0); // == 3.0
+ outputBuffer[tid] = outVal;
+} \ No newline at end of file