Пример #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);
  }
Пример #2
0
  @Override
  protected Type glbWithNonTerminal(RascalType other) {
    IConstructor otherSym = ((NonTerminalType) other).symbol;

    if (SymbolAdapter.isIterPlus(symbol) && SymbolAdapter.isIterStar(otherSym)) {
      return this;
    } else if (SymbolAdapter.isIterPlus(otherSym) && SymbolAdapter.isIterStar(symbol)) {
      return other;
    } else if (SymbolAdapter.isIterPlusSeps(symbol) && SymbolAdapter.isIterStarSeps(otherSym)) {
      return this;
    } else if (SymbolAdapter.isIterPlusSeps(otherSym) && SymbolAdapter.isIterStarSeps(symbol)) {
      return other;
    }

    return SymbolAdapter.isEqual(otherSym, symbol) ? other : TF.voidType();
  }
  @Override
  public ITree filterProduction(ITree tree, Object environment) {
    String cons = TreeAdapter.getConstructorName(tree);

    if (cons != null) {
      Environment env = (Environment) environment;
      Result<IValue> var = env.getFrameVariable(cons);

      if (var != null && var instanceof ICallableValue) {
        ICallableValue function = (ICallableValue) var;

        try {
          Result<IValue> result = null;
          if (TreeAdapter.isContextFree(tree)) {
            // For context free trees, try it without layout and literal arguments first.
            result = call(function, TreeAdapter.getASTArgs(tree));
          }

          if (result == null) {
            result = call(function, TreeAdapter.getArgs(tree));
          }

          if (result == null) {
            return tree;
          }

          if (result.getType().isBottom()) {
            return tree;
          }

          if (!(result.getType() instanceof NonTerminalType
              && SymbolAdapter.isEqual(
                  ((NonTerminalType) result.getType()).getSymbol(), TreeAdapter.getType(tree)))) {
            // do not call the function if it does not return the right type
            return tree;
          }

          return (ITree) result.getValue();
        } catch (Filtered f) {
          return null;
        }
      }
    }

    return tree;
  }
Пример #4
0
  @Override
  protected Type lubWithNonTerminal(RascalType other) {
    IConstructor otherSym = ((NonTerminalType) other).symbol;

    // * eats +
    if (SymbolAdapter.isIterPlus(symbol) && SymbolAdapter.isIterStar(otherSym)) {
      return other;
    } else if (SymbolAdapter.isIterPlus(otherSym) && SymbolAdapter.isIterStar(symbol)) {
      return this;
    } else if (SymbolAdapter.isIterPlusSeps(symbol) && SymbolAdapter.isIterStarSeps(otherSym)) {
      return other;
    } else if (SymbolAdapter.isIterPlusSeps(otherSym) && SymbolAdapter.isIterStarSeps(symbol)) {
      return this;
    }

    return SymbolAdapter.isEqual(otherSym, symbol) ? this : RascalValueFactory.Tree;
  }