#ifndef GOOSE_BUILTINS_HELPERS_H
#define GOOSE_BUILTINS_HELPERS_H
#include "parse/parse.h"
namespace goose::builtins
{
extern void RegisterRule( sema::Env& env, const 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< llr::BasicBlock > ParseSubStatement( parse::Parser& p, uint32_t precedence );
enum class ValUnifyError
{
NoSolution,
Ambiguous
};
// Unify 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 ), TERM( ptr< void >() ), TERM( (void*)nullptr ), forward< T >( extra )... );
}
template< typename I >
auto MkStdType( I&& identity )
{
return VEC( forward< I >( identity ), TERM( ptr< void >() ), TERM( (void*)nullptr ) );
}
// Same as above, but directly specify the llvm type pointer.
template< typename I, typename L, typename... T >
auto MkStdRTType( I&& identity, L&& llvmType, T&&... extra )
{
return VEC( forward< I >( identity ), TERM( ptr< void >() ), forward< L >( llvmType ), forward< T >( extra )... );
}
template< typename I, typename L >
auto MkStdRTType( I&& identity, L&& llvmType )
{
return VEC( forward< I >( identity ), TERM( ptr< void >() ), forward< L >( llvmType ) );
}
}
#endif