@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; } }