summaryrefslogtreecommitdiffstats
path: root/source/slang/parser.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2017-11-05 16:39:38 -0500
committerGitHub <noreply@github.com>2017-11-05 16:39:38 -0500
commit296e89ca4f3d6d99126bf2ee59666bc946add431 (patch)
treebff41e36c9b6843d83a5ca5e83645310be6687f3 /source/slang/parser.cpp
parentc6fb1de9547bd24a693915b758cc35499f1d949f (diff)
parentff7c46a11787ca6ecebf0a224772a41efef33fc0 (diff)
Merge pull request #243 from csyonghe/master
Adding associated types
Diffstat (limited to 'source/slang/parser.cpp')
-rw-r--r--source/slang/parser.cpp65
1 files changed, 60 insertions, 5 deletions
diff --git a/source/slang/parser.cpp b/source/slang/parser.cpp
index 8ec6f70ca..57956485a 100644
--- a/source/slang/parser.cpp
+++ b/source/slang/parser.cpp
@@ -1396,6 +1396,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,
@@ -1418,8 +1428,7 @@ namespace Slang
return typeExpr;
}
- static TypeSpec
- parseTypeSpec(Parser* parser)
+ static TypeSpec parseTypeSpec(Parser* parser)
{
TypeSpec typeSpec;
@@ -1452,9 +1461,20 @@ namespace Slang
RefPtr<Expr> typeExpr = basicType;
- if (parser->LookAheadToken(TokenType::OpLess))
+ bool shouldLoop = true;
+ while (shouldLoop)
{
- typeExpr = parseGenericApp(parser, typeExpr);
+ switch (peekTokenType(parser))
+ {
+ case TokenType::OpLess:
+ typeExpr = parseGenericApp(parser, typeExpr);
+ break;
+ case TokenType::Dot:
+ typeExpr = parseMemberType(parser, typeExpr);
+ break;
+ default:
+ shouldLoop = false;
+ }
}
// GLSL allows `[]` directly in a type specifier
@@ -2089,6 +2109,41 @@ namespace Slang
}
}
+ 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 (AdvanceIf(parser, TokenType::Colon))
+ {
+ while (!parser->tokenReader.IsAtEnd())
+ {
+ auto paramConstraint = new GenericTypeConstraintDecl();
+ parser->FillPosition(paramConstraint);
+
+ auto paramType = DeclRefType::Create(
+ parser->getSession(),
+ DeclRef<Decl>(assocTypeDecl, nullptr));
+
+ auto paramTypeExpr = new SharedTypeExpr();
+ paramTypeExpr->loc = assocTypeDecl->loc;
+ paramTypeExpr->base.type = paramType;
+ paramTypeExpr->type = QualType(getTypeType(paramType));
+
+ paramConstraint->sub = TypeExp(paramTypeExpr);
+ paramConstraint->sup = parser->ParseTypeExp();
+
+ AddMember(assocTypeDecl, paramConstraint);
+ if (!AdvanceIf(parser, TokenType::Comma))
+ break;
+ }
+ }
+ parser->ReadToken(TokenType::Semicolon);
+ return assocTypeDecl;
+ }
+
static RefPtr<RefObject> parseInterfaceDecl(Parser* parser, void* /*userData*/)
{
RefPtr<InterfaceDecl> decl = new InterfaceDecl();
@@ -4029,8 +4084,8 @@ namespace Slang
// Add syntax for declaration keywords
#define DECL(KEYWORD, CALLBACK) \
addBuiltinSyntax<Decl>(session, scope, #KEYWORD, &CALLBACK)
-
DECL(typedef, ParseTypeDef);
+ DECL(associatedtype,ParseAssocType);
DECL(cbuffer, parseHLSLCBufferDecl);
DECL(tbuffer, parseHLSLTBufferDecl);
DECL(__generic, ParseGenericDecl);