/* ==============================================
* Simtools : The tools library used in JSynoptic
* ==============================================
*
* Project Info: http://jsynoptic.sourceforge.net/index.html
*
* This library is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation;
* either version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* (C) Copyright 2003, by :
* Corporate:
* Astrium SAS (MATRA MARCONI SPACE)
* EADS CRC
* Individual:
* Nicolas Brodu
*
*
* $Id: ExpressionNode.java,v 1.3 2005/05/10 17:10:19 brodu Exp $
*
* Changes
* -------
* 08-Oct-2003 : Creation (NB);
*
*/
package jsynoptic.parser;
import java.util.HashSet;
import java.util.Set;
/**
* This is the base class for all our nodes
* It has an evaluate() function, which evaluates the subtree under this node and return a Number value
* As a commodity to avoid duplicate code, it also has a function to return the list of variables used
* at any place in the tree
*/
public abstract class ExpressionNode extends SimpleNode implements Cloneable {
/**
* From SimpleNode
* @param i
*/
public ExpressionNode(int i) {
super(i);
}
/**
* From SimpleNode
* @param p
* @param i
*/
public ExpressionNode(ExpressionParser p, int i) {
super(p, i);
}
/** Evaluate the subtree under this node and return the computation result as a number */
public abstract Number evaluate();
/** Return the list of variables used at any place in the tree.
* @return The vector of all variable used, of type VariableDefinition. The returned vector may be empty, but not null
*/
public Set getVariables() {
Set ret = new HashSet();
if ((this instanceof NodeForFunctionCall) && (((NodeForFunctionCall)this).implementation instanceof VariableDefinition))
ret.add(((NodeForFunctionCall)this).implementation);
for (int i=0; i<this.jjtGetNumChildren(); ++i) {
Node n = jjtGetChild(i);
if (n instanceof ExpressionNode) ret.addAll(((ExpressionNode)n).getVariables());
}
return ret;
}
public Object clone() {
ExpressionNode theClone = null;
try {
theClone = (ExpressionNode)super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace(); // Should not happen!!!
}
// Object clone does shallow copy => force deep copy
if (theClone.children!=null) {
theClone.children = (jsynoptic.parser.Node[])children.clone();
for (int i=0; i<theClone.children.length; ++i) {
// clone only ExpressionNode children
Node childClone = theClone.children[i];
if (childClone instanceof ExpressionNode)
childClone = (Node)((ExpressionNode)childClone).clone();
// set parent to clone, if this is the case
if (childClone instanceof SimpleNode) ((SimpleNode)childClone).parent = theClone;
// finally update child
theClone.children[i] = childClone;
}
}
return theClone;
}
}