Package abstrasy

Source Code of abstrasy.Interpreter$PackageEntry

package abstrasy;


import abstrasy.consoleui.OutputTextArea;

import abstrasy.externals.AExtTools;

import abstrasy.interpreter.AbortException;
import abstrasy.interpreter.FreezeTimeOut;
import abstrasy.interpreter.InterpreterException;
import abstrasy.interpreter.ListPackageContents;
import abstrasy.interpreter.RestartException;
import abstrasy.interpreter.RetryException;
import abstrasy.interpreter.SilentException;
import abstrasy.interpreter.StdErrors;

import java.awt.event.ActionEvent;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import java.lang.ref.WeakReference;
import java.lang.reflect.Method;

import java.net.URL;
import java.net.URLClassLoader;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.Properties;
import java.util.Vector;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Timer;


/**
* Abstrasy Interpreter
*
* Copyright : Copyright (c) 2006-2012, Luc Bruninx.
*
* Concédée sous licence EUPL, version 1.1 uniquement (la «Licence»).
*
* Vous ne pouvez utiliser la présente oeuvre que conformément à la Licence.
* Vous pouvez obtenir une copie de la Licence à l’adresse suivante:
*
*   http://www.osor.eu/eupl
*
* Sauf obligation légale ou contractuelle écrite, le logiciel distribué sous
* la Licence est distribué "en l’état", SANS GARANTIES OU CONDITIONS QUELLES
* QU’ELLES SOIENT, expresses ou implicites.
*
* Consultez la Licence pour les autorisations et les restrictions
* linguistiques spécifiques relevant de la Licence.
*
*
* @author Luc Bruninx
* @version 1.0
*/


public class Interpreter extends Thread {

    /**
     * Variables de version et de révisions:
     * -------------------------------------
     *
     * Veuillez ne pas modifier les numéros de version et de révision.
     * Ceux-ci sont réservés pour déterminer le niveau de révision et
     * la version principale du langage que l'interpréteur est capable
     * d'exécuter.
     *
     */
    public static final String version = "1.0";
    public static final int revisionInt = 6342;

    /**
     * Numéro de sous-révision à votre disposition pour répertorier vos
     * propres modifications.
     */
    public static final int subrevisionInt = 0;

    /**
     * Conformément aux lois qui protègent le droit d'auteur, veuillez laisser
     * inchangée toutes les mentions de copyright de l'auteur.
     */
    public static final String revision = Interpreter.revisionInt + "." + subrevisionInt;
    public static final String copyright = "Copyright (c) 2006-2012, Luc Bruninx.";
    public static final String TITLE_APP = "Abstrasy Interpreter " + version + " rev:" + revision + " - " + copyright;

    /**
     * Taille de la pile (de frames) et de la pile du Thread exécutant l'interpréteur.
     */
    public static int DEFAULT_STATICHEAP_SIZE = 2048;
    // Sur un systeme 64 bits, nous doublons arbitrairement la taille de la pile.
    // Celle-ci est augmentée par rapport aux valeurs habituels pour des arch 32 bits
    // (512Ko au lieu de 320Ko) de manière supporter l'imbrication des méthodes
    // exec_q() et eval_q() de Node.
    public static int DEFAULT_INTERPRETER_STACK_SIZE = (512 * 1024) * (System.getProperty("sun.arch.data.model", "32").equals("64") ? 2: 1);

    private boolean timeOutRaising = false;
    private boolean breakingFromSEMAPHORE = false;
    private boolean endingFromSEMAPHORE = false;
   
    //
    public static final int BREAKCODE_NONE = 0;
    public static final int BREAKCODE_LOOP = 1;
    public static final int BREAKCODE_TAIL = 2;
    public static final int BREAKCODE_RETURN = 3;
    public static final int BREAKCODE_REINFER = 4;

    private int breakCode = BREAKCODE_NONE;

    private boolean inLoop = false;

    private boolean canLoop = false;

    private boolean tailNode = false;
    private boolean terminalNode=false;

    private long callerSignature = 0;

    private Node wrapperFunction = null;
    private Node thisFunction = null;
    private Node self=null;
    private Node root=null;
    private Node iface=null;
   

    private static InterpreterSemaphore semaphore = new InterpreterSemaphore();
    private OutputTextArea outputTextArea = null;
    private OutputTextArea logTextArea = null;

    private long executionTimeOut = 15000;
    private long deadlockTime = 0;

    private boolean timeOutCheck = false;

    /**
     * exitCode : code de retour en cas d'arrêt brusque (forcé)...
     */
    static private int exitCode = 0;
    static private boolean _hasExitCode = false;

    static public void setExitCode(int _exitCode) {
        exitCode = _exitCode;
        _hasExitCode = true;
    }

    static public int getExitCode() {
        return exitCode;
    }

    static public boolean hasExitCode() {
        return _hasExitCode;
    }

    private Interpreter() {
        super(null, null, "", DEFAULT_INTERPRETER_STACK_SIZE);
    }

    public static final Interpreter SHARED_INTERPRETER = new Interpreter();
   
    private Action timeOutAction = new AbstractAction() {

        public void actionPerformed(ActionEvent e) {
            if (timeOutCheck) {
                timeOutRaising = (System.currentTimeMillis() > deadlockTime);
                if (__thisInterpreter != null) {
                    if (!__thisInterpreter.isAlive()) {
                        Interpreter.Log("Interpreter breaking -> TimeOutThread Ending...");
                        timeOutTimer.stop();
                    }
                }
            }
        }

    };
    private Timer timeOutTimer = new Timer(100, timeOutAction);

    private String source = null;

    private Node node = null;

    public void setNode(Node node) {
        this.node = node;
    }

    public Node getNode() {
        return node;
    }

    private Node returnedNode = null;

    public Node getReturnedNode() {
        return returnedNode;
    }

    private Exception lastException = null;

    public Exception getLastException() {
        return lastException;
    }

    /**
     * Il ne peut y avoir qu'une seul restart Exception par thread...
     */
    private RestartException restartException = new RestartException();

    public RestartException getRestartException(Node from, Node perform, Node args) {
        restartException.setFrom(from);
        restartException.setPerform(perform);
        restartException.setArgs(args);
        return restartException;
    }

    /**
     * Section de controle du debugage et des logs...
     */
    private static boolean debugMode = false;


    /**
     * Permet d'activer le mode de débogage de l'interpréteur
     *
     * @param mode
     */
    public final static void setDebugMode(boolean mode) {
        debugMode = mode;
    }

    public final static boolean isDebugMode() {
        return debugMode;
    }

    public final static void LogTitle(String str) {
        if (debugMode) {
            System.out.println("### " + str);
            Interpreter interpreter = Interpreter.mySelf();
            if (interpreter != null) {
                OutputTextArea logArea = interpreter.getLogTextArea();
                if (logArea != null) {
                    try{
                        logArea.write("### " + str + "\n");
                    }
                    catch(Exception e){e.printStackTrace();}
                }
            }
        }
    }

    public final static void Log(String str) {
        if (debugMode) {
            System.out.println("  # " + str);
            Interpreter interpreter = Interpreter.mySelf();
            if (interpreter != null) {
                OutputTextArea logArea = interpreter.getLogTextArea();
                if (logArea != null) {
                    try{
                        logArea.write("  # " + str + "\n");
                    }
                    catch(Exception e){e.printStackTrace();}
                }
            }
        }
    }

    public final static void LogAlways(String str) {
        System.out.println("  > " + str);
        Interpreter interpreter = Interpreter.mySelf();
        if (interpreter != null) {
            OutputTextArea logArea = interpreter.getLogTextArea();
            if (logArea != null) {
                try{
                    logArea.write("  # " + str + "\n");
                }
                catch(Exception e){e.printStackTrace();}
            }
        }
    }

    public static long StartChrono() {
        return System.currentTimeMillis();
    }

    public static void LogChrono(long start, String txt) {
        if (debugMode) {
            long res = System.currentTimeMillis() - start;
            Interpreter.LogAlways(txt + " : " + res + "ms.");
        }
        return;
    }


    private Interpreter motherThread = null;

    public Interpreter getMotherThread() {
        return motherThread;
    }

    private boolean interThread = false;

    public boolean isInterThread() {
        return interThread;
    }

    public void setInterThread(boolean ithread) {
        this.interThread = ithread;
    }


    public static InterpreterSemaphore getSemaphore() {
        return semaphore;
    }


    public void setTimeOutCheck(boolean timeOutCheck) {
        this.timeOutCheck = timeOutCheck;
    }

    public boolean isTimeOutCheck() {
        return timeOutCheck;
    }

    public void setExecutionTimeOut(long executionTimeOut) {
        this.executionTimeOut = executionTimeOut;
    }

    public long getExecutionTimeOut() {
        return executionTimeOut;
    }

    public void setDeadlockTime(long deadlockTime) {
        this.deadlockTime = deadlockTime;
    }

    public long getDeadlockTime() {
        return deadlockTime;
    }

    public void setTimeOutRaising(boolean timeOutRaising) {
        this.timeOutRaising = timeOutRaising;
    }

    public boolean isTimeOutRaising() {
        // cas fail-over...
        if (failOver) {
            return false;
        }
        // traitement habituel...
        return timeOutRaising;
    }

    public void setTimeOutTimer(Timer timeOutTimer) {
        this.timeOutTimer = timeOutTimer;
    }

    public Timer getTimeOutTimer() {
        return timeOutTimer;
    }

    public void setBreakingFromSEMAPHORE(boolean breakingFromSEMAPHORE) {
        this.breakingFromSEMAPHORE = breakingFromSEMAPHORE;
    }

