AllocateStatement.java

package edu.udel.cis.vsl.tass.model.impl.statement;

import java.util.Collection;

import edu.udel.cis.vsl.tass.model.IF.ModelFactoryIF;
import edu.udel.cis.vsl.tass.model.IF.SyntaxException;
import edu.udel.cis.vsl.tass.model.IF.expression.ExpressionIF;
import edu.udel.cis.vsl.tass.model.IF.expression.LHSExpressionIF;
import edu.udel.cis.vsl.tass.model.IF.location.AllocateLocationIF;
import edu.udel.cis.vsl.tass.model.IF.statement.AllocateStatementIF;
import edu.udel.cis.vsl.tass.model.IF.type.PointerTypeIF;
import edu.udel.cis.vsl.tass.model.IF.type.TypeIF;
import edu.udel.cis.vsl.tass.model.IF.type.TypeIF.TypeKind;
import edu.udel.cis.vsl.tass.model.IF.variable.SharedVariableIF;
import edu.udel.cis.vsl.tass.model.IF.variable.VariableIF;

public class AllocateStatement extends Statement implements AllocateStatementIF {

	private LHSExpressionIF lhs;

	private TypeIF elementType;

	private ExpressionIF size;

	public AllocateStatement(ModelFactoryIF factory,
			AllocateLocationIF sourceLocation, LHSExpressionIF lhs,
			TypeIF elementType, ExpressionIF size) throws SyntaxException {
		super(factory, sourceLocation, StatementKind.ALLOCATE);
		if (lhs == null)
			throw new NullPointerException("lhs is null");
		if (elementType == null)
			throw new NullPointerException("elementType is null");
		if (size == null)
			throw new NullPointerException("numElements expression is null");
		if (lhs.type().kind() != TypeKind.POINTER) {
			throw new SyntaxException(lhs,
					"Expected LHS expression of pointer type");
		} else {
			PointerTypeIF pointerType = (PointerTypeIF) lhs.type();
			TypeIF baseType = pointerType.baseType();

			if (!baseType.equals(elementType)
					&& baseType.kind() != TypeKind.VOID)
				throw new SyntaxException(lhs,
						"Expected left hand side to have type pointer-to-void or pointer-to-"
								+ elementType + ":\n" + pointerType);
		}
		if (size.type().kind() != TypeKind.INTEGER) {
			throw new SyntaxException(size,
					"Expected expression of integer type:\n" + size.type());
		}
		factory.checkScope(lhs, sourceLocation.scope());
		factory.checkScope(size, sourceLocation.scope());
		this.lhs = lhs;
		this.elementType = elementType;
		this.size = size;
	}

	public TypeIF elementType() {
		return elementType;
	}

	public LHSExpressionIF lhs() {
		return lhs;
	}

	public ExpressionIF size() {
		return size;
	}

	public String toString() {
		return lhs + " = (" + elementType.shortName() + "*) malloc(" + size
				+ ");";
	}

	// there is no shared heap at this time.
	public void complete() throws SyntaxException {
		Collection<SharedVariableIF> shared = process().model().scope()
				.properSharedVariables();

		super.complete();
		isLocal = true;
		for (VariableIF variable : lhs.freeVariables()) {
			if (variable instanceof SharedVariableIF
					&& shared.contains((SharedVariableIF) variable)) {
				isLocal = false;
				return;
			}
		}
		for (VariableIF variable : size.freeVariables()) {
			if (variable instanceof SharedVariableIF
					&& shared.contains((SharedVariableIF) variable)) {
				isLocal = false;
				return;
			}
		}
	}
}