#include "sema.h"
using namespace goose;
using namespace goose::sema;
TypeCheckingContext::TypeCheckingContext( const Context& c ) :
m_context( c )
{}
TypeCheckingContext::TypeCheckingContext( Context&& c ) :
m_context( move( c ) )
{}
uint32_t TypeCheckingContext::getLHSHoleIndex( StringId name ) const
{
if( name == "_"_sid )
return InvalidIndex;
HoleName holeName( name, LHSSubContext().namespaceIndex );
auto it = m_pCow->holeDict.find( holeName );
if( it == m_pCow->holeDict.end() )
return InvalidIndex;
return it->second;
}
uint32_t TypeCheckingContext::getRHSHoleIndex( StringId name ) const
{
if( name == "_"_sid )
return InvalidIndex;
HoleName holeName( name, RHSSubContext().namespaceIndex );
auto it = m_pCow->holeDict.find( holeName );
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 index )
{
if( name == "_"_sid )
{
++m_numAnonymousHoles;
return;
}
HoleName holeName( name, LHSSubContext().namespaceIndex );
CoW( m_pCow )->holeDict.emplace( holeName, index );
if( m_valuesAreRequired )
setValueRequired( index );
}
void TypeCheckingContext::setRHSHoleIndex( StringId name, uint32_t index )
{
if( name == "_"_sid )
{
++m_numAnonymousHoles;
return;
}
HoleName holeName( name, RHSSubContext().namespaceIndex );
CoW( m_pCow )->holeDict.emplace( holeName, index );
if( m_valuesAreRequired )
setValueRequired( index );
}
void TypeCheckingContext::eraseLHSName( StringId name )
{
HoleName holeName( name, LHSSubContext().namespaceIndex );
CoW( m_pCow )->holeDict.erase( holeName );
}
void TypeCheckingContext::eraseRHSName( StringId name )
{
HoleName holeName( name, RHSSubContext().namespaceIndex );
CoW( m_pCow )->holeDict.erase( holeName );
}
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