    public boolean isBreakingFromSEMAPHORE() {
        // cas fail-over...
        if (failOver) {
            return false;
        }
        // traitement habituel...
        return breakingFromSEMAPHORE;
    }

    public void setEndingFromSEMAPHORE(boolean endingFromSEMAPHORE) {
        this.endingFromSEMAPHORE = endingFromSEMAPHORE;
    }

    public boolean isEndingFromSEMAPHORE() {
        // cas fail-over...
        if (failOver) {
            return false;
        }
        // traitement habituel...
        return endingFromSEMAPHORE;
    }

    private StaticHeap GLOBAL = null;

    public void setGLOBAL(StaticHeap GLOBAL) {
        this.GLOBAL = GLOBAL;
    }

    public StaticHeap getGLOBAL() {
        return GLOBAL;
    }

    private String pluggedLibrariesPath = "";

    public static String getPluggedLibrariesPath() {
        return Interpreter.mySelf().pluggedLibrariesPath;
    }

    public static void setPluggedLibrariesPath(String path) {
        Interpreter.mySelf().pluggedLibrariesPath = path;
    }

    private static Node _Registry_ = null;

    public static Node getRegistry_() {
        if (_Registry_ == null) {
            _Registry_ = Node.createNamespace(new Heap()).letFinal(true);
        }
        return _Registry_;
    }

    public static Heap Application_Heaps = new_Application_Heap();
    public static Heap Reserved = new Heap();
    public static Heap Modules = new Heap();
    public static Heap BuiltIn_Reserved = new Heap();

    private static Node _Modules_ = null;

    public static Node getModules_() {
        if (_Modules_ == null) {
            _Modules_ = Node.createNamespace(Modules).letFinal(true);
        }
        return _Modules_;
    }

    private final static Heap new_Application_Heap() {
        _Registry_ = null;
        _Modules_ = null;
        Heap ah = new Heap();
        ah.put(PCoder.REGISTRY, getModules_());
        return ah;
    }

    static {
        BuiltIn_Reserved.put(PCoder.TRUE, new Node(Node.TRUE).letFinal(true));
        BuiltIn_Reserved.put(PCoder.FALSE, new Node(Node.FALSE).letFinal(true));
        BuiltIn_Reserved.put(PCoder.PI, new Node(Math.PI).letFinal(true));
        BuiltIn_Reserved.put(PCoder.NAPIER, new Node(Math.E).letFinal(true));
        BuiltIn_Reserved.put(PCoder.EULER, new Node(0.5772156649015329).letFinal(true));
        BuiltIn_Reserved.put(PCoder.MAIN, new Node(Node.TRUE).letFinal(true));
        BuiltIn_Reserved.put(PCoder.INTERPRETER_REVISION, new Node(Interpreter.revisionInt).letFinal(true));
    }

    private static Vector<PackageEntry> packagesAdded = null;

    public void setBreakCode(int breakCode) {
        this.breakCode = breakCode;
    }
   
    public int getBreakCode() {
        return breakCode;
    }

    public boolean hasNoBreakCode() {
        return breakCode == BREAKCODE_NONE;
    }

    public void consumeBreakCode_onLoop() {
        if (getBreakCode() == BREAKCODE_LOOP) {
            setBreakCode(BREAKCODE_NONE);
        }
    }


    public void consumeBreakCode_onTail() {
        if (getBreakCode() == BREAKCODE_TAIL) {
            setBreakCode(BREAKCODE_NONE);
        }
    }

    public void consumeBreakCode_onReturn() {
        if (getBreakCode() == BREAKCODE_RETURN) {
            setBreakCode(BREAKCODE_NONE);
        }
    }

    public void setCallerSignature(long callerSignature) {
        this.callerSignature = callerSignature;
        //System.out.println("Set Caller Signature : "+callerSignature);
    }

    public long getCallerSignature() {
        return callerSignature;
    }

    public void setTailNode(boolean tailNode) {
        this.tailNode = tailNode;
    }

    public boolean isTailNode() {
        return tailNode;
    }

    public void setTerminalNode(boolean terminalNode) {
        this.terminalNode = terminalNode;
    }

    public boolean isTerminalNode() {
        return terminalNode;
    }

    public void setThisFunction(Node thisNode) {
        this.thisFunction = thisNode;
    }

    public Node getThisFunction() {
        return thisFunction;
    }

    public void setWrapperFunction(Node wrapper) {
        this.wrapperFunction = wrapper;
    }

    public Node getWrapperFunction() {
        return wrapperFunction;
    }
   
    public void setSelf(Node self) {
        this.self = self;
    }

    public Node getSelf() {
        return self;
    }
   
    public void setRoot(Node root) {
        this.root = root;
    }

    public Node getRoot() {
        return root;
    }
  
    public void setIface(Node iface) {
        this.iface = iface;
    }

    public Node getIface() {
        return iface;
    }
   
    private static class PackageEntry {

        private String packageName;
        private String moduleName;

        PackageEntry(String packageName, String moduleName) {
            this.packageName = packageName;
            this.moduleName = moduleName;
        }

        void setPackageName(String packageName) {
            this.packageName = packageName;
        }

        String getPackageName() {
            return packageName;
        }

        void setModuleName(String moduleName) {
            this.moduleName = moduleName;
        }

        String getModuleName() {
            return moduleName;
        }

    }

    /**
     * Permet d'ajouter les classes External_* du paquetage dont le nom est indiqué au pcfx stimulé.
     *
     * Il suffira alors d'importer le pcfx dans un script pour accéder au classes abstraites définies
     * External_*:
     *
     * (import 'Nom-Module)
     *
     *
     * @param package_name
     * @param module_name
     */
    public static void addPackageName(String package_name, String module_name) {
        if (packagesAdded == null) {
            packagesAdded = new Vector<PackageEntry>();
        }
        boolean addIt = true;
        for (int i = 0; i < packagesAdded.size(); i++) {
            PackageEntry pe = packagesAdded.elementAt(i);
            if (pe.getPackageName().compareTo(package_name) != 0) {
                addIt = false;
                i = packagesAdded.size();
            }
        }
        if (addIt) {
            packagesAdded.addElement(new PackageEntry(package_name, module_name));
        }
        //
        //
    }

    public static void removePackageName(String name) {
        if (packagesAdded != null) {
            Vector<PackageEntry> vtmp = new Vector<PackageEntry>();
            for (int i = 0; i < packagesAdded.size(); i++) {
                PackageEntry pe = packagesAdded.elementAt(i);
                if (pe.getPackageName().compareTo(name) != 0) {
                    vtmp.addElement(pe);
                }
            }
            packagesAdded = vtmp;
        }
    }

    public static void clearPackagesNames() {
        packagesAdded = null;
    }

    public static void addResourcesPath(String path) throws Exception {
        Node iPaths = Reserved.get(PCoder.RESOURCES_PATH);
        if (iPaths == null) {
            iPaths = Node.createCList();
        }
        if (path != null) {
            boolean commite = true;
            for (int i = 0; i < iPaths.size(); i++) {
                Node entree = iPaths.getSubNode(i,Node.TYPE_STRING);
                if (entree.getString().equals(path)) {
                    commite = false;
                    i = iPaths.size();
                }
            }
            if (commite) {
                Interpreter.Log("Add " + PCoder.RESOURCES_PATH + " : " + path);
                iPaths.addElement(new Node(path));
            }
        }
        Reserved.put(PCoder.RESOURCES_PATH, iPaths);
    }

    public static void addLibrariesPath(String path) throws Exception {
        Node iPaths = Reserved.get(PCoder.LIBRARIES_PATH);
        if (iPaths == null) {
            iPaths = Node.createCList();
        }
        if (path != null) {
            boolean commite = true;
            for (int i = 0; i < iPaths.size(); i++) {
                Node entree = iPaths.getSubNode(i,Node.TYPE_STRING);
                if (entree.getString().equals(path)) {
                    commite = false;
                    i = iPaths.size();
                }
            }
            if (commite) {
                Interpreter.Log("Add " + PCoder.LIBRARIES_PATH + " : " + path);
                iPaths.addElement(new Node(path));
            }
        }
        Reserved.put(PCoder.LIBRARIES_PATH, iPaths);
    }

    public static void addImportsPath(String path) throws Exception {
        Node iPaths = Reserved.get(PCoder.IMPORTS_PATH);
        if (iPaths == null) {
            iPaths = Node.createCList();
        }
        if (path != null) {
            boolean commite = true;
            for (int i = 0; i < iPaths.size(); i++) {
                Node entree = iPaths.getSubNode(i,Node.TYPE_STRING);
                if (entree.getString().equals(path)) {
                    commite = false;
                    i = iPaths.size();
                }
            }
            if (commite) {
                Interpreter.Log("Add " + PCoder.IMPORTS_PATH + " : " + path);
                iPaths.addElement(new Node(path));
            }
        }
        Reserved.put(PCoder.IMPORTS_PATH, iPaths);
    }

    public static final void registerSourceAbsolutePath(String sourceFilePath) throws Exception {
        addImportsPath(Tools.directoryOfFile(sourceFilePath));
        addImportsPath(Tools.directoryOfFile(sourceFilePath) + PCoder.IMPORTS_RELPATH + File.separator);
        addLibrariesPath(Tools.directoryOfFile(sourceFilePath));
        addLibrariesPath(Tools.directoryOfFile(sourceFilePath) + PCoder.LIBRARIES_RELPATH + File.separator);
        addResourcesPath(Tools.directoryOfFile(sourceFilePath));
        addResourcesPath(Tools.directoryOfFile(sourceFilePath) + PCoder.RESOURCES_RELPATH + File.separator);
    }

