diff options
Diffstat (limited to 'source/slang/parser.cpp')
| -rw-r--r-- | source/slang/parser.cpp | 65 |
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); |
