@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()); }
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; } }
@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()); }
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; }
private static Type lub(List<AbstractFunction> candidates) { Set<FunctionType> alternatives = new HashSet<FunctionType>(); Iterator<AbstractFunction> iter = candidates.iterator(); if (!iter.hasNext()) { return TF.voidType(); } FunctionType first = iter.next().getFunctionType(); Type returnType = first.getReturnType(); alternatives.add(first); AbstractFunction l = null; while (iter.hasNext()) { l = iter.next(); if (l.getFunctionType().getReturnType() == returnType) { alternatives.add(l.getFunctionType()); } else { return TF.valueType(); } } return RascalTypeFactory.getInstance().overloadedFunctionType(alternatives); }