/*package*/ public NonTerminalType(IConstructor cons) { // TODO refactor this into different factory methods in RascalTypeFactory if (cons.getConstructorType() == RascalValueFactory.Tree_Appl) { // Note that here we go from * to + lists if the list is not empty this.symbol = TreeAdapter.getType((ITree) cons); } else if (cons.getConstructorType() == RascalValueFactory.Tree_Amb) { ISet alts = TreeAdapter.getAlternatives((ITree) cons); if (!alts.isEmpty()) { ITree first = (ITree) alts.iterator().next(); this.symbol = TreeAdapter.getType(first); } else { this.symbol = IRascalValueFactory.getInstance().constructor(RascalValueFactory.Symbol_Empty); } } else if (cons.getConstructorType() == RascalValueFactory.Tree_Cycle) { this.symbol = TreeAdapter.getType((ITree) cons); } else if (cons.getType() == RascalValueFactory.Symbol) { this.symbol = cons; } else if (cons.getType() == RascalValueFactory.Production) { this.symbol = ProductionAdapter.getType(cons); } else { throw new ImplementationError("Invalid concrete syntax type constructor:" + cons); } }
public ITree filterAmbiguity(ITree ambCluster, Object environment) { ISet alts = (ISet) ambCluster.get("alternatives"); if (alts.size() == 0) { return null; } Environment env = (Environment) environment; Result<IValue> var = env.getFrameVariable("amb"); if (var != null && var instanceof ICallableValue) { Type type = RascalTypeFactory.getInstance().nonTerminalType(ambCluster); ICallableValue func = (ICallableValue) var; try { Result<IValue> result = func.call(new Type[] {TF.setType(type)}, new IValue[] {alts}, null); if (result.getType().isBottom()) { return ambCluster; } ITree r = (ITree) result.getValue(); if (TreeAdapter.isAmb(r)) { ISet returnedAlts = TreeAdapter.getAlternatives(r); if (returnedAlts.size() == 1) { return (ITree) returnedAlts.iterator().next(); } else if (returnedAlts.size() == 0) { return null; } else { return r; } } return (ITree) result.getValue(); } catch (ArgumentMismatch e) { return ambCluster; } } return ambCluster; }
@Override protected Result<IBool> equalToConcreteSyntax(ConcreteSyntaxResult that) { IConstructor left = this.getValue(); IConstructor right = that.getValue(); if (TreeAdapter.isLayout(left) && TreeAdapter.isLayout(right)) { return bool(true, ctx); } if (TreeAdapter.isAppl(left) && TreeAdapter.isAppl(right)) { IConstructor p1 = TreeAdapter.getProduction(left); IConstructor p2 = TreeAdapter.getProduction(right); if (!p1.isEqual(p2)) { return bool(false, ctx); } IList l1 = TreeAdapter.getArgs(left); IList l2 = TreeAdapter.getArgs(right); if (l1.length() != l2.length()) { return bool(false, ctx); } for (int i = 0; i < l1.length(); i++) { IValue kid1 = l1.get(i); IValue kid2 = l2.get(i); // Recurse here on kids to reuse layout handling etc. Result<IBool> result = makeResult(kid1.getType(), kid1, ctx).equals(makeResult(kid2.getType(), kid2, ctx)); if (!result.getValue().getValue()) { return bool(false, ctx); } if (TreeAdapter.isContextFree(left)) { i++; // skip layout } } return bool(true, ctx); } if (TreeAdapter.isChar(left) && TreeAdapter.isChar(right)) { return bool((TreeAdapter.getCharacter(left) == TreeAdapter.getCharacter(right)), ctx); } if (TreeAdapter.isAmb(left) && TreeAdapter.isAmb(right)) { ISet alts1 = TreeAdapter.getAlternatives(left); ISet alts2 = TreeAdapter.getAlternatives(right); if (alts1.size() != alts2.size()) { return bool(false, ctx); } // TODO: this is very inefficient again: for (IValue alt1 : alts1) { for (IValue alt2 : alts2) { Result<IBool> result = makeResult(alt1.getType(), alt1, ctx).equals(makeResult(alt2.getType(), alt2, ctx)); if (result.getValue().getValue()) { // As soon an alt1 is equal to an alt2 // continue the outer loop. continue again; } } // If an alt1 is not equal to any of the the alt2's return false; return bool(false, ctx); } return bool(true, ctx); } return bool(false, ctx); }