ReceiveStatement.java

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

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.expression.UnaryExpressionIF;
import edu.udel.cis.vsl.tass.model.IF.location.ReceiveLocationIF;
import edu.udel.cis.vsl.tass.model.IF.statement.ReceiveStatementIF;
import edu.udel.cis.vsl.tass.model.IF.type.TypeIF.TypeKind;

public class ReceiveStatement extends Statement implements ReceiveStatementIF {

	private LHSExpressionIF buffer;

	private ExpressionIF source;

	private ExpressionIF tag;

	/**
	 * Variable (or other LHS expression) into which to store the size of the
	 * message, when a message is received. This is optional, so could be null.
	 */
	private LHSExpressionIF size;

	public ReceiveStatement(ModelFactoryIF factory,
			ReceiveLocationIF sourceLocation, LHSExpressionIF buffer,
			ExpressionIF source, ExpressionIF tag, LHSExpressionIF size)
			throws SyntaxException {
		super(factory, factory.notEmptyExpression(sourceLocation.model(),
				source, factory.integerLiteralExpression(sourceLocation
						.process().pid()), tag), sourceLocation,
				StatementKind.RECEIVE);
		if (source.type().kind() != TypeKind.INTEGER)
			throw new SyntaxException(source,
					"Source argument should be integer type, not "
							+ source.type());
		if (tag.type().kind() != TypeKind.INTEGER)
			throw new SyntaxException(tag,
					"Tag argument should be integer type, not " + tag.type());
		factory.checkScope(buffer, sourceLocation.scope());
		if (tag.kind() == ExpressionIF.ExpressionKind.ANY) {
			ExpressionIF tagCore = ((UnaryExpressionIF) tag).expression();

			if (!(tagCore instanceof LHSExpressionIF))
				throw new SyntaxException(tag,
						"Argument to any not left-hand side expression");
			factory.checkScope(tagCore, sourceLocation.scope());
		} else {
			factory.checkScope(tag, sourceLocation.scope());
		}
		if (source.kind() == ExpressionIF.ExpressionKind.ANY) {
			throw new SyntaxException(source,
					"Source expression for receive cannot use \"any\"");
		} else {
			factory.checkScope(source, sourceLocation.scope());
		}
		this.buffer = buffer;
		this.tag = tag;
		this.source = source;
		this.size = size;
	}

	public ReceiveStatement(ModelFactoryIF factory,
			ReceiveLocationIF sourceLocation, LHSExpressionIF buffer,
			ExpressionIF source, ExpressionIF tag) throws SyntaxException {
		this(factory, sourceLocation, buffer, source, tag, null);
	}

	public LHSExpressionIF buffer() {
		return buffer;
	}

	public ExpressionIF tag() {
		return tag;
	}

	public ExpressionIF source() {
		return source;
	}

	public String toString() {
		String result = "recv(" + buffer + "," + source + "," + tag;

		if (size != null)
			result += ", " + size;
		result += ");";
		return result;
	}

	public void complete() throws SyntaxException {
		super.complete();
		isLocal = false;
	}

	@Override
	public LHSExpressionIF size() {
		return size;
	}
}