#ifndef SYMBOL_CHECKING_HH
#define SYMBOL_CHECKING_HH

#include "ast.hh"
#include <set>
#include <map>

namespace type_checking {
    // forward declaration
    class TypeInfo;
};

namespace symbol_checking {

    typedef type_checking::TypeInfo tinfo_t;
    class symbol_less {
    public:
	bool operator()(const char *s1, const char *s2) const
        { return strcmp(s1, s2) < 0; }
    };
    typedef std::map<const char*, tinfo_t*, symbol_less> symbol_map_t;



    class Redefinition : public ast::Exception {
	const char *_symbol;
    public:
	Redefinition(const ast::Ast &ast, const char *symbol)
	    : ast::Exception(ast), _symbol(symbol)
	{}
	const char     *symbol() const { return _symbol; }
	virtual void print_error_msg(std::ostream &os);
    };



    class SymbolTable {
	SymbolTable  *_outer_scope;
	symbol_map_t  _this_scope;

	SymbolTable();
	SymbolTable(SymbolTable&);

	const tinfo_t        *lookup_this_scope    (const char *symbol) const;
	const tinfo_t        *lookup_local_scopes  (const char *symbol) const;
	static const tinfo_t *lookup_global_scopes (const char *symbol);

	friend class SymbolDefinitionVisitor;
	void define_symbol(const char *symbol, tinfo_t *tinfo);

    public:
	SymbolTable(ast::Ast &ast, SymbolTable *outer_scope);
	const tinfo_t *lookup(const char *symbol) const;
	SymbolTable *outer_scope() { return _outer_scope; }
    };

    std::set<tinfo_t*> *globals();
    std::set<tinfo_t*> *parameters();
    std::set<tinfo_t*> *locals();
};

#endif // SYMBOL_CHECKING_HH


syntax highlighted by Code2HTML, v. 0.9.1