Goose  Artifact [d982fea706]

Artifact d982fea70651225250f67a83afade82a71c3d8eb9ff11f979281ff3b995a49be:

  • File bs/eir/term.h — part of check-in [176ee856a6] at 2021-02-12 23:57:22 on branch trunk — Added a "flavor" term to holes to be able to have specific rules for TVar holes and for forwarding holes. Refactored forwarding holes to use this, instead of being represented as compound expressions (which would probably have broken down horribly in some complex type checking scenarios) (user: achavasse size: 2918)

#ifndef GOOSE_EIR_TERM_H
#define GOOSE_EIR_TERM_H

namespace goose::eir
{
    class Vector;
    using pvec = ptr< Vector >;

    // We use a distinct type to store locations so that we can handle it differently
    // in the pattern matching algorithms. We consider all LocationId to be equal to one another
    // regardless of their value. This way we can keep it around in IR expessions without having
    // to construct specific patterns to ignore it. (The fact that the location at which two value
    // are defined might be different is never relevant)
    enum class LocationId : uint32_t {};

    enum class Delimiter
    {
        OpenParen,
        OpenBrace,
        OpenBracket,

        CloseParen,
        CloseBrace,
        CloseBracket
    };

    struct STerm;

    class Hole
    {
        public:
            Hole() = default;

            Hole( const StringId& name );

            template< typename F >
            Hole( const StringId& name, F&& flavor ) :
                m_name( name ),
                m_flavor( make_shared< STerm >( STerm{ forward< F >( flavor ) } ) )
            {}

            const auto& name() const { return m_name; }
            const auto& flavor() const;

            bool operator<( const Hole& rhs ) const;
            bool operator==( const Hole& rhs ) const;

        private:
            StringId m_name;
            ptr< STerm > m_flavor = make_shared< STerm >();
    };

    using Term = variant
    <
        uint32_t,
        LocationId,
        string,
        StringId,
        Delimiter,
        Hole,
        AnyTerm,
        VecOfLength,
        ptr< void >,
        void*,
        pvec,

        // Representation for ct_int, the compile time only integers
        // with "unlimited" precision
        BigInt,

        // Compile time representation for normal, fixed size integers
        APSInt
    >;

    extern bool operator==( const Term& lhs, const Term& rhs );
    extern bool operator!=( const Term& lhs, const Term& rhs );

    struct STerm
    {
        Term content;
    };

    inline Hole::Hole( const StringId& name ) : Hole( name, Term( AnyTerm( "_"_sid ) ) ) {}
    inline const auto& Hole::flavor() const { return m_flavor->content; }

    extern ostream& operator<<( ostream& out, const Term& t );

    // A term associated with a location id.
    // Used to represent tokens and tokens/values coming out of the resolver.
    using TermLoc = pair< eir::Term, uint32_t >;
}

#define TERM( x )           eir::Term( x )
#define TSTR( x )           TERM( string( x ) )
#define TSID( x )           TERM( #x##_sid )
#define HOLE( ... )         TERM( ( eir::Hole{ __VA_ARGS__ } ) )
#define ANYTERM( x )        TERM( eir::AnyTerm( #x##_sid ) )
#define VECOFLENGTH( x )    TERM( eir::VecOfLength( #x##_sid ) )
#define VEC( ... )          TERM( eir::Vector::Make( __VA_ARGS__ ) )
#define REPEAT( x )         eir::Repetition( x )

#endif