#ifndef GOOSE_SEMA_TC_RULESET_H
#define GOOSE_SEMA_TC_RULESET_H
#ifndef NDEBUG
#define TCRULES_DEBUG
#endif
namespace goose::sema
{
class TypeCheckingContext;
#ifndef NDEBUG
struct TCRuleInfo
{
TCRuleInfo() {}
TCRuleInfo( const source_location& sl ) :
pFilename( sl.file_name() ),
line( sl.line() )
{
}
const char* pFilename = nullptr;
uint32_t line = 0;
};
#else
struct TCRuleInfo
{
TCRuleInfo() {}
TCRuleInfo( const source_location& sl ) {}
};
#endif
class TypeCheckingRuleSet
{
public:
using BinaryFunc =
function< TCGen( const Term& lhs, const Term& rhs, const TypeCheckingContext& ) >;
using UnaryFunc = function< optional< Term >( const Term& lhs, TypeCheckingContext& ) >;
struct BinaryRule
{
BinaryFunc func;
TCRuleInfo infos;
bool exclusive = false;
};
struct UnaryRule
{
UnaryFunc func;
TCRuleInfo infos;
};
TypeCheckingRuleSet();
void addTypeCheckingRule( const Term& pat1, const Term& pat2, BinaryFunc f,
bool exclusive = false, TCRuleInfo infos = source_location::current() );
void addUnificationRule( const Term& pat, BinaryFunc f, bool exclusive = false,
TCRuleInfo infos = source_location::current() );
void addUnificationRule( const Term& pat1, const Term& pat2, BinaryFunc f,
bool exclusive = false, TCRuleInfo infos = source_location::current() );
void addHalfUnificationRule(
const Term& pat, UnaryFunc f, TCRuleInfo infos = source_location::current() );
const auto& typeCheckingRules() const { return m_typeCheckingRules; }
const auto& uniRules() const { return m_uniRules; }
const auto& halfUniRules() const { return m_halfUniRules; }
private:
Trie< BinaryRule > m_typeCheckingRules;
Trie< BinaryRule > m_uniRules;
Trie< UnaryRule > m_halfUniRules;
};
} // namespace goose::sema
#endif