#ifndef _ASSOCIATE_H_ #define _ASSOCIATE_H_ #include #include #include #include #include #include #include #include "SynTree/Expression.h" #include "diet_map.h" class Association; class SingleName; class PointAssociation; class RangeAssociation; // ** exceptions class AssocException : public std::exception { public: AssocException() {} AssocException( std::string _what ) : what( _what ) {} ~AssocException() throw () {} std::string get_what() const { return what; } void set_what( std::string newValue ) { what = newValue; } private: std::string what; }; // ** visitors class AssociationVisitor { public: AssociationVisitor() {} virtual ~AssociationVisitor() {} virtual void visit( SingleName * ) = 0; virtual void visit( PointAssociation * ) = 0; virtual void visit( RangeAssociation * ) = 0; }; // ** containers class Association { public: virtual ~Association(); virtual Association *clone() = 0; virtual long int add_single( std::string, Expression *) = 0; virtual long int add_single( long int, Expression *expr) = 0; virtual Association *operator[]( int idx ) = 0; virtual Association *operator[]( std::string ) = 0; // virtual AssociationIterator *get_iterator() = 0; virtual void accept( AssociationVisitor & ) = 0; virtual void display( std::ostream & ) = 0; }; class SingleName : public Association { public: SingleName( Expression *initExpr = 0 ) : expr( initExpr ) {} virtual ~SingleName(); virtual SingleName *clone() { return 0; // XXX! } virtual long int add_single( long int idx, Expression *newExpr) { if ( expr == 0 ) //|| *expr == *newExpr ) expr = newExpr; return 0; } virtual long int add_single( std::string str, Expression *newExpr) { if ( expr == 0 ) //|| *expr == *newExpr ) expr = newExpr; return 0; } virtual Association *operator[]( int idx ) { assert(false); } virtual Association *operator[]( std::string idx ) { assert(false); } virtual void accept( AssociationVisitor &v ) { v.visit( this ); } virtual void display( std::ostream &os ) { os << "Single association" << std::endl; } Expression *get_expr() const { return expr; } private: Expression *expr; Expression *deflt; }; class PointAssociation : public Association { public: typedef std::map< std::string, std::pair< long int, Association *> > map_type; PointAssociation() {} PointAssociation( const PointAssociation &other ) { copy( other.anonym.begin(), other.anonym.end(), back_inserter( anonym )); } virtual ~PointAssociation(); virtual PointAssociation *clone() { return ( new PointAssociation( *this ) ); } virtual long int add_single( long int idx, Expression *expr) { long int ret; if ( idx >= (long int)ordering.size() ) throw AssocException("extra (spurious) members"); if ( ordering[ idx ] == "") std::cerr << "Checkpoint 2" << std::endl; else { assert( table[ordering[idx]].second != 0 ); ret = idx; table[ ordering[idx] ].second->add_single("", expr ); } return ret; } virtual long int add_single( std::string idx, Expression *expr) { if ( idx == "" ) std::cerr << "Checkpoint 1" << std::endl; else { map_type::iterator j; if ( (j = table.find( idx )) == table.end() ) // this doesn't amount for reachable members deeper down the structure, fix throw AssocException("No such member"); else return add_single( j->second.first, expr ); } return -1; } void add_member( std::string str ) { if ( table.find( str ) != table.end() ) return; ordering.push_back( str ); if ( str != "" ) { std::pair p( ordering.size() - 1, 0 ); table.insert( std::pair< std::string, std::pair >(str, p) ); } return; } virtual void set_member( std::string str, Association *assoc ) { if ( str == "" ) anonym.push_back( assoc ); else if ( table.find( str ) == table.end() ) throw AssocException( "no such member" ); else table[ str ] = std::pair(ordering.size() - 1, assoc); return; } virtual Association *operator[]( int idx ) { if ( ordering[idx] == "" ) { std::cerr << "Error, anonymous members not implemented yet" << std::endl; throw 0; } else return table[ ordering[idx] ].second; } virtual Association *operator[]( std::string idx ) { if ( table.find( idx ) == table.end() ) throw AssocException("Member not found"); else return table[ idx ].second; } /* virtual AssociationIterator *get_iterator() { PointAssocIterator *it; return it; } */ void accept( AssociationVisitor &v ) { v.visit( this ); } virtual void display( std::ostream &os ) { os << "Point association: " << std::endl; for ( map_type::iterator i = table.begin(); i != table.end(); i++ ) { os << "Member [" << i->first << ", index = " << i->second.first << "]"; if ( i->second.second != 0 ) i->second.second->display( os ); else std::cerr << "No recursive association" << std::endl; os << std::endl; } } const int size() const { return ordering.size(); } private: PointAssociation &operator=(const PointAssociation &); std::vector ordering; std::list< Association * > anonym; std::map< std::string, std::pair > table; }; class RangeAssociation : public Association { public: static const int UNDEF; RangeAssociation( int _hi= UNDEF ) : hi( _hi ) { std::cerr << "Constructed RangeAssociation with: [" << hi << "]" << std::endl; } virtual ~RangeAssociation(); virtual RangeAssociation *clone() { return 0; // XXX !!!! } virtual Association *operator[]( int idx ) { return 0; // XXX !!! } virtual Association *operator[]( std::string idx ) { assert(false); return 0; } /* virtual AssociationIterator *get_iterator() { RangeAssocIterator *it; return it; } */ virtual long int add_single( long int idx, Expression *newExpr) { return 0; } virtual long int add_single( std::string, Expression *) { return 0; } void accept( AssociationVisitor &v ) { v.visit( this ); } virtual void display( std::ostream &os ) { os << "Range association, with limit: " << std::endl; } private: int hi; diet::diet_tree tree; /* for ( diet_tree::iterator i = tree.begin(); i != tree.end(); i++ ) std::cout << "--(" << (*i).first << ", " << (*i).second << ")--" << std::endl; diet_tree tree; tree.insert(100,200); */ }; // ** builders class AssociationBuilder { public: /* AssociationBuilder( Declaration * ) */ virtual ~AssociationBuilder() {} virtual Association *get_assoc() = 0; virtual Association *grab_assoc() = 0; virtual void set_assoc( Association * ) = 0; }; class AssociationFiller { public: // AssociationFiller( Declaration * ) {} virtual ~AssociationFiller() {} virtual Association *get_assoc() = 0; virtual void set_assoc( Association * ) = 0; }; #endif //#define _ASSOCIATE_H_ /* Local Variables: mode: c++ End: */