LibstdioModelTransformer.java

package edu.udel.cis.vsl.tass.library.libstdio;

import edu.udel.cis.vsl.tass.config.CompareConfiguration;
import edu.udel.cis.vsl.tass.config.RunConfiguration;
import edu.udel.cis.vsl.tass.model.IF.AbstractFunctionIF;
import edu.udel.cis.vsl.tass.model.IF.FunctionIF;
import edu.udel.cis.vsl.tass.model.IF.ModelFactoryIF;
import edu.udel.cis.vsl.tass.model.IF.ModelIF;
import edu.udel.cis.vsl.tass.model.IF.ModelTransformerIF;
import edu.udel.cis.vsl.tass.model.IF.ProcessIF;
import edu.udel.cis.vsl.tass.model.IF.SyntaxException;
import edu.udel.cis.vsl.tass.model.IF.SystemFunctionIF;
import edu.udel.cis.vsl.tass.model.IF.scope.ScopeIF;
import edu.udel.cis.vsl.tass.model.IF.type.TypeIF;

/**
 * Modifies TASS model to accommodate library stdio, the standard I/O library.
 * 
 * Add the following abstract functions in the system level scope:
 * 
 * String STDIO_intToString(int n, String format);
 * 
 * String STDIO_realToString(real x, String format);
 * 
 * int STDIO_stringToInt(String s, String format);
 * 
 * real STDIO_stringToReal(String s, String format);
 * 
 * If in compare mode, add output variable STDIO_outputFiles.
 * 
 * For any process that uses stdio functions: adds process global variable
 * STDIO_files.
 * 
 * @author siegel
 * 
 */
public class LibstdioModelTransformer implements ModelTransformerIF {

	private ModelFactoryIF modelFactory;

	private RunConfiguration configuration;

	public LibstdioModelTransformer(ModelFactoryIF modelFactory) {
		this.modelFactory = modelFactory;
		this.configuration = modelFactory.configuration();
	}

	@Override
	public void transform(ModelIF model) throws SyntaxException {
		int libraryId = modelFactory.libraryId("stdio");
		int numProcs = model.numProcs();
		TypeIF fileType = modelFactory.getRecordType("STDIO_File");
		TypeIF fileVectorType = modelFactory.vectorType(fileType);
		TypeIF stringType = modelFactory
				.arrayType(modelFactory.characterType());
		TypeIF integerType = modelFactory.integerType();
		TypeIF realType = modelFactory.rationalType();
		AbstractFunctionIF intToString = modelFactory.newAbstractFunction(
				"STDIO_intToString", stringType, 2);
		AbstractFunctionIF realToString = modelFactory.newAbstractFunction(
				"STDIO_realToString", stringType, 2);
		AbstractFunctionIF stringToInt = modelFactory.newAbstractFunction(
				"STDIO_stringToInt", integerType, 2);
		AbstractFunctionIF stringToReal = modelFactory.newAbstractFunction(
				"STDIO_stringToReal", realType, 2);

		configuration = modelFactory.configuration();
		assert libraryId >= 0;
		modelFactory.newFormalVariable(intToString, integerType, "n", 0);
		modelFactory.newFormalVariable(intToString, stringType, "format", 1);
		modelFactory.newFormalVariable(realToString, realType, "x", 0);
		modelFactory.newFormalVariable(realToString, stringType, "format", 1);
		modelFactory.newFormalVariable(stringToInt, stringType, "s", 0);
		modelFactory.newFormalVariable(stringToInt, stringType, "format", 1);
		modelFactory.newFormalVariable(stringToReal, stringType, "s", 0);
		modelFactory.newFormalVariable(stringToReal, stringType, "format", 1);
		if (configuration instanceof CompareConfiguration)
			model.newOutputVariable(fileVectorType, "STDIO_outputFiles");
		for (int i = 0; i < numProcs; i++) {
			ProcessIF process = model.process(i);
			ScopeIF scope = process.scope();
			boolean include = false;

			for (FunctionIF function : scope.functions()) {
				if (function instanceof SystemFunctionIF) {
					SystemFunctionIF systemFunction = (SystemFunctionIF) function;
					if (systemFunction.libraryId() == libraryId) {
						include = true;
						break;
					}
				}
			}
			if (include) {
				model.newVariable(process.scope(), fileVectorType,
						"STDIO_files");
			}
		}
	}

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

	public ModelFactoryIF modelFactory() {
		return modelFactory;
	}

}