package abstrasy.pcfx;
import abstrasy.Hash;
import abstrasy.Node;
import abstrasy.PCoder;
import abstrasy.Tools;
import abstrasy.interpreter.InterpreterException;
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_ref extends PCFx {
public PCFx_ref() {
}
/**
* eval
*
* @param startAt Node
* @return Node
* @throws Exception
* @todo Implémenter cette méthode abstrasy.PCFx
*/
public Node eval(Node startAt) throws Exception {
/**
* formes: (@ valuable)
*
* (@ liste index)
* (@ liste clé)
*
* (@ objet 'symbole)
*
*
*/
/**
* vérification élémentaire
*/
startAt.isGoodArgsLength(false, 2);
/**
* début du traitement
*/
int i = 1; // index des arguments...
Node target = startAt.getSubNode(i++, Node.VTYPE_VALUABLE);
boolean xprotected = target.isFinalNode();
if (startAt.size() == 2)
/**
* forme (@valuable)
*/
return Node.createRef(target);
/**
* sinon, c'est la forme (@ liste/objet index/cle)...
*/
switch (target.getType()) {
case Node.TYPE_HASH:
{
/*
* Hash:
* -----
*
* forme (@hash clé)
*
*/
startAt.isGoodArgsCnt(3);
Hash hash = target.getHash();
target = hash.ref(startAt.getSubNode(2, Hash.KEY_TYPES));
return Node.createRef(target);
}
case Node.TYPE_CLIST:
{
/*
* Liste:
* =====
*
* forme (@liste index) : vecteur à une dimension.
* (@liste index ... index) : multi-dimension.
*
*/
while (i < startAt.size()) {
target.requireNodeType(Node.TYPE_CLIST); // la recherche ne peut être réalisée que dans des listes...
Node indice = startAt.getSubNode(i++, Node.TYPE_NUMBER);
// index...
int index = (int) indice.getNumber();
//
// support de l'index négatif à partir de la fin...
//
target = target.elementAt(Tools.computeAbsoluteIndex(target.size(), index, 1));
}
return Node.createRef(target);
}
case Node.TYPE_NAMESPACE:
case Node.TYPE_EXTERNAL:
case Node.TYPE_FUNCTION:
{
/*
* deleguable:
* ==========
*
* forme (@objet 'symbole)
*/
return Node.createRef(Node.VDelegable.evalMethod(target, PCoder.getMethod(PCoder.PC_REF), startAt, 2));
}
}
throw new InterpreterException(StdErrors.Argument_type_mismatch);
}
}