isBindingVar[i] = false;
Environment env = ctx.getCurrentEnvt();
if (child instanceof TypedMultiVariablePattern) {
TypedMultiVariablePattern tmvVar = (TypedMultiVariablePattern) child;
Type tmvType = tmvVar.getType(env, null);
String name = tmvVar.getName();
varName[i] = name;
isListVar[i] = true;
listVarOccurrences[i] = 1;
++nListVar;
if(!tmvVar.isAnonymous() && allVars.contains(name)) {
throw new RedeclaredVariable(name, getAST());
} else if(tmvType.comparable(listSubject.getType().getElementType())
|| (tmvVar.bindingInstance() && tmvType.comparable(listSubject.getType()))) {
tmvVar.convertToListType();
if (!tmvVar.isAnonymous()) {
allVars.add(name);
}
isBindingVar[i] = true;
} else {
hasNext = false;
return;
}
}
else if(child instanceof MultiVariablePattern){
MultiVariablePattern multiVar = (MultiVariablePattern) child;
String name = multiVar.getName();
varName[i] = name;
isListVar[i] = true;
nListVar++;
if(!multiVar.isAnonymous() && allVars.contains(name)){
isBindingVar[i] = false;
} else if(multiVar.isAnonymous()){
isBindingVar[i] = true;
} else {
allVars.add(name);
Result<IValue> varRes = env.getVariable(name);
if (varRes == null || multiVar.bindingInstance()) {
isBindingVar[i] = true;
} else {
isBindingVar[i] = false;
Type varType = varRes.getType();
if (isAnyListType(varType)){
if (!varType.comparable(listSubjectType)) {
hasNext = false;
return;
}
} else {
if(!(varType instanceof NonTerminalType) && !(varType.comparable(staticListSubjectElementType))) {
hasNext = false;
return;
}
}
}
}
}
else if (child instanceof ConcreteListVariablePattern) {
ConcreteListVariablePattern listVar = (ConcreteListVariablePattern) child;
String name = listVar.getName();
varName[i] = name;
isListVar[i] = true;
if (!listVar.isAnonymous()) {
allVars.add(name);
}
plusList[i] = listVar.isPlusList();
isBindingVar[i] = true;
listVarOccurrences[i] = 1;
nListVar++;
}
else if(child instanceof QualifiedNamePattern){
QualifiedNamePattern qualName = (QualifiedNamePattern) child;
String name = qualName.getName();
varName[i] = name;
if(!qualName.isAnonymous() && allVars.contains(name)){
/*
* A variable that was declared earlier in the pattern
*/
isListVar[i] = true;
nListVar++;
listVarOccurrences[i]++;
} else if(qualName.isAnonymous()){
/*
* Nothing to do
*/
} else {
Result<IValue> varRes = env.getVariable(name);
if(varRes == null || qualName.bindingInstance()){
// A completely new non-list variable, nothing to do
} else {
Type varType = varRes.getType();
if (isAnyListType(varType)){
/*
* A variable declared in the current scope.
*/
if(varType.comparable(listSubjectType)){
isListVar[i] = true;
isBindingVar[i] = varRes.getValue() == null;
nListVar++;
} else {
hasNext = false;
return;
}
} else {
if(varType instanceof NonTerminalType){
// suppress comparable test for Nonterminal types
// TODO: this should be done better
} else
if(!varType.comparable(staticListSubjectElementType)){
hasNext = false;
return;
}
}
}
}
}
else if(child instanceof VariableBecomesPattern){
// Nothing to do
}
else {
if (debug) {
System.err.println("List: child " + child);
System.err.println("List: child is a" + child.getClass());
}
Type childType = child.getType(env, null);
// TODO: pattern matching should be specialized such that matching appl(prod...)'s does not
// need to use list matching on the fixed arity children of the application of a production
if(!(childType instanceof NonTerminalType) && !childType.comparable(staticListSubjectElementType)){
hasNext = false;
return;
}
java.util.List<IVarPattern> childVars = child.getVariables();
if(!childVars.isEmpty()){