Package org.rascalmpl.interpreter.result

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

/*******************************************************************************
* 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.makeResult;

import java.util.Map;

import org.eclipse.imp.pdb.facts.IBool;
import org.eclipse.imp.pdb.facts.IConstructor;
import org.eclipse.imp.pdb.facts.IInteger;
import org.eclipse.imp.pdb.facts.IListWriter;
import org.eclipse.imp.pdb.facts.INode;
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.Name;
import org.rascalmpl.interpreter.IEvaluatorContext;
import org.rascalmpl.interpreter.env.Environment;
import org.rascalmpl.interpreter.staticErrors.UndeclaredAnnotation;
import org.rascalmpl.interpreter.staticErrors.UnexpectedType;
import org.rascalmpl.interpreter.staticErrors.UnsupportedSubscriptArity;
import org.rascalmpl.interpreter.utils.Names;
import org.rascalmpl.interpreter.utils.RuntimeExceptionFactory;

public class NodeResult extends ElementResult<INode> {

  public NodeResult(Type type, INode node, IEvaluatorContext ctx) {
    super(type, node, ctx);
  }

  @Override
  public <V extends IValue> Result<IBool> equals(Result<V> that) {
    return that.equalToNode(this);
  }

  @Override
  public <V extends IValue> Result<IBool> nonEquals(Result<V> that) {
    return that.nonEqualToNode(this);
  }

  @Override
  public <V extends IValue> LessThanOrEqualResult lessThanOrEqual(Result<V> result) {
    return result.lessThanOrEqualNode(this);
  }
 
  @Override
  public Result<IBool> is(Name name) {
    return ResultFactory.bool(getValue().getName().equals(Names.name(name)), ctx);
  }
 
  @Override
  public Result<IBool> has(Name name) {
    INode node = getValue();
    if(node instanceof IConstructor)
      return ResultFactory.bool(((IConstructor) node).has(Names.name(name)), ctx);
    else
      return ResultFactory.bool(false, ctx);
  }
 
  @SuppressWarnings("unchecked")
  @Override
  public <U extends IValue, V extends IValue> Result<U> subscript(Result<?>[] subscripts) {
    if (subscripts.length != 1) {
      throw new UnsupportedSubscriptArity(getType(), subscripts.length, ctx.getCurrentAST());
    }
    if (!((Result<IValue>)subscripts[0]).getType().isInteger()) {
      throw new UnexpectedType(getTypeFactory().integerType(),
          ((Result<IValue>)subscripts[0]).getType(), ctx.getCurrentAST());
    }
    IInteger index = ((IntegerResult)subscripts[0]).getValue();
    int idx = index.intValue();
    if (idx < 0){
      idx = idx + getValue().arity();
    }
    if ( (idx >= getValue().arity()) || (idx < 0)) {
      throw RuntimeExceptionFactory.indexOutOfBounds(index, ctx.getCurrentAST(), ctx.getStackTrace());
    }
    Type elementType = getTypeFactory().valueType();
    return makeResult(elementType, getValue().get(idx), ctx);
  }
 
  @Override
  public <U extends IValue, V extends IValue> Result<U> slice(Result<?> first, Result<?> second, Result<?> end) {
    return super.slice(first, second, end, getValue().arity());
  }
 
  public Result<IValue> makeSlice(int first, int second, int end){
    IListWriter w = getValueFactory().listWriter();
    int increment = second - first;
    if(first == end || increment == 0){
      // nothing to be done
    } else
    if(first <= end){
      for(int i = first; i >= 0 && i < end; i += increment){
        w.append(getValue().get(i));
      }
    } else {
      for(int j = first; j >= 0 && j > end && j < getValue().arity(); j += increment){
        w.append(getValue().get(j));
      }
    }
    TypeFactory tf = TypeFactory.getInstance();
    return makeResult(tf.listType(tf.valueType()), w.done(), ctx);
  }
 
  //////
 
  @Override
  protected LessThanOrEqualResult lessThanOrEqualNode(NodeResult that) {
    INode left = that.getValue();
    INode right = getValue();
   
    int compare = left.getName().compareTo(right.getName());
   
    if (compare <= -1) {
      return new LessThanOrEqualResult(true, false, ctx);
    }
   
    if (compare >= 1){
      return new LessThanOrEqualResult(false, false, ctx);
    }
   
    // if the names are not ordered, then we order lexicographically on the arguments:
   
    int leftArity = left.arity();
    int rightArity = right.arity();
   
    if (leftArity < rightArity) {
      return new LessThanOrEqualResult(true, false, ctx);
    }
   
    if (leftArity > rightArity) {
      return new LessThanOrEqualResult(false, false, ctx);
    }
   
    for (int i = 0; i < Math.min(leftArity, rightArity); i++) {
      IValue leftArg = left.get(i);
      IValue rightArg = right.get(i);
      LessThanOrEqualResult loe = makeResult(leftArg.getType(), leftArg, ctx).lessThanOrEqual(makeResult(rightArg.getType(), rightArg,ctx));

      if (loe.getLess() && !loe.getEqual()) {
        return new LessThanOrEqualResult(true, false, ctx);
      }

      if (!loe.getEqual()) {
        return new LessThanOrEqualResult(false, false, ctx);
      }
    }
   
    if (!left.mayHaveKeywordParameters() && !right.mayHaveKeywordParameters()) {
      if (left.asAnnotatable().hasAnnotations() || right.asAnnotatable().hasAnnotations()) {
        // bail out
        return new LessThanOrEqualResult(false, true, ctx);
      }
    }
   
    if (!left.asWithKeywordParameters().hasParameters() && right.asWithKeywordParameters().hasParameters()) {
      return new LessThanOrEqualResult(true, false, ctx);
    }

    if (left.asWithKeywordParameters().hasParameters() && !right.asWithKeywordParameters().hasParameters()) {
      return new LessThanOrEqualResult(false, false, ctx);
    }
   
    if (left.asWithKeywordParameters().hasParameters() && right.asWithKeywordParameters().hasParameters()) {
      Map<String, IValue> paramsLeft = left.asWithKeywordParameters().getParameters();
      Map<String, IValue> paramsRight = right.asWithKeywordParameters().getParameters();
      if (paramsLeft.size() < paramsRight.size()) {
        return new LessThanOrEqualResult(true, false, ctx);
      }
      if (paramsLeft.size() > paramsRight.size()) {
        return new LessThanOrEqualResult(false, false, ctx);
      }
      if (paramsRight.keySet().containsAll(paramsLeft.keySet()) && !paramsRight.keySet().equals(paramsLeft.keySet())) {
        return new LessThanOrEqualResult(true, false, ctx);
      }
      if (paramsLeft.keySet().containsAll(paramsLeft.keySet()) && !paramsRight.keySet().equals(paramsLeft.keySet())) {
        return new LessThanOrEqualResult(false, false, ctx);
      }
      //assert paramsLeft.keySet().equals(paramsRight.keySet());
      for (String k: paramsLeft.keySet()) {
        IValue paramLeft = paramsLeft.get(k);
        IValue paramRight = paramsRight.get(k);
        LessThanOrEqualResult loe = makeResult(paramLeft.getType(), paramLeft, ctx).lessThanOrEqual(makeResult(paramRight.getType(), paramRight,ctx));

          if (loe.getLess() && !loe.getEqual()) {
            return new LessThanOrEqualResult(true, false, ctx);
          }

          if (!loe.getEqual()) {
            return new LessThanOrEqualResult(false, false, ctx);
          }
      }
     }
   
     return new LessThanOrEqualResult(false, true, ctx);
     //return new LessThanOrEqualResult(leftArity < rightArity, leftArity == rightArity, ctx);
  }

  @Override
  protected Result<IBool> equalToNode(NodeResult that) {
    return that.equalityBoolean(this);
  }
 
  @Override
  protected Result<IBool> nonEqualToNode(NodeResult that) {
    return that.nonEqualityBoolean(this);
  }
 
  @Override
  public <U extends IValue> Result<U> getAnnotation(String annoName, Environment env) {
    Type annoType = env.getAnnotationType(getType(), annoName);
 
    if (annoType == null) {
      throw new UndeclaredAnnotation(annoName, getType(), ctx.getCurrentAST());
    }
 
    IValue annoValue = getValue().asAnnotatable().getAnnotation(annoName);
    if (annoValue == null) {
      throw RuntimeExceptionFactory.noSuchAnnotation(annoName, ctx.getCurrentAST(), null);
    }
    // TODO: applyRules?
    return makeResult(annoType, annoValue, ctx);
  }

}
TOP

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

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.