staticSetSubjectType = subject.getType();
setSubjectElementType = setSubject.getElementType();
staticSubjectElementType = staticSetSubjectType.isSet() ? staticSetSubjectType.getElementType() : tf.valueType();
if(debug)System.err.println("setSubjectType = " + setSubjectType + ", staticSetSubjectType = " + staticSetSubjectType + ", setSubjectElementType = " + setSubjectElementType + ", staticSubjectElementType =" + staticSubjectElementType);
Environment env = ctx.getCurrentEnvt();
//fixedSetElements = ctx.getValueFactory().set(getType(env).getElementType());
fixedSetElements = ctx.getValueFactory().set(setSubjectElementType);
nVar = 0;
patVars = new HashSet<String>();
allVars = new HashMap<String, IVarPattern>();
varName = new String[patternSize]; // Some overestimations
isSetVar = new boolean[patternSize];
isBinding = new boolean[patternSize];
isNested = new boolean[patternSize];
varVal = new IValue[patternSize];
varPat = new IMatchingResult[patternSize];
varGen = new Iterator<?>[patternSize];
/*
* Pass #1: determine the (ordinary and set) variables in the pattern
*/
for(int i = 0; i < patternSize; i++){
IMatchingResult child = patternChildren.get(i);
if(debug)System.err.println("child = " + child);
if (child instanceof TypedMultiVariablePattern) {
TypedMultiVariablePattern tmvVar = (TypedMultiVariablePattern) child;
Type childType = child.getType(env, null);
String name = tmvVar.getName();
if (!tmvVar.isAnonymous() && allVars.containsKey(name)) {
throw new RedeclaredVariable(name, getAST());
}
if(childType.comparable(staticSubjectElementType)
|| (tmvVar.bindingInstance() && childType.comparable(staticSetSubjectType))) {
tmvVar.covertToSetType();
if (!tmvVar.isAnonymous()) {
patVars.add(name);
allVars.put(name, (IVarPattern)child);
}
varName[nVar] = name;
varPat[nVar] = child;
isSetVar[nVar] = true;
isBinding[nVar] = true;
isNested[nVar] = false;
++nVar;
} else {
hasNext = false;
return;
}
} else if(child instanceof TypedVariablePattern){
TypedVariablePattern patVar = (TypedVariablePattern) child;
Type childType = child.getType(env, null);
String name = ((TypedVariablePattern)child).getName();
if(!patVar.isAnonymous() && allVars.containsKey(name)){
throw new RedeclaredVariable(name, getAST());
}
if(childType.comparable(staticSubjectElementType)){
/*
* An explicitly declared set or element variable.
*/
if(!patVar.isAnonymous()){
patVars.add(name);
allVars.put(name, (IVarPattern)child);
}
varName[nVar] = name;
varPat[nVar] = child;
isSetVar[nVar] = false;
isBinding[nVar] = true;
isNested[nVar] = false;
nVar++;
} else {
hasNext = false;
return;
// We would like to throw new UnexpectedType(setSubject.getType(), childType, getAST());
// but we can't do this in the context of a visit, because we might actually visit another set!
}
} else if(child instanceof MultiVariablePattern){
/*
* Explicitly declared set variable
*/
MultiVariablePattern multiVar = (MultiVariablePattern) child;
String name = multiVar.getName();
varName[nVar] = name;
varPat[nVar] = child;
isSetVar[nVar] = true;
isBinding[nVar] = true;
isNested[nVar] = false;
nVar++;
} else if(child instanceof QualifiedNamePattern){
/*
* Use of a variable
*/
QualifiedNamePattern qualName = (QualifiedNamePattern) child;
String name = qualName.getName();
if (!qualName.isAnonymous() && allVars.containsKey(name)) {
/*
* A set/element variable that was declared earlier in the pattern itself,
* or in a preceding nested pattern element.
*/
if(!patVars.contains(name)){
/*
* It occurred in an earlier nested subpattern.
*/
varName[nVar] = name;
varPat[nVar] = child;
// If is was declared as set in the current pattern then we are sure it is a set variable,
// otherwise we assume for now that it is not but we check this again later in matchVar.
isSetVar[nVar] = declaredAsSetVar(name);
isBinding[nVar] = false;
isNested[nVar] = false;
nVar++;
} else {
/*
* Ignore it (we are dealing with sets, remember).
*/
}
} else if(qualName.isAnonymous()){
varName[nVar] = name;
varPat[nVar] = child;
isSetVar[nVar] = false;
isBinding[nVar] = false;
isNested[nVar] = false;
nVar++;
} else {
/*
* A non-anonymous variable, not seen before.
*/
if(debug)System.err.println("Non-anonymous var, not seen before: " + name);
Result<IValue> varRes = env.getVariable(name);
if(varRes == null || qualName.bindingInstance()){
// Completely new variable that was not yet declared in this pattern or its subpatterns
varName[nVar] = name;
varPat[nVar] = child;