ASTStructLiteral.java

package edu.udel.cis.vsl.tass.front.minimp.ast.expression;

import java.util.Vector;

import edu.udel.cis.vsl.tass.front.minimp.ast.type.ASTArrayType;
import edu.udel.cis.vsl.tass.front.minimp.ast.type.ASTStructType;
import edu.udel.cis.vsl.tass.front.minimp.ast.type.ASTTypeIF;
import edu.udel.cis.vsl.tass.model.IF.SyntaxException;

public class ASTStructLiteral extends ASTLiteralExpression {
	private ASTExpressionIF[] fieldValue;

	public ASTStructLiteral(ASTTypeIF type, ASTExpressionIF[] fieldValue) {
		super(type);
		this.fieldValue = new ASTExpressionIF[fieldValue.length];
		for (int i = 0; i < fieldValue.length; i++) {
			this.fieldValue[i] = fieldValue[i];
		}
	}

	public ASTStructLiteral(ASTTypeIF type) {
		super(type);
		this.fieldValue = new ASTExpressionIF[((ASTStructType) type)
				.numFieldTypes()];
	}

	public int numValues() {
		return this.fieldValue.length;
	}

	public ASTExpressionIF getFieldValue(int index) {
		return this.fieldValue[index];
	}

	public void setFieldValue(Integer[] index, ASTExpressionIF value)
			throws SyntaxException {
		ASTTypeIF fieldType = ((ASTStructType) (this.exprType))
				.getFieldType(index[0]);
		if (fieldType instanceof ASTArrayType
				|| fieldType instanceof ASTStructType) {
			Integer[] newIndices = new Integer[index.length - 1];
			for (int i = 1; i < index.length; i++) {
				newIndices[i - 1] = index[i];
			}
			// This is the first value for this array/struct literal at this
			// field index.
			if (this.fieldValue[index[0]] == null) {
				// Process array type field
				if (fieldType instanceof ASTArrayType) {
					Vector<Integer> dimensionList = new Vector<Integer>();
					ASTTypeIF temp = fieldType;
					while (temp instanceof ASTArrayType) {
						dimensionList
								.add(Integer
										.valueOf(((ASTIntegerLiteral) (((ASTArrayType) temp)
												.getLength())).getValue()));
						temp = ((ASTArrayType) temp).getBaseType();
					}
					Integer[] dimensions = new Integer[dimensionList.size()];
					dimensionList.toArray(dimensions);
					this.fieldValue[index[0]] = new ASTArrayLiteral(fieldType,
							dimensions);
					((ASTArrayLiteral) (this.fieldValue[index[0]])).setLiteral(
							newIndices, value);
				}
				// Process struct type field
				else {
					this.fieldValue[index[0]] = new ASTStructLiteral(fieldType);
					((ASTStructLiteral) (this.fieldValue[index[0]]))
							.setFieldValue(newIndices, value);
				}
			} else {
				if (fieldType instanceof ASTArrayType) {
					((ASTArrayLiteral) (this.fieldValue[index[0]])).setLiteral(
							newIndices, value);
				} else {
					((ASTStructLiteral) (this.fieldValue[index[0]]))
							.setFieldValue(newIndices, value);
				}
			}

		} else {
			if (index.length == 1) {
				if (fieldType.equals(value.getType())) {
					this.fieldValue[index[0]] = value;
				} else {
					throw new SyntaxException(value.getSource(),
							"Type inconsistency in struct literal: "
									+ fieldType + " and " + value.getType());
				}
			} else {
				throw new SyntaxException(value.getSource(),
						"Too many indices in struct literal, only 1 allowed instead of "
								+ index.length);
			}
		}
	}
}