    private static final boolean isStrInList_(String str, Node nodes) throws Exception {
        boolean res = false;
        for (int i = 0; i < nodes.size(); i++) {
            res = nodes.getSubNode(i,Node.TYPE_STRING).getString().equals(str);
            if (res) {
                i = nodes.size();
            }
        }
        return res;
    }

    public static void addImportsBaseURL(String baseurl) throws Exception {
        Node iPaths = Reserved.get(PCoder.IMPORTS_BASE_URL);
        if (iPaths == null) {
            iPaths = Node.createCList();
        }
        if (baseurl != null && !isStrInList_(baseurl, iPaths)) {
            Interpreter.Log("Add " + PCoder.IMPORTS_BASE_URL + " : " + baseurl);
            iPaths.addElement(new Node(baseurl));
        }
        Reserved.put(PCoder.IMPORTS_BASE_URL, iPaths);
    }

    public static void addLibrariesBaseURL(String baseurl) throws Exception {
        Node iPaths = Reserved.get(PCoder.LIBRARIES_BASE_URL);
        if (iPaths == null) {
            iPaths = Node.createCList();
        }
        if (baseurl != null && !isStrInList_(baseurl, iPaths)) {
            Interpreter.Log("Add " + PCoder.LIBRARIES_BASE_URL + " : " + baseurl);
            iPaths.addElement(new Node(baseurl));
        }
        Reserved.put(PCoder.LIBRARIES_BASE_URL, iPaths);
    }

    public static void addResourcesBaseURL(String baseurl) throws Exception {
        Node iPaths = Reserved.get(PCoder.RESOURCES_BASE_URL);
        if (iPaths == null) {
            iPaths = Node.createCList();
        }
        if (baseurl != null && !isStrInList_(baseurl, iPaths)) {
            Interpreter.Log("Add " + PCoder.RESOURCES_BASE_URL + " : " + baseurl);
            iPaths.addElement(new Node(baseurl));
        }
        Reserved.put(PCoder.RESOURCES_BASE_URL, iPaths);
    }

    public static void addReserved(String packName) throws Exception {
        Interpreter.Log("Add built-in package : " + packName);
        String ressourceName = (packName).replace('/', '.'); // Attention ici à la représentation initiale du packName (dossier avec '/').
        Vector<String> externals = makeReserved(ressourceName);
        String packFilter = packName + ".External_";
        for (int i = 0; i < externals.size(); i++) {
            String cname = (String) externals.elementAt(i);
            //System.out.println("CNAME:"+cname);
            String sname = cname.substring(packFilter.length(), cname.length());
            //System.out.println("SNAME:"+sname);
            //
            //if (!((sname.charAt(0) == '_') || (sname.charAt(sname.length() - 1) == '_'))) {
            sname = sname.replace('_', '-');
            //}
            /*if (sname.startsWith("is-")) {
        sname = sname.substring(3, sname.length()) + "?";
           }*/
            //
            if (Reserved.get(sname) != null) {
                Interpreter.Log(".Replace built-in class : " + sname + " as " + cname);
                Reserved.put(sname, Node.createPattern(cname));
            }
            else {
                Interpreter.Log(".Add built-in class : " + sname + " as " + cname);
                Reserved.put(sname, Node.createPattern(cname));
            }
        }
    }

    public static Node loadLibrary(String packName) throws Exception {
        String ressourceName = (packName).replace('/', '.'); // Attention ici à la représentation initiale du packName (dossier avec '/').
        Vector<String> externals = makeReserved(ressourceName);

        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        InputStream istream = loader.getResourceAsStream(packName + "/" + PCoder.LIBRARY_PROPERTIES);
        Properties props = new Properties();
        props.load(istream);
        String namespace = props.getProperty("name", null);
        if (namespace == null) {
            throw new InterpreterException(StdErrors.extend(StdErrors.External_error, "undefined space-name in " + packName + "/" + PCoder.LIBRARY_PROPERTIES));
        }
        Node library = Node.createNamespace(null);
        Heap libHeap = (Heap)library.getExternal();
        if (ressourceName.startsWith("abstrasy.")) {
            Interpreter.Log("Add built-in external package : " + packName + " as " + namespace + ":*");
        }
        else {
            Interpreter.Log("Add external package : " + packName + " as " + namespace + ":*");
        }
        String packFilter = packName + ".External_";

        for (int i = 0; i < externals.size(); i++) {
            String cname = (String) externals.elementAt(i); // doit cloner l'intitulé de la chaîne...
            //System.out.println("CNAME:"+cname);
            String sname = cname.substring(packFilter.length(), cname.length());
            //System.out.println("SNAME:"+sname);
            //
            if (!((sname.charAt(0) == '_') || (sname.charAt(sname.length() - 1) == '_'))) {
                sname = sname.replace('_', '-');
            }

            if (libHeap.get(sname) != null) {
                Interpreter.Log(".Replace external class : " + namespace + ":" + sname + " as " + cname);
                libHeap.put(sname, Node.createPattern(cname));
            }
            else {
                Interpreter.Log(".Add external class : " + namespace + ":" + sname + " as " + cname);
                libHeap.put(sname, Node.createPattern(cname));
            }
        }

        return library;

    }


    public static void addLibraryReserved(String packName) throws Exception {
        Heap namedH = new Heap();
        String ressourceName = (packName).replace('/', '.'); // Attention ici à la représentation initiale du packName (dossier avec '/').
        Vector<String> externals = makeReserved(ressourceName);

        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        InputStream istream = loader.getResourceAsStream(packName + "/" + PCoder.LIBRARY_PROPERTIES);
        Properties props = new Properties();
        props.load(istream);
        String namespace = props.getProperty("name", null);
        if (namespace == null) {
            throw new InterpreterException(StdErrors.extend(StdErrors.External_error, "undefined space-name in " + packName + "/" + PCoder.LIBRARY_PROPERTIES));
        }
        if (ressourceName.startsWith("abstrasy.")) {
            Interpreter.Log("Add built-in external package : " + packName + " as " + namespace + ":*");
        }
        else {
            Interpreter.Log("Add external package : " + packName + " as " + namespace + ":*");
        }
        String packFilter = packName + ".External_";
        for (int i = 0; i < externals.size(); i++) {
            String cname = (String) externals.elementAt(i); // doit cloner l'intitulé de la chaîne...
            //System.out.println("CNAME:"+cname);
            String sname = cname.substring(packFilter.length(), cname.length());
            //System.out.println("SNAME:"+sname);
            //
            if (!((sname.charAt(0) == '_') || (sname.charAt(sname.length() - 1) == '_'))) {
                sname = sname.replace('_', '-');
            }

            if (namedH.get(sname) != null) {
                Interpreter.Log(".Replace external class : " + namespace + ":" + sname + " as " + cname);
                namedH.put(sname, Node.createPattern(cname));
            }
            else {
                Interpreter.Log(".Add external class : " + namespace + ":" + sname + " as " + cname);
                namedH.put(sname, Node.createPattern(cname));
            }
        }

        synchronized (Interpreter.Modules) {
            if (Interpreter.Modules == null) {
                Interpreter.Log("WARNING : Libraries null !!!...");
                throw new InterpreterException(StdErrors.Internal_error);
            }
            if (Interpreter.Modules.get(namespace) != null) {
                Interpreter.Log(".Mixin library : " + namespace + ":* ...");
                //throw new InterpreterException(InterpreterException.EC_EXTERNAL,
                //                               "Espace de nommage déjà défini : " + namespace + ":* pour " + packName);
                /**
                 * fusionner...
                 *
           */
                Node modNode = Interpreter.Modules.get(namespace);
                Heap modHeap = (Heap)modNode.getExternal();
                modHeap.fusion(namedH);

            }
            else {
                Interpreter.Log(".Add library : " + namespace + "...");
                Interpreter.Modules.put(namespace, Node.createNamespace(namedH));
            }
        }
    }

    public static Node plugLibrary_jar(File jarFile) throws Exception {
        String class_path = System.getProperty("java.class.path");
        String path_separator = System.getProperty("path.separator");
        if (class_path.indexOf(path_separator + jarFile.getAbsolutePath()) < 0) {

            // le plugin n'est pas déjà inséré...
            try {
                Interpreter.Log("Loading external library : " + jarFile.getAbsolutePath() + " ...");
                // trouver les noms de packages principaux...
                Vector<String> packages = new Vector<String>();
                InputStream is = new BufferedInputStream(new FileInputStream(jarFile));
                JarInputStream jis = new JarInputStream(is);
                JarEntry entry;
                while ((entry = jis.getNextJarEntry()) != null) {
                    try {
                        //parse the class name
                        String cName = entry.getName();
                        if ((cName.indexOf('/') >= 0)) {
                            String package_name = cName.split("/")[0];
                            if (!cName.equals("META-INF")) {
                                boolean found = false;
                                for (int i = 0; i < packages.size(); i++) {
                                    found = (packages.elementAt(i)).equals(package_name);
                                    if (found) {
                                        i = packages.size();
                                    }
                                }
                                if (!found) {
                                    packages.addElement(package_name);
                                    Interpreter.Log(".Finding external package : " + package_name + " ...");
                                }
                            }
                        }
                    }
                    catch (Exception e) {
                        if (Interpreter.isDebugMode()) {
                            e.printStackTrace();
                        }
                        //don't do anything - we want to keep looping
                    }
                }

                // insérer le plugin:
                String jURL = "jar:" + jarFile.toURI().toURL().toString() + "!/";
                URL[] urls = { new URL(jURL) };
                class_path += path_separator + jarFile.getAbsolutePath();
                System.setProperty("java.class.path", class_path);
                ClassLoader aCL = Thread.currentThread().getContextClassLoader();
                URLClassLoader aUrlCL = new URLClassLoader(urls, aCL);
                Thread.currentThread().setContextClassLoader(aUrlCL);
                if (packages.size() > 1) {
                    throw new InterpreterException(StdErrors.extend(StdErrors.Library_error, "More than one package"));
                }
                return loadLibrary((String) packages.elementAt(0));


            }
            catch (Exception ex) {
                Interpreter.Log(ex.getMessage());
                if (Interpreter.isDebugMode()) {
                    ex.printStackTrace();
                }
                throw new InterpreterException(StdErrors.Library_error);
            }
        }
        return null;
    }


