#ifndef GOOSE_EIR_TERM_H #define GOOSE_EIR_TERM_H namespace goose::eir { class Vector; using pvec = ptr< Vector >; enum class Delimiter { OpenParen, OpenBrace, OpenBracket, CloseParen, CloseBrace, CloseBracket }; struct STerm; class Hole { public: Hole() = default; Hole( StringId name ); template< typename K > Hole( StringId name, K&& kind ) : m_name( name ), m_kind( make_shared< STerm >( STerm{ forward< K >( kind ) } ) ) {} const auto& name() const { return m_name; } const auto& kind() const; bool operator<( const Hole& rhs ) const; bool operator==( const Hole& rhs ) const; private: StringId m_name; ptr< STerm > m_kind = make_shared< STerm >(); }; using Term = variant < uint32_t, LocationId, string, StringId, Delimiter, Hole, AnyTerm, VecOfLength, pvec, // Representation for ct_int, the compile time only integers // with "unlimited" precision BigInt, // Compile time representation for normal, fixed size integers APSInt, ptr< void >, void* >; 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( StringId name ) : Hole( name, Term( "anykind"_sid ) ) {} inline const auto& Hole::kind() const { return m_kind->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, LocationId >; } #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