#ifndef GOOSE_BUILTINS_HELPERS_H #define GOOSE_BUILTINS_HELPERS_H namespace goose::parse { class Parser; class Rule; } namespace goose::builtins { class Propositions; 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 Value EmitTypePredicatesCheck( const Context& c, const Value& val, const ptr< Propositions >& props, 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