#ifndef PARSER_STRUCT_H
#define PARSER_STRUCT_H

#include <list>
#include <string>
#include <vector>

#include "hub/named.h"
#include "vhdl_expressions.h"

//----------------------------------------------------------------------------------------------
enum Mode{ M_UNKNOWN,M_IN,M_OUT,M_INOUT,M_BUFFER,M_LINKAGE };
enum ObjClass{ O_NONE,O_CONSTANT,O_SIGNAL,O_VARIABLE,O_FILE }; 
enum Direction{D_TO,D_DOWNTO};
// ----------------------------------------------------------------------------------------------
typedef std::list<StringToken> IdentifierList;
typedef IdentifierList* pIdentifierList;

// ==========================================================================
// association elements
// ==========================================================================
class GenAssocElem{
	public:
		virtual ~GenAssocElem(){}
};
typedef GenAssocElem* pGenAssocElem;

typedef std::list<pGenAssocElem>GenAssocList;
typedef GenAssocList* pGenAssocList;
// ----------------------------------------------------------------------------------------------

class RangeAssocElem : public GenAssocElem {
		int left;
		int right;
		Direction direction;
	public:
		RangeAssocElem( int l,int r,Direction d): left(l),right(r),direction(d){}
		virtual ~RangeAssocElem() {}
		bool validate(void);
		int Range();
};
// ----------------------------------------------------------------------------------------------

class SigName;
typedef SigName* pSigName;
class NamedAssocElem : public GenAssocElem {
	public:
		pExpr actual_;
		pSigName formal_;
		NamedAssocElem(pExpr a,pSigName f = NULL): actual_(a),formal_(f){}
};
// ==========================================================================
// names
// ==========================================================================
class SigName {
protected:
	StringToken mark_;
public:
	SigName(const StringToken& st): mark_(st){}
	StringToken& GetMark(){ return mark_; }
	virtual StringToken GenerateName(void){ return mark_; }
	virtual  ~SigName(){}
};

class IndexName : public SigName {
	pGenAssocList indexes_;
public:
	IndexName(const StringToken& st,pGenAssocList l):SigName(st),indexes_(l){}
	virtual StringToken GenerateName(void);
	virtual ~IndexName(){ delete indexes_; }
};

// ==========================================================================
// types
// ==========================================================================
class Type{ 
public:
	StringToken mark;
	Type(const StringToken& st ): mark(st){}
	virtual ~Type(){}
};
typedef Type* pType;

class SimpleType : public Type{
public:
	SimpleType(const StringToken& st): Type(st){}
	virtual ~SimpleType(){}
};
//----------------------------------------------------------------------------------------------
class ArrayType : public Type{
public:
	GenAssocList list;
	ArrayType(const StringToken& st,GenAssocList& l) : Type(st), list(l){}
	virtual ~ArrayType(){}
};
// ----------------------------------------------------------------------------------------------

class InterfaceDecl{
	public:
	StringToken portName;
	ObjClass objClass;
	Mode mode;
	pType type;
	//init expr
	InterfaceDecl(const StringToken& st,ObjClass oc, Mode m, pType t ) :
		portName(st) , objClass(oc), mode(m), type(t){}
	std::vector<StringToken> GeneratePortNames(); 
	~InterfaceDecl(){}
};

typedef std::list<InterfaceDecl> InterfaceList;
typedef InterfaceList* pInterfaceList;

// bison parsers semantic types
union vhdl_types {
  int ival;
  std::string *sval;
  char chval;
  bool boolean;
  pType type;
  pInterfaceList interfList;
  pIdentifierList identList;
  ObjClass objClass;
  Mode mode;
  Direction dir;
  pGenAssocElem genAssocElem;
  pGenAssocList pgenAssocList;
  pSigName psigName;
  pExpr pexpr;
  pStringToken stoken;
};



#endif
