#include <cassert>
#include <iostream>
using namespace std;

#include "ParseNode.h"
#include "SynTree/Expression.h"
#include "SynTree/Initializer.h"

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 )
    : expr( 0 ), 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 << ", ";
	    } // while
	    os << ")";
	} // if
	if ( expr ) expr->printOneLine(os);
    } else {  // It's an aggregate
	os << "[--";
	if ( next_init() != 0 )
	    next_init()->printOneLine(os);
	if (aggregate) os << "--]";
    } // if

    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 );
	} // if

	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 );
    } // if

    return 0;
}
