Package abstrasy.pcfx

Source Code of abstrasy.pcfx.PCFx_import

package abstrasy.pcfx;


import abstrasy.ASymbol;
import abstrasy.Heap;
import abstrasy.Interpreter;
import abstrasy.Node;
import abstrasy.PCoder;
import abstrasy.SourceFile;

import abstrasy.interpreter.InterpreterException;
import abstrasy.interpreter.StdErrors;

import java.io.File;

import java.net.URL;


/**
* 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 PCFx_import extends PCFx {

    public PCFx_import() {
    }

    private static final void _check_symbol_(ASymbol symbole) throws InterpreterException {
        /**
         * le symbole ne peut pas être composé...
         */
        if (symbole.getIdsCnt() > 1)
            throw new InterpreterException(StdErrors.Invalid_symbol);
       
        /**
         * il doit au minimum être immutable
         */
        if (!symbole.isImmutable()) {
            throw new InterpreterException(StdErrors.Immutable_symbol_required);
        }
    }
   
    private static final void _provide_(Node n_provide, String moduleID) throws Exception {
        // traiter la liste provide si elle existe...
            for (int i = 0; i < n_provide.size(); i++) {
                ASymbol p_symbole = n_provide.elementAt(i).getSymbol();
                // vérification du symbole : local et immutable
                _check_symbol_(p_symbole);
                // lien 'Symbole <-(synonyme)- 'Module:Symbole
                Heap.defv(p_symbole, Heap.getv(new ASymbol(moduleID + PCoder.SEP + p_symbole.getStr())));
            }
    }

    /**
     * eval
     *
     * @param startAt Node
     * @return Node
     * @throws Exception
     * @todo Implémenter cette méthode abstrasy.PCFx
     */

    public Node eval(Node startAt) throws Exception {
        /*
         * formes :
         *
         *      (import 'Module)
         *      (import 'Module provide 'Symbole0 'Symbole1 ....)
         *
         *      (import 'Module from "chemin_fichier")
         *      (import 'Module from "chemin_fichier" provide 'Symbole0 'Symbole1 ....)
         *
         */

        /**
         * Analyser la syntaxe de la forme...
         */
        Node n_module = null;
        Node n_from = null;
        Node n_provide = Node.createCList();

        // longueur minimum à ce stade: (import 'Module) = 2
        int mxarg = 2;
        startAt.isGoodArgsLength(false, mxarg);
        int iarg = 1; // index de l'arg courant...

        // récupérer le symbole du module...
        n_module = startAt.getSubNode(iarg++, Node.TYPE_QSYMBOL);

        // s'il y a plus d'argument...
        while (startAt.size() > mxarg) {

            // alors il y en a au moins 2 en plus...
            mxarg += 2;
            startAt.isGoodArgsLength(false, mxarg);

            // récupération de l'opérateur de clause
            Node c_op = startAt.getSubNode(iarg++, Node.TYPE_PCODE);
            //
            if (c_op.isPCode(PCoder.PC_FROM)) {
                // forme ... from "chemin" ...
                n_from = startAt.getSubNode(iarg++, Node.TYPE_STRING);
            }
            else if (c_op.isPCode(PCoder.PC_PROVIDE)) {
                // forme ... provide 'S1 'S2 .... 'Sn )
                while (iarg < startAt.size()) {
                    n_provide.addElement(startAt.getSubNode(iarg++, Node.TYPE_QSYMBOL));
                }
                mxarg = startAt.size();
            }
            else {
                // erreur...
                throw new InterpreterException(StdErrors.Syntax_error);
            }
        }

        Node rnode = null;

        /*
         * préparation du symbole du module...
         */
        ASymbol symbole = n_module.getSymbol();
        // vérification du symbole : local et immutable
        _check_symbol_(symbole);

        //

        /**
         * ne pas aller plus loin si le module est déjà chargé...
         */
        ASymbol moduleID = new ASymbol(PCoder.REGISTRY + PCoder.SEP + symbole.getStr());
        if (Heap.exists(moduleID)) {
            Heap.defv(symbole, Heap.getv(moduleID));
           
            // traiter la liste provide si elle existe...
            _provide_(n_provide,moduleID.getStr());

            return null;
        }

        /**
         * Le module n'est pas encore chargé.
         * =================================
         *
         * On va le charger...
         *
         */

        // déterminer le nom du fichier à chercher...
        Node npath = n_from == null ? new Node(symbole.getRootNamespace()): n_from;


        // chercher le fichier...
        File src = SourceFile.findSourceFileName(npath.getString());
       
        // c'est parti!...
        String msrc = "";
        SourceFile in = null;

        if (src != null) {
            in = new SourceFile(src.getAbsolutePath());
        }
        else {
            Node iPaths = Heap.getv(ASymbol.SYMBOL_IMPORTS_PATH);
            if (iPaths != null) {
                if (iPaths.getQType()==Node.TYPE_CLIST) {
                    for (int ip = (iPaths.size() - 1); ip >= 0; ip--) {
                        Node pval = iPaths.elementAt(ip);
                        if (pval.isString()) {
                            src = SourceFile.findSourceFileName(pval.getString() + npath.getString());
                            if (src != null) {
                                in = new SourceFile(src.getAbsolutePath());
                                ip = -1;
                            }
                        }
                    }
                }
            }
        }
        if (in == null) {
            Node iPaths = Heap.getv(ASymbol.SYMBOL_IMPORTS_BASE_URL);
            if (iPaths != null) {
                if (iPaths.getQType()==Node.TYPE_CLIST) {
                    for (int ip = (iPaths.size() - 1); ip >= 0; ip--) {
                        Node pval = iPaths.elementAt(ip);
                        if (pval.isString()) {
                            URL surl = SourceFile.findSourceURLName(pval.getString() + npath.getString());
                            if (surl != null) {
                                in = new SourceFile(surl);
                                ip = -1;
                            }
                        }
                    }
                }
            }

        }
        if (in != null) {
            try {
                in.load();
                msrc = in.getSource();
                Interpreter interpreter = Interpreter.interpr_getNewChildInterpreter();
                //Register continue dans le même thread...
                Heap.push(); // mais en créant une closure
                interpreter.setSource(msrc);
                interpreter.compile();
                Heap.DynamicConstants.setMAIN_FALSE();
                if ((rnode = interpreter.getNode().exec(false)) != null) {
                    Interpreter.Log("Retour Import ??? " + rnode);
                }
                Heap.pull();

                // enregistrer le module
                Heap.defv(new ASymbol(symbole.getLocalName()), Heap.getv(moduleID));
               
               
                // traiter la liste provide si elle existe...
                _provide_(n_provide,moduleID.getStr());
               
                return null;

            }
            catch (Exception ex) {
                if (Interpreter.isDebugMode()) {
                    ex.printStackTrace();
                }
                throw new InterpreterException(StdErrors.createTrace(startAt, ex));
            }

        }
        else {
            throw new InterpreterException(StdErrors.Cannot_import_module);
        }

    }

}
TOP

Related Classes of abstrasy.pcfx.PCFx_import

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.