#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( const StringId& name ) const
{
if( name == "_"_sid )
return InvalidIndex;
HoleName holeName( name, m_currentLHSNamespaceIndex );
auto it = m_pCow->holeDict.find( holeName );
if( it == m_pCow->holeDict.end() )
return InvalidIndex;
return it->second;
}
uint32_t TypeCheckingContext::getRHSHoleIndex( const StringId& name ) const
{
if( name == "_"_sid )
return InvalidIndex;
HoleName holeName( name, m_currentRHSNamespaceIndex );
auto it = m_pCow->holeDict.find( holeName );
if( it == m_pCow->holeDict.end() )
return InvalidIndex;
return it->second;
}
uint32_t TypeCheckingContext::createValue()
{
CoW( m_pCow )->values.push_back( StoredValue() );
uint32_t index = m_pCow->values.size() - 1;
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( const StringId& name, uint32_t index )
{
if( name == "_"_sid )
{
++m_numAnonymousHoles;
return;
}
HoleName holeName( name, m_currentLHSNamespaceIndex );
CoW( m_pCow )->holeDict.emplace( holeName, index );
if( m_valuesAreRequired )
setValueRequired( index );
}
void TypeCheckingContext::setRHSHoleIndex( const StringId& name, uint32_t index )
{
if( name == "_"_sid )
{
++m_numAnonymousHoles;
return;
}
HoleName holeName( name, m_currentRHSNamespaceIndex );
CoW( m_pCow )->holeDict.emplace( holeName, index );
if( m_valuesAreRequired )
setValueRequired( index );
}
void TypeCheckingContext::eraseLHSName( const StringId& name )
{
HoleName holeName( name, m_currentLHSNamespaceIndex );
CoW( m_pCow )->holeDict.erase( holeName );
}
void TypeCheckingContext::eraseRHSName( const StringId& name )
{
HoleName holeName( name, m_currentRHSNamespaceIndex );
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 );
}