    public static void linkResources_jar(File jarFile) throws Exception {
        String class_path = System.getProperty("java.class.path");
        String path_separator = System.getProperty("path.separator");
        if (class_path.indexOf(path_separator + jarFile.getAbsolutePath()) < 0) {

            // le plugin n'est pas déjà inséré...
            try {
                Interpreter.Log("Link external resources : " + jarFile.getAbsolutePath() + " ...");
                // Etablir la liaison avec la paquetage de resources...
                String jURL = "jar:" + jarFile.toURI().toURL().toString() + "!/";
                URL[] urls = { new URL(jURL) };
                class_path += path_separator + jarFile.getAbsolutePath();
                System.setProperty("java.class.path", class_path);
                ClassLoader aCL = Thread.currentThread().getContextClassLoader();
                URLClassLoader aUrlCL = new URLClassLoader(urls, aCL);
                Thread.currentThread().setContextClassLoader(aUrlCL);

                // on lie simplement la resource dans le classpath...

            }
            catch (Exception ex) {
                Interpreter.Log(ex.getMessage());
                if (Interpreter.isDebugMode()) {
                    ex.printStackTrace();
                }
                throw new InterpreterException(StdErrors.Resource_error);
            }
        }
    }


    public static void classpath_addFile(String s) throws IOException {
        File f = new File(s);
        classpath_addFile(f);
    } //end method

    public static void classpath_addFile(File f) throws IOException {
        classpath_addURL(f.toURI().toURL());
    } //end method

    private static final Class<?>[] __parameters = new Class<?>[] { URL.class };

    public static void classpath_addURL(URL u) throws IOException {
        URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader();
        Class<?> sysclass = URLClassLoader.class;
        try {
            Method method = sysclass.getDeclaredMethod("addURL", __parameters);
            method.setAccessible(true);
            method.invoke(sysloader, new Object[] { u });
        }
        catch (Throwable t) {
            if (Interpreter.isDebugMode()) {
                t.printStackTrace();
            }
            throw new IOException("Error, could not add URL to system classloader");
        } //end try catch
    } //end method

    private static final String getFileNameFromURL(URL url) {
        String ufstr = url.toString().replace(File.separatorChar, '/'); // attention à Windows ??? \dir -> /dir !!!
        String path_separator = "/";
        int lasti = ufstr.lastIndexOf(path_separator, ufstr.length());
        return ufstr.substring((lasti < 0 ? 0: lasti), ufstr.length());
    }

    private static final String getDirectoryNameFromURL(URL url) {
        String ufstr = url.toString().replace(File.separatorChar, '/'); // attention à Windows ??? \dir -> /dir !!!
        String path_separator = "/";
        int lasti = ufstr.lastIndexOf(path_separator, (ufstr.charAt(ufstr.length() - 1) == '/' ? ufstr.length() - 1: ufstr.length()));
        return ufstr.substring((lasti < 0 ? 0: lasti), (ufstr.charAt(ufstr.length() - 1) == '/' ? ufstr.length() - 1: ufstr.length()));
    }

    private static String getNewEAIC() {
        String temp_path = System.getProperty("java.io.tmpdir");
        String res = null;
        File fres = null;
        while (res == null) {
            // création d'un Extension Abstrasy Interpretor Contex ...
            res = temp_path + File.separator + "EAIC-" + java.util.UUID.randomUUID().toString();
            fres = new File(res);
            if (fres.exists()) {
                res = null;
            }
        }
        fres.mkdirs();
        Interpreter.Log("Extended Abstrasy Cache " + res + " created...");
        return res;
    }

    private static synchronized void removeEAIC() {
        if (EAIC_TEMP_DIR != null) {
            File eaicd = new File(EAIC_TEMP_DIR);
            if (eaicd.exists()) {
                File[] eaicf = eaicd.listFiles();
                for (int i = 0; i < eaicf.length; i++) {
                    try {
                        eaicf[i].delete();
                    }
                    finally {
                    }
                }
                try {
                    eaicd.delete();
                }
                finally {
                }
                EAIC_TEMP_DIR = null;
                Interpreter.Log("Extended Abstrasy Cache " + eaicd.getAbsolutePath() + " removed...");
            }
        }
    }

    public static synchronized void resetEAIC() {
        if (EAIC_TEMP_DIR != null) {
            Interpreter.Log("Extended Abstrasy Cache resetting...");
            removeEAIC();
            //EAIC_TEMP_DIR = getNewEAIC();
        }
    }

    private static String EAIC_TEMP_DIR = null;

    public static synchronized String getCurrentEAIC() {
        if (EAIC_TEMP_DIR == null) {
            EAIC_TEMP_DIR = getNewEAIC();
        }
        return EAIC_TEMP_DIR;
    }

    static {
        Runtime.getRuntime().addShutdownHook(new Thread() {

                public void run() {
                    Interpreter.removeEAIC();
                }

            });
    }

    public static void linkResources_jar(URL jarFile) throws Exception {
        /**
     * Le principe ne marche pas avec un accès direct à l'URL...
     * Il est donc nécessaire de rapatrier le fichier avant de poursuivre...
     */
        String class_path = System.getProperty("java.class.path");
        //System.out.println("CLASSPATH: "+class_path);
        String path_separator = System.getProperty("path.separator");
        String tmpJFN = getCurrentEAIC() + File.separator + getFileNameFromURL(jarFile);
        if (class_path.indexOf(path_separator + new File(tmpJFN).getAbsolutePath()) < 0) {

            // le plugin n'est pas déjà inséré...
            try {
                Interpreter.Log("Get external resources : " + getFileNameFromURL(jarFile) + " from URL \"" + jarFile.toString() + "\" ...");
                InputStream is = new BufferedInputStream(jarFile.openStream());
                String tempFileN = tmpJFN;
                File tempFile = new File(tempFileN);
                if (tempFile.exists()) {
                    tempFile.delete();
                }
                FileOutputStream fos = new FileOutputStream(tempFile);
                byte[] sb = new byte[65536];
                while (true) {
                    int stb = is.read(sb);
                    if (stb == -1) {
                        break;
                    }
                    fos.write(sb, 0, stb);
                }
                is.close();
                fos.close();
                linkResources_jar(tempFile); // et puis on fait le lien...
            }
            catch (Exception ex) {
                if (Interpreter.isDebugMode()) {
                    ex.printStackTrace();
                }
                throw new Exception(ex.getMessage());
            }

        }

    }

    public static Node plugLibrary_jar(URL jarFile) throws Exception {
        /**
     * Le principe ne marche pas avec un accès direct à l'URL...
     * Il est donc nécessaire de rapatrier le fichier avant de poursuivre...
     */
        String class_path = System.getProperty("java.class.path");
        //System.out.println("CLASSPATH: "+class_path);
        String path_separator = System.getProperty("path.separator");
        String tmpJFN = getCurrentEAIC() + File.separator + getFileNameFromURL(jarFile);
        if (class_path.indexOf(path_separator + new File(tmpJFN).getAbsolutePath()) < 0) {

            // le plugin n'est pas déjà inséré...
            try {
                Interpreter.Log("Get external library : " + getFileNameFromURL(jarFile) + " from URL \"" + jarFile.toString() + "\" ...");
                InputStream is = new BufferedInputStream(jarFile.openStream());
                String tempFileN = tmpJFN;
                File tempFile = new File(tempFileN);
                if (tempFile.exists()) {
                    tempFile.delete();
                }
                FileOutputStream fos = new FileOutputStream(tempFile);
                byte[] sb = new byte[65536];
                while (true) {
                    int stb = is.read(sb);
                    if (stb == -1) {
                        break;
                    }
                    fos.write(sb, 0, stb);
                }
                is.close();
                fos.close();
                return plugLibrary_jar(tempFile);
            }
            catch (Exception ex) {
                if (Interpreter.isDebugMode()) {
                    ex.printStackTrace();
                }
                throw new Exception(ex.getMessage());
            }

        }

        return null;

    }

