/*******************************************************************************
* Copyright (c) 2009-2013 CWI
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* * Jurgen J. Vinju - Jurgen.Vinju@cwi.nl - CWI
* * Emilie Balland - (CWI)
* * Paul Klint - Paul.Klint@cwi.nl - CWI
* * Mark Hills - Mark.Hills@cwi.nl (CWI)
* * Arnold Lankamp - Arnold.Lankamp@cwi.nl
*******************************************************************************/
package org.rascalmpl.interpreter.matching;
import java.util.Iterator;
import org.rascalmpl.ast.Expression;
import org.rascalmpl.interpreter.IEvaluatorContext;
import org.rascalmpl.interpreter.result.Result;
import org.rascalmpl.interpreter.result.ResultFactory;
import org.rascalmpl.value.IValue;
import org.rascalmpl.value.type.Type;
public class EnumeratorResult extends BasicBooleanResult {
private IMatchingResult pat;
private Iterator<?> iterator;
private Expression expression;
private Type elementType;
private boolean firstTime; // TODO: can probably be removed.
/*
* Constructor for a standard enumerator
*/
public EnumeratorResult(IEvaluatorContext ctx, IMatchingResult matchPattern, Expression expression){
super(ctx, expression);
this.pat = matchPattern;
this.expression = expression;
}
@Override
public void init() {
firstTime = true;
}
@Override
public boolean hasNext(){
if (firstTime) {
hasNext = true;
return true;
}
if (hasNext) {
boolean hn = pat.hasNext() || iterator.hasNext();
if(!hn){
hasNext = false;
}
return hn;
}
return false;
}
@Override
public boolean next() {
if (firstTime) {
firstTime = false;
Result<IValue> result = expression.interpret(ctx.getEvaluator());
elementType = IteratorFactory.elementType(ctx, result);
iterator = IteratorFactory.make(ctx, pat, result, true);
}
/*
* First, explore alternatives that remain to be matched by the current pattern
*/
while (pat.hasNext()){
if(pat.next()){
return true;
}
}
/*
* Next, fetch a new data element (if any) and create a new pattern.
*/
while (iterator.hasNext()){
IValue v = (IValue) iterator.next();
pat.initMatch(ResultFactory.makeResult(elementType, v, ctx));
while(pat.hasNext()){
if(pat.next()){
return true;
}
}
}
hasNext = false;
return false;
}
}