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

flabbergast.Lookup Maven / Gradle / Ivy

package flabbergast;

import java.util.LinkedList;
import java.util.List;

/**
 * Do lookup by creating a grid of contexts where the value might reside and all
 * the needed names.
 */
public class Lookup extends Computation {
    public static class DoLookup implements ComputeValue {
        private final String[] names;
        public DoLookup(String... names) {
            this.names = names;
        }

        public Computation invoke(TaskMaster task_master,
                                  SourceReference source_reference, Context context, Frame self,
                                  Frame container) {
            if (names.length == 0) {
                return new FailureComputation(task_master, source_reference, "Missing names in lookup.");
            }
            for (String name : names) {
                if (!task_master.verifySymbol(source_reference, name)) {
                    return BlackholeComputation.INSTANCE;
                }
            }
            return new Lookup(task_master, source_reference, names, context);
        }
    }
    private class Attempt implements ConsumeResult {
        int frame;
        int name;
        Frame result_frame;
        Frame source_frame;

        public Attempt(int name, int frame, Frame source_frame) {
            this.name = name;
            this.frame = frame;
            this.source_frame = source_frame;
        }

        @Override
        public void consume(Object return_value) {
            if (name == names.length - 1) {
                result = return_value;
                wakeupListeners();
            } else if (return_value instanceof Frame) {
                result_frame = ((Frame) return_value);
                Attempt next = new Attempt(name + 1, frame, result_frame);
                known_attempts.add(next);
                if (result_frame.getOrSubscribe(names[name + 1], next)) {
                    return;
                }
                activateNext();
            } else {
                task_master.reportLookupError(Lookup.this,
                                              return_value.getClass());
            }
        }

    }

    private int frame_index = 0;

    private final Frame[] frames;

    private LinkedList known_attempts = new LinkedList();

    /**
     * The name components in the lookup expression.
     */
    private String[] names;
    private SourceReference source_reference;

    public Lookup(TaskMaster task_master, SourceReference source_ref,
                  String[] names, Context context) {
        super(task_master);
        this.source_reference = source_ref;
        this.names = names;
        frames = new Frame[context.getLength()];
        int frame_index = 0;
        for (Frame frame : context) {
            frames[frame_index] = frame;
            frame_index++;
        }
    }

    private void activateNext() {
        while (frame_index < frames.length) {
            int index = frame_index++;
            Attempt root_attempt = new Attempt(0, index, frames[index]);
            known_attempts.add(root_attempt);
            if (frames[index].getOrSubscribe(names[0], root_attempt)) {
                return;
            }
        }
        task_master.reportLookupError(this, null);
    }

    public Frame get(int name, int frame) {
        for (int index = 0; index < known_attempts.size(); index++) {
            Attempt current = known_attempts.get(index);
            if (current.frame == frame && current.name > name
                    || current.frame > frame) {
                return null;
            }
            if (current.frame == frame && current.name == name) {
                return current.source_frame;
            }
        }
        return null;
    }

    public int getFrameCount() {
        return frames.length;
    }

    public Frame getLastFrame() {
        return known_attempts.getLast().source_frame;
    }

    public String getLastName() {
        return names[known_attempts.getLast().name];
    }

    public String getName() {
        StringBuilder sb = new StringBuilder();
        for (int n = 0; n < names.length; n++) {
            if (n > 0) {
                sb.append(".");
            }
            sb.append(names[n]);
        }
        return sb.toString();
    }

    public String getName(int index) {
        return names[index];
    }

    public int getNameCount() {
        return names.length;
    }

    public SourceReference getSourceReference() {
        return source_reference;
    }

    @Override
    protected void run() {
        activateNext();

    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy