#include "ParseNode.h"
#include "SynTree/Expression.h"
#include "SynTree/Initializer.h"
#include "utility.h"
#include "SemanticError.h"
// #include <cstdlib> // for strtol
#include <cassert>


InitializerNode::InitializerNode( ExpressionNode *_expr, bool aggrp, ExpressionNode *des )
  : expr( _expr ), aggregate( aggrp ), designator( des ), kids( 0 )
{
  if ( aggrp )
    kids = dynamic_cast< InitializerNode *>( get_link() );

  if ( kids != 0 )
    set_link( 0 );
}

InitializerNode::InitializerNode( InitializerNode *init, bool aggrp, ExpressionNode *des )
  : aggregate( aggrp ), designator( des ), kids( 0 )
{
  if (init != 0)
    set_link(init);

  if ( aggrp )
      kids = dynamic_cast< InitializerNode *>( get_link() );

  if ( kids != 0 )
    set_next( 0 );
}

InitializerNode::~InitializerNode() {
  delete expr;
}

void InitializerNode::print( std::ostream &os, int indent ) const {
  os << std::string(indent, ' ') << "Initializer expression" << std::endl;
}

void InitializerNode::printOneLine( std::ostream &os ) const {
  if (!aggregate)
    {

      if ( designator != 0 )
	{
	  os << "designated by: (";
	  ExpressionNode  *curdes = designator;
	  while( curdes != 0){
	    curdes->printOneLine(os);
	    curdes = (ExpressionNode *)(curdes->get_link());
	    if(curdes) os << ", ";
	  }
	  os << ")";
	}

      if (expr) expr->printOneLine(os);
    }
  else  // It's an aggregate
    {
      os << "[--";
      if( next_init() != 0 )
	next_init()->printOneLine(os);

      if (aggregate) os << "--]";
    }

  InitializerNode * moreInit;
  if  ( get_link() != 0 && ((moreInit = dynamic_cast< InitializerNode * >( get_link() ) ) != 0) )
    moreInit->printOneLine( os );
}

Initializer *InitializerNode::build() const {
  // if ( get_expression() == 0 ) return 0;  // XXX (?)

  if ( aggregate )
    {
      assert( next_init() != 0 );

      std::list< Initializer *> initlist;
      buildList<Initializer, InitializerNode>( next_init(), initlist );

      std::list< Expression *> designlist;
      if ( designator != 0 )
	buildList<Expression, ExpressionNode>( designator, designlist );

      return new ListInit( initlist, designlist );
    }
  else
    {
      std::list< Expression *> designators;

      if ( designator != 0 )
	buildList<Expression, ExpressionNode>( designator, designators );

      if ( get_expression() != 0)
	return new SingleInit( get_expression()->build(), designators );
    }

  return 0;
}


