//
// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
//
// The contents of this file are covered under the licence agreement in the
// file "LICENCE" distributed with Cforall.
//
// InitializerNode.cc --
//
// Author           : Rodolfo G. Esteves
// Created On       : Sat May 16 13:20:24 2015
// Last Modified By : Peter A. Buhr
// Last Modified On : Mon Jul  4 15:37:15 2016
// Update Count     : 15
//

#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 ), maybeConstructed( true ) {
	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 ), maybeConstructed( true ) {
	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, maybeConstructed );
	} else {
		std::list< Expression *> designators;

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

		if ( get_expression() != 0)
			return new SingleInit( maybeBuild<Expression>( get_expression() ), designators, maybeConstructed );
	} // if

	return 0;
}

// Local Variables: //
// tab-width: 4 //
// mode: c++ //
// compile-command: "make install" //
// End: //
