summaryrefslogtreecommitdiffstats
path: root/source/slang/parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/parser.cpp')
-rw-r--r--source/slang/parser.cpp250
1 files changed, 29 insertions, 221 deletions
diff --git a/source/slang/parser.cpp b/source/slang/parser.cpp
index e2085eb7d..3abc47ede 100644
--- a/source/slang/parser.cpp
+++ b/source/slang/parser.cpp
@@ -8,7 +8,7 @@
namespace Slang
{
- // Pre-declare
+ // pre-declare
static Name* getName(Parser* parser, String const& text);
// Helper class useful to build a list of modifiers.
@@ -79,7 +79,11 @@ namespace Slang
class Parser
{
public:
- TranslationUnitRequest* translationUnit;
+ NamePool* namePool;
+ SourceLanguage sourceLanguage;
+
+ NamePool* getNamePool() { return namePool; }
+ SourceLanguage getSourceLanguage() { return sourceLanguage; }
int anonymousCounter = 0;
@@ -124,27 +128,26 @@ namespace Slang
currentScope = currentScope->parent;
}
Parser(
+ Session* session,
TokenSpan const& _tokens,
DiagnosticSink * sink,
RefPtr<Scope> const& outerScope)
: tokenReader(_tokens)
, sink(sink)
, outerScope(outerScope)
+ , m_session(session)
{}
Parser(const Parser & other) = default;
- Session* getSession()
- {
- return translationUnit->compileRequest->mSession;
- }
- RefPtr<ModuleDecl> Parse();
+ Session* m_session = nullptr;
+ Session* getSession() { return m_session; }
+
Token ReadToken();
Token ReadToken(TokenType type);
Token ReadToken(const char * string);
bool LookAheadToken(TokenType type, int offset = 0);
bool LookAheadToken(const char * string, int offset = 0);
void parseSourceFile(ModuleDecl* program);
- RefPtr<ModuleDecl> ParseProgram();
RefPtr<Decl> ParseStruct();
RefPtr<ClassDecl> ParseClass();
RefPtr<Stmt> ParseStatement();
@@ -578,11 +581,6 @@ namespace Slang
return false;
}
- RefPtr<ModuleDecl> Parser::Parse()
- {
- return ParseProgram();
- }
-
RefPtr<RefObject> ParseTypeDef(Parser* parser, void* /*userData*/)
{
RefPtr<TypeDefDecl> typeDefDecl = new TypeDefDecl();
@@ -694,7 +692,7 @@ namespace Slang
Token token(TokenType::Identifier, scopedIdentifier, scopedIdSourceLoc);
// Get the name pool
- auto namePool = parser->translationUnit->compileRequest->getNamePool();
+ auto namePool = parser->getNamePool();
// Since it's an Identifier have to set the name.
token.ptrValue = namePool->getName(token.Content);
@@ -910,7 +908,7 @@ namespace Slang
static Name* getName(Parser* parser, String const& text)
{
- return parser->translationUnit->compileRequest->getNamePool()->getName(text);
+ return parser->getNamePool()->getName(text);
}
static NameLoc expectIdentifier(Parser* parser)
@@ -1859,7 +1857,7 @@ namespace Slang
}
// GLSL allows `[]` directly in a type specifier
- if (parser->translationUnit->sourceLanguage == SourceLanguage::GLSL)
+ if (parser->getSourceLanguage() == SourceLanguage::GLSL)
{
typeExpr = parsePostfixTypeSuffix(parser, typeExpr);
}
@@ -1929,7 +1927,7 @@ namespace Slang
// Just as a safety net, only apply this logic for
// a file that is being passed in as "true" Slang code.
//
- if(parser->translationUnit->sourceLanguage == SourceLanguage::Slang)
+ if(parser->getSourceLanguage() == SourceLanguage::Slang)
{
if(typeSpec.decl)
{
@@ -2313,171 +2311,6 @@ namespace Slang
return ParseHLSLBufferDecl(parser, "TextureBuffer");
}
- static void removeModifier(
- Modifiers& modifiers,
- RefPtr<Modifier> modifier)
- {
- RefPtr<Modifier>* link = &modifiers.first;
- while (*link)
- {
- if (*link == modifier)
- {
- *link = (*link)->next;
- return;
- }
-
- link = &(*link)->next;
- }
- }
-
- static RefPtr<Decl> parseGLSLBlockDecl(
- Parser* parser,
- Modifiers& modifiers)
- {
- // An GLSL block like this:
- //
- // uniform Foo { int a; float b; } foo;
- //
- // is treated as syntax sugar for a type declaration
- // and then a global variable declaration using that type:
- //
- // struct $anonymous { int a; float b; };
- // Block<$anonymous> foo;
- //
- // where `$anonymous` is a fresh name.
- //
- // If a "local name" like `foo` is not given, then
- // we make the declaration "transparent" so that lookup
- // will see through it to the members inside.
-
-
- SourceLoc pos = parser->tokenReader.PeekLoc();
-
- // The initial name before the `{` is only supposed
- // to be made visible to reflection
- auto reflectionNameToken = parser->ReadToken(TokenType::Identifier);
-
- // Look at the qualifiers present on the block to decide what kind
- // of block we are looking at. Also *remove* those qualifiers so
- // that they don't interfere with downstream work.
- String blockWrapperTypeName;
- if( auto uniformMod = modifiers.findModifier<HLSLUniformModifier>() )
- {
- removeModifier(modifiers, uniformMod);
- blockWrapperTypeName = "ConstantBuffer";
- }
- else if( auto inMod = modifiers.findModifier<InModifier>() )
- {
- removeModifier(modifiers, inMod);
- blockWrapperTypeName = "__GLSLInputParameterGroup";
- }
- else if( auto outMod = modifiers.findModifier<OutModifier>() )
- {
- removeModifier(modifiers, outMod);
- blockWrapperTypeName = "__GLSLOutputParameterGroup";
- }
- else if( auto bufferMod = modifiers.findModifier<GLSLBufferModifier>() )
- {
- removeModifier(modifiers, bufferMod);
- blockWrapperTypeName = "__GLSLShaderStorageBuffer";
- }
- else
- {
- // Unknown case: just map to a constant buffer and hope for the best
- blockWrapperTypeName = "ConstantBuffer";
- }
-
- // We are going to represent each buffer as a pair of declarations.
- // The first is a type declaration that holds all the members, while
- // the second is a variable declaration that uses the buffer type.
- RefPtr<StructDecl> blockDataTypeDecl = new StructDecl();
- RefPtr<VarDecl> blockVarDecl = new VarDecl();
-
- addModifier(blockDataTypeDecl, new ImplicitParameterGroupElementTypeModifier());
- addModifier(blockVarDecl, new ImplicitParameterGroupVariableModifier());
-
- // Attach the reflection name to the block so we can use it
- auto reflectionNameModifier = new ParameterGroupReflectionName();
- reflectionNameModifier->nameAndLoc = NameLoc(reflectionNameToken);
- addModifier(blockVarDecl, reflectionNameModifier);
-
- // Both declarations will have a location that points to the name
- parser->FillPosition(blockDataTypeDecl.Ptr());
- parser->FillPosition(blockVarDecl.Ptr());
-
- // Generate a unique name for the data type
- blockDataTypeDecl->nameAndLoc.name = generateName(parser, "ParameterGroup_" + String(reflectionNameToken.Content));
-
- // TODO(tfoley): We end up constructing unchecked syntax here that
- // is expected to type check into the right form, but it might be
- // cleaner to have a more explicit desugaring pass where we parse
- // these constructs directly into the AST and *then* desugar them.
-
- // Construct a type expression to reference the buffer data type
- auto blockDataTypeExpr = new VarExpr();
- blockDataTypeExpr->loc = blockDataTypeDecl->loc;
- blockDataTypeExpr->name = blockDataTypeDecl->getName();
- blockDataTypeExpr->scope = parser->currentScope.Ptr();
-
- // Construct a type exrpession to reference the type constructor
- auto blockWrapperTypeExpr = new VarExpr();
- blockWrapperTypeExpr->loc = pos;
- blockWrapperTypeExpr->name = getName(parser, blockWrapperTypeName);
- // Always need to look this up in the outer scope,
- // so that it won't collide with, e.g., a local variable called `ConstantBuffer`
- blockWrapperTypeExpr->scope = parser->outerScope;
-
- // Construct a type expression that represents the type for the variable,
- // which is the wrapper type applied to the data type
- auto blockVarTypeExpr = new GenericAppExpr();
- blockVarTypeExpr->loc = blockVarDecl->loc;
- blockVarTypeExpr->FunctionExpr = blockWrapperTypeExpr;
- blockVarTypeExpr->Arguments.Add(blockDataTypeExpr);
-
- blockVarDecl->type.exp = blockVarTypeExpr;
-
- // The declarations in the body belong to the data type.
- parseAggTypeDeclBody(parser, blockDataTypeDecl.Ptr());
-
- if( parser->LookAheadToken(TokenType::Identifier) )
- {
- // The user gave an explicit name to the block,
- // so we need to use that as our variable name
- blockVarDecl->nameAndLoc = NameLoc(parser->ReadToken(TokenType::Identifier));
-
- // TODO: in this case we make actually have a more complex
- // declarator, including `[]` brackets.
- }
- else
- {
- // synthesize a dummy name
- blockVarDecl->nameAndLoc.name = generateName(parser, "parameterGroup_" + String(reflectionNameToken.Content));
-
- // Otherwise we have a transparent declaration, similar
- // to an HLSL `cbuffer`
- auto transparentModifier = new TransparentModifier();
- transparentModifier->loc = pos;
- addModifier(blockVarDecl, transparentModifier);
- }
-
- // Expect a trailing `;`
- parser->ReadToken(TokenType::Semicolon);
-
- // Because we are constructing two declarations, we have a thorny
- // issue that were are only supposed to return one.
- // For now we handle this by adding the type declaration to
- // the current scope manually, and then returning the variable
- // declaration.
- //
- // Note: this means that any modifiers that have already been parsed
- // will get attached to the variable declaration, not the type.
- // There might be cases where we need to shuffle things around.
-
- AddMember(parser->currentScope, blockDataTypeDecl);
-
- return blockVarDecl;
- }
-
static void parseOptionalInheritanceClause(Parser* parser, AggTypeDeclBase* decl)
{
if (AdvanceIf(parser, TokenType::Colon))
@@ -3020,27 +2853,8 @@ namespace Slang
//
// - A keyword-based declaration (e.g., `cbuffer ...`)
// - The beginning of a type in a declarator-based declaration (e.g., `int ...`)
- // - A GLSL block declaration (e.g., `uniform Foo { ... }`)
-
- // Let's deal with the GLSL block case first. This is something like:
- //
- // uniform Foo { ... };
- //
- // The `uniform` keyword has already been parsed as a modifier,
- // so the identifier we are looking at is `Foo`. If the token
- // after that is `{`, we assume this is a block.
- //
- // Of course, we only want to allow this syntax when parsing GLSL...
- if (parser->translationUnit->sourceLanguage == SourceLanguage::GLSL)
- {
- if( parser->LookAheadToken(TokenType::LBrace, 1) )
- {
- decl = parseGLSLBlockDecl(parser, modifiers);
- break;
- }
- }
- // Next we will check whether we can use the identifier token
+ // First we will check whether we can use the identifier token
// as a declaration keyword and parse a declaration using
// its associated callback:
RefPtr<Decl> parsedDecl;
@@ -3184,15 +2998,6 @@ namespace Slang
currentScope = nullptr;
}
- RefPtr<ModuleDecl> Parser::ParseProgram()
- {
- RefPtr<ModuleDecl> program = new ModuleDecl();
-
- parseSourceFile(program.Ptr());
-
- return program;
- }
-
RefPtr<Decl> Parser::ParseStruct()
{
RefPtr<StructDecl> rs = new StructDecl();
@@ -3591,7 +3396,7 @@ namespace Slang
// parsing HLSL code.
//
- bool brokenScoping = translationUnit->sourceLanguage == SourceLanguage::HLSL;
+ bool brokenScoping = getSourceLanguage() == SourceLanguage::HLSL;
// We will create a distinct syntax node class for the unscoped
// case, just so that we can correctly handle it in downstream
@@ -4439,14 +4244,18 @@ namespace Slang
return parsePrefixExpr(this);
}
- RefPtr<Expr> parseTypeFromSourceFile(TranslationUnitRequest* translationUnit,
+ RefPtr<Expr> parseTypeFromSourceFile(
+ Session* session,
TokenSpan const& tokens,
DiagnosticSink* sink,
- RefPtr<Scope> const& outerScope)
+ RefPtr<Scope> const& outerScope,
+ NamePool* namePool,
+ SourceLanguage sourceLanguage)
{
- Parser parser(tokens, sink, outerScope);
- parser.translationUnit = translationUnit;
+ Parser parser(session, tokens, sink, outerScope);
parser.currentScope = outerScope;
+ parser.namePool = namePool;
+ parser.sourceLanguage = sourceLanguage;
return parser.ParseType();
}
@@ -4457,12 +4266,11 @@ namespace Slang
DiagnosticSink* sink,
RefPtr<Scope> const& outerScope)
{
- Parser parser(tokens, sink, outerScope);
-
- parser.translationUnit = translationUnit;
-
+ Parser parser(translationUnit->getSession(), tokens, sink, outerScope);
+ parser.namePool = translationUnit->getNamePool();
+ parser.sourceLanguage = translationUnit->sourceLanguage;
- return parser.parseSourceFile(translationUnit->SyntaxNode.Ptr());
+ return parser.parseSourceFile(translationUnit->getModuleDecl());
}
static void addBuiltinSyntaxImpl(