    /**
     * Charge tous les composants par défaut nécessaire au fonctionnement de l'interpréteur.
     *
     * @throws Exception
     */
    public static void makeDefaultReserved() throws Exception {
        addLibrariesPath(null); // réinitialiser la liste
        addImportsPath(null); // réinitialiser la liste
        addResourcesPath(null); //réinitialiser la liste
        addLibrariesPath(getCurrentDirectory());
        addLibrariesPath(getCurrentDirectory() + PCoder.LIBRARIES_RELPATH + File.separator);
        addImportsPath(getCurrentDirectory());
        addImportsPath(getCurrentDirectory() + PCoder.IMPORTS_RELPATH + File.separator);
        addResourcesPath(getCurrentDirectory());
        addResourcesPath(getCurrentDirectory() + PCoder.RESOURCES_RELPATH + File.separator);
        addImportsBaseURL(null); // réinitialiser la liste
        addLibrariesBaseURL(null); // réinitialiser la liste
        addResourcesBaseURL(null); // réinitialiser la liste
        addImportsBaseURL(getInterpreterImportsBaseURL());
        addLibrariesBaseURL(getInterpreterLibrariesBaseURL());
        addResourcesBaseURL(getInterpreterResourcesBaseURL());
        String packName = AExtTools.class.getPackage().getName();
        addReserved(packName);
        if (packagesAdded != null) {
            for (int i = 0; i < packagesAdded.size(); i++) {
                PackageEntry pe = packagesAdded.elementAt(i);
                addLibraryReserved(pe.getPackageName());
            }
        }
    }

    public static Vector<String> makeReserved(String packName) {
        Vector<String> r1 = new Vector<String>();
        String packFilter = packName + ".External_";
        //System.out.println("makeReserved: "+ packName);
        ListPackageContents lpc = new ListPackageContents(packName, false);
        Iterator<String> iter = lpc.getPackageContents().iterator();
        while (iter.hasNext()) {
            String item = iter.next();
            //System.out.println("makeReserved : "+item);
            if (item.startsWith(packFilter) && (item.indexOf('$') < 0)) {
                r1.addElement(item);
            }
        }
        return r1;
    }

    public static String getInterpreterImportsBaseURL() {
        String underFile = "_.properties";
        URL url = Interpreter.class.getResource(PCoder.IMPORTS_RELPATH + "/" + underFile);
        String ts2 = url.toString();
        String res = ts2.substring(0, ts2.length() - underFile.length());
        return res;
    }

    public static String getInterpreterLibrariesBaseURL() {
        String underFile = "_.properties";
        URL url = Interpreter.class.getResource(PCoder.LIBRARIES_RELPATH + "/" + underFile);
        String ts2 = url.toString();
        String res = ts2.substring(0, ts2.length() - underFile.length());
        return res;
    }

    public static String getInterpreterResourcesBaseURL() {
        String underFile = "_.properties";
        URL url = Interpreter.class.getResource(PCoder.RESOURCES_RELPATH + "/" + underFile);
        String ts2 = url.toString();
        String res = ts2.substring(0, ts2.length() - underFile.length());
        return res;
    }

    public static String getCurrentDirectory() {
        String cd = new File(".").getAbsolutePath();
        if (cd.endsWith(".")) {
            cd = cd.substring(0, cd.length() - 1);
        }
        return cd;
    }

    private final void _check_GLOBAL(){
        if (GLOBAL == null) {
            this.GLOBAL = new StaticHeap(DEFAULT_STATICHEAP_SIZE);
            this.GLOBAL.push(BuiltIn_Reserved);
            this.GLOBAL.push(Reserved);
            //this.GLOBAL.push(Libraries);
            this.GLOBAL.push(Application_Heaps);
            this.GLOBAL.push();
        }
    }

    public void softReset() {
        this.executionTimeOut = 15000;
        this.deadlockTime = 0;
        this.timeOutCheck = false;
        this.breakingFromSEMAPHORE = false;
        this.endingFromSEMAPHORE = false;
        this.inLoop = false;
        this.canLoop = false;
        this.failOver = false;
        this.returnedNode = null;
        this.lastException = null;
        this.node = null;
        this.returnedNode = null;
        this.lastException = null;
        this.source = null;
        this.GLOBAL = null;
        Application_Heaps = Interpreter.new_Application_Heap();
        _check_GLOBAL();
        this.threadlock_A.clear();
        this.threadlock_R.clear();
        this.pendingMsg = null;
    }

    public void hardReset() throws Exception {
        Reserved = new Heap();
        Modules = new Heap();
        resetEAIC();
        softReset();
        makeDefaultReserved();
    }


    public static final String SUPERINTERPRETER_THREAD_NAME = "__Supervisor__";

    private static Interpreter _superInterpreter = null;

    private static final void interpr_resetSuperInterpreter() throws Exception {
        _superInterpreter.hardReset();
        _superInterpreter.setName(SUPERINTERPRETER_THREAD_NAME);
    }

    /**
     * Retourne l'instance du super-interpreteur (le thread superviseur).
     * Dans le même temps, cette méthode permet de réinitialiser la VM.
     * Pour cela, il suffit de placer forceReset sur true.
     * @param forceReset
     * @return instance du super-interpreter
     */
    public static final int GETSUPERINTERPRETER_LESSMODE = 0;
    public static final int GETSUPERINTERPRETER_HARDMODE = 1;
    public static final int GETSUPERINTERPRETER_SOFTMODE = 2;

    public static final Interpreter interpr_getSuperInterpreter(int gsi_mode) throws Exception {
        if (_superInterpreter == null || (gsi_mode != GETSUPERINTERPRETER_LESSMODE)) {
            _superInterpreter = new Interpreter();
        }
        if (gsi_mode == GETSUPERINTERPRETER_HARDMODE) {
            interpr_resetSuperInterpreter();
        }
        else if (gsi_mode == GETSUPERINTERPRETER_SOFTMODE) {
            _superInterpreter.softReset();
        }
        return _superInterpreter;
    }

    /**
     * Retourne une nouvel interpreter fils sans paramètres spécifiques.
     * @return
     */
    public static final Interpreter interpr_getNewChildInterpreter() {
        Interpreter interp = new Interpreter();
        interp.setName(Interpreter.mySelf().getName() + "-child");
        return interp;
    }

    public static final Interpreter interpr_getNewThreadInterpreter(String threadName) {
        Interpreter interpreter = Interpreter.mySelf();
        Interpreter interp = new Interpreter();
        interp.motherThread = interpreter;
        interp.source = interpreter.source;
        interp.node = interpreter.node;
        interp.outputTextArea = interpreter.outputTextArea;
        interp.executionTimeOut = interpreter.executionTimeOut;
        interp.deadlockTime = interpreter.deadlockTime;
        interp.timeOutCheck = interpreter.timeOutCheck;
        interp.breakingFromSEMAPHORE = interpreter.breakingFromSEMAPHORE;
        synchronized (interpreter.GLOBAL) {
            interp.GLOBAL = new StaticHeap(interpreter.GLOBAL);
            /* Correctif du bug launchpad#1017442, l.bruninx (2012-06-25) */
            interp.GLOBAL.push();
            interp.GLOBAL.current().put(PCoder.ARGV, Node.createCList());
            interp.GLOBAL.push();
            /* Correctif du bug launchpad#1017442, l.bruninx (2012-06-25) */
        }
        interp.setInterThread(true);
        //this.setPriority(interpreter.getPriority()+1);
        interp.parse_strCnt = interpreter.parse_strCnt;
        interp.parse_parCnt = interpreter.parse_parCnt;
        interp.parse_dicCnt = interpreter.parse_dicCnt;
        interp.parse_accCnt = interpreter.parse_accCnt;
        interp.parse_croCnt = interpreter.parse_croCnt;
        interp.parse_linCnt = interpreter.parse_linCnt;
        interp.parse_strLineOffset = interpreter.parse_strLineOffset;
        synchronized (semaphore) {
            if (threadName != null && threadName.trim().length() != 0) {
                String nThreadName = threadName;
                int index = 0;
                while (semaphore.isThreadsExists(threadName)) {
                    nThreadName = threadName + "-" + Integer.toString(++index);
                }
                interp.setName(nThreadName);
            }
            else {
                String nThreadName = semaphore.getUniqueThreadName();
                interp.setName(nThreadName);
            }
            Interpreter.Log("Register thread " + interp);
            Interpreter.semaphore.registerThread(interp);
        }
        return interp;
    }

    public static final Interpreter interpr_cloneInterpreter(Interpreter interpreter) {
        Interpreter interp = new Interpreter();
        interp.motherThread = interpreter;
        interp.source = interpreter.source;
        interp.node = interpreter.node;
        interp.outputTextArea = interpreter.outputTextArea;
        interp.executionTimeOut = interpreter.executionTimeOut;
        interp.deadlockTime = interpreter.deadlockTime;
        interp.timeOutCheck = interpreter.timeOutCheck;
        interp.breakingFromSEMAPHORE = interpreter.breakingFromSEMAPHORE;
        synchronized (interpreter.GLOBAL) {
            interp.GLOBAL = new StaticHeap(interpreter.GLOBAL);
        }
        interp.setInterThread(interpreter.isInterThread());
        //this.setPriority(interpreter.getPriority()+1);
        // interp.setExitCode(interpreter.getExitCode()); !!! ATTENTION : NE PAS UTILISER -> force l'arret de l'interpreteur...
        interp.parse_strCnt = interpreter.parse_strCnt;
        interp.parse_parCnt = interpreter.parse_parCnt;
        interp.parse_dicCnt = interpreter.parse_dicCnt;
        interp.parse_accCnt = interpreter.parse_accCnt;
        interp.parse_croCnt = interpreter.parse_croCnt;
        interp.parse_linCnt = interpreter.parse_linCnt;
        interp.parse_strLineOffset = interpreter.parse_strLineOffset;
        synchronized (semaphore) {
            String threadName = interpreter.getName();
            if (threadName != null && threadName.trim().length() != 0) {
                String nThreadName = threadName;
                int index = 0;
                while (semaphore.isThreadsExists(threadName)) {
                    nThreadName = threadName + "-" + Integer.toString(++index);
                }
                interp.setName(nThreadName);
            }
            else {
                String nThreadName = semaphore.getUniqueThreadName();
                interp.setName(nThreadName);
            }
            Interpreter.Log("Register thread " + interp);
            Interpreter.semaphore.registerThread(interp);
        }
        return interp;
    }


