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.cpp126
1 files changed, 121 insertions, 5 deletions
diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp
index 580215fc7..57a21a90a 100644
--- a/source/slang/slang-parser.cpp
+++ b/source/slang/slang-parser.cpp
@@ -4202,6 +4202,108 @@ namespace Slang
return stmt;
}
+ static Stmt* parseTargetSwitchStmt(Parser* parser)
+ {
+ TargetSwitchStmt* stmt = parser->astBuilder->create<TargetSwitchStmt>();
+ parser->FillPosition(stmt);
+ parser->ReadToken();
+ if (!beginMatch(parser, MatchedTokenType::CurlyBraces))
+ {
+ return stmt;
+ }
+ Token closingBraceToken;
+ while (!AdvanceIfMatch(parser, MatchedTokenType::CurlyBraces, &closingBraceToken))
+ {
+ List<Token> caseNames;
+ for (;;)
+ {
+ if (parser->LookAheadToken("case"))
+ {
+ parser->ReadToken();
+ caseNames.add(parser->ReadToken());
+ parser->ReadToken(TokenType::Colon);
+ }
+ else if (parser->LookAheadToken("default"))
+ {
+ auto token = parser->ReadToken();
+ parser->ReadToken(TokenType::Colon);
+ token.setContent(UnownedStringSlice(""));
+ caseNames.add(token);
+ }
+ else
+ break;
+ }
+ if (caseNames.getCount() == 0)
+ {
+ parser->sink->diagnose(
+ parser->tokenReader.peekLoc(),
+ Diagnostics::unexpectedTokenExpectedTokenType,
+ parser->tokenReader.peekToken(),
+ "'case' or 'default'");
+ parser->isRecovering = true;
+ goto recover;
+ }
+ else
+ {
+ Stmt* bodyStmt = nullptr;
+ for (;;)
+ {
+ if (parser->LookAheadToken("case") || parser->LookAheadToken("default") || parser->LookAheadToken(TokenType::RBrace) ||
+ parser->LookAheadToken(TokenType::EndOfFile))
+ break;
+ auto nextStmt = parser->ParseStatement(stmt);
+ if (nextStmt)
+ {
+ if (!bodyStmt)
+ {
+ bodyStmt = nextStmt;
+ }
+ else if (auto seqStmt = as<SeqStmt>(bodyStmt))
+ {
+ seqStmt->stmts.add(nextStmt);
+ }
+ else
+ {
+ SeqStmt* newBody = parser->astBuilder->create<SeqStmt>();
+ newBody->loc = bodyStmt->loc;
+ newBody->stmts.add(bodyStmt);
+ newBody->stmts.add(nextStmt);
+ bodyStmt = newBody;
+ }
+ }
+ }
+
+ for (auto caseName : caseNames)
+ {
+ TargetCaseStmt* targetCase = parser->astBuilder->create<TargetCaseStmt>();
+ auto cap = findCapabilityAtom(caseName.getContent());
+ if (caseName.getContent().getLength() && cap == CapabilityAtom::Invalid)
+ {
+ parser->sink->diagnose(caseName.loc, Diagnostics::unknownTargetName, caseName.getContent());
+ }
+ targetCase->capability = int32_t(cap);
+ targetCase->loc = caseName.loc;
+ targetCase->body = bodyStmt;
+ stmt->targetCases.add(targetCase);
+ }
+ }
+ recover:;
+ TryRecover(parser);
+ }
+ return stmt;
+ }
+
+ static Stmt* parseIntrinsicAsmStmt(Parser* parser)
+ {
+ IntrinsicAsmStmt* stmt = parser->astBuilder->create<IntrinsicAsmStmt>();
+ parser->FillPosition(stmt);
+ parser->ReadToken();
+
+ stmt->asmText = getStringLiteralTokenValue(parser->ReadToken(TokenType::StringLiteral));
+ parser->ReadToken(TokenType::Semicolon);
+ return stmt;
+ }
+
GpuForeachStmt* ParseGpuForeachStmt(Parser* parser)
{
// Hard-coding parsing of the following:
@@ -4421,6 +4523,10 @@ namespace Slang
}
else if (LookAheadToken("switch"))
statement = ParseSwitchStmt(this);
+ else if (LookAheadToken("__target_switch"))
+ statement = parseTargetSwitchStmt(this);
+ else if (LookAheadToken("__intrinsic_asm"))
+ statement = parseIntrinsicAsmStmt(this);
else if (LookAheadToken("case"))
statement = ParseCaseStmt(this);
else if (LookAheadToken("default"))
@@ -6160,11 +6266,18 @@ namespace Slang
return SPIRVAsmOperand{flavor, tok, varExpr};
};
+ const auto slangTypeExprOperand = [&](auto flavor) {
+ auto tok = parser->tokenReader.peekToken();
+ const auto typeExpr = parser->ParseType();
+ return SPIRVAsmOperand{ flavor, tok, typeExpr };
+ };
+
// The result marker
if(parser->LookAheadToken("result"))
{
return SPIRVAsmOperand{SPIRVAsmOperand::ResultMarker, parser->ReadToken()};
}
+
// A regular identifier
else if(parser->LookAheadToken(TokenType::Identifier))
{
@@ -6206,7 +6319,7 @@ namespace Slang
// A $$foo type
else if(AdvanceIf(parser, TokenType::DollarDollar))
{
- return slangIdentOperand(SPIRVAsmOperand::SlangType);
+ return slangTypeExprOperand(SPIRVAsmOperand::SlangType);
}
Unexpected(parser);
@@ -6756,8 +6869,8 @@ namespace Slang
static NodeBase* parseSPIRVCapabilityModifier(Parser* parser, void*)
{
- Token token;
- token = parser->ReadToken();
+ parser->ReadToken(TokenType::LParent);
+ Token token = parser->ReadToken(TokenType::Identifier);
auto modifier = parser->astBuilder->create<RequiredSPIRVCapabilityModifier>();
const SPIRVCoreGrammarInfo& spirvInfo =
parser->astBuilder->getGlobalSession()->getSPIRVCoreGrammarInfo();
@@ -6765,9 +6878,12 @@ namespace Slang
if (!cap)
{
parser->sink->diagnose(token, Diagnostics::unknownSPIRVCapability, token);
- return nullptr;
}
- modifier->capability = int32_t(*cap);
+ else
+ {
+ modifier->capability = (int32_t)cap.value();
+ }
+ parser->ReadToken(TokenType::RParent);
return modifier;
}