Goose  Artifact [d7c3eafd32]

Artifact d7c3eafd32a7e459456202bb94c32d115ffdc3c1c1b689471244d062d2b9eaac:

  • File bs/cir/helpers.h — part of check-in [0d5427d49b] at 2022-05-23 08:44:00 on branch cir-stack-language —
    • CIR instructions are now stored in lists
    • Execute: handle the stack
    • Converted some instructions to use the stack
    (user: zlodo size: 2764)

#ifndef GOOSE_CIR_HELPERS_H
#define GOOSE_CIR_HELPERS_H

namespace goose::cir
{
    class Instruction;
    using InstrSeq = list< Instruction >;

    extern bool IsValueConstantOrExecutable( const eir::Value& val );
    extern bool CanValueBeEagerlyEvaluated( const eir::Value& val );

    extern void AppendInstrSeq( InstrSeq& is, InstrSeq&& isToAppend );
    extern void AppendInstrSeq( InstrSeq& is, const InstrSeq& isToAppend );

    extern void AppendValue( InstrSeq& is, Value&& v );
    extern void AppendValue( InstrSeq& is, const Value& v );

    template< typename I >
    void AppendToInstrSeq( InstrSeq& is, I&& instr )
    {
        using II = remove_cvref_t< I >;

        if constexpr( is_same_v< II, InstrSeq > )
        {
            AppendInstrSeq( is, forward< I >( instr ) );
        }
        else if constexpr( is_same_v< II, Value > )
        {
            AppendValue( is, forward< I >( instr ) );
        }
        else
        {
            is.emplace_back( Instruction( forward< I >( instr ) ) );
        }
    }

    static inline void AppendToInstrSeq( InstrSeq& is, const ptr< InstrSeq >& instr )
    {
        AppendToInstrSeq( is, *instr );
    }

    static inline void AppendToInstrSeq( InstrSeq& is, ptr< InstrSeq >&& instr )
    {
        AppendToInstrSeq( is, move( *instr ) );
    }

    template< typename HI, typename... TI >
    void AppendToInstrSeq( InstrSeq& is, HI&& headInstr, TI&&... tailInstrs )
    {
        AppendToInstrSeq( is, forward< HI >( headInstr ) );
        AppendToInstrSeq( is, forward< TI >( tailInstrs )... );
    }

    template< typename T, typename... I >
    auto BuildComputedValue( T&& type, I&&... instrs )
    {
        auto is = make_shared< InstrSeq >();
        AppendToInstrSeq( *is, forward< I >( instrs )... );

        return eir::Value( forward< T >( type ), move( is ) );
    }

    template< typename T >
    class TempStorage
    {
        public:
            template< typename TT >
            auto& set( uint32_t index, TT&& x )
            {
                auto [it, inserted] = m_storage.try_emplace( index );
                it->second = forward< TT >( x );
                return it->second;
            }

            const T* get( uint32_t index ) const
            {
                auto it = m_storage.find( index );
                if( it == m_storage.end() )
                    return nullptr;

                return &it->second;
            }

            T* get( uint32_t index )
            {
                auto it = m_storage.find( index );
                if( it == m_storage.end() )
                    return nullptr;

                return &it->second;
            }

        private:
            unordered_map< uint32_t, T > m_storage;
    };
}

#endif