Package org.rascalmpl.interpreter.result

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

/*******************************************************************************
  * 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
*   * 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 java.util.Iterator;
import java.util.Map.Entry;

import org.eclipse.imp.pdb.facts.IBool;
import org.eclipse.imp.pdb.facts.IInteger;
import org.eclipse.imp.pdb.facts.IMap;
import org.eclipse.imp.pdb.facts.IMapWriter;
import org.eclipse.imp.pdb.facts.ISetWriter;
import org.eclipse.imp.pdb.facts.IValue;
import org.eclipse.imp.pdb.facts.exceptions.UndeclaredFieldException;
import org.eclipse.imp.pdb.facts.type.Type;
import org.eclipse.imp.pdb.facts.type.TypeStore;
import org.rascalmpl.ast.Field;
import org.rascalmpl.interpreter.IEvaluatorContext;
import org.rascalmpl.interpreter.staticErrors.UndeclaredField;
import org.rascalmpl.interpreter.staticErrors.UnexpectedType;
import org.rascalmpl.interpreter.staticErrors.UnsupportedOperation;
import org.rascalmpl.interpreter.staticErrors.UnsupportedSubscriptArity;
import org.rascalmpl.interpreter.utils.RuntimeExceptionFactory;
import org.rascalmpl.values.ValueFactoryFactory;

public class MapResult extends ElementResult<IMap> {
 
  public MapResult(Type type, IMap map, IEvaluatorContext ctx) {
    super(type, map, ctx);
  }
 
  @Override
  public <U extends IValue, V extends IValue> Result<U> add(Result<V> result) {
    return result.addMap(this);
   
  }

  @Override
  public <U extends IValue, V extends IValue> Result<U> subtract(Result<V> result) {
    return result.subtractMap(this);
   
  }
 

  @Override
  public <U extends IValue, V extends IValue> Result<U> intersect(Result<V> result) {
    return result.intersectMap(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 (!getType().getKeyType().comparable(key.getType())) {
      throw new UnexpectedType(getType().getKeyType(), key.getType(), ctx.getCurrentAST());
    }
    IValue v = getValue().get(key.getValue());
    if (v == null){
      throw RuntimeExceptionFactory.noSuchKey(key.getValue(), ctx.getCurrentAST(), ctx.getStackTrace());
    }
    return makeResult(getType().getValueType(), v, ctx);
  }
 
  @Override
  public <V extends IValue> Result<IBool> equals(Result<V> that) {
    return that.equalToMap(this);
  }

  @Override
  public <U extends IValue> Result<U> fieldAccess(String name, TypeStore store) {
    if (name.equals(type.getKeyLabel())) {
      ISetWriter w = getValueFactory().setWriter();
      w.insertAll(value);
      return makeResult(getTypeFactory().setType(type.getKeyType()), w.done(), ctx);
    }
    else if (name.equals(type.getValueLabel())) {
      ISetWriter w = getValueFactory().setWriter();
      Iterator<IValue> it = value.valueIterator();
      while (it.hasNext()) {
        w.insert(it.next());
      }
      return makeResult(getTypeFactory().setType(type.getValueType()), w.done(), ctx);
    }

    throw new UndeclaredField(name, type, ctx.getCurrentAST());
  }
 
  @Override
  public <U extends IValue, V extends IValue> Result<U> fieldUpdate(
      String name, Result<V> repl, TypeStore store) {
    if(type.getKeyLabel() != null){
      if (type.getKeyLabel().equals(name)) {
        throw new UnsupportedOperation("You can not update the keys of a map using the field update operator", ctx.getCurrentAST());
      }
      else if (type.getValueLabel().equals(name)) {
        // interesting operation, sets the image of all keys to one default
        if (!repl.getType().isSubtypeOf(type.getValueType())) {
          throw new UnexpectedType(type.getValueType(), repl.getType(), ctx.getCurrentAST());
        }

        IMapWriter w = getValueFactory().mapWriter();

        for (IValue key : value) {
          w.put(key, repl.getValue());
        }

        return makeResult(type, w.done(), ctx);
      }
    }
   
    throw new UndeclaredFieldException(type, name);
  }
 
  @Override
  public <V extends IValue> Result<IBool> nonEquals(Result<V> that) {
    return that.nonEqualToMap(this);
  }

  @Override
  public <V extends IValue> Result<IBool> lessThan(Result<V> that) {
    return that.lessThanMap(this);
  }
 
  @Override
  public <V extends IValue> LessThanOrEqualResult lessThanOrEqual(Result<V> that) {
    return that.lessThanOrEqualMap(this);
  }

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

 
  @Override
  public <V extends IValue> Result<IBool> in(Result<V> result) {
    return result.inMap(this);
 
 
  @Override
  public <V extends IValue> Result<IBool> notIn(Result<V> result) {
    return result.notInMap(this);
 
 
  ////
 
  protected <V extends IValue> Result<IBool> elementOf(ElementResult<V> elementResult) {
    return bool(getValue().containsKey(elementResult.getValue()), ctx);
  }

  protected <V extends IValue> Result<IBool> notElementOf(ElementResult<V> elementResult) {
    return bool(!getValue().containsKey(elementResult.getValue()), ctx);
  }
 
  @Override
  protected <U extends IValue> Result<U> addMap(MapResult m) {
    // Note the reverse
    return makeResult(getType().lub(m.getType()), m.value.join(value), ctx);
  }
 
  @Override
  protected <U extends IValue> Result<U> addListRelation(ListRelationResult that) {
    return that.addMap(this);
  }
 
  @Override
  protected <U extends IValue> Result<U> subtractMap(MapResult m) {
    // Note the reverse
    return makeResult(m.getType(), m.getValue().remove(getValue()), ctx);
  }
 
  @Override
  protected <U extends IValue> Result<U> intersectMap(MapResult m) {
    // Note the reverse
    return makeResult(m.getType(), m.getValue().common(getValue()), ctx);
  }

 
  @Override
  protected Result<IBool> equalToMap(MapResult that) {
    return that.equalityBoolean(this);
  }
 
  @Override
  protected Result<IBool> nonEqualToMap(MapResult that) {
    return that.nonEqualityBoolean(this);
  }
 
  @Override
  protected Result<IBool> lessThanMap(MapResult that) {
    // note reversed args: we need that < this
    return bool(that.getValue().isSubMap(getValue()) && !that.getValue().isEqual(getValue()), ctx);
  }
 
  @Override
  protected LessThanOrEqualResult lessThanOrEqualMap(MapResult that) {
    boolean subMap = that.getValue().isSubMap(getValue());
    boolean equals = that.getValue().isEqual(getValue());
    return new LessThanOrEqualResult(subMap && !equals, equals, ctx);
  }

  @Override
  protected Result<IBool> greaterThanMap(MapResult that) {
    LessThanOrEqualResult loe = that.lessThanOrEqualMap(this);
    if (!loe.getEqual()) {
      return loe.isLess();
    }
    return bool(false, ctx);
  }
 
  @Override
  protected Result<IBool> greaterThanOrEqualMap(MapResult that) {
    return that.lessThanOrEqualMap(this);
  }
 
 
  @Override
  public <U extends IValue, V extends IValue> Result<U> compose(
      Result<V> right) {
    return right.composeMap(this);
  }
 
  @Override
  public <U extends IValue> Result<U> composeMap(MapResult left) {
    if (left.getType().getValueType().comparable(getType().getKeyType())) {   
      Type mapType = getTypeFactory().mapType(left.getType().getKeyType(), getType().getValueType());
      return ResultFactory.makeResult(mapType, left.getValue().compose(getValue()), ctx);
    }
   
    return undefinedError("composition", left);
  }
 
  @Override
  public Result<IValue> fieldSelect(int[] selectedFields) {
    ISetWriter w = getValueFactory().relationWriter();
   
    // TODO: poor mans implementation can be made much faster without intermediate relation building
    Iterator<Entry<IValue,IValue>> it = value.entryIterator();
    while (it.hasNext()) {
      Entry<IValue,IValue> entry = it.next();
      w.insert(getValueFactory().tuple(entry.getKey(), entry.getValue()));
    }
   
    return makeResult(getTypeFactory().setType(type.getFieldTypes()), w.done(), ctx).fieldSelect(selectedFields);
  }
 
  @Override
  public Result<IValue> fieldSelect(Field[] selectedFields) {
    int nFields = selectedFields.length;
    int fieldIndices[] = new int[nFields];
    Type baseType = this.getType();
   
    for (int i = 0; i < nFields; i++) {
      Field f = selectedFields[i];
      if (f.isIndex()) {
        fieldIndices[i] = ((IInteger) f.getFieldIndex()
            .interpret(this.ctx.getEvaluator()).getValue()).intValue();
      } else {
        String fieldName = org.rascalmpl.interpreter.utils.Names
            .name(f.getFieldName());
        try {
          fieldIndices[i] = baseType.getFieldIndex(fieldName);
        } catch (UndeclaredFieldException e) {
          throw new UndeclaredField(fieldName, baseType,
              ctx.getCurrentAST());
        }
      }

      if (fieldIndices[i] < 0 || fieldIndices[i] > 1) {
        throw org.rascalmpl.interpreter.utils.RuntimeExceptionFactory
            .indexOutOfBounds(ValueFactoryFactory.getValueFactory().integer(fieldIndices[i]),
                ctx.getCurrentAST(), ctx.getStackTrace());
      }
    }
   
    return this.fieldSelect(fieldIndices);
  }
 
}
TOP

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

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.