Example #1
0
  @Override
  public boolean isSubtypeOfNonTerminal(RascalType other) {
    if (other == this) {
      return true;
    }
    IConstructor otherSym = ((NonTerminalType) other).symbol;

    if ((SymbolAdapter.isIterPlus(symbol)
            && (SymbolAdapter.isIterStar(otherSym) || SymbolAdapter.isIterPlus(otherSym)))
        || (SymbolAdapter.isIterStar(symbol) && SymbolAdapter.isIterStar(otherSym))) {
      RascalType nt1 = (RascalType) RTF.nonTerminalType(SymbolAdapter.getSymbol(symbol));
      RascalType nt2 = (RascalType) RTF.nonTerminalType(SymbolAdapter.getSymbol(otherSym));
      return nt1.isSubtypeOfNonTerminal(nt2);
    } else if ((SymbolAdapter.isIterPlusSeps(symbol)
            && (SymbolAdapter.isIterStarSeps(otherSym) || SymbolAdapter.isIterPlusSeps(otherSym)))
        || (SymbolAdapter.isIterStarSeps(symbol) && SymbolAdapter.isIterStarSeps(otherSym))) {
      RascalType nt1 = (RascalType) RTF.nonTerminalType(SymbolAdapter.getSymbol(symbol));
      RascalType nt2 = (RascalType) RTF.nonTerminalType(SymbolAdapter.getSymbol(otherSym));

      if (nt1.isSubtypeOfNonTerminal(nt2)) {
        IList seps1 = SymbolAdapter.getSeparators(symbol);
        IList seps2 = SymbolAdapter.getSeparators(otherSym);

        // this works around broken regular prods in the RVM which have the wrong or missing layout
        // symbols:
        int sep1index = seps1.length() == 3 ? 1 : 0;
        int sep2index = seps2.length() == 3 ? 1 : 0;

        nt1 = (RascalType) RTF.nonTerminalType((IConstructor) seps1.get(sep1index));
        nt2 = (RascalType) RTF.nonTerminalType((IConstructor) seps2.get(sep2index));
        return nt1.isSubtypeOfNonTerminal(nt2);
      }

      return false;
    } else if (SymbolAdapter.isOpt(symbol) && SymbolAdapter.isOpt(otherSym)) {
      RascalType nt1 = (RascalType) RTF.nonTerminalType(SymbolAdapter.getSymbol(symbol));
      RascalType nt2 = (RascalType) RTF.nonTerminalType(SymbolAdapter.getSymbol(otherSym));
      return nt1.isSubtypeOfNonTerminal(nt2);
    }
    //	  else if (SymbolAdapter.isSequence(symbol) && SymbolAdapter.isSeq(otherSym)) {
    // TODO pairwise issubtype
    //	  }

    if (SymbolAdapter.isParameter(otherSym)) {
      RascalType bound = (RascalType) RTF.nonTerminalType((IConstructor) otherSym.get("bound"));
      return isSubtypeOf(bound);
    }

    // TODO co-variance for the other structured symbols (sequence, opt, list)
    return SymbolAdapter.isEqual(otherSym, symbol);
  }
  private static Result<IValue> call(ICallableValue function, IList args) {
    try {
      int nrOfArgs = args.length();
      Type[] types = new Type[nrOfArgs];
      IValue[] actuals = new IValue[nrOfArgs];

      for (int i = nrOfArgs - 1; i >= 0; --i) {
        IValue arg = args.get(i);
        types[i] = RascalTypeFactory.getInstance().nonTerminalType((IConstructor) arg);
        actuals[i] = arg;
      }

      return function.call(types, actuals, null);
    } catch (MatchFailed e) {
      return null;
    } catch (Failure f) {
      return null;
    }
  }