package abstrasy.pcfx;
import abstrasy.Hash;
import abstrasy.Node;
import abstrasy.PCoder;
import java.util.ArrayList;
/**
* 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_substitute extends PCFx {
public PCFx_substitute() {
}
final static Node replaceSymbol(Node meta, Node[] symbols, Node values[]) throws Exception {
if (meta.hasChilds())
for (int i = 0; i < meta.size(); i++)
meta.setElementAt(replaceSymbol(meta.elementAt(i), symbols, values), i);
for (int i = 0; i < symbols.length; i++)
if (Node.equalsNodes(meta, symbols[i]))
return Node.createClone(values[i]);
return meta;
}
/**
* eval
*
* @param startAt Node
* @return Node
* @throws Exception
* @todo Implémenter cette méthode abstrasy.PCFx
*/
public Node eval(Node startAt) throws Exception {
/*
* formes : (substitute ... by ... in ...)
* (substitute hash in ...)
*/
startAt.isGoodArgsCnt(4, 6);
Node c = null;
switch (startAt.size()) {
case 6:
{
/*
* (substitute a by b in c)
*/
startAt.requirePCode(2, PCoder.PC_BY);
startAt.requirePCode(4, PCoder.PC_IN);
c = Node.createClone(startAt.getSubNode(5, Node.VTYPE_METAEXPRESSION));
Node a = startAt.getSubNode(1, Node.VTYPE_VALUABLE);
Node b = startAt.getSubNode(3, Node.VTYPE_VALUABLE);
a = Node.quoteEncoded_decode(a);
if (!b.isQuoted())
b = Node.quoteEncoded_encode(b);
b = Node.quoteEncoded_decode(b);
c = replaceSymbol(c, new Node[] { a }, new Node[] { b });
break;
}
case 4:
{
startAt.requirePCode(2, PCoder.PC_IN);
c = Node.createClone(startAt.getSubNode(3, Node.VTYPE_METAEXPRESSION));
Hash l = startAt.getSubNode(1, Node.TYPE_HASH).getHash();
Node[] symbols = new Node[l.size()];
Node[] values = new Node[l.size()];
ArrayList<Node> kn = l.keys_nodes();
for (int i = 0; i < kn.size(); i++) {
Node a = kn.get(i);
a.requireNodeType(Node.TYPE_QSYMBOL);
Node b = l.ref(a);
a = Node.quoteEncoded_decode(a); /* astuce pour ici */
if (!b.isQuoted())
b = Node.quoteEncoded_encode(b);
b = Node.quoteEncoded_decode(b);
symbols[i] = a;
values[i] = b;
}
c = replaceSymbol(c, symbols, values);
break;
}
default:
}
return c;
}
}