package org.reuseware.air.coconut;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.reuseware.air.util.FileProcessingProblem;
/**
* The singleton composition language interpreter system
*
* @author Jendrik Johannes
*/
public class InterpreterSystem {
private InterpreterSystem() { }
private static class SingletonHolder {
private final static InterpreterSystem instance = new InterpreterSystem();
}
public static InterpreterSystem getInstance() {
return SingletonHolder.instance;
}
/**
* Starts the interpretation process of a fragment AST.
*
* @param fragment AST root
* @param env
* @param envTypes
* @param problems
* @throws CoreException
*/
public void interpret(EObject startingNode, Map<String, List<EObject>> env,
Map<String, EClass> envTypes, List<FileProcessingProblem> problems) throws CoreException {
if (startingNode == null)
throw new IllegalArgumentException();
// get interpreter module for root type
IUpperLevelInterpreter interpreter = InterpreterRegistry.getInstance().getInterpreterModule(startingNode.eClass());
initialiseComposers();
// traverse fragment AST
traverseChildren(startingNode, env, envTypes, problems);
if (interpreter != null) {
interpreter.interpret(startingNode, env, envTypes, problems);
}
}
private void initialiseComposers() throws CoreException{
Map<EClass, IComplexOperator> operators = ComposerRegistry.getInstance().getComplexOperatorMap();
Set<IComplexOperator> initialised = new HashSet<IComplexOperator>();
for (Iterator<IComplexOperator> i = operators.values().iterator(); i.hasNext(); ) {
IComplexOperator operator = i.next();
if(!initialised.contains(operator)){
operator.initialize();
initialised.add(operator);
}
}
}
/**
*
*
* @param fragment
* @param env
* @param envTypes
* @param problems
* @throws CoreException
*/
private void traverseChildren(EObject fragment, Map<String, List<EObject>> env,
Map<String, EClass> envTypes, List<FileProcessingProblem> problems) throws CoreException {
//collection of fragments already interpreted
Set<EObject> interpretedFragments = new HashSet<EObject>();
// rerun after interpretation (AST might have changed)
boolean rerun = true;
while (rerun) {
rerun = false;
for (Iterator<EObject> i = fragment.eContents().iterator(); i.hasNext(); ) {
EObject f = (EObject) i.next();
if (interpretedFragments.contains(f)) {
rerun = false;
break;
}
// get interpreter
IUpperLevelInterpreter interpreter = InterpreterRegistry.getInstance().getInterpreterModule(f.eClass());
traverseChildren(f, env, envTypes, problems);
if (interpreter != null) {
interpreter.interpret(f, env, envTypes, problems);
interpretedFragments.add(f);
rerun = true;
break;
}
}
}
}
}