#ifndef GOOSE_SEMA_TC_RULESET_H
#define GOOSE_SEMA_TC_RULESET_H
//#define TCRULES_DEBUG
namespace goose::sema
{
class TypeCheckingContext;
#ifndef NDEBUG
struct TCRuleInfo
{
const char* pFilename = nullptr;
uint32_t line = 0;
};
#define TCRINFOS TCRuleInfo{ __FILE__, __LINE__ }
#else
struct TCRuleInfo
{};
#define TCRINFOS TCRuleInfo{}
#endif
using TCGen = Generator< pair< Term, TypeCheckingContext > >;
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( TCRuleInfo&& infos, const Term& pat1, const Term& pat2, BinaryFunc f, bool exclusive = false );
void addUnificationRule( TCRuleInfo&& infos, const Term& pat, BinaryFunc f, bool exclusive = false );
void addUnificationRule( TCRuleInfo&& infos, const Term& pat1, const Term& pat2, BinaryFunc f, bool exclusive = false );
void addHalfUnificationRule( TCRuleInfo&& infos, const Term& pat, UnaryFunc f );
const auto& typeCheckingRules() const { return m_typeCheckingRules; }
const auto& uniRules() const { return m_uniRules; }
const auto& halfUniRules() const { return m_halfUniRules; }
private:
Trie< Trie< BinaryRule > > m_typeCheckingRules;
Trie< BinaryRule > m_uniRules;
Trie< UnaryRule > m_halfUniRules;
};
}
#endif