Package net.fortytwo.ripple.query

Source Code of net.fortytwo.ripple.query.LazyStackEvaluator$EvaluatorSink

package net.fortytwo.ripple.query;

import net.fortytwo.flow.Sink;
import net.fortytwo.ripple.RippleException;
import net.fortytwo.ripple.model.Closure;
import net.fortytwo.ripple.model.ModelConnection;
import net.fortytwo.ripple.model.Operator;
import net.fortytwo.ripple.model.RippleList;
import net.fortytwo.ripple.model.RippleValue;
import net.fortytwo.ripple.model.StackMapping;

// Note: not thread-safe, on account of stop()

/**
* @author Joshua Shinavier (http://fortytwo.net)
*/
public class LazyStackEvaluator extends StackEvaluator {

    private boolean stopped = true;

    protected class EvaluatorSink implements Sink<RippleList> {
        private Sink<RippleList> sink;
        private final ModelConnection mc;

        public EvaluatorSink(final Sink<RippleList> sink,
                             final ModelConnection mc) {
            this.sink = sink;
            //System.out.println(this + "( " + sink + ")");
            this.mc = mc;
        }

        public void put(final RippleList arg)
                throws RippleException {
            if (stopped) {
                return;
            }

            //System.out.println(this + " -- stack = " + stack);
            RippleValue first = arg.getFirst();
            //System.out.println( "   first.isActive() = " + first.isActive() );
            //System.out.println("   first = " + stack.getFirst());

            if (null != first.getMapping()) {
                RippleList rest = arg.getRest();
                //System.out.println("   rest = " + rest);

                final StackMapping f = first.getMapping();
                //System.out.println("   f = " + f);
                //System.out.println("   f.arity() = " + f.arity());

                // Nullary functions don't need their argument stacks reduced.
                // They shouldn't even care if the stack is empty.
                if (f.arity() == 0) {
                    f.apply(rest, this, mc);
                }

                // Functions with positive arity do require the stack to be
                // reduced, to one level per argument.
                else {
                    // We simply ignore stacks which can't be reduced to
                    // something with a passive item on top.
                    if (rest.isNil()) {
                        // sink.put( stack );
                    } else {
                        final Sink<RippleList> thisEval = this;
                        Sink<RippleList> argSink = new Sink<RippleList>() {
                            public void put(final RippleList arg) throws RippleException {
                                Closure c = new Closure(f, arg.getFirst());
                                new EvaluatorSink(thisEval, mc).put(arg.getRest().push(new Operator(c)));
                            }
                        };

                        // Reduce the argument portion of the stack.
                        new EvaluatorSink(argSink, mc).put(arg.getRest());
                    }
                }
            } else {
                sink.put(arg);
            }
        }
    }

    public void apply(final RippleList arg,
                      final Sink<RippleList> solutions,
                      final ModelConnection mc) throws RippleException {
        if (arg.isNil()) {
            return;
        }

        /*
        Sink<StackContext, RippleException> debugSink = new Sink<StackContext, RippleException>() {
            public void put(final StackContext ctx) throws RippleException {
                System.out.println("yielding value: " + ctx.getStack());
                solutions.put(ctx);
            }
        };
        //*/

        EvaluatorSink evalSink = new EvaluatorSink(solutions, mc);
        //EvaluatorSink evalSink = new EvaluatorSink( debugSink );
        stopped = false;

        try {
            evalSink.put(arg);
        }

        // Attempt to recover from stack overflow.
        catch (StackOverflowError e) {
            throw new RippleException(e);
        }
    }

    public void stop() {
        synchronized (this) {
            stopped = true;
        }
    }
}
TOP

Related Classes of net.fortytwo.ripple.query.LazyStackEvaluator$EvaluatorSink

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.