All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.basking2.sdsai.itrex.functions.functional.PipelineFunction Maven / Gradle / Ivy

There is a newer version: 1.1.23
Show newest version
package com.github.basking2.sdsai.itrex.functions.functional;

import com.github.basking2.sdsai.itrex.EvaluationContext;
import com.github.basking2.sdsai.itrex.Evaluator;
import com.github.basking2.sdsai.itrex.SExprRuntimeException;
import com.github.basking2.sdsai.itrex.functions.FunctionInterface;
import static com.github.basking2.sdsai.itrex.iterators.Iterators.wrap;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;


/**
 * A function that returns a function that ties many functions together.
 *
 * For readability any strings that are "|" or "=<" are ignored.
 */
public class PipelineFunction implements FunctionInterface> {

    @Override
    public FunctionInterface apply(final Iterator iterator, final EvaluationContext evaluationContext) {
        final List> pipeline = new ArrayList<>();

        while (iterator.hasNext()) {
            final Object o = iterator.next();
            if (o instanceof FunctionInterface) {
                @SuppressWarnings("unchecked")
                final FunctionInterface f = (FunctionInterface)o;
                pipeline.add(f);
            }
            else if ("=>".equals(o) || "|".equals(o)) {
                // Nop.
            }
            else {
                final FunctionInterface f = evaluationContext.getFunction(o);

                if (f == null) {
                    throw new SExprRuntimeException("No such function: "+o);
                }

                pipeline.add(f);
            }
        }

        return new FunctionInterface() {

            @Override
            public Object apply(final Iterator iterator, final EvaluationContext evaluationContext) {
                Object result = null;
                @SuppressWarnings("unchecked")
                Iterator args = (Iterator)iterator;
                for (final FunctionInterface f : pipeline) {
                    result = f.apply(args, evaluationContext);
                    args = wrap(result);
                }

                return result;
            }
        };
    }
}