#ifndef GOOSE_PARSE_RESOLVER_H
#define GOOSE_PARSE_RESOLVER_H
namespace goose::parse
{
class Resolver
{
public:
Resolver( const ptr< lex::TokenProvider >& tokProv, const sema::Context& c ) :
m_tokProvider( tokProv ),
m_context( c ),
m_valueStoreVersion( c.env()->valueStoreVersion() )
{}
Resolver( const Resolver& r, const sema::Context& c ) :
m_tokProvider( r.m_tokProvider ),
m_context( c ),
m_valueStoreVersion( c.env()->valueStoreVersion() )
{}
const auto& context() const { return m_context; }
auto& context() { return m_context; }
bool eos() const;
uint32_t currentLocation() { return m_tokProvider->currentLocation(); }
// Consume the next token. Bound identifiers are resolved.
optional< TermLoc > consume();
// Consume the next token. No resolution is performed on identifiers.
optional< TermLoc > consumeUnresolved();
optional< TermLoc > lookAhead( size_t distance = 0 );
optional< TermLoc > lookAheadUnresolved( size_t distance = 0 );
// Consume the next unit from the provider and yield each token that it contains.
// An unit is:
// - any brace, paren or bracket block and every unit they contain
// - any other token
Generator< TermLoc > consumeUnit();
void clearLookAheadCache() const;
private:
TermLoc resolve( const TermLoc& t ) const;
void clearCacheIfNeeded() const
{
if( m_context.env()->valueStoreVersion() == m_valueStoreVersion )
return;
clearLookAheadCache();
}
Generator< TermLoc > consumeBlock( Delimiter end );
ptr< lex::TokenProvider > m_tokProvider;
sema::Context m_context;
mutable deque< TermLoc > m_lookAheadCache;
mutable uint64_t m_valueStoreVersion = 0;
};
}
#endif