#ifndef VHDL_EXPRESSIONS_H
#define VHDL_EXPRESSIONS_H

#include <string>
#include "location.hh"
#include "named.h"
// ---------------------------------------------------------------------
class StringToken: public hub::Name, public yy::location {
	public:
		StringToken(void){}
		StringToken(const char* s): hub::Name(s), yy::location(){}
		StringToken(const std::string& name,const yy::location& loc): hub::Name(name),yy::location(loc){}
		yy::location Location(void) const { return (yy::location)(*this); }
		hub::Name GetName(void)const { return (hub::Name)(*this); }
};
typedef StringToken* pStringToken;

inline std::ostream& operator<< (std::ostream& ostr, const StringToken& st){
	ostr << st.GetName();
	return ostr;
}
// ---------------------------------------------------------------------
class VhdlParserClient;
class Expr{
public:
	virtual ~Expr(){}
	virtual StringToken* Connect(VhdlParserClient* client,bool createNet=true)=0;
};
typedef Expr* pExpr;
// ---------------------------------------------------------------------
class BinOp: public Expr {
	pExpr left_;
	pExpr right_;
	StringToken operator_;
public:
	typedef enum { REL,LOG,ADD,MULT,SHFT }OpType;
	OpType opType_;
	BinOp(pExpr l,const StringToken& o,pExpr r,OpType op);
	pExpr Left() { return left_; }
	pExpr Right(){ return right_; }
	virtual ~BinOp(){ delete left_; delete right_; }
	virtual StringToken* Connect(VhdlParserClient* client,bool createNet=true);
};
// ---------------------------------------------------------------------
class UnOp : public Expr {
	std::string operator_;
	pExpr expr_;
public:
	UnOp(pExpr e,const StringToken& o);
	virtual ~UnOp(){ delete expr_; }
	virtual StringToken* Connect(VhdlParserClient* client,bool createNet=true);
};
// ---------------------------------------------------------------------
class LiteralExpr: public Expr {
	int val_;
public:
	LiteralExpr(int val): val_(val){}
	int Val(){ return val_; }
	virtual ~LiteralExpr(){}
	virtual StringToken* Connect(VhdlParserClient* client,bool createNet=true);
};
// ---------------------------------------------------------------------
class SigName;
class NameExpr: public Expr {
	SigName* name_;
public:
	NameExpr(SigName* n):name_(n){}
	virtual ~NameExpr();
	virtual StringToken* Connect(VhdlParserClient* client,bool createNet=true);
};


#endif
