package tefkat.engine.runtime.impl; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import tefkat.engine.runtime.Binding; import tefkat.engine.runtime.BindingPair; import tefkat.engine.runtime.Context; import tefkat.engine.runtime.Expression; import tefkat.engine.runtime.Function; //import tefkat.engine.runtime.Function; //import tefkat.engine.runtime.Function2; import tefkat.engine.runtime.NotGroundException; import tefkat.engine.runtime.ResolutionException; final class ExprExpander { final private List results = new ArrayList(); final private Context context; final private Function function; final private List actuals; final private Object[] params; final private boolean collect; /** * * @param function Function to call for each set of actual parameter values * @param unifier outer Binding context for the calls * @param actuals List of Expressions to evaluate to obtain the parameter values * @param collect true means preserve nesting of result values * @throws NotGroundException * @throws ResolutionException */ ExprExpander(Context context, Function function, Binding unifier, List actuals, boolean collect) throws NotGroundException, ResolutionException { this.context = context; this.function = function; this.actuals = actuals; this.collect = collect; params = new Object[actuals.size()]; expandParams(unifier, 0); } private void expandParams(Binding binding, int i) throws NotGroundException, ResolutionException { if (i == params.length) { Object result = function.call(context, binding, params); if (null != result) { if (!collect && result instanceof Collection) { results.addAll((Collection) result); } else { results.add(result); } } else { context.warn("Function call returned null: " + function + "(" + params + ")"); } } else { List values = ((Expression) actuals.get(i)).eval(context, binding); for (final Iterator itr = values.iterator(); itr.hasNext(); ) { Object obj = itr.next(); Binding newUnifier; if (obj instanceof BindingPair) { newUnifier = new Binding(binding); newUnifier.composeRight((BindingPair) obj); obj = ((BindingPair) obj).getValue(); System.err.println(params[i] + " = " + obj); System.err.println(binding); System.err.println(newUnifier); } else { newUnifier = binding; } params[i] = obj; expandParams(newUnifier, i+1); } } } List getResults() { return results; } }