CompositeTypeNode.java

package edu.udel.cis.vsl.tass.ast.impl.type;

import java.io.PrintWriter;
import java.util.NoSuchElementException;

import edu.udel.cis.vsl.tass.ast.IF.ASTNodeIF;
import edu.udel.cis.vsl.tass.ast.IF.IdentifierNodeIF;
import edu.udel.cis.vsl.tass.ast.IF.PairNodeIF;
import edu.udel.cis.vsl.tass.ast.IF.SequenceNodeIF;
import edu.udel.cis.vsl.tass.ast.IF.type.CompositeTypeNodeIF;
import edu.udel.cis.vsl.tass.ast.IF.type.TypeNodeIF;
import edu.udel.cis.vsl.tass.ast.impl.ASTNode;

public class CompositeTypeNode extends ASTNode implements CompositeTypeNodeIF {

	private IdentifierNodeIF name;
	private SequenceNodeIF<PairNodeIF<IdentifierNodeIF, TypeNodeIF>> fields;
	private boolean isUnion;

	public CompositeTypeNode(long id) {
		super(id);
	}
	
	public CompositeTypeNode(long id, IdentifierNodeIF name,
			SequenceNodeIF<PairNodeIF<IdentifierNodeIF, TypeNodeIF>> fields,
			boolean isUnion) {
		super(id);
		this.name = name;
		this.fields = fields;
		this.isUnion = isUnion;
	}

	@Override
	public IdentifierNodeIF name() {
		return name;
	}

	@Override
	public SequenceNodeIF<PairNodeIF<IdentifierNodeIF, TypeNodeIF>> fields() {
		return fields;
	}

	@Override
	public boolean isUnion() {
		return isUnion;
	}

	@Override
	public void setName(IdentifierNodeIF name) {
		this.name = name;
	}

	@Override
	public void setFields(
			SequenceNodeIF<PairNodeIF<IdentifierNodeIF, TypeNodeIF>> fields) {
		this.fields = fields;
	}

	@Override
	public void setUnion(boolean union) {
		this.isUnion = union;
	}

	@Override
	public int numChildren() {
		return 2;
	}

	@SuppressWarnings("unchecked")
	@Override
	public void setChild(int i, ASTNodeIF child) throws NoSuchElementException {
		switch (i) {
		case 0:
			name = (IdentifierNodeIF) child;
			break;
		case 1:
			// Java can't type check generics, so make sure the child has the
			// right type.
			for (int j = 0; j < child.numChildren(); j++) {
				PairNodeIF<IdentifierNodeIF, TypeNodeIF> pair = 
					((PairNodeIF<IdentifierNodeIF,TypeNodeIF>)
					 ((SequenceNodeIF<PairNodeIF<IdentifierNodeIF,TypeNodeIF>>)child)
					 .child(j));
				assert pair.left() instanceof IdentifierNodeIF;
				assert pair.right() instanceof TypeNodeIF;
			}
			fields = (SequenceNodeIF<PairNodeIF<IdentifierNodeIF, TypeNodeIF>>) child;
			break;
		default:
			throw new NoSuchElementException("Node " + id()
					+ " does not have a child with index " + i + ".");
		}
	}

	@Override
	public ASTNodeIF child(int index) throws NoSuchElementException {
		switch (index) {
		case 0:
			return name;
		case 1:
			return fields;
		default:
			throw new NoSuchElementException("Node " + id()
					+ " does not have a child with index " + index + ".");
		}
	}

	@Override
	public String toString() {
		return name.toString() + "{" + fields.toString() + "}";
	}

	@Override
	public void print(String prefix, PrintWriter out) {
		out.println(prefix + " AST Node " + id() + ", Composite Type");
		name.print(prefix + "|", out);
		fields.print(prefix + "|", out);
	}

}