public OverloadedFunction add(AbstractFunction candidate) { List<AbstractFunction> joined = new ArrayList<AbstractFunction>(primaryCandidates.size() + 1); joined.addAll(primaryCandidates); List<AbstractFunction> defJoined = new ArrayList<AbstractFunction>(defaultCandidates.size() + 1); defJoined.addAll(defaultCandidates); if (candidate.isDefault() && !defJoined.contains(candidate)) { defJoined.add(candidate); } else if (!candidate.isDefault() && !joined.contains(candidate)) { joined.add(candidate); } return new OverloadedFunction( "(" + name + "+" + candidate.getName() + ")", lub(joined).lub(lub(defJoined)), joined, defJoined, ctx); }
public OverloadedFunction(AbstractFunction function) { super(function.getType(), null, function.getEval()); this.name = function.getName(); this.primaryCandidates = new ArrayList<AbstractFunction>(1); this.defaultCandidates = new ArrayList<AbstractFunction>(1); if (function.isDefault()) { defaultCandidates.add(function); } else { primaryCandidates.add(function); } this.isStatic = function.isStatic(); }
/** * This function groups occurrences of pattern dispatched functions as one "PatternFunction" that * has a hash table to look up based on outermost function symbol. A group is a bunch of functions * that have an ADT as a first parameter type and a call or tree pattern with a fixed name as the * first parameter pattern, or it is a singleton other case. The addAll function retains the order * of the functions from the candidates list, in order to preserve shadowing rules! */ private void addAll( List<AbstractFunction> container, List<AbstractFunction> candidates, boolean nonDefault) { @SuppressWarnings("unchecked") Map<String, List<AbstractFunction>>[] constructors = new Map[10]; @SuppressWarnings("unchecked") Map<IConstructor, List<AbstractFunction>>[] productions = new Map[10]; List<AbstractFunction> other = new LinkedList<AbstractFunction>(); for (AbstractFunction func : candidates) { if (nonDefault && func.isDefault()) { continue; } if (!nonDefault && !func.isDefault()) { continue; } String label = null; IConstructor prod = null; if (func.isPatternDispatched()) { // this one is already hashed, but we might find more to add to that map in the next round Map<String, List<AbstractFunction>> funcMap = ((AbstractPatternDispatchedFunction) func).getMap(); int pos = func.getIndexedArgumentPosition(); for (String key : funcMap.keySet()) { addFuncsToMap(pos, constructors, funcMap.get(key), key); } } else if (func.isConcretePatternDispatched()) { // this one is already hashed, but we might find more to add to that map in the next round Map<IConstructor, List<AbstractFunction>> funcMap = ((ConcretePatternDispatchedFunction) func).getMap(); int pos = func.getIndexedArgumentPosition(); for (IConstructor key : funcMap.keySet()) { addProdsToMap(pos, productions, funcMap.get(key), key); } } else { // a new function definition, that may be hashable int pos = func.getIndexedArgumentPosition(); label = func.getIndexedLabel(); prod = func.getIndexedProduction(); if (label != null) { // we found another one to hash addFuncToMap(pos, constructors, func, label); } else if (prod != null) { addProdToMap(pos, productions, func, prod); } else { other.add(func); } } } for (int i = 0; i < constructors.length; i++) { if (constructors[i] != null && !constructors[i].isEmpty()) { container.add( new AbstractPatternDispatchedFunction( ctx.getEvaluator(), i, name, type, constructors[i])); } } for (int i = 0; i < productions.length; i++) { if (productions[i] != null && !productions[i].isEmpty()) { container.add( new ConcretePatternDispatchedFunction( ctx.getEvaluator(), i, name, type, productions[i])); } } container.addAll(other); }