    private Exception interThreadException = null;

    public void setInterThreadException(Exception ex, Interpreter interThrd) {
        if (Interpreter.isDebugMode()) {
            ex.printStackTrace();
        }
        interThreadException = new InterpreterException(StdErrors.createTrace(interThrd, ex));
    }

    /**
     * Détection automatique des deadlocks et livelocks...
     */
    // liste non bloquante des verrous acquis...
    private ConcurrentLinkedQueue<Node> threadlock_A = new ConcurrentLinkedQueue<Node>();
    // liste non bloquante des verrous demandé (donc en attente)...
    private ConcurrentLinkedQueue<Node> threadlock_R = new ConcurrentLinkedQueue<Node>();

    public void threadlock_A_add(Node node) {
        threadlock_A.add(node);
    }

    public void threadlock_A_remove(Node node) {
        threadlock_A.remove(node);
    }

    public boolean threadlock_A_has(Node node) {
        return threadlock_A.contains(node);
    }

    public void threadlock_R_add(Node node) {
        threadlock_R.add(node);
    }

    public void threadlock_R_remove(Node node) {
        threadlock_R.remove(node);
    }

    public boolean threadlock_R_has(Node node) {
        return threadlock_R.contains(node);
    }

    public void thowsDeadlock(Interpreter inter) throws InterpreterException {
        /*
         * Est-ce que je demande un verrous ?...
         */
        if (inter != null && inter != this && !threadlock_R.isEmpty()) {
            /*
             * Détecter une circularité...
             * ========================
             *
             * Pour commencer, est-ce qu'un de mes verrous acquis est demandé par l'autre processus ?...
             */
            boolean hasA = false;
            Iterator<Node> myA = threadlock_A.iterator();
            while (myA.hasNext() && !hasA) {
                hasA = hasA || inter.threadlock_R_has(myA.next()); // or pour passer à true s'il y en a un...
            }
            if (hasA) {
                /*
                 * Si un de mes verrous est demandé par l'autre processus...
                 * Est-ce qu'un des verrous que je demande est déjà aquis par lui ?...
                 */
                boolean hasR = false;
                Iterator<Node> myR = threadlock_R.iterator();
                while (myR.hasNext() && !hasR) {
                    hasR = hasR || inter.threadlock_A_has(myR.next()); // or pour passer à true s'il y en a un...
                }
                /*
                 * Si c'est le cas aussi, alors nous sommes inter-bloqués...
                 */
                if (hasA && hasR) {
                    throw new InterpreterException(StdErrors.Deadlock_error);
                }
            }
        }
        /*
         * sinon, pas de problème....
         */
        return;
    }


    /**
     * Gestion des piles du processus courant
     */
   
    /*
     * Piles pour l'opérateur/méthode equ?:
     * -----------------------------------
     *  Permet d'éliminer l'exploration inutile des éléments circulaires.
     */
    private NodeTags equStack_A = new NodeTags();
   
    public NodeTags getEquStack_A(){
        return equStack_A;
    }
   
    private NodeTags equStack_B = new NodeTags();
   
    public NodeTags getEquStack_B(){
        return equStack_B;
    }
   
    /*
     * Piles pour l'opérateur/méthode compare:
     * --------------------------------------
     *  Permet d'éliminer l'exploration inutile des éléments circulaires.
     */
    private NodeTags compareStack_A = new NodeTags();
   
    public NodeTags getCompareStack_A(){
        return compareStack_A;
    }
   
    private NodeTags compareStack_B = new NodeTags();
   
    public NodeTags getCompareStack_B(){
        return compareStack_B;
    }
   
    /**
     * Gestion générale des threads: Hooks, messages et signaux...
     */

    private boolean threadStop = false;
    private boolean threadSuspend = false;
    private int threadLock = 0; // compteur de verroux (à partir de rev6251)
    private int threadInLockSection = 0; // compteur de section (lock v{...})...
    static private Vector<WeakReference<Runnable>> supervisorHooks = new Vector<WeakReference<Runnable>>();
    private ConcurrentLinkedQueue<Node> threadMessages = new ConcurrentLinkedQueue<Node>();
    private ConcurrentLinkedQueue<Object> threadSignals = new ConcurrentLinkedQueue<Object>();


    final private static Object DEFAULT_SIGNAL = new Object();

    private Object threadSuspendLock = new Object();

    public Object thread_getSuspendLock() {
        return threadSuspendLock;
    }

    public boolean isThreadSuspended() {
        return threadSuspend;
    }

    public boolean isThreadStopped() {
        // cas fail-over...
        if (failOver) {
            return false;
        }
        // traitement habituel...
        return threadStop;
    }

    public void setThreadStopped(boolean stopstatus) {
        threadStop = stopstatus;
    }

    public boolean isThreadRaising() throws Exception {
        // cas fail-over...
        if (failOver) {
            return false;
        }
        // traitement habituel...
        throwInterThreadException();
        return threadStop || timeOutRaising || breakingFromSEMAPHORE;
    }

    /** **********************************************
     *
     *       Implementation du Modèle d'acteurs:
     *
     *  **********************************************
     *
     *  Tous les processus légers sont des acteurs.
     *  Il y a un acteur principal, il s'agit du superviseur.
     *  Les acteurs peuvent requérir un traitement atomique de certaines actions.
     *  Un acteur peut s'endormir (pendant un certain délai) lui-même uniquement.
     *  Un acteur peut se suspendre lui-même uniquement.
     *  Un acteur peut en réveiller un autre mais jamais lui-même.
     *  Un acteur peut tuer un autre acteur mais jamais lui-même.
     *  Le acteurs communiquent entre eux par l'envoie et la réception de messages.
     *
     *  Le superviseur peut recevoir un hook qui est une tâche à effectuer lors de l'arrêt du processus superviseur.
     *
     */

    /**
     * Gestion de l'acteur principal : le superviseur.
     *
     */

    /**
     * obtenir l'objet Interpreter du superviseur
     * @return
     */
    static public Interpreter supervisor_getInterpreter() {
        return _superInterpreter;
    }

    /**
     * ajouter un hook au superviseur.
     * @param hook
     */
    static public Object supervisor_PUTHOOK(Runnable hook) {
        WeakReference<Runnable> weakRef = new WeakReference<Runnable>(hook);
        synchronized (supervisorHooks) {
            supervisorHooks.addElement(weakRef);
        }
        return weakRef;
    }

    /**
     * Supprimer le hook sans l'exécuter
     *
     * @param weakRef
     */
    static public void supervisor_REMOVEHOOK(Object weakRef) {
        synchronized (supervisorHooks) {
            if (weakRef != null) {
                supervisorHooks.remove(weakRef);
                WeakReference<?> wref = (WeakReference<?>) weakRef;
                wref.clear();
            }

        }
    }

    static private Runnable supervisor_GETHOOK() {
        Runnable res = null;
        synchronized (supervisorHooks) {
            int queue = supervisorHooks.size() - 1;
            if (queue >= 0) {
                WeakReference<Runnable> weakRef = supervisorHooks.elementAt(queue);
                supervisorHooks.remove(queue);
                res = weakRef.get();
            }
        }
        return res;
    }

    static public boolean supervisor_HASHOOK() {
        boolean res = false;
        synchronized (supervisorHooks) {
            res = (supervisorHooks.size() > 0);
        }
        return res;
    }

    static private void supervisor_CONSUMEHOOK() {
        synchronized (supervisorHooks) {
            while (supervisorHooks.size() > 0) {
                Interpreter.Log("   --> CONSUMEHOOK #" + supervisorHooks.size() + "...");
                Runnable hook = supervisor_GETHOOK();
                if (hook != null) {
                    try {
                        hook.run();
                    }
                    finally {
                    }
                }
            }


        }
        return;
    }

    public void actor_PUTMSG(Node node) {
        //synchronized (threadMessages) {
        threadMessages.add(node);
        //}
    }

    public Node actor_GETMSG() {
        //Node res = null;
        //synchronized (threadMessages) {
        //  if (threadMessages.size() > 0) {
        //    res = (Node) threadMessages.elementAt(0);
        //    threadMessages.remove(0);
        //  }
        //}
        return (Node) threadMessages.poll();
        //return res;
    }

    public boolean actor_HASMSG() {
        //boolean res = false;
        //synchronized (threadMessages) {
        return (threadMessages.size() > 0);
        //}
        //return res;
        //
        // La méthode size() est déjà synchronisée...
    }

    public void actor_EMPTYMSGS() {
        //synchronized (threadMessages) {
        if (threadMessages.size() > 0) {
            Interpreter.Log("   --> REMOVING " + threadMessages.size() + " THREAD-MSG...");
        }
        threadMessages.clear();
        //threadMessages.removeAllElements();
        //}
        return;
    }

    public void actor_SIGNAL() {
        //synchronized (threadSignals) {
        threadSignals.add(DEFAULT_SIGNAL);
        //}
    }

    public boolean actor_CONSUMESIGNAL() {
        //boolean res = false;
        //synchronized (threadSignals) {
        //  if (threadSignals.size() > 0) {
        //    res = true;
        //    threadSignals.remove(0);
        //  }
        //}
        return threadSignals.poll() != null;
    }

    public boolean actor_HASSIGNALS() {
        boolean res = false;
        //synchronized (threadSignals) {
        res = (threadSignals.size() > 0);
        //}
        return res;
    }

