Esempio n. 1
0
  @Override
  public Type getKeywordArgumentTypes(Environment scope) {
    ArrayList<String> labels = new ArrayList<>();
    ArrayList<Type> types = new ArrayList<>();
    // TODO: I am not sure this is what we want. Double names will end up twice in the tuple type...

    for (AbstractFunction c : primaryCandidates) {
      Type args = c.getKeywordArgumentTypes(scope);

      if (args != null && args.hasFieldNames()) {
        for (String label : args.getFieldNames()) {
          labels.add(label);
          types.add(args.getFieldType(label));
        }
      }
    }

    for (AbstractFunction c : defaultCandidates) {
      Type args = c.getKeywordArgumentTypes(scope);

      if (args != null && args.hasFieldNames()) {
        for (String label : args.getFieldNames()) {
          labels.add(label);
          types.add(args.getFieldType(label));
        }
      }
    }

    return TF.tupleType(
        types.toArray(new Type[types.size()]), labels.toArray(new String[labels.size()]));
  }
Esempio n. 2
0
  public Element compute(Element parameter) {

    for (AbstractFunction fn : fns) {
      if (Element.pfalse.equals(fn.compute(parameter))) return Element.pfalse;
    }
    return Element.ptrue;
  }
Esempio n. 3
0
 public List<AbstractFunction> getTests() {
   List<AbstractFunction> result = new LinkedList<AbstractFunction>();
   for (AbstractFunction f : getFunctions()) {
     if (f.isTest()) {
       result.add(f);
     }
   }
   return result;
 }
Esempio n. 4
0
  @Override
  public String toString() {
    StringBuilder b = new StringBuilder();
    for (AbstractFunction l : primaryCandidates) {
      b.append(l.toString());
      b.append(' ');
    }
    for (AbstractFunction l : defaultCandidates) {
      b.append(l.toString());
      b.append(' ');
    }

    return b.toString();
  }
Esempio n. 5
0
  @Override
  public OverloadedFunction cloneInto(Environment env) {
    List<AbstractFunction> newCandidates = new ArrayList<>();
    for (AbstractFunction f : primaryCandidates) {
      newCandidates.add((AbstractFunction) f.cloneInto(env));
    }

    List<AbstractFunction> newDefaultCandidates = new ArrayList<>();
    for (AbstractFunction f : defaultCandidates) {
      newDefaultCandidates.add((AbstractFunction) f.cloneInto(env));
    }
    OverloadedFunction of =
        new OverloadedFunction(name, getType(), newCandidates, newDefaultCandidates, isStatic, ctx);
    of.setPublic(isPublic());
    return of;
  }
Esempio n. 6
0
  public OverloadedFunction(AbstractFunction function) {
    super(function.getType(), null, function.getEval());

    this.name = function.getName();

    this.primaryCandidates = new ArrayList<AbstractFunction>(1);
    this.defaultCandidates = new ArrayList<AbstractFunction>(1);

    if (function.isDefault()) {
      defaultCandidates.add(function);
    } else {
      primaryCandidates.add(function);
    }

    this.isStatic = function.isStatic();
  }
Esempio n. 7
0
  public OverloadedFunction add(AbstractFunction candidate) {
    List<AbstractFunction> joined = new ArrayList<AbstractFunction>(primaryCandidates.size() + 1);
    joined.addAll(primaryCandidates);
    List<AbstractFunction> defJoined =
        new ArrayList<AbstractFunction>(defaultCandidates.size() + 1);
    defJoined.addAll(defaultCandidates);

    if (candidate.isDefault() && !defJoined.contains(candidate)) {
      defJoined.add(candidate);
    } else if (!candidate.isDefault() && !joined.contains(candidate)) {
      joined.add(candidate);
    }

    return new OverloadedFunction(
        "(" + name + "+" + candidate.getName() + ")",
        lub(joined).lub(lub(defJoined)),
        joined,
        defJoined,
        ctx);
  }
Esempio n. 8
0
  private static Result<IValue> callWith(
      List<AbstractFunction> candidates,
      Type[] argTypes,
      IValue[] argValues,
      Map<String, IValue> keyArgValues,
      boolean mustSucceed) {
    AbstractFunction failed = null;
    Failure failure = null;

    for (AbstractFunction candidate : candidates) {
      if ((candidate.hasVarArgs() && argValues.length >= candidate.getArity() - 1)
          || candidate.getArity() == argValues.length
          || candidate.hasKeywordArguments()) {
        try {
          return candidate.call(argTypes, argValues, keyArgValues);
        } catch (MatchFailed m) {
          // could happen if pattern dispatched
        } catch (Failure e) {
          failed = candidate;
          failure = e;
          // could happen if function body throws fail
        }
      }
    }

    if (failed != null && mustSucceed) {
      throw new UnguardedFail(failed.ast, failure);
    }

    return null;
  }
