Goose  tc-context.cpp at [a2a6841c8b]

File bs/sema/tc-context.cpp artifact 5c55bd7f8a part of check-in a2a6841c8b


#include "sema.h"

using namespace goose;
using namespace goose::sema;

uint32_t TypeCheckingContext::SubContext::repetitionIndex( uint32_t depth ) const
{
    if( !m_repetitionIndices || m_repetitionIndices->size() <= depth )
        return 0;

    return ( *m_repetitionIndices )[depth];
}

void TypeCheckingContext::SubContext::setRepetitionIndex( uint32_t depth, uint32_t index )
{
    if( !m_repetitionIndices )
        m_repetitionIndices = make_shared< RepIndicesVec >();

    auto& indices = CoW( m_repetitionIndices );

    if( indices->size() <= depth )
        indices->resize( depth + 1 );

    ( *indices )[depth] = index;
}

TypeCheckingContext::TypeCheckingContext( const Context& c ) :
    m_context( c )
{}

TypeCheckingContext::TypeCheckingContext( Context&& c ) :
    m_context( move( c ) )
{}

uint32_t TypeCheckingContext::getLHSHoleIndex( StringId name, uint32_t repetitionIndex ) const
{
    if( name == "_"_sid )
        return InvalidIndex;

    HoleKey holeKey( name, LHSSubContext().namespaceIndex, repetitionIndex );

    auto it = m_pCow->holeDict.find( holeKey );
    if( it == m_pCow->holeDict.end() )
        return InvalidIndex;

    return it->second;
}

uint32_t TypeCheckingContext::getRHSHoleIndex( StringId name, uint32_t repetitionIndex ) const
{
    if( name == "_"_sid )
        return InvalidIndex;

    HoleKey holeKey( name, RHSSubContext().namespaceIndex, repetitionIndex );

    auto it = m_pCow->holeDict.find( holeKey );
    if( it == m_pCow->holeDict.end() )
        return InvalidIndex;

    return it->second;
}

uint32_t TypeCheckingContext::createValue( bool required )
{
    CoW( m_pCow )->values.emplace_back( StoredValue{ nullopt, required } );
    uint32_t index = m_pCow->values.size() - 1;
    if( required )
        ++m_numUnknownValues;
    return index;
}

void TypeCheckingContext::setValueRequired( uint32_t index )
{
    assert( m_pCow->values.size() > index );

    if( m_pCow->values[index].m_required )
        return;

    CoW( m_pCow )->values[index] = { m_pCow->values[index].m_term, true };

    if( !m_pCow->values[index].m_term )
        ++m_numUnknownValues;
}

void TypeCheckingContext::setLHSHoleIndex( StringId name, uint32_t repetitionIndex, uint32_t index )
{
    if( name == "_"_sid )
    {
        ++m_numAnonymousHoles;
        return;
    }

    HoleKey holeKey( name, LHSSubContext().namespaceIndex, repetitionIndex );
    CoW( m_pCow )->holeDict.emplace( holeKey, index );

    if( m_valuesAreRequired )
        setValueRequired( index );
}

void TypeCheckingContext::setRHSHoleIndex( StringId name, uint32_t repetitionIndex, uint32_t index )
{
    if( name == "_"_sid )
    {
        ++m_numAnonymousHoles;
        return;
    }

    HoleKey holeKey( name, RHSSubContext().namespaceIndex, repetitionIndex );
    CoW( m_pCow )->holeDict.emplace( holeKey, index );

    if( m_valuesAreRequired )
        setValueRequired( index );
}

void TypeCheckingContext::eraseLHSName( StringId name )
{
    HoleKey holeKeyMin( name, LHSSubContext().namespaceIndex, 0 );
    HoleKey holeKeyMax( name, LHSSubContext().namespaceIndex, ~0 );

    auto begin = CoW( m_pCow )->holeDict.lower_bound( holeKeyMin );
    auto end = CoW( m_pCow )->holeDict.upper_bound( holeKeyMax );

    CoW( m_pCow )->holeDict.erase( begin, end );
}

void TypeCheckingContext::eraseRHSName( StringId name )
{
    HoleKey holeKeyMin( name, RHSSubContext().namespaceIndex, 0 );
    HoleKey holeKeyMax( name, RHSSubContext().namespaceIndex, ~0 );

    auto begin = CoW( m_pCow )->holeDict.lower_bound( holeKeyMin );
    auto end = CoW( m_pCow )->holeDict.upper_bound( holeKeyMax );

    CoW( m_pCow )->holeDict.erase( begin, end );
}

bool TypeCheckingContext::isHoleLocked( uint32_t index ) const
{
    return m_pCow->lockedHoles.find( index ) != m_pCow->lockedHoles.end();
}

void TypeCheckingContext::lockHole( uint32_t index )
{
    CoW( m_pCow )->lockedHoles.emplace( index );
}

void TypeCheckingContext::unlockHole( uint32_t index )
{
    CoW( m_pCow )->lockedHoles.erase( index );
}

#ifndef NDEBUG
void TypeCheckingContext::TCRuleTrace( const TCRuleInfo* pRule ) const
{
    CoW( m_pCow )->currentTypeCheckingTrace.emplace_back( pRule );
}

void TypeCheckingContext::PushRuleTraceForParam() const
{
    auto* pCow = CoW( m_pCow ).get();
    pCow->paramsTypeCheckingTrace.emplace_back( move( pCow->currentTypeCheckingTrace ) );
}

void TypeCheckingContext::DumpParamsTraces( ostream& out ) const
{
    uint32_t i = 0;

    for( auto&& x : m_pCow->paramsTypeCheckingTrace )
    {
        out << "== TypeChecking trace for param #" << i++ << endl;
        for( auto&& y : x )
            cout << "   " << y->pFilename << ':' << y->line << endl;
    }
}
#endif