diff options
Diffstat (limited to 'source/slang/slang-parser.cpp')
| -rw-r--r-- | source/slang/slang-parser.cpp | 80 |
1 files changed, 64 insertions, 16 deletions
diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp index c939e0a38..ed20e0d2e 100644 --- a/source/slang/slang-parser.cpp +++ b/source/slang/slang-parser.cpp @@ -208,6 +208,10 @@ namespace Slang Parser* parser, ContainerDecl* containerDecl); + static void parseModernParamList( + Parser* parser, + CallableDecl* decl); + // static void Unexpected( @@ -1208,7 +1212,7 @@ namespace Slang } static void parseParameterList( - Parser* parser, + Parser* parser, CallableDecl* decl) { parser->ReadToken(TokenType::LParent); @@ -2645,6 +2649,7 @@ namespace Slang Modifiers modifiers = ParseModifiers(parser); AccessorDecl* decl = nullptr; + auto loc = peekToken(parser).loc; if( AdvanceIf(parser, "get") ) { decl = parser->astBuilder->create<GetterDecl>(); @@ -2662,9 +2667,24 @@ namespace Slang Unexpected(parser); return nullptr; } + decl->loc = loc; AddModifiers(decl, modifiers.first); + parser->PushScope(decl); + + // A `set` declaration should support declaring an explicit + // name for the parameter representing the new value. + // + // We handle this by supporting an arbitrary parameter list + // on any accessor, and then assume that semantic checking + // will diagnose any cases that aren't allowed. + // + if(parser->tokenReader.peekTokenType() == TokenType::LParent) + { + parseModernParamList(parser, decl); + } + if( parser->tokenReader.peekTokenType() == TokenType::LBrace ) { decl->body = parser->parseBlockStatement(); @@ -2674,25 +2694,14 @@ namespace Slang parser->ReadToken(TokenType::Semicolon); } + parser->PopScope(); + + return decl; } - static NodeBase* ParseSubscriptDecl(Parser* parser, void* /*userData*/) + static void parseStorageDeclBody(Parser* parser, ContainerDecl* decl) { - SubscriptDecl* decl = parser->astBuilder->create<SubscriptDecl>(); - parser->FillPosition(decl); - parser->PushScope(decl); - - // TODO: the use of this name here is a bit magical... - decl->nameAndLoc.name = getName(parser, "operator[]"); - - parseParameterList(parser, decl); - - if( AdvanceIf(parser, TokenType::RightArrow) ) - { - decl->returnType = parser->ParseTypeExp(); - } - if( AdvanceIf(parser, TokenType::LBrace) ) { // We want to parse nested "accessor" declarations @@ -2708,6 +2717,25 @@ namespace Slang // empty body should be treated like `{ get; }` } + } + + static NodeBase* ParseSubscriptDecl(Parser* parser, void* /*userData*/) + { + SubscriptDecl* decl = parser->astBuilder->create<SubscriptDecl>(); + parser->FillPosition(decl); + parser->PushScope(decl); + + // TODO: the use of this name here is a bit magical... + decl->nameAndLoc.name = getName(parser, "operator[]"); + + parseParameterList(parser, decl); + + if( AdvanceIf(parser, TokenType::RightArrow) ) + { + decl->returnType = parser->ParseTypeExp(); + } + + parseStorageDeclBody(parser, decl); parser->PopScope(); return decl; @@ -2718,6 +2746,25 @@ namespace Slang return parser->ReadToken(tokenType).type == tokenType; } + static NodeBase* ParsePropertyDecl(Parser* parser, void* /*userData*/) + { + PropertyDecl* decl = parser->astBuilder->create<PropertyDecl>(); + parser->FillPosition(decl); + parser->PushScope(decl); + + decl->nameAndLoc = expectIdentifier(parser); + + if( expect(parser, TokenType::Colon) ) + { + decl->type = parser->ParseTypeExp(); + } + + parseStorageDeclBody(parser, decl); + + parser->PopScope(); + return decl; + } + static void parseModernVarDeclBaseCommon( Parser* parser, VarDeclBase* decl) @@ -5254,6 +5301,7 @@ namespace Slang DECL(extension, ParseExtensionDecl); DECL(__init, parseConstructorDecl); DECL(__subscript, ParseSubscriptDecl); + DECL(property, ParsePropertyDecl); DECL(interface, parseInterfaceDecl); DECL(syntax, parseSyntaxDecl); DECL(attribute_syntax,parseAttributeSyntaxDecl); |
