summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/slang-parser.cpp')
-rw-r--r--source/slang/slang-parser.cpp80
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);