summaryrefslogtreecommitdiffstats
path: root/source/slang/parser.cpp
diff options
context:
space:
mode:
authorTim Foley <tfoley@nvidia.com>2017-07-07 14:30:26 -0700
committerTim Foley <tfoley@nvidia.com>2017-07-08 18:18:36 -0700
commitf69bc6cdb10aab2d1b202668cb7ecbcc0ddf33f2 (patch)
tree21d5e647382c60a164c0b1c8c570dbcf5b1ac3f4 /source/slang/parser.cpp
parentf3fe9dddb8c528b4f9955d9105908600b4a8d0c8 (diff)
Fully parse function bodies, even in "rewriter" mode
This is in anticipation of needing to have more complete knowledge to be able to handle user code that `import`s library functionality. The big picture of this change is just to remove the `UnparsedStmt` class that was used to hold the bodies of user functions as opaque token streams, and thus to let the full parser and compiler loose on that code. That is the easy part, of course, and the hard part is all the fixes that this requires in the rest of the compielr to make this even remotely work. Subsequent commit address a lot of other issues, so this particular commit mostly represents work-in-progress. One detail is that this change puts a conditional around nearly every diagnostic message in `check.cpp` to suppress thing when in rewriter mode. I have yet to check how that works out if there are errors in anything we actually need to understand for the purposes of generating reflection data.
Diffstat (limited to 'source/slang/parser.cpp')
-rw-r--r--source/slang/parser.cpp185
1 files changed, 43 insertions, 142 deletions
diff --git a/source/slang/parser.cpp b/source/slang/parser.cpp
index b134f9645..2056bf809 100644
--- a/source/slang/parser.cpp
+++ b/source/slang/parser.cpp
@@ -1392,6 +1392,28 @@ namespace Slang
return genericApp;
}
+ // Parse option `[]` braces after a type expression, that indicate an array type
+ static RefPtr<ExpressionSyntaxNode> parsePostfixTypeSuffix(
+ Parser* parser,
+ RefPtr<ExpressionSyntaxNode> inTypeExpr)
+ {
+ auto typeExpr = inTypeExpr;
+ while (parser->LookAheadToken(TokenType::LBracket))
+ {
+ RefPtr<IndexExpressionSyntaxNode> arrType = new IndexExpressionSyntaxNode();
+ arrType->Position = typeExpr->Position;
+ arrType->BaseExpression = typeExpr;
+ parser->ReadToken(TokenType::LBracket);
+ if (!parser->LookAheadToken(TokenType::RBracket))
+ {
+ arrType->IndexExpression = parser->ParseExpression();
+ }
+ parser->ReadToken(TokenType::RBracket);
+ typeExpr = arrType;
+ }
+ return typeExpr;
+ }
+
static TypeSpec
parseTypeSpec(Parser* parser)
{
@@ -1431,11 +1453,16 @@ namespace Slang
typeExpr = parseGenericApp(parser, typeExpr);
}
+ // GLSL allows `[]` directly in a type specifier
+ if (parser->translationUnit->sourceLanguage == SourceLanguage::GLSL)
+ {
+ typeExpr = parsePostfixTypeSuffix(parser, typeExpr);
+ }
+
typeSpec.expr = typeExpr;
return typeSpec;
}
-
static RefPtr<DeclBase> ParseDeclaratorDecl(
Parser* parser,
ContainerDecl* containerDecl)
@@ -2572,50 +2599,6 @@ namespace Slang
RefPtr<StatementSyntaxNode> Parser::ParseBlockStatement()
{
- if( translationUnit->compileFlags & SLANG_COMPILE_FLAG_NO_CHECKING )
- {
- // We have been asked to parse the input, but not attempt to understand it.
-
- // TODO: record start/end locations...
-
- List<Token> tokens;
-
- ReadToken(TokenType::LBrace);
-
- int depth = 1;
- for( ;;)
- {
- switch( tokenReader.PeekTokenType() )
- {
- case TokenType::EndOfFile:
- goto done;
-
- case TokenType::RBrace:
- depth--;
- if(depth == 0)
- goto done;
- break;
-
- case TokenType::LBrace:
- depth++;
- break;
-
- default:
- break;
- }
-
- auto token = tokenReader.AdvanceToken();
- tokens.Add(token);
- }
- done:
- ReadToken(TokenType::RBrace);
-
- RefPtr<UnparsedStmt> unparsedStmt = new UnparsedStmt();
- unparsedStmt->tokens = tokens;
- return unparsedStmt;
- }
-
-
RefPtr<ScopeDecl> scopeDecl = new ScopeDecl();
RefPtr<BlockStmt> blockStatement = new BlockStmt();
blockStatement->scopeDecl = scopeDecl;
@@ -2816,19 +2799,7 @@ namespace Slang
}
auto typeExpr = typeSpec.expr;
- while (LookAheadToken(TokenType::LBracket))
- {
- RefPtr<IndexExpressionSyntaxNode> arrType = new IndexExpressionSyntaxNode();
- arrType->Position = typeExpr->Position;
- arrType->BaseExpression = typeExpr;
- ReadToken(TokenType::LBracket);
- if (!LookAheadToken(TokenType::RBracket))
- {
- arrType->IndexExpression = ParseExpression();
- }
- ReadToken(TokenType::RBracket);
- typeExpr = arrType;
- }
+ typeExpr = parsePostfixTypeSuffix(this, typeExpr);
return typeExpr;
}
@@ -2915,83 +2886,6 @@ namespace Slang
}
}
- Operator GetOpFromToken(Token & token)
- {
- switch(token.Type)
- {
- case TokenType::Comma:
- return Operator::Sequence;
- case TokenType::OpAssign:
- return Operator::Assign;
- case TokenType::OpAddAssign:
- return Operator::AddAssign;
- case TokenType::OpSubAssign:
- return Operator::SubAssign;
- case TokenType::OpMulAssign:
- return Operator::MulAssign;
- case TokenType::OpDivAssign:
- return Operator::DivAssign;
- case TokenType::OpModAssign:
- return Operator::ModAssign;
- case TokenType::OpShlAssign:
- return Operator::LshAssign;
- case TokenType::OpShrAssign:
- return Operator::RshAssign;
- case TokenType::OpOrAssign:
- return Operator::OrAssign;
- case TokenType::OpAndAssign:
- return Operator::AddAssign;
- case TokenType::OpXorAssign:
- return Operator::XorAssign;
- case TokenType::OpOr:
- return Operator::Or;
- case TokenType::OpAnd:
- return Operator::And;
- case TokenType::OpBitOr:
- return Operator::BitOr;
- case TokenType::OpBitXor:
- return Operator::BitXor;
- case TokenType::OpBitAnd:
- return Operator::BitAnd;
- case TokenType::OpEql:
- return Operator::Eql;
- case TokenType::OpNeq:
- return Operator::Neq;
- case TokenType::OpGeq:
- return Operator::Geq;
- case TokenType::OpLeq:
- return Operator::Leq;
- case TokenType::OpGreater:
- return Operator::Greater;
- case TokenType::OpLess:
- return Operator::Less;
- case TokenType::OpLsh:
- return Operator::Lsh;
- case TokenType::OpRsh:
- return Operator::Rsh;
- case TokenType::OpAdd:
- return Operator::Add;
- case TokenType::OpSub:
- return Operator::Sub;
- case TokenType::OpMul:
- return Operator::Mul;
- case TokenType::OpDiv:
- return Operator::Div;
- case TokenType::OpMod:
- return Operator::Mod;
- case TokenType::OpInc:
- return Operator::PostInc;
- case TokenType::OpDec:
- return Operator::PostDec;
- case TokenType::OpNot:
- return Operator::Not;
- case TokenType::OpBitNot:
- return Operator::BitNot;
- default:
- throw "Illegal TokenType.";
- }
- }
-
static RefPtr<ExpressionSyntaxNode> parseOperator(Parser* parser)
{
Token opToken;
@@ -3194,9 +3088,8 @@ namespace Slang
// but for now we will follow some hueristics.
case TokenType::LParent:
{
- parser->ReadToken(TokenType::LParent);
+ Token openParen = parser->ReadToken(TokenType::LParent);
- RefPtr<ExpressionSyntaxNode> expr;
if (peekTypeName(parser) && parser->LookAheadToken(TokenType::RParent, 1))
{
RefPtr<TypeCastExpressionSyntaxNode> tcexpr = new TypeCastExpressionSyntaxNode();
@@ -3204,15 +3097,18 @@ namespace Slang
tcexpr->TargetType = parser->ParseTypeExp();
parser->ReadToken(TokenType::RParent);
tcexpr->Expression = parser->ParseExpression(Precedence::Multiplicative); // Note(tfoley): need to double-check this
- expr = tcexpr;
+ return tcexpr;
}
else
{
- expr = parser->ParseExpression();
+ RefPtr<ExpressionSyntaxNode> base = parser->ParseExpression();
parser->ReadToken(TokenType::RParent);
- }
- return expr;
+ RefPtr<ParenExpr> parenExpr = new ParenExpr();
+ parenExpr->Position = openParen.Position;
+ parenExpr->base = base;
+ return parenExpr;
+ }
}
// An initializer list `{ expr, ... }`
@@ -3476,7 +3372,11 @@ namespace Slang
indexExpr->BaseExpression = expr;
parser->FillPosition(indexExpr.Ptr());
parser->ReadToken(TokenType::LBracket);
- indexExpr->IndexExpression = parser->ParseExpression();
+ // TODO: eventually we may want to support multiple arguments inside the `[]`
+ if (!parser->LookAheadToken(TokenType::RBracket))
+ {
+ indexExpr->IndexExpression = parser->ParseExpression();
+ }
parser->ReadToken(TokenType::RBracket);
expr = indexExpr;
@@ -3539,6 +3439,7 @@ namespace Slang
case TokenType::OpDec:
case TokenType::OpNot:
case TokenType::OpBitNot:
+ case TokenType::OpAdd:
case TokenType::OpSub:
{
RefPtr<PrefixExpr> prefixExpr = new PrefixExpr();