#ifndef EMPATHY_PARSE_RESOLVER_H
#define EMPATHY_PARSE_RESOLVER_H
namespace empathy::parse
{
class Resolver
{
public:
Resolver( const ptr< lex::TokenProvider >& tokProv, const sema::Context& c ) :
m_tokProvider( tokProv ),
m_context( c )
{}
Resolver( const Resolver& r, const sema::Context& c ) :
m_tokProvider( r.m_tokProvider ),
m_context( c )
{}
const auto& context() const { return m_context; }
auto& context() { return m_context; }
bool eos() const;
// Consume the next token. Bound identifiers are resolved, newlines are filtered.
optional< TermLoc > consume();
// Consume the next token. No resolution is performed on identifiers, newlines are filtered.
optional< TermLoc > consumeUnresolved();
// Consume the next token. No resolution is performed on identifiers, newlines are not filtered.
optional< TermLoc > consumeRaw();
optional< TermLoc > lookAhead( size_t distance = 0 );
optional< TermLoc > lookAheadUnresolved( size_t distance = 0 );
optional< TermLoc > lookAheadRaw( size_t distance = 0 );
// Clear the resolver's cached resolution of unconsumed values.
// This is necessary after binding a new name, otherwise
// if that name is used immediately after while the unsuccessful
// resolution is still cached, it won't be resolved.
void clearLookAheadCache();
// Consume newlines until a non newline token or eos is reached.
void consumeNewLines();
// 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();
private:
TermLoc resolve( const TermLoc& t ) const;
Generator< TermLoc > consumeBlock( Delimiter end );
ptr< lex::TokenProvider > m_tokProvider;
sema::Context m_context;
deque< TermLoc > m_lookAheadCache;
};
}
#endif