StartOfFinder.java

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

import edu.udel.cis.vsl.tass.ast.IF.ASTFactoryIF;
import edu.udel.cis.vsl.tass.ast.IF.ASTNodeIF;
import edu.udel.cis.vsl.tass.ast.IF.ASTTransformerIF;
import edu.udel.cis.vsl.tass.ast.IF.AbstractSyntaxTreeIF;
import edu.udel.cis.vsl.tass.ast.IF.expression.OperatorNodeIF;
import edu.udel.cis.vsl.tass.ast.IF.expression.VariableReferenceNodeIF;
import edu.udel.cis.vsl.tass.ast.IF.type.ArrayTypeNodeIF;
import edu.udel.cis.vsl.tass.model.IF.SyntaxException;

/**
 * This class finds instances where arrays are referenced without a subscript
 * expression and replaces each reference with a StartOfNodeIF.
 * 
 * @author Timothy Zirkel (zirkel)
 * 
 */
public class StartOfFinder implements ASTTransformerIF {

	ASTFactoryIF factory;
	
	@Override
	public void transform(AbstractSyntaxTreeIF ast) throws SyntaxException {
		factory = ast.factory();
		traverse(ast.rootNode());
	}

	/**
	 * This method recursively traverses the AST and checks whether each node is
	 * an operator that might have an array reference that needs to be replaced
	 * with a StartOfNode. If it is, the expression is checked and the
	 * StartOfNode inserted if necessary.
	 */
	private void traverse(ASTNodeIF node) {
		if (node instanceof OperatorNodeIF) {
			checkAndFix((OperatorNodeIF) node);
		}
		for (int i = 0; i < node.numChildren(); i++) {
			if (node.child(i) != null) {
				traverse(node.child(i));
			}
		}
	}

	/**
	 * Takes an operator node, checks if any of the operands are references to
	 * arrays, and replaces each such reference with a StartOfNode.
	 */
	private void checkAndFix(OperatorNodeIF node) {
		for (int i = 0; i < node.numChildren(); i++) {
			if (node.getArgument(i) instanceof VariableReferenceNodeIF
					&& ((VariableReferenceNodeIF) node.getArgument(i))
							.referent().type() instanceof ArrayTypeNodeIF) {
				node.setArgument(i, factory
						.startOfNode((VariableReferenceNodeIF) node
								.getArgument(i)));
			}
		}
	}

	@Override
	public String name() {
		return "StartOfFinder";
	}

}