Goose  Artifact [cccc115485]

Artifact cccc11548519700f25a95df4e36d2f1e02885cf3c2d7dd96ea4bebe8ccf708a9:

  • File bs/builtins/helpers.h — part of check-in [4d4d76607a] at 2023-03-05 22:24:05 on branch trunk —
    • removed fmtlib, now use std::format
    • vastly improved the overload resolution debugging tools
    • prelude: started adding some extra error detection for small things that don't need to be builtin
    • prelude: started working on implementing #for for tuples, some stuff needs to be addressed still
    • fixed some type checking issue with wrapped args
    • fixed superfluous nested lifetime scope in brace blocks (which caused redundant calls to some extension points)
    (user: zlodo size: 5878)

#ifndef GOOSE_BUILTINS_HELPERS_H
#define GOOSE_BUILTINS_HELPERS_H

namespace goose::parse
{
    class Parser;
    class Rule;
}

namespace goose::builtins
{
    extern const Term& EmptyPredicates();

    template< typename T >
    void DefineConstant( sema::Env& env, StringId name, T&& val )
    {
        env.storeValue( AppendToVectorTerm( RootG0Identity(), TERM( name ) ), ANYTERM( _ ), forward< T >( val ) );
    }

    extern void RegisterRule( sema::Env& env, StringId name, parse::Rule&& rule );

    // Utility function used to parse flow control statements, such as if and loops.
    // This parses a sub statement, which can be enclosed in a brace block or not.
    // It will get its own scope, with visibility rules setup to see the current
    // scope.
    // It returns a pointer to the final basic block generated by the statement.
    ptr< cir::BasicBlock > ParseSubStatement( parse::Parser& p, uint32_t precedence );

    enum class ValUnifyError
    {
        NoSolution,
        Ambiguous
    };

    // Typecheck the provided value with a value placeholder of the specified type,
    // and return the result or an error code.
    variant< Value, ValUnifyError > ConvertValueToType( const Context& c, const Value& val, const Term& type );

    // Helpers to create a standard type construction, as a vector starting with an identity, followed by an optional pointer to predicates
    // and an optional pointer to a llvm type.
    template< typename I, typename... T >
    auto MkStdType( I&& identity, T&&... extra )
    {
        return VEC( forward< I >( identity ), EmptyPredicates(), TERM( (void*)nullptr ), forward< T >( extra )... );
    }

    template< typename I >
    auto MkStdType( I&& identity )
    {
        return VEC( forward< I >( identity ), EmptyPredicates(), TERM( (void*)nullptr ) );
    }

    // Same as above, but directly specify the llvm type pointer.
    template< typename I, typename... T >
    auto MkStdRTType( I&& identity, const void* cgType, T&&... extra )
    {
        return VEC( forward< I >( identity ), EmptyPredicates(), const_cast< void* >( cgType ), forward< T >( extra )... );
    }

    template< typename I >
    auto MkStdRTType( I&& identity, const void* cgType )
    {
        return VEC( forward< I >( identity ), EmptyPredicates(), const_cast< void* >( cgType ) );
    }

    extern void PoisonBuilder( const Context& c,
        source_location sloc = source_location::current() );

    extern bool BuilderAllowsOverloading( const Context& c,
        source_location sloc = source_location::current() );
    extern ptr< cir::CFG > GetCFG( const Context& c,
        source_location sloc = source_location::current() );

    extern uint32_t GetBreakableScopeLevels( const Context& c,
        source_location sloc = source_location::current() );
    extern uint32_t GetContinuableScopeLevels( const Context& c,
        source_location sloc = source_location::current() );

    extern void BeginVisibilityScope( Context& c,
        source_location sloc = source_location::current() );

    extern void BeginLifetimeScope( const Context& c,
        source_location sloc = source_location::current() );
    extern void EndLifetimeScope( const Context& c,
        source_location sloc = source_location::current() );

    extern void BeginBreakableScope( const Context& c,
        source_location sloc = source_location::current() );
    extern void EndBreakableScope( const Context& c,
        source_location sloc = source_location::current() );
    extern void BeginContinuableScope( const Context& c,
        source_location sloc = source_location::current() );
    extern void EndContinuableScope( const Context& c,
        source_location sloc = source_location::current() );

    extern void DeclareValue( const Context& c, const Value& val, uint32_t index,
        source_location sloc = source_location::current() );

    extern bool DestroyLiveValue( const Context& c, const Value& val,
        source_location sloc = source_location::current() );
    extern bool DestroyCurrentLifetimeScopeValues( const Context& c,
        source_location sloc = source_location::current() );
    extern bool DestroyAllLiveValues( const Context& c,
        source_location sloc = source_location::current() );
    extern bool DestroyAllLiveValuesFromBreakScope( const Context& c, uint32_t breakScopeLevel,
        source_location sloc = source_location::current() );
    extern bool DestroyAllLiveValuesFromContinueScope( const Context& c, uint32_t continueScopeLevel,
        source_location sloc = source_location::current() );

    extern bool CanInvokeGhostFuncs( const Context& c,
        source_location sloc = source_location::current() );

    extern void CTForEach( const Context& c, const Value& decl, const Value& container, const ptr< vector< TermLoc > >& body,
        source_location sloc = source_location::current() );

    extern bool IsTrivialInitialization( const Context& c, const Value& lhsType, const Value& rhsType,
        source_location sloc = source_location::current() );
    extern bool IsTrivialAssignment( const Context& c, const Value& lhsType, const Value& rhsType,
        source_location sloc = source_location::current() );

    struct TypeTypePattern
    {
        static const Term& GetPattern()
        {
            static auto pat = TypeType();
            return pat;
        }
    };

    struct CTTypePattern
    {
        static const Term& GetPattern()
        {
            static auto pat = ValueToEIR( Value( TypeType(), VEC( TSID( ct_type ), REPEAT( HOLE( "_"_sid ) ) ) ) );
            return pat;
        }
    };

    struct RTTypePattern
    {
        static const Term& GetPattern()
        {
            static auto pat = ValueToEIR( Value( TypeType(), VEC( TSID( rt_type ), REPEAT( HOLE( "_"_sid ) ) ) ) );
            return pat;
        }
    };
}

#endif