summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-parser.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2022-08-03 12:08:37 -0700
committerGitHub <noreply@github.com>2022-08-03 12:08:37 -0700
commite81a5fe56f3177fc3c7040e2320ae083e3746eb7 (patch)
tree884c15287bc10050e7883897dd266b27e62bff66 /source/slang/slang-parser.cpp
parent260fc5fbe58f2cf976d64993054c638769bc280f (diff)
Basic pointer usages. (#2342)
Diffstat (limited to 'source/slang/slang-parser.cpp')
-rw-r--r--source/slang/slang-parser.cpp91
1 files changed, 73 insertions, 18 deletions
diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp
index dbf329e9a..cdf418d3d 100644
--- a/source/slang/slang-parser.cpp
+++ b/source/slang/slang-parser.cpp
@@ -1807,9 +1807,10 @@ namespace Slang
case Declarator::Flavor::Pointer:
{
auto ptrDeclarator = (PointerDeclarator*) declarator.Ptr();
-
- // TODO(tfoley): we don't support pointers for now
- // ioInfo->typeSpec = new PointerTypeExpr(ioInfo->typeSpec);
+ auto ptrTypeExpr = astBuilder->create<PointerTypeExpr>();
+ ptrTypeExpr->loc = ptrDeclarator->starLoc;
+ ptrTypeExpr->base.exp = ioInfo->typeSpec;
+ ioInfo->typeSpec = ptrTypeExpr;
declarator = ptrDeclarator->inner;
}
@@ -2014,6 +2015,17 @@ namespace Slang
memberExpr->name = expectIdentifier(parser).name;
return memberExpr;
}
+ static Expr* parseStaticMemberType(Parser* parser, Expr* base, SourceLoc opLoc)
+ {
+ // When called the :: or . have been consumed, so don't need to consume here.
+
+ StaticMemberExpr* memberExpr = parser->astBuilder->create<StaticMemberExpr>();
+ memberExpr->memberOperatorLoc = opLoc;
+ parser->FillPosition(memberExpr);
+ memberExpr->baseExpression = base;
+ memberExpr->name = expectIdentifier(parser).name;
+ return memberExpr;
+ }
// Parse option `[]` braces after a type expression, that indicate an array type
static Expr* parsePostfixTypeSuffix(
@@ -2021,18 +2033,31 @@ namespace Slang
Expr* inTypeExpr)
{
auto typeExpr = inTypeExpr;
- while (parser->LookAheadToken(TokenType::LBracket))
+ for (;;)
{
- IndexExpr* arrType = parser->astBuilder->create<IndexExpr>();
- arrType->loc = typeExpr->loc;
- arrType->baseExpression = typeExpr;
- parser->ReadToken(TokenType::LBracket);
- if (!parser->LookAheadToken(TokenType::RBracket))
+ Token token;
+ if (parser->LookAheadToken(TokenType::LBracket))
{
- arrType->indexExpression = parser->ParseExpression();
+ IndexExpr* arrType = parser->astBuilder->create<IndexExpr>();
+ arrType->loc = typeExpr->loc;
+ arrType->baseExpression = typeExpr;
+ parser->ReadToken(TokenType::LBracket);
+ if (!parser->LookAheadToken(TokenType::RBracket))
+ {
+ arrType->indexExpression = parser->ParseExpression();
+ }
+ parser->ReadToken(TokenType::RBracket);
+ typeExpr = arrType;
}
- parser->ReadToken(TokenType::RBracket);
- typeExpr = arrType;
+ else if (AdvanceIf(parser, TokenType::OpMul, &token))
+ {
+ PointerTypeExpr* ptrType = parser->astBuilder->create<PointerTypeExpr>();
+ ptrType->loc = token.loc;
+ ptrType->base.exp = typeExpr;
+ typeExpr = ptrType;
+ }
+ else
+ break;
}
return typeExpr;
}
@@ -2309,7 +2334,7 @@ namespace Slang
case TokenType::Scope:
{
auto opToken = parser->ReadToken(TokenType::Scope);
- typeExpr = parseMemberType(parser, typeExpr, opToken.loc);
+ typeExpr = parseStaticMemberType(parser, typeExpr, opToken.loc);
break;
}
case TokenType::Dot:
@@ -4368,7 +4393,7 @@ namespace Slang
// with any side effects.
//
//
- if (LookAheadToken(TokenType::Identifier))
+ if (LookAheadToken(TokenType::Identifier) || LookAheadToken(TokenType::OpMul))
{
// Reset the cursor and try to parse a declaration now.
// Note: the declaration will consume any modifiers
@@ -5171,6 +5196,10 @@ namespace Slang
static bool _isCast(Parser* parser, Expr* expr)
{
+ if (as<PointerTypeExpr>(expr))
+ {
+ return true;
+ }
// We can't just look at expr and look up if it's a type, because we allow
// out-of-order declarations. So to a first approximation we'll try and
@@ -5231,6 +5260,8 @@ namespace Slang
}
case TokenType::OpAdd:
case TokenType::OpSub:
+ case TokenType::OpMul:
+ case TokenType::OpBitAnd:
{
// + - are ambiguous, it could be a binary + or - so -> expression, or unary -> cast
//
@@ -5300,6 +5331,24 @@ namespace Slang
return false;
}
+ static bool tryParseExpression(Parser* parser, Expr* &outExpr, TokenType tokenTypeAfter)
+ {
+ auto cursor = parser->tokenReader.getCursor();
+ auto isRecovering = parser->isRecovering;
+ auto oldSink = parser->sink;
+ DiagnosticSink newSink(parser->sink->getSourceManager(), nullptr);
+ parser->sink = &newSink;
+ outExpr = parser->ParseExpression();
+ parser->sink = oldSink;
+ parser->isRecovering = isRecovering;
+ if (outExpr && newSink.getErrorCount() == 0 && parser->LookAheadToken(tokenTypeAfter))
+ {
+ return true;
+ }
+ parser->tokenReader.setCursor(cursor);
+ return false;
+ }
+
static Expr* parseAtomicExpr(Parser* parser)
{
switch( peekTokenType(parser) )
@@ -5319,12 +5368,12 @@ namespace Slang
case TokenType::LParent:
{
Token openParen = parser->ReadToken(TokenType::LParent);
-
- if (peekTypeName(parser) && parser->LookAheadToken(TokenType::RParent, 1))
+ Expr* typeExpr = nullptr;
+ if (peekTypeName(parser) && parser->LookAheadToken(TokenType::RParent))
{
TypeCastExpr* tcexpr = parser->astBuilder->create<ExplicitCastExpr>();
parser->FillPosition(tcexpr);
- tcexpr->functionExpr = parser->ParseType();
+ tcexpr->functionExpr = typeExpr;
parser->ReadToken(TokenType::RParent);
auto arg = parsePrefixExpr(parser);
@@ -5339,7 +5388,11 @@ namespace Slang
// branch will be taken. This is okay in so far as SomeScope::Thing will parse
// as an expression.
- Expr* base = parser->ParseExpression();
+ Expr* base = nullptr;
+ if (!tryParseExpression(parser, base, TokenType::RParent))
+ {
+ base = parser->ParseType();
+ }
parser->ReadToken(TokenType::RParent);
@@ -5853,6 +5906,8 @@ namespace Slang
case TokenType::OpNot:
case TokenType::OpInc:
case TokenType::OpDec:
+ case TokenType::OpMul:
+ case TokenType::OpBitAnd:
{
PrefixExpr* prefixExpr = parser->astBuilder->create<PrefixExpr>();
parser->FillPosition(prefixExpr);