Package abstrasy.pcfx

Source Code of abstrasy.pcfx.PCFx_perform

package abstrasy.pcfx;


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

import abstrasy.interpreter.BaseContextSnapshot;
import abstrasy.interpreter.InterpreterException;
import abstrasy.interpreter.RestartException;
import abstrasy.interpreter.SilentException;
import abstrasy.interpreter.StdErrors;


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

    public PCFx_perform() {
    }

    private final static void _clear_closure_(Heap closure){ if (closure.isLoaded()) closure.clear(); }
   
    /**
     * eval
     *
     * @param startAt Node
     * @return Node
     * @throws Exception
     * @todo Implémenter cette méthode abstrasy.PCFx
     */
    public Node eval(Node startAt) throws Exception {
        /**
         * forme: (perform {...})                  -> n'affecte pas argv
         *        (perform [args] {...})
         *        (perform 'Symbole {...})         -> n'affecte pas argv
         *        (perform 'Symbole [args] {...})
         *
       */

        Node snode = null; // symbole
        Node xnode = null; // lazy
        Node anode = null; // args (list)

        /**
         * Analyse des arguments...
         * Basée sur le nombre d'arguments...
         */
        switch (startAt.size()) {
            case 2:
                /**
                 * (perform {...})
                 */
                xnode = startAt.getSubNode(1, Node.TYPE_LAZY);
                break;
            case 4:
                /**
                 * (perfom 'Symbole [args] {...})
                 */
                snode = startAt.getSubNode(1, Node.TYPE_QSYMBOL);
                anode = startAt.getSubNode(2, Node.TYPE_CLIST);
                xnode = startAt.getSubNode(3, Node.TYPE_LAZY);
                break;
            case 3:
                /**
                 * (perform [args] {...})
                 * (perform 'Symbole {...})
                 */
                snode = startAt.getSubNode(1, Node.TYPE_QSYMBOL | Node.TYPE_CLIST);
                if (!snode.isQSymbol()) {
                    // si n'est pas un QSymbol, c'est forcément une liste...
                    anode = snode;
                    snode = null;
                }
                xnode = startAt.getSubNode(2, Node.TYPE_LAZY);
                break;
            default:
                /**
                 * problème...
                 */
                throw new InterpreterException(StdErrors.Argument_count_mismatch);

        }

        /**
         * si le symbole est défini...
         * vérifier qu'il soit bien immutable...
         */
        if (snode != null) {
            ASymbol symbole=snode.getSymbol();
            if (symbole.getStr().indexOf(PCoder.SEP) >= 0)
                    throw new InterpreterException(StdErrors.Local_symbol_required);
            if (!symbole.isImmutable())
                throw new InterpreterException(StdErrors.Immutable_symbol_required);
        }

        /**
         * préparer la gestion de la pile de manière terminale...
         */
        Interpreter interpreter = Interpreter.mySelf();
        StaticHeap global = interpreter.getGLOBAL();

        global.push();
        // retenir le heap de control
        Heap controlh=global.current();
       
        /**
         * si la forme compte un symbole...
         */
        if (snode != null)
            Heap.defv(snode.getSymbol(), xnode);



        /**
         * la section a besoin d'un contexte.
         */
        global.push();
        // on retient la référence du contexte courant...
        Heap local=global.current();

        /**
         * A toutes fins utiles, on sauve l'état de la pile...
         */
        BaseContextSnapshot contextSnapshot = new BaseContextSnapshot(interpreter);
       
       
        /**
         * Début de la boucle...
         */

        boolean retry = true;
        Node res = null;
   
        boolean oldInLoop=interpreter.isInLoop();

        while (retry) {
           
            if (anode!=null)
                controlh.put(PCoder.ARGV, anode);
            else
                controlh.put(PCoder.ARGV, Node.createCList());
           
            try {
                _clear_closure_(local);
                interpreter.setInLoop(true);
                res = xnode.exec(true);
                retry = false;
            }
            catch (RestartException retrex) {
                contextSnapshot.restore();
                Node experform = retrex.getPerform();
               
                if (experform == null)
                    retry = true;
               
                else if (xnode.equalsIdentity(experform))
                    retry = true;
           
                else {
                    retry = false;
                    throw retrex;
                }
               
                anode = retrex.getArgs();
               
               
            }
            catch (SilentException silex) {
                contextSnapshot.restore();
                retry = false;
                throw silex;
            }
            catch (Exception excep) {
                contextSnapshot.restore();
                retry = false;
                throw excep; // fait suivre l'exception...
            }
        }

        interpreter.setInLoop(oldInLoop);
       
        // heap local
        global.pull();
        // headp controlh
        global.pull();
       
        return res;

    }

}
TOP

Related Classes of abstrasy.pcfx.PCFx_perform

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.