package org.overture.interpreter.assistant.pattern; import java.util.List; import java.util.Vector; import org.overture.ast.analysis.AnalysisException; import org.overture.ast.assistant.IAstAssistant; import org.overture.ast.intf.lex.ILexNameToken; import org.overture.ast.patterns.AIdentifierPattern; import org.overture.ast.patterns.PPattern; import org.overture.interpreter.assistant.IInterpreterAssistantFactory; import org.overture.interpreter.runtime.Context; import org.overture.interpreter.utilities.pattern.AllNamedValuesLocator; import org.overture.interpreter.values.NameValuePairList; import org.overture.interpreter.values.Value; import org.overture.typechecker.assistant.pattern.PPatternAssistantTC; public class PPatternAssistantInterpreter extends PPatternAssistantTC implements IAstAssistant { protected static IInterpreterAssistantFactory af; @SuppressWarnings("static-access") public PPatternAssistantInterpreter(IInterpreterAssistantFactory af) { super(af); this.af = af; } /** A value for getLength meaning "any length" */ public static int ANY = -1; public NameValuePairList getNamedValues(PPattern p, Value expval, Context ctxt) throws AnalysisException { List<AIdentifierPattern> ids = af.createPPatternAssistant().findIdentifiers(p); // Go through the list of IDs, marking duplicate names as constrained. This is // because we have to permute sets that contain duplicate variables, so that // we catch permutations that match constrained values of the variable from // elsewhere in the pattern. int count = ids.size(); for (int i = 0; i < count; i++) { ILexNameToken iname = ids.get(i).getName(); for (int j = i + 1; j < count; j++) { if (iname.equals(ids.get(j).getName())) { ids.get(i).setConstrained(true); ids.get(j).setConstrained(true); } } } List<NameValuePairList> all = getAllNamedValues(p, expval, ctxt); return all.get(0); // loose choice here! } public List<AIdentifierPattern> findIdentifiers(PPattern pattern) { try { return pattern.apply(af.getIdentifierPatternFinder());// FIXME: should we handle exceptions like this } catch (AnalysisException e) { return new Vector<AIdentifierPattern>(); // Most have none } } public List<NameValuePairList> getAllNamedValues(PPattern pattern, Value expval, Context ctxt) throws AnalysisException { return pattern.apply(af.getAllNamedValuesLocator(), new AllNamedValuesLocator.Newquestion(expval, ctxt)); } /** * @param pattern * @return The "length" of the pattern (eg. sequence and set patterns). */ public int getLength(PPattern pattern) { try { return pattern.apply(af.getLengthFinder());// FIXME: should we handle exceptions like this } catch (AnalysisException e) { return 1; // Most only identify one member } } /** * @param pattern * @return True if the pattern has constraints, such that matching values should be permuted, where necessary, to * find a match. */ public boolean isConstrained(PPattern pattern) { try { return pattern.apply(af.getConstrainedPatternChecker());// FIXME: should we handle exceptions like this } catch (AnalysisException e) { return true; } } }