Package org.rascalmpl.interpreter.result

Source Code of org.rascalmpl.interpreter.result.ListResult

/*******************************************************************************
* 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
*   * Tijs van der Storm - Tijs.van.der.Storm@cwi.nl
*   * Paul Klint - Paul.Klint@cwi.nl - CWI
*   * Mark Hills - Mark.Hills@cwi.nl (CWI)
*   * Arnold Lankamp - Arnold.Lankamp@cwi.nl
*******************************************************************************/
package org.rascalmpl.interpreter.result;

import static org.rascalmpl.interpreter.result.ResultFactory.bool;
import static org.rascalmpl.interpreter.result.ResultFactory.makeResult;

import org.eclipse.imp.pdb.facts.IBool;
import org.eclipse.imp.pdb.facts.IInteger;
import org.eclipse.imp.pdb.facts.IList;
import org.eclipse.imp.pdb.facts.IListWriter;
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.interpreter.IEvaluatorContext;
import org.rascalmpl.interpreter.staticErrors.UnexpectedType;
import org.rascalmpl.interpreter.staticErrors.UnsupportedSubscriptArity;
import org.rascalmpl.interpreter.utils.RuntimeExceptionFactory;

public class ListResult extends ListOrRelationResult<IList> {
 
  public ListResult(Type type, IList list, IEvaluatorContext ctx) {
    super(type, list, ctx);
  }
   
  @Override
  public <U extends IValue, V extends IValue> Result<U> add(Result<V> result) {
    return result.addList(this);
  }
 
  @Override
  public <U extends IValue, V extends IValue> Result<U> subtract(Result<V> result) {
    return result.subtractList(this);
  }
 
  @Override
  public <U extends IValue, V extends IValue> Result<U> join(Result<V> that) {
    return that.joinList(this);
  }
 
  @Override
  public <U extends IValue, V extends IValue> Result<U> intersect(Result<V> result) {
    return result.intersectList(this);
  }

  @Override
  public <U extends IValue, V extends IValue> Result<U> multiply(Result<V> result) {
    return result.multiplyList(this);
  }
 