    public void actor_EMPTYSIGNALS() {
        //synchronized (threadSignals) {
        if (threadSignals.size() > 0) {
            Interpreter.Log("   --> REMOVING " + threadSignals.size() + " THREAD-SIGNALS...");
        }
        //threadSignals.removeAllElements();
        threadSignals.clear();
        //}
        return;
    }

    /*
     * actor_LOCKMUTEX et actor_UNLOCKMUTEX ne devraient être accédé qu'à partir de l'acteur lui-même.
     * Ces méthodes n'ont donc pas besoin d'être synchronisées.
     */

    public void actor_LOCKMUTEX() {
        threadLock++;
    }

    public void actor_UNLOCKMUTEX() {
        threadLock--;
    }

    public boolean actor_ISMUTEX() {
        return threadLock != 0;
    }

    /*
     * actor_LOCKSECTION, actor_UNLOCKSECTION, et actor_ISLOCKEDSECTION ne devraient être accédée qu'à partir de
     * l'acteur lui-même pour marquer les sections atomiques.
     * Il n'y adonc pas besoin de synchronisation.
     */

    public void actor_LOCKSECTION() {
        threadInLockSection++;
    }

    public void actor_UNLOCKSECTION() {
        threadInLockSection--;
    }

    public boolean actor_ISLOCKEDSECTION() {
        return threadInLockSection != 0;
    }

    /*
     * Il ne devrait pas y avoir de compétition pour accéder à actor_STOP.
     * Il est donc inutile de synchronizer la méthode.
     */

    public void actor_STOP() {
        threadStop = true;
    }


    /*
     * Situation de compétition possible, mais devrait être extraimement rare.
     * Utiliser donc une stratégie optimiste du type test-and-set
     */

    public void actor_SUSPEND() {
        while (!threadSuspend) {
            threadSuspend = true;
        }
    }

    public void actor_RESUME() {
        while (threadSuspend) {
            threadSuspend = false;
        }
    }

    /**
     *
     * Gestion des listes des messages postposés (c-à-d mis en attente).
     *
     **/
    private LinkedList<Node> pendingMsg = null;
    /*
     * Permet l'implémentation de (pending{ ... (postpone msg)...})
     * Les message postposés sont ajoutés à la fin de la queue (pendingMsg).
     * Lorsqu'on sort de la section controlée par pending, tous les messages postposés sont replacés dans la boite
     * de réception.
     *
     *
     */

    /**
     * Ouvre une nouvelle queue de messages en attente.
     *
     * @return la référence de la liste précédente
     */
    public LinkedList<Node> pendingMsg_OPEN() {
        LinkedList<Node> old = pendingMsg;
        pendingMsg = new LinkedList<Node>();
        return old;
    }

    /**
     * Ferme la queue de message en attente courrante et restaure la précédente.
     *
     * En fermant la queue courante, les éventuels messages qu'elle contient sont
     * automatiquement ajouté à la boite à message de l'acteur.
     *
     * @param old : ancienne queue retournée par pendingMsg_OPEN().
     */
    public void pendingMsg_CLOSE(LinkedList<Node> old) throws Exception {
        if (!pendingMsg.isEmpty()) {
            if (!threadMessages.addAll(pendingMsg)) {
                /*
                 * Si le ou les messages ne peuvent être ajoutés, une exception doit être produite...
                 */
                throw new InterpreterException(StdErrors.Internal_error);
            }
        }
        pendingMsg = old;
    }

    /**
     * Teste si une queue de messages en attente a été ouverte...
     *
     * @return true si une queue est disponible.
     */
    public boolean pendingMsg_HASQUEUE() {
        return pendingMsg != null;
    }

    /**
     * Ajoute le message postposé à la fin de la queue pendingMsg.
     * @param message
     */
    public void pendingMsg_POSTPONE(Node message) throws Exception {
        if (!pendingMsg.add(message)) {
            /*
             * Si le message ne peut être ajouté, une exception doit être produite...
             */
            throw new InterpreterException(StdErrors.Internal_error);
        }
    }

    /**
     * Teste s'il y a des messages mis en d'attente.
     *
     * Attention, s'il n'y a pas de liste d'attente, il n'y a pas de message en attente non plus...
     *
     * @return true, s'il y a des messages en attente.
     */
    public boolean pendingMsg_HASPOSTPONED() {
        return pendingMsg != null && !pendingMsg.isEmpty();
    }

    /*
     * Gestion fail-over pour hiniber l'arrêt brutal de l'interpréteur...
     */
    private boolean failOver = false;

    public final void setFailOver(boolean failOver) {
        this.failOver = failOver;
    }

    public final boolean isFailOver() {
        return failOver;
    }

    /*
     * Lancement d'exception en fonction de l'état de l'interpréteur...
     */

    public final void throwInterThreadException() throws Exception {

        if (failOver)
            return;


        if (interThreadException != null) {
            // fin Exception dans un thread fils...
            if (timeOutTimer.isRunning()) {
                timeOutTimer.stop();
            }
            Exception ex = interThreadException;
            interThreadException = null;
            throw ex;
        }

        if (breakingFromSEMAPHORE) {
            // fin Breaking...
            if (timeOutTimer.isRunning()) {
                timeOutTimer.stop();
            }
            throw new InterpreterException(StdErrors.Breaking_exception);
        }

        if (timeOutRaising) {
            // fin TimeOut Raising...
            if (timeOutTimer.isRunning()) {
                timeOutTimer.stop();
            }
            timeOutCheck = false;
            timeOutRaising = false;

            throw new InterpreterException(StdErrors.Timed_expired_exception);
        }

        if (endingFromSEMAPHORE || threadStop) {
            // fin silencieuse
            if (timeOutTimer.isRunning()) {
                timeOutTimer.stop();
            }
            throw new SilentException();
        }

    }

    /*
     * Optimisation Java 6 : suppression du NodePool au bénéfice du GC de la JVM.
     * -------------------------------------------------------------------------
     *
     * 27 janvier 2011.
     *
     */

    public final static Interpreter mySelf() {
        Thread rThread = Thread.currentThread();
        if (rThread instanceof Interpreter) {
            Interpreter ms = (Interpreter) rThread;
            if (ms.isInterThread()) {
                ms.breakingFromSEMAPHORE = Interpreter.semaphore.isSignalBreak();
                ms.endingFromSEMAPHORE = Interpreter.semaphore.isSignalEnd();
            }
            return ms;
        }
        return null;
    }

    /*
     * Le paramètre canLoop est automatiquement restauré lors de la sortie d'une
     * boucle itérative.
     *
     * Cette restauration est également réalisée en cas d'exception.
     */

    public final void setCanLoop(boolean canLoop) {
        this.canLoop = canLoop;
    }

    public final boolean isCanLoop() {
        return canLoop;
    }

    public final void setInLoop(boolean inLoop) {
        this.inLoop = inLoop;
    }

    public final boolean isInLoop() {
        return inLoop;
    }


    /*
     * Remplace le couple de tests: isCanLoop() && hasNoBreakCode() de manière à permettre un test supplémentaire:
     *  -Si isCanLoop()->true et hasNoBreakCode()->false (avec BREAKCODE_LOOP), il s'agit d'un skip-loop
     */

    public final boolean isCanIterate() {
        if (canLoop) {
            switch(breakCode){
                case BREAKCODE_NONE:
                    return true;
                case BREAKCODE_LOOP:
                    // canLook est affirmatif, aussi on absorbe ce break-loop...
                    // il s'agit d'un skip-loop...
                    breakCode = BREAKCODE_NONE;
                    return true;
                default:
                    return false;
            }
        }
        else {
            // autres ??!... Alors on arrête...
            return false;
            }
    }

    private Interpreter __thisInterpreter = null;

    private Node interpreterArgs = null;

    public void setInterpreterArgs(Node interpreterArgs) {
        this.interpreterArgs = interpreterArgs;
    }

    public Node getInterpreterArgs() {
        return interpreterArgs==null ? Node.createCList() : interpreterArgs;
    }

