#include "NameMatcher.h"
#include "NameMatcher.h"

namespace Tuples {
  NameMatcher::NameMatcher( std::list< DeclarationWithType* > &formals )
    : current( 0 ) {
    int cnt = 0;
    for( std::list< DeclarationWithType *>::const_iterator f = formals.begin(); f != formals.end(); ++f ) {
      table.insert( std::pair< std::string, int >( (*f)->get_name(), cnt++ ) );
      index.push_back(*f);
    }
    exprs.reserve( index.size() );
  }

  NameMatcher::~NameMatcher() {}

  void NameMatcher::match( ResolvExpr::AltList &alternatives ) throw (NoMatch) {
    if( alternatives.size() != index.size() )
      throw NoMatch("Length of actuals and formals differ");

    for( ResolvExpr::AltList::const_iterator a = alternatives.begin(); a != alternatives.end(); ++a ) {
      if( a->expr->get_argName() != 0 )
	if ( NameExpr *name = dynamic_cast<NameExpr *>( a->expr->get_argName() ) ) {
	  if ( table.find( name->get_name() ) != table.end() ) {
	    std::cerr << "Rearranging to " << table[ name->get_name() ] << "position in the list." << std::endl;
	    exprs[ table[ name->get_name() ] ] = &(*a);
	  } else
	    throw NoMatch( name->get_name() + "no such  designation" );
	} /*else if( TupleExpr *tup = dynamic_cast<TupleExpr *>( a->expr->get_argName() ) )
	    std::cerr << "Designated expression" << std::endl; */
      exprs.push_back( &(*a) );
    }

    /*std::cerr << "In matcher/match: ";
    if ( exprs.size() != index.size() )
      std::cerr << "exprs and index differ in length" << std::endl;
    else
      std::cerr << "is all good." << std::endl;
    */
  }

  ResolvExpr::Alternative &NameMatcher::get_next() throw (NoMoreElements) {
    if( current++ >= (int)(index.size()) )
      throw NoMoreElements();
    return *(new ResolvExpr::Alternative());
  }
} // namespace Tuples
