package jadex.javaparser.javaccimpl;
import jadex.commons.SUtil;
import jadex.javaparser.IParsedExpression;
import jadex.javaparser.IValueFetcher;
import java.io.PrintWriter;
import java.io.StringWriter;
/**
* Base class of expression node hierarchy.
*/
public abstract class ExpressionNode extends SimpleNode implements IParsedExpression
{
//-------- attributes --------
/** The token text (if any). */
protected String text;
/** The expression text (if any). */
protected String expressiontext;
/** The imports (if any). */
protected String[] imports;
/** The type model. */
// protected OAVTypeModel tmodel;
/** The static type (if any). */
protected Class static_type;
/** Is the node value constant
(independent of evaluation context and parameters)? */
protected boolean constant;
/** The constant value (if any). */
protected Object constant_value;
//-------- constructors --------
/**
* Create an expression node.
* @param p The parser.
* @param id The id.
*/
public ExpressionNode(ParserImpl p, int id)
{
super(p, id);
this.imports = p.getImports();
// this.tmodel = p.getTypeModel();
//this.static_type = Object.class; // not yet
}
//-------- attribute accessors --------
/**
* Get the full expression text.
* @param text The expression text.
*/
public void setExpressionText(String expressiontext)
{
this.expressiontext = expressiontext;
}
/**
* Get the full expression text.
*/
public String getExpressionText()
{
return expressiontext;
}
/**
* Set the token text.
* @param text The token text.
*/
public void setText(String text)
{
this.text = text;
}
/**
* Append to the token text.
* @param text The text to append.
*/
public void appendText(String text)
{
this.text = this.text==null ? text : this.text+text;
}
/**
* Set the static type.
* @param static_type The static type.
*/
public void setStaticType(Class static_type)
{
this.static_type = static_type;
}
/**
* Set the constant value.
* @param constant_value The constant value.
*/
public void setConstantValue(Object constant_value)
{
this.constant_value = constant_value;
}
/**
* Get the constant value.
* The constant value of a node may be known,
* when it is independent of the evaluation context,
* and the child nodes are constant, too.
* @return The constant value.
*/
public Object getConstantValue()
{
return this.constant_value;
}
/**
* Set if the node is constant.
* @param constant The constant.
*/
public void setConstant(boolean constant)
{
this.constant = constant;
}
/**
* Get if the node is constant.
* The node is constant, when it is independent
* of the evaluation context, and the child nodes
* are constant, too.
* @return The constant flag.
*/
public boolean isConstant()
{
return this.constant;
}
/**
* Create a string representation of this node for dumping in a tree.
* @return A string representation of this node.
*/
public String toString(String prefix)
{
return prefix + ParserImplTreeConstants.jjtNodeName[id]+"("+text+")";
}
/**
* Create a string representation of this node for dumping in a tree.
* @return A string representation of this node.
*/
public String toPlainString()
{
return super.toString();
}
/**
* Create a string representation of this node for dumping in a tree.
* @return A string representation of this node.
*/
public String toString()
{
return "<" + toPlainString() + ">";
}
/**
* Create a string for a subnode.
* Automatically adds braces if necessary.
* @param subnode The index of the subnode.
* @return The string for the subnode.
*/
protected String subnodeToString(int subnode)
{
Node node = jjtGetChild(subnode);
if(node.jjtGetNumChildren()==0)
return node.toPlainString();
else
return "(" + node.toPlainString() + ")";
}
//-------- ITerm methods --------
/**
* Get the expression text.
* @return The text.
*/
public String getText()
{
return this.text;
}
/**
* Evaluate the expression in the given state
* with respect to given parameters.
* @param params The parameters (string, value pairs), if any.
* @return The value of the term.
*/
public abstract Object getValue(IValueFetcher fetcher); //throws Exception;
/**
* Get the static type.
* If no information about the return type of an expression
* is available (e.g. because it depends on the evaluation context),
* the static type is null.
* @return The static type.
*/
public Class getStaticType()
{
return static_type;
}
//-------- expression methods --------
/**
* Set a static java type.
* /
protected void setStaticType(Class clazz)
{
setStaticType(tmodel.getJavaType(clazz));
}*/
/**
* Get unbound parameter nodes.
* @return The unbound parameter nodes.
*/
protected ParameterNode[] getUnboundParameterNodes()
{
// Default: Return unbound parameters of subnodes.
ParameterNode[] ret = new ParameterNode[0];
for(int i=0; i<jjtGetNumChildren(); i++)
{
ret = (ParameterNode[])SUtil.joinArrays(ret,
((ExpressionNode)jjtGetChild(i)).getUnboundParameterNodes());
}
return ret;
}
/**
* This method should be overridden to perform
* all possible checks and precompute all values
* (e.g. the static_type), which are independent
* of the evaluation context and parameters.
*/
public void precompile()
{
}
/**
* Precompile this node and all subnodes.
*/
public void precompileTree()
{
// Precompile subtree first !
for(int i=0; i<jjtGetNumChildren(); i++)
{
((ExpressionNode)jjtGetChild(i)).precompileTree();
}
// Now precompile this node.
precompile();
}
/**
* (Re)throw an exception that occured during parsing
* and add a useful error message.
* @param ex The exception to be rethrown (if any).
*/
protected void throwParseException(Throwable ex) throws ParseException
{
Node root = this;
while(root.jjtGetParent()!=null)
root = root.jjtGetParent();
StringWriter sw = new StringWriter();
ex.printStackTrace(new PrintWriter(sw));
throw new ParseException("Exception while parsing expression: "
+root.toPlainString()+"\n"+sw);
}
/**
* (Re)throw an exception that occured during evaluation
* and add a useful error message.
* @param ex The exception to be rethrown (if any).
*/
protected void throwEvaluationException(Throwable ex) throws RuntimeException
{
Node root = this;
while(root.jjtGetParent()!=null)
root = root.jjtGetParent();
StringWriter sw = new StringWriter();
ex.printStackTrace(new PrintWriter(sw));
throw new RuntimeException("Exception while evaluating expression: "
+root.toPlainString()+"\n"+sw);
}
}