summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-parser.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2022-08-10 14:11:27 -0700
committerGitHub <noreply@github.com>2022-08-10 14:11:27 -0700
commit88f04c29244af23c1cdd472d8d1ae3e5a650494e (patch)
tree398e55440e8f7ad157d15b2b75d9887236eaa126 /source/slang/slang-parser.cpp
parentfcdb4629c4c3dd2931eaa88b96b668d914c4519c (diff)
`is` and `as` operator and `Optional<T>`. (#2355)
* `is` and `as` operator and `Optional<T>`. * Fix. Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'source/slang/slang-parser.cpp')
-rw-r--r--source/slang/slang-parser.cpp41
1 files changed, 34 insertions, 7 deletions
diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp
index 17794a4b5..4baa7211e 100644
--- a/source/slang/slang-parser.cpp
+++ b/source/slang/slang-parser.cpp
@@ -4735,9 +4735,9 @@ namespace Slang
- Precedence GetOpLevel(Parser* parser, TokenType type)
+ Precedence GetOpLevel(Parser* parser, const Token& token)
{
- switch(type)
+ switch(token.type)
{
case TokenType::QuestionMark:
return Precedence::TernaryConditional;
@@ -4790,6 +4790,10 @@ namespace Slang
case TokenType::OpMod:
return Precedence::Multiplicative;
default:
+ if (token.getContent() == "is" || token.getContent() == "as")
+ {
+ return Precedence::RelationalComparison;
+ }
return Precedence::Invalid;
}
}
@@ -4840,16 +4844,39 @@ namespace Slang
auto expr = inExpr;
for(;;)
{
- auto opTokenType = parser->tokenReader.peekTokenType();
- auto opPrec = GetOpLevel(parser, opTokenType);
+ auto opToken = parser->tokenReader.peekToken();
+ auto opPrec = GetOpLevel(parser, opToken);
if(opPrec < prec)
break;
+ // Special case the "is" and "as" operators.
+ if (opToken.type == TokenType::Identifier)
+ {
+ if (opToken.getContent() == "is")
+ {
+ auto isExpr = parser->astBuilder->create<IsTypeExpr>();
+ isExpr->value = expr;
+ parser->ReadToken();
+ isExpr->typeExpr = parser->ParseTypeExp();
+ expr = isExpr;
+ continue;
+ }
+ else if (opToken.getContent() == "as")
+ {
+ auto asExpr = parser->astBuilder->create<AsTypeExpr>();
+ asExpr->value = expr;
+ parser->ReadToken();
+ asExpr->typeExpr = parser->ParseType();
+ expr = asExpr;
+ continue;
+ }
+ }
+
auto op = parseOperator(parser);
// Special case the `?:` operator since it is the
// one non-binary case we need to deal with.
- if(opTokenType == TokenType::QuestionMark)
+ if(opToken.type == TokenType::QuestionMark)
{
SelectExpr* select = parser->astBuilder->create<SelectExpr>();
select->loc = op->loc;
@@ -4869,7 +4896,7 @@ namespace Slang
for(;;)
{
- auto nextOpPrec = GetOpLevel(parser, parser->tokenReader.peekTokenType());
+ auto nextOpPrec = GetOpLevel(parser, parser->tokenReader.peekToken());
if((GetAssociativityFromLevel(nextOpPrec) == Associativity::Right) ? (nextOpPrec < opPrec) : (nextOpPrec <= opPrec))
break;
@@ -4877,7 +4904,7 @@ namespace Slang
right = parseInfixExprWithPrecedence(parser, right, nextOpPrec);
}
- if (opTokenType == TokenType::OpAssign)
+ if (opToken.type == TokenType::OpAssign)
{
AssignExpr* assignExpr = parser->astBuilder->create<AssignExpr>();
assignExpr->loc = op->loc;