public static boolean isConcreteListType(Type type) { if (type instanceof NonTerminalType) { IConstructor sym = ((NonTerminalType) type).getSymbol(); return SymbolAdapter.isAnyList(sym); } return false; }
@Override public <U extends IValue, V extends IValue> Result<U> fieldUpdate( String name, Result<V> repl, TypeStore store) { IConstructor tree = getValue(); if (TreeAdapter.isAppl(tree)) { int found = -1; IConstructor foundType = null; IConstructor prod = TreeAdapter.getProduction(tree); IList syms = ProductionAdapter.getSymbols(prod); // TODO: find deeper into optionals, alternatives and sequences checking the actual arguments // for presence/absence of optional trees. for (int i = 0; i < syms.length(); i++) { IConstructor sym = (IConstructor) syms.get(i); if (SymbolAdapter.isLabel(sym)) { if (SymbolAdapter.getLabel(sym).equals(name)) { found = i; foundType = SymbolAdapter.delabel(sym); break; } } } if (found != -1) { Type nont = RascalTypeFactory.getInstance().nonTerminalType(foundType); if (repl.getType().isSubtypeOf(nont)) { IList args = TreeAdapter.getArgs(tree).put(found, repl.getValue()); return makeResult(getType(), tree.set("args", args), ctx); } throw new UnexpectedType(nont, repl.getType(), ctx.getCurrentAST()); } if (Factory.Tree_Appl.hasField(name)) { Type fieldType = Factory.Tree_Appl.getFieldType(name); if (repl.getType().isSubtypeOf(fieldType)) { throw new UnsupportedOperation( "changing " + name + " in concrete tree", ctx.getCurrentAST()); } throw new UnexpectedType(fieldType, repl.getType(), ctx.getCurrentAST()); } throw RuntimeExceptionFactory.noSuchField(name, ctx.getCurrentAST(), ctx.getStackTrace()); } throw new UnsupportedOperation("field update", ctx.getCurrentAST()); }
@Override public Result<IBool> has(Name name) { if (TreeAdapter.isAppl(getValue())) { IConstructor prod = TreeAdapter.getProduction(getValue()); IList syms = ProductionAdapter.getSymbols(prod); String tmp = Names.name(name); // TODO: find deeper into optionals, checking the actual arguments for presence/absence of // optional trees. for (IValue sym : syms) { if (SymbolAdapter.isLabel((IConstructor) sym)) { if (SymbolAdapter.getLabel((IConstructor) sym).equals(tmp)) { return ResultFactory.bool(true, ctx); } } } } return ResultFactory.bool(false, ctx); }
@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 <U extends IValue> Result<U> fieldAccess(String name, TypeStore store) { IConstructor tree = getValue(); if (TreeAdapter.isAppl(tree)) { int found = -1; IConstructor foundType = null; IConstructor prod = TreeAdapter.getProduction(tree); if (!ProductionAdapter.isRegular(prod)) { IList syms = ProductionAdapter.getSymbols(prod); // TODO: find deeper into optionals, checking the actual arguments for presence/absence of // optional trees. for (int i = 0; i < syms.length(); i++) { IConstructor sym = (IConstructor) syms.get(i); while (SymbolAdapter.isConditional(sym)) { sym = SymbolAdapter.getSymbol(sym); } if (SymbolAdapter.isLabel(sym)) { if (SymbolAdapter.getLabel(sym).equals(name)) { found = i; foundType = SymbolAdapter.delabel(sym); } } } if (found != -1) { Type nont = RascalTypeFactory.getInstance().nonTerminalType(foundType); IValue child = TreeAdapter.getArgs(tree).get(found); return makeResult(nont, child, ctx); } } } if (tree.getConstructorType().hasField(name)) { return makeResult(tree.getConstructorType().getFieldType(name), tree.get(name), ctx); } throw RuntimeExceptionFactory.noSuchField(name, ctx.getCurrentAST(), ctx.getStackTrace()); }
@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; }
@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; }
private boolean isDesugarCandidate(IConstructor o) { if (o instanceof AnnotatedConstructorFacade) { AnnotatedConstructorFacade acf = (AnnotatedConstructorFacade) o; if (acf.getType() instanceof NonTerminalType) { NonTerminalType ntt = (NonTerminalType) acf.getType(); String name = SymbolAdapter.toString(ntt.getSymbol(), false); if (eval.getCurrentEnvt().lookupAbstractDataType(name) != null || eval.getCurrentEnvt().lookupConcreteSyntaxType(name) != null) { return true; } } return false; } // TODO Hack. return (o.getClass() .toString() .equals("class org.eclipse.imp.pdb.facts.impl.fast.Constructor")); // System.out.println("Scheiße!"); // System.out.println(o.getClass()); // return false; }
public boolean isOptionalType() { return SymbolAdapter.isOpt(getSymbol()); }
public boolean isConcreteListType() { return SymbolAdapter.isAnyList(getSymbol()); }
@Override public String toString() { return SymbolAdapter.toString(symbol, false); }
@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); }