  @Override
  public <V extends IValue> Result<IBool> in(Result<V> result) {
    return result.inList(this);
 
 
  @Override
  public <V extends IValue> Result<IBool> notIn(Result<V> result) {
    return result.notInList(this);
 
 
  @Override
  public <V extends IValue> Result<IBool> equals(Result<V> that) {
    return that.equalToList(this);
  }

  @Override
  public <V extends IValue> Result<IBool> nonEquals(Result<V> that) {
    return that.nonEqualToList(this);
  }
 
  @Override
  public <V extends IValue> Result<IBool> lessThan(Result<V> that) {
    return that.lessThanList(this);
  }
 
  @Override
  public <V extends IValue> LessThanOrEqualResult lessThanOrEqual(Result<V> that) {
    return that.lessThanOrEqualList(this);
  }

  @Override
  public <V extends IValue> Result<IBool> greaterThan(Result<V> that) {
    return that.greaterThanList(this);
  }
 
  @Override
  public <V extends IValue> Result<IBool> greaterThanOrEqual(Result<V> that) {
    return that.greaterThanOrEqualList(this);
  }


  @Override
  @SuppressWarnings("unchecked")
  public <U extends IValue, V extends IValue> Result<U> subscript(Result<?>[] subscripts) {
    if (subscripts.length != 1) {
      throw new UnsupportedSubscriptArity(getType(), subscripts.length, ctx.getCurrentAST());
    }
    Result<IValue> key = (Result<IValue>) subscripts[0];
    if (!key.getType().isInteger()) {
      throw new UnexpectedType(TypeFactory.getInstance().integerType(), key.getType(), ctx.getCurrentAST());
    }
    if (getValue().length() == 0) {
      throw RuntimeExceptionFactory.emptyList(ctx.getCurrentAST(), ctx.getStackTrace());
    }
    IInteger index = ((IInteger)key.getValue());
   
    int idx = index.intValue();
    if(idx < 0){
      idx = idx + getValue().length();
    }
    if ( (idx >= getValue().length()) || (idx < 0) ) {
      throw RuntimeExceptionFactory.indexOutOfBounds(index, ctx.getCurrentAST(), ctx.getStackTrace());
    }
    return makeResult(getType().getElementType(), getValue().get(idx), ctx);
  }
 
  /////
 
  @Override
  protected <U extends IValue> Result<U> addList(ListResult l) {
    // Note the reverse concat
    return makeResult(getType().lub(l.getType()), l.getValue().concat(getValue()), ctx);
  }

  @Override
  protected <U extends IValue> Result<U> subtractList(ListResult l) {
    // Note the reversal of args
    IList list = l.getValue();
    for (IValue v: getValue()) {
      if (list.contains(v)) {
        list = list.delete(v);
      }
    }
    return makeResult(l.getType(), list, ctx);
  }

  @Override
  protected <U extends IValue> Result<U> multiplyList(ListResult that) {
    Type t1 = that.type.getElementType();
    Type t2 = type.getElementType();
    // Note: reverse
    Type type = getTypeFactory().listType(getTypeFactory().tupleType(t1, t2));
    IListWriter w = this.getValueFactory().listWriter();
    for (IValue v1 : that.getValue()) {
      for (IValue v2 : getValue()) {
        w.append(getValueFactory().tuple(v1, v2))
      }
    }
    return makeResult(type, w.done(), ctx)
  }
 
  @Override
  protected <U extends IValue> Result<U> intersectList(ListResult that) {
    // Note the reversal of args
    IListWriter w = this.getValueFactory().listWriter();
    Type type = getType().lub(that.getType());
    for(IValue v : that.getValue())
      if(getValue().contains(v))
        w.append(v);
    return makeResult(type, w.done(), ctx);
  }
 
  <U extends IValue, V extends IValue> Result<U> appendElement(ElementResult<V> that) {
    // this is called by addLists in element types.
    Type newType = getTypeFactory().listType(that.getType().lub(getType().getElementType()));
    return makeResult(newType, value.append(that.getValue()), ctx);
  }

  protected <U extends IValue, V extends IValue> Result<U> removeElement(ElementResult<V> value) {
    IList list = getValue();
    return makeResult(getType(), list.delete(value.getValue()), ctx);
  }

  protected <V extends IValue> Result<IBool> elementOf(ElementResult<V> elementResult) {
    return bool((getValue().contains(elementResult.getValue())), ctx);
  }

  protected <V extends IValue> Result<IBool> notElementOf(ElementResult<V> elementResult) {
    return bool((!getValue().contains(elementResult.getValue())), ctx);
  }
 
  @Override
  protected Result<IBool> equalToList(ListResult that) {
    return that.equalityBoolean(this);
  }
 
  @Override
  protected Result<IBool> nonEqualToList(ListResult that) {
    return that.nonEqualityBoolean(this);
  }
 
  @Override
  protected Result<IBool> nonEqualToListRelation(ListRelationResult that) {
    return that.nonEqualityBoolean(this);
  }
 
  @Override
  protected Result<IBool> greaterThanList(ListResult that) {
    return that.lessThanList(this);
  }
 
  @Override
  protected Result<IBool> greaterThanOrEqualList(ListResult that) {
    return that.lessThanOrEqualList(this);
  }
 
  @Override
  protected Result<IBool> lessThanList(ListResult that) {
    IList val = that.getValue();
   
    if (val.length() > value.length()) {
      return bool(false, ctx);
    }
   
    OUTER:for (int iThat = 0, iThis = 0; iThat < val.length(); iThat++) {
      for (iThis = Math.max(iThis, iThat) ; iThis < value.length(); iThis++) {
        if (val.get(iThat).isEqual(value.get(iThis))) {
          iThis++;
          continue OUTER;
        }
      }
      return bool(false, ctx);
    }

    return bool(val.length() != value.length(), ctx);
  }
 
  @Override
  protected LessThanOrEqualResult lessThanOrEqualList(ListResult that) {
    IList left = that.getValue();
    IList right = getValue();
   
    if (left.length() == 0) {
      return new LessThanOrEqualResult(right.length() > 0, right.length() == 0, ctx);
    }
    else if (left.length() > right.length()) {
      return new LessThanOrEqualResult(false, false, ctx);
    }
   
    OUTER:for (int iThat = 0, iThis = 0; iThat < left.length(); iThat++) {
      for (iThis = Math.max(iThis, iThat) ; iThis < right.length(); iThis++) {
        if (left.get(iThat).isEqual(right.get(iThis))) {
          continue OUTER;
        }
      }
      return new LessThanOrEqualResult(false, false, ctx);
    }
   
    return new LessThanOrEqualResult(left.length() < right.length(), left.length() == right.length(), ctx);
  }
 
  @Override
  protected <U extends IValue> Result<U> joinListRelation(ListRelationResult that) {
    // Note the reverse of arguments, we need "that join this"
    int arity1 = that.getValue().asRelation().arity();
    Type eltType = getType().getElementType();
    Type tupleType = that.getType().getElementType();
    Type fieldTypes[] = new Type[arity1 + 1];
    for (int i = 0;  i < arity1; i++) {
      fieldTypes[i] = tupleType.getFieldType(i);
    }
    fieldTypes[arity1] = eltType;
    Type resultTupleType = getTypeFactory().tupleType(fieldTypes);
    IListWriter writer = getValueFactory().listWriter();
    IValue fieldValues[] = new IValue[arity1 + 1];
    for (IValue relValue: that.getValue()) {
      for (IValue setValue: this.getValue()) {
        for (int i = 0; i < arity1; i++) {
          fieldValues[i] = ((ITuple)relValue).get(i);
        }
        fieldValues[arity1] = setValue;
        writer.append(getValueFactory().tuple(fieldValues));
      }
    }
    Type resultType = getTypeFactory().lrelTypeFromTuple(resultTupleType);
    return makeResult(resultType, writer.done(), ctx);
  }

  @Override
  protected <U extends IValue> Result<U> joinList(ListResult that) {
    // Note the reverse of arguments, we need "that join this"
    // join between sets degenerates to product
    Type tupleType = getTypeFactory().tupleType(that.getType().getElementType(),
        getType().getElementType());
    return makeResult(getTypeFactory().lrelTypeFromTuple(tupleType),
        that.getValue().product(getValue()), ctx);
  }
 
}
TOP

Related Classes of org.rascalmpl.interpreter.result.ListResult

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.