#pragma once

#include <functional>
#include <unordered_set>
#include <unordered_map>
#include "ast.h"
#include "global.h"

using namespace std;


class Environment{
public:
	using Hook = function<AST(Environment&,const AST&)>;
	using Hook2 = function<AST(Environment&,const AST&,const AST&)>;

private:
	unordered_map<string,AST> defs;
	unordered_map<string,Hook> hooks;

	bool reduce(AST &ast,i64 depth=0);
	bool betareduce(AST &ast,i64 depth);
	bool resolve(AST &ast);

public:
	void load(const Environment &other);

	AST run(const AST &ast);

	void define(const Name &name,const AST &ast);
	void define(const Name &name,const Hook &hook);
	void define2(const Name &name,const Hook2 &hook2);

	AST get(const Name &name);
};