org.tros.torgo.interpreter.InterpreterThread.java Source code

Java tutorial

Introduction

Here is the source code for org.tros.torgo.interpreter.InterpreterThread.java

Source

/*
 * Copyright 2015-2016 Matthew Aguirre
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.tros.torgo.interpreter;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import org.apache.commons.lang3.event.EventListenerSupport;
import org.tros.utils.HaltMonitor;

/**
 * Interpreter Thread Interface
 *
 * @author matta
 */
public abstract class InterpreterThread extends Thread {

    private final HaltMonitor monitor;
    private CodeBlock script;
    private final String source;
    private final EventListenerSupport<InterpreterListener> listeners = EventListenerSupport
            .create(InterpreterListener.class);
    protected final Scope scope;

    /**
     * Constructor
     *
     * @param source
     * @param scope
     */
    public InterpreterThread(String source, Scope scope) {
        this.scope = scope;
        this.source = source;
        this.monitor = new HaltMonitor();
    }

    /**
     * Check to see if the thread is halted.
     *
     * @return
     */
    public final boolean isHalted() {
        return monitor.isHalted();
    }

    /**
     * Halt the thread.
     */
    public final void halt() {
        monitor.halt();
    }

    /**
     * Add a specified listener.
     *
     * @param listener
     */
    public final void addInterpreterListener(InterpreterListener listener) {
        listeners.addListener(listener);
    }

    /**
     * Remove a specified listener.
     *
     * @param listener
     */
    public final void removeInterpreterListener(InterpreterListener listener) {
        listeners.removeListener(listener);
    }

    /**
     * Get the lexical analysis results from the source. Uses ANTLR to parse and
     * set up for interpreting.
     *
     * @param source
     * @return
     */
    protected abstract LexicalAnalyzer getLexicalAnalysis(String source);

    /**
     * Threaded function.
     */
    @Override
    public final void run() {
        listeners.fire().started();
        try {
            //walk the parse tree and build the execution map
            LexicalAnalyzer l = getLexicalAnalysis(source);

            script = l.getEntryPoint();
            InterpreterListener listener = new InterpreterListener() {

                @Override
                public void started() {
                }

                @Override
                public void finished() {
                }

                @Override
                public void error(Exception e) {
                    listeners.fire().error(e);
                }

                @Override
                public void message(String msg) {
                    listeners.fire().message(msg);
                }

                /**
                 * Pass on the currStatement event to any listeners.
                 *
                 * @param block
                 * @param scope
                 */
                @Override
                public void currStatement(CodeBlock block, Scope scope) {
                    listeners.fire().currStatement(block, scope);
                }
            };
            for (CodeBlock cb : l.getCodeBlocks()) {
                cb.addInterpreterListener(listener);
                monitor.addHaltListener(cb);
            }
            //interpret the script
            process(script);
        } catch (Exception ex) {
            listeners.fire().error(ex);
            org.tros.utils.logging.Logging.getLogFactory().getLogger(InterpreterThread.class).fatal(null, ex);
            try {
                Class<?> lc = Class.forName("org.tros.utils.logging.LogConsole");
                Field field = lc.getField("CONSOLE");
                java.lang.reflect.Method m = field.getType().getMethod("setVisible", boolean.class);
                Object fieldInstance = field.get(null);
                m.invoke(fieldInstance, true);
            } catch (ClassNotFoundException | NoSuchFieldException | SecurityException | NoSuchMethodException
                    | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex1) {
            }
        }
        listeners.fire().finished();
    }

    /**
     * Start the processing of the script.
     *
     * @param entryPoint
     */
    protected abstract void process(CodeBlock entryPoint);

    /**
     * Wait for the interpreter thread to terminate.
     */
    public final void waitForTermination() {
        try {
            join();
        } catch (InterruptedException ex) {
            org.tros.utils.logging.Logging.getLogFactory().getLogger(InterpreterThread.class).fatal(null, ex);
        }
    }

    public final void addScopeListener(ScopeListener listener) {
        scope.addScopeListener(listener);
    }

    public final void removeScopeListener(ScopeListener listener) {
        scope.removeScopeListener(listener);
    }
}