package jadex.javaparser.javaccimpl; import jadex.javaparser.IValueFetcher; /** * Boolean node performs mathematical operations on it's (two) child nodes. */ public class BooleanNode extends ExpressionNode { //-------- constants -------- /** The and (&&) operator. */ public static final int AND = 1; /** The or (||) operator. */ public static final int OR = 2; /** The not (!) operator. */ public static final int NOT = 3; //-------- attributes -------- /** The operation. */ protected int op; //-------- constructors -------- /** * Create a node. * @param p The parser. * @param id The id. */ public BooleanNode(ParserImpl p, int id) { super(p, id); setStaticType(Boolean.class); } //-------- attribute accessors -------- /** * Set the token text. * @param text The token text. */ public void setText(String text) { super.setText(text); this.op = fromString(text); } //-------- evaluation -------- /** * Check argument types, and precompute expression * when some children are constant. */ public void precompile() { // Check number of children and operator type. if((op==AND || op==OR) && jjtGetNumChildren()<2 || op==NOT && jjtGetNumChildren()!=1) { throw new ParseException("Wrong number of subterms for expression: "+this); } if(!(op==AND || op==OR || op==NOT)) { throw new ParseException("Unknown operator type "+op+": "+this); } boolean allfalse = true; boolean alltrue = true; for(int i=0; i<jjtGetNumChildren(); i++) { // Check type of children. ExpressionNode node = (ExpressionNode)jjtGetChild(i); Class type = node.getStaticType(); if(type!=null && !type.equals(Boolean.class)) { throw new ParseException("Term of expression not boolean: "+this); } // Precompute constant value, when children are constant. if(node.isConstant()) { try { boolean val = ((Boolean)node.getValue(null)).booleanValue(); allfalse = allfalse && !val; alltrue = alltrue && val; if(op==NOT) { setConstant(true); setConstantValue(new Boolean(!val)); } else if(op==AND && !val) { // If one term of AND is false, expression is false. setConstant(true); setConstantValue(new Boolean(false)); } else if(op==OR && val) { // If one term of OR is true, expression is true. setConstant(true); setConstantValue(new Boolean(true)); } } catch(Exception e) { } } else { // Value unknown. allfalse = false; alltrue = false; } } // Save constant value, when all terms of and are true, // or all terms of or are false. if(op==AND && alltrue) { setConstant(true); setConstantValue(new Boolean(true)); } else if(op==OR && allfalse) { setConstant(true); setConstantValue(new Boolean(false)); } } /** * 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 Object getValue(IValueFetcher fetcher) //throws Exception { if(isConstant()) { return getConstantValue(); } boolean ret; switch(op) { // Evaluate AND expression. case AND: ret = true; for(int i=0; i<jjtGetNumChildren() && ret; i++) { Object val = ((ExpressionNode)jjtGetChild(i)).getValue(fetcher); // System.out.println("Term "+i+": "+val); if(!(val instanceof Boolean)) { throw new RuntimeException("Term of expression not boolean: "+this+", "+val); } ret = ((Boolean)val).booleanValue(); } break; // Evaluate OR expression. case OR: ret = false; for(int i=0; i<jjtGetNumChildren() && !ret; i++) { Object val = ((ExpressionNode)jjtGetChild(i)).getValue(fetcher); // System.out.println("Term "+i+": "+val); if(!(val instanceof Boolean)) { throw new RuntimeException("Term of expression not boolean: "+this); } ret = ((Boolean)val).booleanValue(); } break; // Evaluate NOT expression. case NOT: Object val = ((ExpressionNode)jjtGetChild(0)).getValue(fetcher); // System.out.println("Term: "+val); if(!(val instanceof Boolean)) { throw new RuntimeException("Term of expression not boolean: "+this); } ret = !((Boolean)val).booleanValue(); break; default: throw new RuntimeException("Unknown operator type "+op+": "+this); } return new Boolean(ret); } /** * Create a string representation of this node and its subnodes. * @return A string representation of this node. */ public String toPlainString() { String ret; if(jjtGetNumChildren()>1) { ret = subnodeToString(0); for(int i=1; i<jjtGetNumChildren(); i++) ret += toString(op) + subnodeToString(i); } else { ret = toString(op) + subnodeToString(0); } return ret; } //-------- static part -------- /** * Convert an operator to a string representation. * @param operator The operator. * @return A string representation of the operator. */ public static String toString(int operator) { switch(operator) { case AND: return "&&"; case OR: return "||"; case NOT: return "!"; default: return ""+operator; } } /** * Convert an operator from a string representation. * @param operator The operator as string. * @return The int value of the operator. */ public static int fromString(String operator) { if("&&".equals(operator)) { return AND; } else if("||".equals(operator)) { return OR; } else if("!".equals(operator)) { return NOT; } else { throw new ParseException("Unknown operator: "+operator); } } }