diff options
| author | Yong He <yonghe@outlook.com> | 2022-08-03 12:08:37 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-08-03 12:08:37 -0700 |
| commit | e81a5fe56f3177fc3c7040e2320ae083e3746eb7 (patch) | |
| tree | 884c15287bc10050e7883897dd266b27e62bff66 /source/slang/slang-parser.cpp | |
| parent | 260fc5fbe58f2cf976d64993054c638769bc280f (diff) | |
Basic pointer usages. (#2342)
Diffstat (limited to 'source/slang/slang-parser.cpp')
| -rw-r--r-- | source/slang/slang-parser.cpp | 91 |
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); |
