package abstrasy.pcfx;
import abstrasy.Node;
import abstrasy.PCoder;
import abstrasy.Tools;
/**
* 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_insert_static extends PCFx {
/**
* respecte la protection de la finalité des listes
*
*/
public PCFx_insert_static() {
}
/**
* eval
*
* @param startAt Node
* @return Node
* @throws Exception
* @todo Implémenter cette méthode abstrasy.PCFx
*/
public Node eval(Node startAt) throws Exception {
/**
* forme (insert! valeur/string in liste/string at position)
* 0 1 2 3 4 5
*/
/**
* Vérification de la syntaxe
*/
startAt.requirePCode(2, PCoder.PC_IN);
startAt.requirePCode(4, PCoder.PC_AT);
startAt.isGoodArgsCnt(6);
Node snode = null;
Node xnode = null;
int index = 0;
startAt.requireNodeType(3, Node.VTYPE_INDIRECTION);
snode = startAt.getSubNode(3, Node.TYPE_STRING | Node.TYPE_CLIST);
snode.requireAccessType(Node.ACCESSVTYPE_MUTABLE_WRITELOCK);
/**
* l'insertion n'a pas de sens sur clé. Il ne peut s'agir que d'un index.
*/
xnode = startAt.getSubNode(5, Node.TYPE_NUMBER);
index = (int) Math.round(xnode.getNumber());
/**
* le nouveau noeud peut être n'importe quel valuable sauf dans la cas d'une chaîne de caractères.
* Dans ce cas, il faut que ce soit une chaîne aussi.
*/
Node nouvNode = startAt.getSubNode(1, (snode.isNodeType(Node.TYPE_STRING) ? Node.TYPE_STRING: Node.VTYPE_VALUABLE));
/**
* estimer la taille selon le type...
*/
int ssize;
if (snode.isString())
ssize = snode.getString().length();
else
ssize = snode.size();
if (snode.getQType() == Node.TYPE_CLIST) {
snode.requireAccessType(Node.ACCESSTYPE_WRITELOCK);
//
// (insert! x in [...] at i)
//
if (index < ssize)
snode.insertElementAt(nouvNode.secure(), Tools.computeAbsoluteIndex(snode.size(), index, 1));
else
snode.addElement(nouvNode.secure());
}
else if (snode.getType() == Node.TYPE_STRING) {
snode.requireAccessType(Node.ACCESSVTYPE_MUTABLE_WRITELOCK);
//
// (insert! "x" in "..." at i)
//
String sn = snode.getString();
index = Tools.computeAbsoluteIndex(sn.length(), index, 1);
if (index == 0)
snode.setString(nouvNode.getString() + sn);
else if (index == ssize)
snode.setString(sn + nouvNode.getString());
else {
String ss = sn.substring(0, index);
String se = sn.substring(index, sn.length());
snode.setString(ss + nouvNode.getString() + se);
}
}
return null;
}
}