scphEditor
Class Operand

java.lang.Object
  extended by java.util.Observable
      extended by scphEditor.CloneableObservable
          extended by scphEditor.OperandVector
              extended by scphEditor.Operand
All Implemented Interfaces:
java.io.Serializable, java.lang.Cloneable
Direct Known Subclasses:
Expression, Identifier

public abstract class Operand
extends OperandVector
implements java.lang.Cloneable

This abstract class models an operand. An operand may be a terminal expression like x or 10; or a compound expression like x+10. This abstract class is the superclass of both, defining common services and default implementations; this is the base class in a composite pattern.

The common services include child management. A compound expression has a number of child operands, e.g., x and 10 are the child operands in x+10. Each child is referred to by a zero-based index; thus, in x+10, x is child #0 and 10 is child #1. Child management, then, consists of methods for:

Naturally, the default implementations of these methods are for leaf nodes (terminal expressions), for which setting and getting children does not make sense; therefore, they always throw exceptions.

A compound expression class must override this and other behaviours and implement them for real. This is done by the Expression class hierarchy, for example.

See Also:
Expression, Serialized Form

Constructor Summary
Operand()
          Default constructor.
 
Method Summary
abstract  void acceptVisitor(OperandVisitor v)
          Interface for OperandVisitor objects to visit this operand concretely.
 void addParen()
          Parenthesizes me.
 java.lang.Object clone()
          Clones this operand.
protected  void deParen()
          De-parenthesizes me.
protected  void ensureParen(Operand owner)
          Parenthesizes me, if I need to be.
abstract  IOperator getOperator()
          Gives the operator in this subexpression.
 boolean getParen()
          Tells if I am already parenthesized.
 boolean getSplit()
          Gets my split status.
protected  boolean needParen(Operand owner)
          Determines if I need to be parenthesized, assuming I am a child of the given operand.
 void removeParen(OperandVector owner)
          De-parenthesizes me, if I do not need parentheses.
 void setSplit(boolean split)
          Sets my split status.
 
Methods inherited from class scphEditor.OperandVector
addChild, countChildren, delChild, getChild, getChildren, setChild
 
Methods inherited from class scphEditor.CloneableObservable
addObserver, cloneObserverList, cloneObserverList, countObservers, deleteObserver, deleteObservers, notifyObservers, notifyObservers
 
Methods inherited from class java.util.Observable
clearChanged, hasChanged, setChanged
 
Methods inherited from class java.lang.Object
equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

Operand

public Operand()
Default constructor.

Method Detail

clone

public java.lang.Object clone()
Clones this operand.

Overrides:
clone in class CloneableObservable
Returns:
A clone of this operand

getOperator

public abstract IOperator getOperator()
Gives the operator in this subexpression. Yes, this is supposed to make sense even for terminals like x and 10. The current plan is that a terminal is both an operand and an operator; but there is also a chance that a terminal returns some kind of empty operator.

Returns:
the Operator object of this operand/subexpression.
See Also:
IOperator

needParen

protected boolean needParen(Operand owner)
Determines if I need to be parenthesized, assuming I am a child of the given operand. I need parentheses iff my operator binding is looser than my parent's, up to associativity. Unary operators are treated as right-associative.

Parameters:
owner - my hypothetical or real parent, or null.
Returns:
true iff I need to be parenthesized.

ensureParen

protected void ensureParen(Operand owner)
Parenthesizes me, if I need to be. Calls needParen() to determine the need and addParen() to do it. This method is normally only used by setChild() of compound expression classes.

Parameters:
owner - my hypothetical or real parent, or null.
See Also:
needParen(scphEditor.Operand), addParen(), OperandVector.setChild(scphEditor.Operand, int)

addParen

public void addParen()
Parenthesizes me.

The default implementation is for leaf nodes and does nothing. Compound expressions should override this properly.


deParen

protected void deParen()
De-parenthesizes me. This method should only be called by internal code such as removeParen().

The default implementation is for leaf nodes and does nothing. Compound expressions should override this properly.

See Also:
removeParen(scphEditor.OperandVector)

removeParen

public void removeParen(OperandVector owner)
De-parenthesizes me, if I do not need parentheses. Calls needParen() to determine the need and deParen() to do it.

Parameters:
owner - my hypothetical or real parent, or null.
See Also:
needParen(scphEditor.Operand), deParen()

getParen

public boolean getParen()
Tells if I am already parenthesized.

This default implementation is for leaf nodes. Compound expressions should override this properly.

Returns:
true iff I am parenthesized. (False for leaf nodes.)

getSplit

public boolean getSplit()
Gets my split status. In other words, whether or not I should be splitted across the line when displayed by a view, like, b = a becomes:
   b
 = a
 
Of course, this is just a hint to the view.

This default implementation is for leaf nodes, which never splits. Compound expressions should override this properly.

Returns:
true iff I should be displayed as splitted. (False for leaf nodes.)

setSplit

public void setSplit(boolean split)
Sets my split status.

This default implementation is for leaf nodes, which never splits. Compound expressions should override this properly.

Parameters:
split - true if you want me to split, false otherwise.

acceptVisitor

public abstract void acceptVisitor(OperandVisitor v)
Interface for OperandVisitor objects to visit this operand concretely. (Visitor pattern.) Absolutely no traversal in any implementation of this method, i.e., this method by itself does not recurse into children of this operand.

Implementations of this method are typically one-liners like:

   v.visitConcreteOperand(this);
 

Parameters:
v - the visitor object that wants to visit this operand.