Goose  Artifact [13e3db5fdb]

Artifact 13e3db5fdbde05605a6de00a5f2fa4e0a8aaf1da6f46eca312f8492792d0dad1:

  • File bs/parse/resolver.h — part of check-in [0184a27429] at 2021-11-26 00:37:31 on branch trunk —
    • Parser: if an infix rules fails to parse, backtrack
    • Parser: it is now possible to define a contextual "default lhs value"
    • Parser: if an infix operator fails parsing, it is retried as an infix operator, using the default lhs value if there is one available
    • Type predicates: setup @val as the default lhs value inside of the proposition list context, so it is now possible to write u32[<10] instead of u32[@val<10]
    (user: zlodo size: 2273)

#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;

            auto 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;

            lex::TokenProvider::pos_type position() const;
            void setPosition( lex::TokenProvider::pos_type position );

        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