    public void run() {
        if (isDebugMode()) {
            Interpreter.LogTitle("NEW INTERPRETER INSTANCE STARTING...");
        }
        if (!this.isInterThread()) {
            if (isDebugMode()) {
                Interpreter.Log("");
                Interpreter.Log("SUPERVISOR-THREAD -> register " + this);
            }
            Interpreter.semaphore.registerThread(this);
            // interpréteur principal
            long startlog = Interpreter.StartChrono();
            try {
                if (isDebugMode()) {
                    Interpreter.Log("");
                    Interpreter.Log("PARSING:");
                    Interpreter.Log(" . Parsing source code : " + this.source.length() + " characters...");
                }
                this.compile();
                Interpreter.LogChrono(startlog, " . Parsing time");
                if (isDebugMode()) {
                    Interpreter.Log(" . Generate AST of "+this.node.size_deep()+" nodes:" +
                            Tools.replaceCSeq("\n"+this.node.toString(),"\n","\n       . "));
                }
               
               
                synchronized (semaphore) {
                    semaphore.reset();
                }

                String res = "";
                returnedNode = null;
                Interpreter.Log("");
                Interpreter.Log("RUNNING AST:");
                startlog = Interpreter.StartChrono();
                __thisInterpreter = mySelf();
                returnedNode = this.execute();
                if (returnedNode != null) {
                    res = returnedNode.toString();
                    Interpreter.Log(" . Result Value : " + res);
                }
                else {
                    res = "";
                }

                synchronized (semaphore) {
                    semaphore.endAllCoroutines(); // déblocage de toutes coroutines...
                }

                Interpreter.LogChrono(startlog, " . Running time");


                if (outputTextArea != null || Main.arg_prompt) {
                    if(outputTextArea != null){
                        if(res.length()>0)
                            outputTextArea.write(res + "\n");
                        outputTextArea.resetStyles();
                        outputTextArea.write("Ready...\n");
                    }
                    else{
                        if(res.length()>0)
                            System.out.println(res);
                        if(!System.getProperty("os.name").toLowerCase().startsWith("windows")){
                            byte[] esc=new byte[]{27,91,48,77 /* <esc>[0m */};
                            System.out.write(esc);
                        }
                        System.out.println("Ready...");
                    }
                }

            }
            catch (Exception ex) {
                if (ex instanceof SilentException) {
                    Interpreter.Log("SUPERVISON-THREAD -> SILENT-EXCEPTION");
                }
                else {
                    this.lastException = ex;
                    Interpreter.Log("ERROR: " + ex);
                    if (Interpreter.isDebugMode()) {
                        ex.printStackTrace();
                    }
                    if (outputTextArea != null) {
                        try{
                            outputTextArea.resetStyles();
                            outputTextArea.write("ERROR...\n" + ex.getMessage() + "\n");
                        }
                        catch(Exception e){e.printStackTrace();}
                    }
                    else{
                        System.err.print("ERROR...\n" + ex.getMessage() + "\n");
                    }
                }
            }
            try {
                // par sécurité...
                synchronized (semaphore) {
                    semaphore.endAllCoroutines(); // déblocage de toutes coroutines...
                }
            }
            catch (Exception ex) {
                if (Interpreter.isDebugMode()) {
                    ex.printStackTrace();
                }
            }

            Interpreter.Log("");
            Interpreter.Log("Resource Counters       :");
            Interpreter.Log("------------------------:--------------------------");
            Interpreter.Log("Heaps : maximum use of  : " + GLOBAL.getMaxUse_cnt());
            Interpreter.Log("      : created         : " + GLOBAL.getCreation_cnt());
            Interpreter.Log("      : reused          : " + GLOBAL.getReuse_cnt());
            Interpreter.Log("      : cleared         : " + GLOBAL.getClearing_cnt());
            Interpreter.Log("------------------------:--------------------------");
            Interpreter.Log("Nodes : created         : " + Node.getSerialCnt());
            Interpreter.Log("      : cloned          : " + Node.getExecCloneCnt());
            Interpreter.Log("");
            // Interpreter.Log("Node Tracker     : " + Node.op_tracker); // pour debug...
            Interpreter.Log("");
            Interpreter.Log("SUPERVISOR-THREAD -> consume shutdown hooks.");
            Interpreter.supervisor_CONSUMEHOOK();
            Interpreter.Log("SUPERVISOR-THREAD -> emptying list of messages.");
            Interpreter.mySelf().actor_EMPTYMSGS();
            Interpreter.Log("SUPERVISOR-THREAD -> emptying list of signals.");
            Interpreter.mySelf().actor_EMPTYSIGNALS();
            Interpreter.Log("SUPERVISOR-THREAD -> unregister " + mySelf());
            Interpreter.semaphore.unregisterThread(mySelf());
            Interpreter.Log("SUPERVISOR-THREAD -> END." + (hasExitCode() ? " (Exit Code = " + getExitCode() + ").": ""));

        }
        else {
            // il s'agit d'une coroutine...
            try {
                try {
                    synchronized (Interpreter.semaphore) {
                        Interpreter.semaphore.wait(10);
                    }
                }
                catch (Exception ex) {
                    if (Interpreter.isDebugMode()) {
                        ex.printStackTrace();
                    }
                }

                Interpreter.Log(mySelf() + " -> execute:");

                String res = "";
                returnedNode = null;
                __thisInterpreter = mySelf();
                returnedNode = this.execute();
                if (returnedNode != null) {
                    res = returnedNode.toString();
                    Interpreter.Log(mySelf() + " -> result: " + res);
                }
                else {
                    res = "";
                }
            }
            catch (SilentException silex) {
                Interpreter.Log(mySelf() + " -> SILENT-EXCEPTION");
            }
            catch (Exception ex) {
                Interpreter mother = mySelf().getMotherThread();
                if (mother != null) {
                    // on a un interpréteur "maman"...
                    //final InterpreterException nex = new InterpreterException();
                    mother.setInterThreadException(ex, mySelf());
                    // S'ASSURER DE LA FIN DU TIMER
                    if (timeOutTimer.isRunning()) {
                        timeOutTimer.stop();
                    }

                }
                else {
                    // traitement par défaut...

                    // S'ASSURER DE LA FIN DU TIMER
                    if (timeOutTimer.isRunning()) {
                        timeOutTimer.stop();
                    }

                    this.lastException = ex;
                    Interpreter.Log("ERROR: " + ex);
                    if (Interpreter.isDebugMode()) {
                        ex.printStackTrace();
                    }
                    if (outputTextArea != null) {
                        try{
                            outputTextArea.resetStyles();
                            outputTextArea.write(mySelf() + " -> ERROR " + ex.getMessage() + "\n");
                        }
                        catch(Exception e){e.printStackTrace();}
                    }
                    else{
                        System.err.print(mySelf() + " -> ERROR " + ex.getMessage() + "\n");
                    }

                }
            }
            // ne prend pas en compte les autres exceptions dans un thread...
            Interpreter.Log(mySelf() + " -> emptying the list of messages.");
            Interpreter.mySelf().actor_EMPTYMSGS();
            Interpreter.Log(mySelf() + " -> emptying the list of signals.");
            Interpreter.mySelf().actor_EMPTYSIGNALS();
            Interpreter.Log(mySelf() + " -> END.");
            Interpreter.semaphore.unregisterThread(mySelf());
            Interpreter.Log(mySelf() + " -> unregister " + mySelf());

        }
    }

    public void setLogTextArea(OutputTextArea logTextArea) {
        this.logTextArea = logTextArea;
    }

    public OutputTextArea getLogTextArea() {
        return logTextArea;
    }

    public void setOutputTextArea(OutputTextArea outputTextArea) {
        this.outputTextArea = outputTextArea;
    }

    public OutputTextArea getOutputTextArea() {
        return outputTextArea;
    }

    public void setSource(String source) {
        this.source = source;
    }

    public String getSource() {
        return source;
    }

    public void compile() throws Exception {
        node = Node.compile(source);
        if (node.isLazy()) {
            node.setType(Node.TYPE_EXPR);
        }
    }

    public Node execute() throws Exception {
        String oClass_path = System.getProperty("java.class.path");
        Node res = null;
        try {
           
            deadlockTime = StartChrono() + executionTimeOut;
           
            _check_GLOBAL();
           
           
            /* Corrige le bug launchpad#1009077 (l.bruninx, 2012-06-07) */
            if(Heap.exists(ASymbol.SYMBOL_ARGV))
                // argv est déjà dans la pile
                Heap.swapv(ASymbol.SYMBOL_ARGV, this.getInterpreterArgs());
            else{
                // argv n'est pas encore dans la pile
                Heap.defv(ASymbol.SYMBOL_ARGV, this.getInterpreterArgs());
                // Il faut protéger l'espace de nom de argv. Il peut être redéfini.
                Heap.push();
            }
            /* Corrige le bug launchpad#1009077, l.bruninx (2012-06-07) */
           
           
            res = node.exec(false);
            if (timeOutTimer.isRunning()) {
                timeOutTimer.stop();
            }
           
        }
        catch (RestartException talex) {
            throw new InterpreterException(StdErrors.createTrace(talex.getFrom(), new InterpreterException(StdErrors.Restart_error)));
        }
        catch (RetryException retryex) {
            throw new InterpreterException(StdErrors.createTrace(retryex.getFrom(), new InterpreterException(StdErrors.Retry_error)));
        }
        catch (AbortException abortex) {
            throw new InterpreterException(StdErrors.createTrace(abortex.getFrom(), new InterpreterException(StdErrors.Retry_error)));
        }
        catch (Exception e) {
            System.setProperty("java.class.path", oClass_path);
            throw e;
        }
        System.setProperty("java.class.path", oClass_path);
        return res;
    }


    public static FreezeTimeOut freezeTimeOut() {
        Interpreter interpreter = Interpreter.mySelf();
        interpreter.timeOutTimer.stop();
        FreezeTimeOut ft = new FreezeTimeOut(0, interpreter.timeOutCheck);
        if (interpreter.timeOutCheck) {
            interpreter.timeOutCheck = false;
            long now_to = System.currentTimeMillis();
            long end_to = interpreter.deadlockTime;
            long reste = end_to - now_to;
            if (reste < 0) {
                reste = 0;
            }
            ft.reste_to = reste;
        }
        return ft;
    }

    public static void unfreezeTimeOut(FreezeTimeOut popFreeze) {
        if (popFreeze.to_state) {
            Interpreter interpreter = Interpreter.mySelf();
            interpreter.deadlockTime = System.currentTimeMillis() + popFreeze.reste_to;
            interpreter.timeOutCheck = true;
            interpreter.timeOutTimer.start();
        }
    }


    /**
     * propriétés générales de la vérification de la syntaxe lors
     * de la compilation.
     */
    int parse_strCnt = 0;
    int parse_parCnt = 0;
    int parse_dicCnt = 0;
    int parse_accCnt = 0;
    int parse_croCnt = 0;
    int parse_linCnt = 0;
    int parse_strLineOffset = 0;


}
TOP

Related Classes of abstrasy.Interpreter$PackageEntry

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.