Goose  Artifact [9f0964c873]

Artifact 9f0964c8738b1fbe2db920d40db605b20d25071cc18cc7965918cebc0bae5c00:

  • File bs/sema/tc-context.cpp — part of check-in [b64ea47f6b] at 2020-06-27 22:05:05 on branch trunk — Clearly separate the type checking rules and the unification rules, instead of lumping them all together in a single set of patterns which is increasingly confusing. (user: achavasse size: 2822)

#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 );
}