#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