Esempio n. 9
0
  private static Type lub(List<AbstractFunction> candidates) {
    Set<FunctionType> alternatives = new HashSet<FunctionType>();
    Iterator<AbstractFunction> iter = candidates.iterator();
    if (!iter.hasNext()) {
      return TF.voidType();
    }
    FunctionType first = iter.next().getFunctionType();
    Type returnType = first.getReturnType();
    alternatives.add(first);

    AbstractFunction l = null;
    while (iter.hasNext()) {
      l = iter.next();
      if (l.getFunctionType().getReturnType() == returnType) {
        alternatives.add(l.getFunctionType());
      } else {
        return TF.valueType();
      }
    }

    return RascalTypeFactory.getInstance().overloadedFunctionType(alternatives);
  }
Esempio n. 10
0
  /**
   * This function groups occurrences of pattern dispatched functions as one "PatternFunction" that
   * has a hash table to look up based on outermost function symbol. A group is a bunch of functions
   * that have an ADT as a first parameter type and a call or tree pattern with a fixed name as the
   * first parameter pattern, or it is a singleton other case. The addAll function retains the order
   * of the functions from the candidates list, in order to preserve shadowing rules!
   */
  private void addAll(
      List<AbstractFunction> container, List<AbstractFunction> candidates, boolean nonDefault) {
    @SuppressWarnings("unchecked")
    Map<String, List<AbstractFunction>>[] constructors = new Map[10];
    @SuppressWarnings("unchecked")
    Map<IConstructor, List<AbstractFunction>>[] productions = new Map[10];
    List<AbstractFunction> other = new LinkedList<AbstractFunction>();

    for (AbstractFunction func : candidates) {
      if (nonDefault && func.isDefault()) {
        continue;
      }
      if (!nonDefault && !func.isDefault()) {
        continue;
      }

      String label = null;
      IConstructor prod = null;

      if (func.isPatternDispatched()) {
        // this one is already hashed, but we might find more to add to that map in the next round
        Map<String, List<AbstractFunction>> funcMap =
            ((AbstractPatternDispatchedFunction) func).getMap();
        int pos = func.getIndexedArgumentPosition();

        for (String key : funcMap.keySet()) {
          addFuncsToMap(pos, constructors, funcMap.get(key), key);
        }
      } else if (func.isConcretePatternDispatched()) {
        // this one is already hashed, but we might find more to add to that map in the next round
        Map<IConstructor, List<AbstractFunction>> funcMap =
            ((ConcretePatternDispatchedFunction) func).getMap();
        int pos = func.getIndexedArgumentPosition();

        for (IConstructor key : funcMap.keySet()) {
          addProdsToMap(pos, productions, funcMap.get(key), key);
        }
      } else {
        // a new function definition, that may be hashable
        int pos = func.getIndexedArgumentPosition();
        label = func.getIndexedLabel();
        prod = func.getIndexedProduction();

        if (label != null) {
          // we found another one to hash
          addFuncToMap(pos, constructors, func, label);
        } else if (prod != null) {
          addProdToMap(pos, productions, func, prod);
        } else {
          other.add(func);
        }
      }
    }

    for (int i = 0; i < constructors.length; i++) {
      if (constructors[i] != null && !constructors[i].isEmpty()) {
        container.add(
            new AbstractPatternDispatchedFunction(
                ctx.getEvaluator(), i, name, type, constructors[i]));
      }
    }

    for (int i = 0; i < productions.length; i++) {
      if (productions[i] != null && !productions[i].isEmpty()) {
        container.add(
            new ConcretePatternDispatchedFunction(
                ctx.getEvaluator(), i, name, type, productions[i]));
      }
    }

    container.addAll(other);
  }
Esempio n. 11
0
 public static void addOrReplaceFunction(AbstractFunction fun) {
   // We shouldn't get there unless that function don't exist
   removeFunction(fun.name(), fun.argTypes());
   declare(fun);
 }
Esempio n. 12
0
  @Override
  protected void initAttrs(Element element) throws ParseException {
    super.initAttrs(element);

    this.inputField = super.getAttr(Constants.ATTR_INPUT);
  }