Package org.rascalmpl.interpreter.matching

Source Code of org.rascalmpl.interpreter.matching.TuplePattern

/*******************************************************************************
* 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)
*   * Mark Hills - Mark.Hills@cwi.nl (CWI)
*   * Arnold Lankamp - Arnold.Lankamp@cwi.nl
*******************************************************************************/
package org.rascalmpl.interpreter.matching;

import java.util.HashMap;
import java.util.List;

import org.eclipse.imp.pdb.facts.ITuple;
import org.eclipse.imp.pdb.facts.IValue;
import org.eclipse.imp.pdb.facts.type.Type;
import org.eclipse.imp.pdb.facts.type.TypeFactory;
import org.rascalmpl.ast.Expression;
import org.rascalmpl.interpreter.IEvaluatorContext;
import org.rascalmpl.interpreter.env.Environment;
import org.rascalmpl.interpreter.result.Result;
import org.rascalmpl.interpreter.result.ResultFactory;

public class TuplePattern extends AbstractMatchingResult {
  private List<IMatchingResult> children;
  private ITuple treeSubject;
  private final TypeFactory tf = TypeFactory.getInstance();
  private int nextChild;
  private Type type;
 
  public TuplePattern(IEvaluatorContext ctx, Expression x, List<IMatchingResult> list){
    super(ctx, x);
   
    this.children = list;
  }
 
  @Override
  public void initMatch(Result<IValue> subject){
    super.initMatch(subject);
    hasNext = false;
   
    if (!subject.getValue().getType().isTuple()) {
      return;
    }
    treeSubject = (ITuple) subject.getValue();

    if (treeSubject.arity() != children.size()){
      return;
    }
   
    hasNext = true;
   
    for (int i = 0; i < children.size(); i += 1){
      IValue childValue = treeSubject.get(i);
      IMatchingResult child = children.get(i);
      child.initMatch(ResultFactory.makeResult(childValue.getType(), childValue, ctx));
      hasNext = child.hasNext();
      if (!hasNext) {
        break; // saves time!
      }
    }
   
    nextChild = 0;
  }
 
  @Override
  public Type getType(Environment env, HashMap<String,IVarPattern> patternVars) {
    if (type == null) {
      Type fieldTypes[] = new Type[children.size()];
      for(int i = 0; i < children.size(); i++){
        fieldTypes[i] = children.get(i).getType(env, patternVars);
        patternVars = merge(patternVars, children.get(i).getVariables());
      }
      type = tf.tupleType(fieldTypes);
    }
    return type;
  }
 
  @Override
  public List<IVarPattern> getVariables(){
    java.util.LinkedList<IVarPattern> res = new java.util.LinkedList<IVarPattern> ();
    for (int i = 0; i < children.size(); i += 1) {
      res.addAll(children.get(i).getVariables());
    }
    return res;
  }
 
  @Override
  public boolean next(){
    checkInitialized();

    if (!hasNext) {
      return false;
    }

    if (children.size() == 0) {
      hasNext = false;
      return true;
    }
   
    while (nextChild >= 0) {
      IMatchingResult nextPattern = children.get(nextChild);

      if (nextPattern.hasNext() && nextPattern.next()) {
        if (nextChild == children.size() - 1) {
          // We need to make sure if there are no
          // more possible matches for any of the tuple's fields,
          // then the next call to hasNext() will definitely returns false.
          hasNext = false;
          for (int i = nextChild; i >= 0; i--) {
            hasNext |= children.get(i).hasNext();
          }
          return true;
        }
       
        nextChild++;
      }
      else {
        nextChild--;

        if (nextChild >= 0) {
          for (int i = nextChild + 1; i < children.size(); i++) {
            IValue childValue = treeSubject.get(i);
            IMatchingResult tailChild = children.get(i);
            tailChild.initMatch(ResultFactory.makeResult(childValue.getType(), childValue, ctx));
          }
        }
      }
    }
      hasNext = false;
      return false;
  }
 
  public List<IMatchingResult> getChildren(){
    return children;
  }
 
  @Override
  public String toString(){
    StringBuilder res = new StringBuilder();
    res.append("<");
    String sep = "";
    for (IBooleanResult mp : children){
      res.append(sep);
      sep = ", ";
      res.append(mp.toString());
    }
    res.append(">");
   
    return res.toString();
  }
}
TOP

Related Classes of org.rascalmpl.interpreter.matching.TuplePattern

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.