// Path: src/java/sizzle/compiler/TypeException.java
// public class TypeException extends RuntimeException {
// 	private static final long serialVersionUID = -5838752670934187621L;
// 
// 	/**
// 	 * Construct a TypeException.
// 	 * 
// 	 * @param text
// 	 *            A {@link String} containing the description of the error
// 	 */
// 	public TypeException(final String text) {
// 		super(text);
// 	}
// 
// 	/**
// 	 * Construct a TypeException caused by another exception.
// 	 * 
// 	 * @param text
// 	 *            A {@link String} containing the description of the error
// 	 * @param e
// 	 *            A {@link Throwable} representing the cause of this type
// 	 *            exception
// 	 */
// 	public TypeException(final String text, final Throwable e) {
// 		super(text, e);
// 	}
// }


import sizzle.compiler.TypeException;
package sizzle.types;


/**
 * A {@link SizzleType} representing an array of scalar values.
 * 
 * @author anthonyu
 * 
 */
public class SizzleArray extends SizzleType {
	private SizzleType type;

	/**
	 * Construct a SizzleArray.
	 */
	public SizzleArray() {
	}

	/**
	 * Construct a SizzleArray.
	 * 
	 * @param sizzleType
	 *            A {@link SizzleType} representing the type of the elements in
	 *            this array
	 */
	public SizzleArray(final SizzleType sizzleType) {
		this.type = sizzleType;
	}

	/** {@inheritDoc} */
	@Override
	public boolean assigns(final SizzleType that) {
		// if that is a function, check its return type
		if (that instanceof SizzleFunction)
			return this.assigns(((SizzleFunction) that).getType());

		// otherwise, if it's not an array, forget it
		if (!(that instanceof SizzleArray))
			return false;

		// if the element types are wrong, forget it
		if (this.type.assigns(((SizzleArray) that).type))
			return true;

		return false;
	}

	/** {@inheritDoc} */
	@Override
	public boolean accepts(final SizzleType that) {
		// if that is a function, check its return type
		if (that instanceof SizzleFunction)
			return this.assigns(((SizzleFunction) that).getType());

		// otherwise, if it's not an array, forget it
		if (!(that instanceof SizzleArray))
			return false;

		// if the element types are wrong, forget it
		if (this.type.accepts(((SizzleArray) that).type))
			return true;

		return false;
	}

	/** {@inheritDoc} */
	@Override
	public boolean compares(final SizzleType that) {
		// FIXME: is this needed?
		// if that is an array..
		if (that instanceof SizzleArray)
			// check against the element types of these arrays
			return this.type.compares(((SizzleArray) that).type);

		// otherwise, forget it
		return false;
	}

	/**
	 * Get the element type of this array.
	 * 
	 * @return A {@link SizzleScalar} representing the element type of this
	 *         array
	 */
	public SizzleScalar getType() {
		if (this.type instanceof SizzleScalar)
			return (SizzleScalar) this.type;

// Path: src/java/sizzle/compiler/TypeException.java
// public class TypeException extends RuntimeException {
// 	private static final long serialVersionUID = -5838752670934187621L;
// 
// 	/**
// 	 * Construct a TypeException.
// 	 * 
// 	 * @param text
// 	 *            A {@link String} containing the description of the error
// 	 */
// 	public TypeException(final String text) {
// 		super(text);
// 	}
// 
// 	/**
// 	 * Construct a TypeException caused by another exception.
// 	 * 
// 	 * @param text
// 	 *            A {@link String} containing the description of the error
// 	 * @param e
// 	 *            A {@link Throwable} representing the cause of this type
// 	 *            exception
// 	 */
// 	public TypeException(final String text, final Throwable e) {
// 		super(text, e);
// 	}
// }


// Path: src/java/sizzle/types/SizzleArray.java
import sizzle.compiler.TypeException;

package sizzle.types;


/**
 * A {@link SizzleType} representing an array of scalar values.
 * 
 * @author anthonyu
 * 
 */
public class SizzleArray extends SizzleType {
	private SizzleType type;

	/**
	 * Construct a SizzleArray.
	 */
	public SizzleArray() {
	}

	/**
	 * Construct a SizzleArray.
	 * 
	 * @param sizzleType
	 *            A {@link SizzleType} representing the type of the elements in
	 *            this array
	 */
	public SizzleArray(final SizzleType sizzleType) {
		this.type = sizzleType;
	}

	/** {@inheritDoc} */
	@Override
	public boolean assigns(final SizzleType that) {
		// if that is a function, check its return type
		if (that instanceof SizzleFunction)
			return this.assigns(((SizzleFunction) that).getType());

		// otherwise, if it's not an array, forget it
		if (!(that instanceof SizzleArray))
			return false;

		// if the element types are wrong, forget it
		if (this.type.assigns(((SizzleArray) that).type))
			return true;

		return false;
	}

	/** {@inheritDoc} */
	@Override
	public boolean accepts(final SizzleType that) {
		// if that is a function, check its return type
		if (that instanceof SizzleFunction)
			return this.assigns(((SizzleFunction) that).getType());

		// otherwise, if it's not an array, forget it
		if (!(that instanceof SizzleArray))
			return false;

		// if the element types are wrong, forget it
		if (this.type.accepts(((SizzleArray) that).type))
			return true;

		return false;
	}

	/** {@inheritDoc} */
	@Override
	public boolean compares(final SizzleType that) {
		// FIXME: is this needed?
		// if that is an array..
		if (that instanceof SizzleArray)
			// check against the element types of these arrays
			return this.type.compares(((SizzleArray) that).type);

		// otherwise, forget it
		return false;
	}

	/**
	 * Get the element type of this array.
	 * 
	 * @return A {@link SizzleScalar} representing the element type of this
	 *         array
	 */
	public SizzleScalar getType() {
		if (this.type instanceof SizzleScalar)
			return (SizzleScalar) this.type;

		throw new TypeException("this shouldn't happen");