package de.unisiegen.tpml.core.expressions ;
import java.awt.Color ;
import java.util.ArrayList ;
import java.util.Enumeration ;
import java.util.LinkedList ;
import java.util.MissingResourceException ;
import java.util.ResourceBundle ;
import de.unisiegen.tpml.core.interfaces.DefaultExpressions ;
import de.unisiegen.tpml.core.interfaces.DefaultIdentifiers ;
import de.unisiegen.tpml.core.interfaces.DefaultTypes ;
import de.unisiegen.tpml.core.interfaces.ShowBondsInput ;
import de.unisiegen.tpml.core.latex.DefaultLatexCommand ;
import de.unisiegen.tpml.core.latex.DefaultLatexInstruction ;
import de.unisiegen.tpml.core.latex.LatexCommandList ;
import de.unisiegen.tpml.core.latex.LatexInstructionList ;
import de.unisiegen.tpml.core.latex.LatexPackage ;
import de.unisiegen.tpml.core.latex.LatexPackageList ;
import de.unisiegen.tpml.core.latex.LatexPrintable ;
import de.unisiegen.tpml.core.latex.LatexString ;
import de.unisiegen.tpml.core.latex.LatexStringBuilder ;
import de.unisiegen.tpml.core.latex.LatexStringBuilderFactory ;
import de.unisiegen.tpml.core.prettyprinter.PrettyPrintable ;
import de.unisiegen.tpml.core.prettyprinter.PrettyString ;
import de.unisiegen.tpml.core.prettyprinter.PrettyStringBuilder ;
import de.unisiegen.tpml.core.prettyprinter.PrettyStringBuilderFactory ;
import de.unisiegen.tpml.core.typechecker.TypeSubstitution ;
import de.unisiegen.tpml.core.types.MonoType ;
import de.unisiegen.tpml.core.types.TypeName ;
import de.unisiegen.tpml.core.util.Theme ;
/**
* Base class for all classes in the expression hierarchy.
*
* @author Benedikt Meurer
* @author Christian Fehler
* @version $Rev:1053 $
* @see PrettyPrintable
*/
public abstract class Expression implements Cloneable , PrettyPrintable ,
PrettyPrintPriorities , LatexPrintable , ShowBondsInput
{
/**
* A level-order enumeration of the expressions within a given expression.
* Used to implement the {@link Expression#levelOrderEnumeration()} method.
*
* @see Expression#levelOrderEnumeration()
*/
private class LevelOrderEnumeration implements Enumeration < Expression >
{
/**
* The queue.
*/
private LinkedList < Expression > queue = new LinkedList < Expression > ( ) ;
/**
* Initializes a new <code>LevelOrderEnumeration</code>.
*
* @param pExpression The input <code>Expression</code>.
*/
LevelOrderEnumeration ( Expression pExpression )
{
this.queue.add ( pExpression ) ;
}
/**
* Returns true, if there are more elements, otherwise false.
*
* @return True, if there are more elements, otherwise false.
* @see Enumeration#hasMoreElements()
*/
public boolean hasMoreElements ( )
{
return ! this.queue.isEmpty ( ) ;
}
/**
* Returns the next element.
*
* @return The next element.
* @see Enumeration#nextElement()
*/
public Expression nextElement ( )
{
Expression e = this.queue.poll ( ) ;
this.queue.addAll ( e.children ( ) ) ;
return e ;
}
}
/**
* The resource bundle.
*/
private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
.getBundle ( "de.unisiegen.tpml.core.expressions.messages" ) ; //$NON-NLS-1$
/**
* Prefix of the {@link Expression}.
*/
protected static final String PREFIX_EXPRESSION = "e" ; //$NON-NLS-1$
/**
* Prefix of the {@link Expression} which is a value.
*/
protected static final String PREFIX_VALUE = "v" ; //$NON-NLS-1$
/**
* Prefix of the {@link Expression} which is a constant.
*/
protected static final String PREFIX_CONST = "c" ; //$NON-NLS-1$
/**
* Prefix of the {@link Inherit}.
*/
protected static final String PREFIX_BODY = "b" ; //$NON-NLS-1$
/**
* Prefix of the {@link Row}.
*/
protected static final String PREFIX_ROW = "r" ; //$NON-NLS-1$
/**
* Prefix of the {@link Row} which is a value.
*/
protected static final String PREFIX_ROW_VALUE = "\u03C9" ; //$NON-NLS-1$
/**
* Prefix of {@link Identifier}s after the first.
*/
public static final String PREFIX_ID_V = "id" ; //$NON-NLS-1$
/**
* Prefix of the first {@link Identifier} of {@link Method}s.
*/
public static final String PREFIX_ID_M = "m" ; //$NON-NLS-1$
/**
* Prefix of the first {@link Identifier} of {@link Attribute}s.
*/
public static final String PREFIX_ID_A = "a" ; //$NON-NLS-1$
/**
* Prefix of the first {@link Identifier} of {@link ObjectExpr}s.
*/
public static final String PREFIX_ID_S = "self" ; //$NON-NLS-1$
/**
* Prefix of the {@link Exn}.
*/
protected static final String PREFIX_EXN = "ep" ; //$NON-NLS-1$
/**
* Prefix of the {@link BinaryOperator}.
*/
protected static final String PREFIX_BINARYOPERATOR = "op" ; //$NON-NLS-1$
/**
* The unused string.
*/
private static final String UNUSED = "unused" ; //$NON-NLS-1$
/**
* Gets the caption for the given class from the resource bundle.
*
* @param pClass The given class.
* @return The caption of the given class.
*/
public static String getCaption ( java.lang.Class < ? > pClass )
{
try
{
return RESOURCE_BUNDLE.getString ( pClass.getSimpleName ( ) ) ;
}
catch ( MissingResourceException e )
{
return pClass.getSimpleName ( ) ;
}
}
/**
* Returns a set of needed latex commands for this latex printable object.
*
* @return A set of needed latex commands for this latex printable object.
*/
public static LatexCommandList getLatexCommandsStatic ( )
{
LatexCommandList commands = new LatexCommandList ( ) ;
commands.add ( new DefaultLatexCommand ( LATEX_PARENTHESIS , 1 , "(#1)" , //$NON-NLS-1$
"e" ) ) ; //$NON-NLS-1$
return commands ;
}
/**
* Returns a set of needed latex instructions for this latex printable object.
*
* @return A set of needed latex instructions for this latex printable object.
*/
public static LatexInstructionList getLatexInstructionsStatic ( )
{
LatexInstructionList instructions = new LatexInstructionList ( ) ;
Color colorExpression = Theme.currentTheme ( ).getExpressionColor ( ) ;
float red = ( float ) Math
.round ( ( ( float ) colorExpression.getRed ( ) ) / 255 * 100 ) / 100 ;
float green = ( float ) Math.round ( ( ( float ) colorExpression
.getGreen ( ) ) / 255 * 100 ) / 100 ;
float blue = ( float ) Math
.round ( ( ( float ) colorExpression.getBlue ( ) ) / 255 * 100 ) / 100 ;
instructions
.add ( new DefaultLatexInstruction (
"\\definecolor{" + LATEX_COLOR_EXPRESSION + "}{rgb}{" //$NON-NLS-1$ //$NON-NLS-2$
+ red + "," //$NON-NLS-1$
+ green + "," //$NON-NLS-1$
+ blue + "}" , LATEX_COLOR_EXPRESSION + ": color of expression text" ) ) ; //$NON-NLS-1$ //$NON-NLS-2$
Color colorKeyword = Theme.currentTheme ( ).getKeywordColor ( ) ;
red = ( float ) Math
.round ( ( ( float ) colorKeyword.getRed ( ) ) / 255 * 100 ) / 100 ;
green = ( float ) Math
.round ( ( ( float ) colorKeyword.getGreen ( ) ) / 255 * 100 ) / 100 ;
blue = ( float ) Math
.round ( ( ( float ) colorKeyword.getBlue ( ) ) / 255 * 100 ) / 100 ;
instructions.add ( new DefaultLatexInstruction (
"\\definecolor{" + LATEX_COLOR_KEYWORD + "}{rgb}{" //$NON-NLS-1$ //$NON-NLS-2$
+ red + "," //$NON-NLS-1$
+ green + "," //$NON-NLS-1$
+ blue + "}" , LATEX_COLOR_KEYWORD + ": color of keywords" ) ) ; //$NON-NLS-1$ //$NON-NLS-2$
Color colorConstant = Theme.currentTheme ( ).getConstantColor ( ) ;
red = ( float ) Math
.round ( ( ( float ) colorConstant.getRed ( ) ) / 255 * 100 ) / 100 ;
green = ( float ) Math
.round ( ( ( float ) colorConstant.getGreen ( ) ) / 255 * 100 ) / 100 ;
blue = ( float ) Math
.round ( ( ( float ) colorConstant.getBlue ( ) ) / 255 * 100 ) / 100 ;
instructions.add ( new DefaultLatexInstruction (
"\\definecolor{" + LATEX_COLOR_CONSTANT + "}{rgb}{" //$NON-NLS-1$ //$NON-NLS-2$
+ red + "," //$NON-NLS-1$
+ green + "," //$NON-NLS-1$
+ blue + "}" , LATEX_COLOR_CONSTANT + ": color of constants" ) ) ; //$NON-NLS-1$ //$NON-NLS-2$
Color colorIdentifier = Theme.currentTheme ( ).getIdentifierColor ( ) ;
red = ( float ) Math
.round ( ( ( float ) colorIdentifier.getRed ( ) ) / 255 * 100 ) / 100 ;
green = ( float ) Math
.round ( ( ( float ) colorIdentifier.getGreen ( ) ) / 255 * 100 ) / 100 ;
blue = ( float ) Math
.round ( ( ( float ) colorIdentifier.getBlue ( ) ) / 255 * 100 ) / 100 ;
instructions.add ( new DefaultLatexInstruction (
"\\definecolor{" + LATEX_COLOR_IDENTIFIER + "}{rgb}{" //$NON-NLS-1$ //$NON-NLS-2$
+ red + "," //$NON-NLS-1$
+ green + "," //$NON-NLS-1$
+ blue + "}" , LATEX_COLOR_IDENTIFIER + ": color of identifiers" ) ) ; //$NON-NLS-1$ //$NON-NLS-2$
Color colorBindingId = Theme.currentTheme ( ).getBindingIdColor ( ) ;
red = ( float ) Math
.round ( ( ( float ) colorBindingId.getRed ( ) ) / 255 * 100 ) / 100 ;
green = ( float ) Math
.round ( ( ( float ) colorBindingId.getGreen ( ) ) / 255 * 100 ) / 100 ;
blue = ( float ) Math
.round ( ( ( float ) colorBindingId.getBlue ( ) ) / 255 * 100 ) / 100 ;
instructions
.add ( new DefaultLatexInstruction (
"\\definecolor{" + LATEX_COLOR_BINDING_ID + "}{rgb}{" //$NON-NLS-1$ //$NON-NLS-2$
+ red + "," //$NON-NLS-1$
+ green + "," //$NON-NLS-1$
+ blue + "}" , LATEX_COLOR_BINDING_ID + ": color of binding identifiers" ) ) ; //$NON-NLS-1$ //$NON-NLS-2$
Color colorBoundId = Theme.currentTheme ( ).getBoundIdColor ( ) ;
red = ( float ) Math
.round ( ( ( float ) colorBoundId.getRed ( ) ) / 255 * 100 ) / 100 ;
green = ( float ) Math
.round ( ( ( float ) colorBoundId.getGreen ( ) ) / 255 * 100 ) / 100 ;
blue = ( float ) Math
.round ( ( ( float ) colorBoundId.getBlue ( ) ) / 255 * 100 ) / 100 ;
instructions
.add ( new DefaultLatexInstruction (
"\\definecolor{" + LATEX_COLOR_BOUND_ID + "}{rgb}{" //$NON-NLS-1$ //$NON-NLS-2$
+ red + "," //$NON-NLS-1$
+ green + "," //$NON-NLS-1$
+ blue + "}" , LATEX_COLOR_BOUND_ID + ": color of bound identifiers" ) ) ; //$NON-NLS-1$ //$NON-NLS-2$
return instructions ;
}
/**
* Returns a set of needed latex packages for this latex printable object.
*
* @return A set of needed latex packages for this latex printable object.
*/
public static LatexPackageList getLatexPackagesStatic ( )
{
LatexPackageList packages = new LatexPackageList ( ) ;
packages.add ( LatexPackage.COLOR ) ;
return packages ;
}
/**
* Cached <code>TreeSet</code> of the free Identifiers, so the free
* Identifier do not need to be determined on every invocation of
* {@link #getIdentifiersFree()}.
*
* @see #getIdentifiersFree()
*/
protected ArrayList < Identifier > identifiersFree = null ;
/**
* A list of all {@link Identifier}s in this {@link Expression}.
*
* @see #getIdentifiersAll()
*/
private ArrayList < Identifier > identifiersAll = null ;
/**
* Cached {@link PrettyStringBuilder}, so the {@link PrettyStringBuilder} do
* not need to be determined on every invocation of
* {@link #toPrettyStringBuilder(PrettyStringBuilderFactory)}.
*
* @see #toPrettyStringBuilder(PrettyStringBuilderFactory)
*/
protected PrettyStringBuilder prettyStringBuilder = null ;
/**
* A list of lists of bound {@link Identifier}s in this {@link Expression}.
*/
protected ArrayList < ArrayList < Identifier >> boundIdentifiers = null ;
/**
* Cached liyt of sub expressions, so the children do not need to be
* determined on every invocation of {@link #children()}.
*
* @see #children()
*/
private ArrayList < Expression > children = null ;
/**
* Cached vector of {@link Attribute} {@link Identifier}.
*
* @see #getDomA()
*/
protected ArrayList < Identifier > domA = null ;
/**
* The parent of this {@link Expression}.
*
* @see #getParent()
* @see #setParent(PrettyPrintable)
*/
protected PrettyPrintable parent = null ;
/**
* The start offset of this {@link Expression} in the source code.
*
* @see #getParserStartOffset()
* @see #setParserStartOffset(int)
*/
protected int parserStartOffset = - 1 ;
/**
* The end offset of this {@link Expression} in the source code.
*
* @see #getParserEndOffset()
* @see #setParserEndOffset(int)
*/
protected int parserEndOffset = - 1 ;
/**
* The prefix of this {@link Expression}.
*
* @see #getPrefix()
*/
protected String prefix = null ;
/**
* The list of the free {@link TypeName}s in this {@link Expression}.
*/
private ArrayList < TypeName > typeNamesFree = null ;
/**
* Returns an {@link ArrayList} of the child {@link Expression}s.
*
* @return An {@link ArrayList} of the child {@link Expression}s.
*/
public final ArrayList < Expression > children ( )
{
if ( this.children == null )
{
if ( this instanceof DefaultExpressions )
{
Expression [ ] expressions = ( ( DefaultExpressions ) this )
.getExpressions ( ) ;
this.children = new ArrayList < Expression > ( expressions.length ) ;
for ( Expression expression : expressions )
{
this.children.add ( expression ) ;
}
}
else
{
this.children = new ArrayList < Expression > ( 0 ) ;
}
}
return this.children ;
}
/**
* Clones this expression, so that the result is an expression equal to this
* expression, but with a different object identity. This is used in the
* substitution of expressions to be able to distinguish different appearances
* of the same identifier in the pretty printer, as required by the
* highlighting of bound variables.
*
* @return a deep clone of this object.
* @see Object#clone()
*/
@ Override
public abstract Expression clone ( ) ;
/**
* Returns <code>true</code> if the expression contains any of the memory
* operations, that is either {@link Assign}, {@link Deref} or {@link Ref}.
* Otherwise <code>false</code> will be returned. This method is used for
* the {@link de.unisiegen.tpml.core.interpreters.InterpreterProofModel}s to
* enable the
* {@link de.unisiegen.tpml.core.interpreters.InterpreterProofModel#isMemoryEnabled()}
* property depending on whether the expression at the root node contains
* memory operations or not. This method uses the
* {@link #levelOrderEnumeration()} method to traverse all sub expressions, so
* this method does not need to be implemented by any derived class, but it'll
* work automagically.
*
* @return <code>true</code> if the expression contains any of the memory
* operations, <code>false</code> otherwise.
* @see #children()
* @see #levelOrderEnumeration()
*/
public final boolean containsMemoryOperations ( )
{
Enumeration < Expression > enumeration = levelOrderEnumeration ( ) ;
while ( enumeration.hasMoreElements ( ) )
{
Expression e = enumeration.nextElement ( ) ;
if ( ( e instanceof Assign ) || ( e instanceof Deref )
|| ( e instanceof Ref ) )
{
return true ;
}
}
return false ;
}
/**
* {@inheritDoc}
*
* @see Object#equals(Object)
*/
@ Override
public abstract boolean equals ( Object pObject ) ;
/**
* Returns the caption of this {@link Expression}.
*
* @return The caption of this {@link Expression}.
*/
public abstract String getCaption ( ) ;
/**
* Returns a list of all {@link Attribute} {@link Identifier}s in the domain
* of this {@link Expression}.
*
* @return A list of all {@link Attribute} {@link Identifier}s in the domain
* of this {@link Expression}.
*/
public ArrayList < Identifier > getDomA ( )
{
if ( this.domA == null )
{
this.domA = new ArrayList < Identifier > ( ) ;
for ( Expression child : children ( ) )
{
this.domA.addAll ( child.getDomA ( ) ) ;
}
}
return this.domA ;
}
/**
* Returns true, if a free Identifier is not a variable and not a method
* {@link Identifier}, otherwise false.
*
* @return True, if a free Identifier is not a variable and not a method
* {@link Identifier}, otherwise false.
*/
public final boolean getIdentifierFreeNotOnlyVariable ( )
{
for ( Identifier id : getIdentifiersFree ( ) )
{
if ( ! ( ( Identifier.Set.VARIABLE.equals ( id.getSet ( ) ) ) || ( Identifier.Set.METHOD
.equals ( id.getSet ( ) ) ) ) )
{
return true ;
}
}
return false ;
}
/**
* Returns a list of all {@link Identifier}s in this {@link Expression}. For
* example "lambda id.x" will return a list with the members "id" and "x".
* This method should only be used to check the disjunction of the
* {@link Identifier}s.
*
* @return A list of all {@link Identifier}s in this {@link Expression}.
* @see #identifiersAll
*/
public final ArrayList < Identifier > getIdentifiersAll ( )
{
if ( this.identifiersAll == null )
{
this.identifiersAll = new ArrayList < Identifier > ( ) ;
if ( this instanceof Identifier )
{
this.identifiersAll.add ( ( Identifier ) this ) ;
return this.identifiersAll ;
}
if ( this instanceof DefaultIdentifiers )
{
Identifier [ ] identifiers = ( ( DefaultIdentifiers ) this )
.getIdentifiers ( ) ;
for ( Identifier id : identifiers )
{
this.identifiersAll.add ( id ) ;
}
}
for ( Expression child : children ( ) )
{
this.identifiersAll.addAll ( child.getIdentifiersAll ( ) ) ;
}
}
return this.identifiersAll ;
}
/**
* Returns the free (unbound) identifiers within the expression, e.g. the name
* of the identifier for an identifier expression or the free identifiers for
* its sub expressions in applications, abstractions and recursions. The
* default implementation in the {@link Expression} class uses introspection
* to determine the sub expressions and calls <code>free()</code>
* recursively on all sub expressions. Some of the derived classes might need
* to override this method if they represents a binding mechanism, like
* {@link Let}, or if they don't have sub expressions, but provide free
* identifiers, like {@link Identifier}.
*
* @return the set of free (unbound) identifiers within the expression.
*/
public ArrayList < Identifier > getIdentifiersFree ( )
{
if ( this.identifiersFree == null )
{
this.identifiersFree = new ArrayList < Identifier > ( ) ;
for ( Expression child : children ( ) )
{
this.identifiersFree.addAll ( child.getIdentifiersFree ( ) ) ;
}
}
return this.identifiersFree ;
}
/**
* Returns a set of needed latex commands for this latex printable object.
*
* @return A set of needed latex commands for this latex printable object.
*/
public LatexCommandList getLatexCommands ( )
{
LatexCommandList commands = new LatexCommandList ( ) ;
commands.add ( getLatexCommandsStatic ( ) ) ;
if ( this instanceof DefaultExpressions )
{
commands.add ( ( ( DefaultExpressions ) this ).getExpressions ( ) ) ;
}
if ( this instanceof DefaultIdentifiers )
{
commands.add ( ( ( DefaultIdentifiers ) this ).getIdentifiers ( ) ) ;
}
if ( this instanceof DefaultTypes )
{
commands.add ( ( ( DefaultTypes ) this ).getTypes ( ) ) ;
}
return commands ;
}
/**
* Returns a list of needed latex instructions for this latex printable
* object.
*
* @return A lsit of needed latex instructions for this latex printable
* object.
*/
public LatexInstructionList getLatexInstructions ( )
{
LatexInstructionList instructions = new LatexInstructionList ( ) ;
instructions.add ( getLatexInstructionsStatic ( ) ) ;
if ( this instanceof DefaultExpressions )
{
instructions.add ( ( ( DefaultExpressions ) this ).getExpressions ( ) ) ;
}
if ( this instanceof DefaultIdentifiers )
{
instructions.add ( ( ( DefaultIdentifiers ) this ).getIdentifiers ( ) ) ;
}
if ( this instanceof DefaultTypes )
{
instructions.add ( ( ( DefaultTypes ) this ).getTypes ( ) ) ;
}
return instructions ;
}
/**
* Returns a set of needed latex packages for this latex printable object.
*
* @return A set of needed latex packages for this latex printable object.
*/
public LatexPackageList getLatexPackages ( )
{
LatexPackageList packages = new LatexPackageList ( ) ;
packages.add ( getLatexPackagesStatic ( ) ) ;
if ( this instanceof DefaultExpressions )
{
packages.add ( ( ( DefaultExpressions ) this ).getExpressions ( ) ) ;
}
if ( this instanceof DefaultIdentifiers )
{
packages.add ( ( ( DefaultIdentifiers ) this ).getIdentifiers ( ) ) ;
}
if ( this instanceof DefaultTypes )
{
packages.add ( ( ( DefaultTypes ) this ).getTypes ( ) ) ;
}
return packages ;
}
/**
* Returns the parent of this {@link Expression}.
*
* @return The parent of this {@link Expression}.
* @see #parent
* @see #setParent(PrettyPrintable)
*/
public final PrettyPrintable getParent ( )
{
return this.parent ;
}
/**
* Returns the parserEndOffset.
*
* @return The parserEndOffset.
* @see #parserEndOffset
* @see #setParserEndOffset(int)
*/
public int getParserEndOffset ( )
{
return this.parserEndOffset ;
}
/**
* Returns the parserStartOffset.
*
* @return The parserStartOffset.
* @see #parserStartOffset
* @see #setParserStartOffset(int)
*/
public int getParserStartOffset ( )
{
return this.parserStartOffset ;
}
/**
* Returns the prefix of this {@link Expression}.
*
* @return The prefix of this {@link Expression}.
* @see #prefix
*/
public String getPrefix ( )
{
if ( this.prefix == null )
{
if ( this.isValue ( ) )
{
this.prefix = PREFIX_VALUE ;
}
else
{
this.prefix = PREFIX_EXPRESSION ;
}
}
return this.prefix ;
}
/**
* Returns a list of the free {@link TypeName}s in this {@link Expression}.
*
* @return A list of the free {@link TypeName}s in this {@link Expression}.
*/
public ArrayList < TypeName > getTypeNamesFree ( )
{
if ( this.typeNamesFree == null )
{
this.typeNamesFree = new ArrayList < TypeName > ( ) ;
MonoType [ ] types = null ;
if ( this instanceof DefaultTypes )
{
types = ( ( DefaultTypes ) this ).getTypes ( ) ;
}
if ( types != null )
{
for ( MonoType type : types )
{
if ( type != null )
{
this.typeNamesFree.addAll ( type.getTypeNamesFree ( ) ) ;
}
}
}
for ( Expression child : children ( ) )
{
this.typeNamesFree.addAll ( child.getTypeNamesFree ( ) ) ;
}
}
return this.typeNamesFree ;
}
/**
* {@inheritDoc}
*
* @see Object#hashCode()
*/
@ Override
public abstract int hashCode ( ) ;
/**
* Returns <code>true</code> if the expression should be considered an
* exception in the big and small step interpreters and must thereby not be
* evaluated any futher, nor must any operation be performed on exceptions.
* The default implementation in the <code>Expression</code> class simply
* returns <code>false</code>, so derived classes will need to override
* this method if their instances should be considered values under certain
* circumstances.
*
* @return <code>true</code> if the expression is an exception,
* <code>false</code> otherwise.
*/
public boolean isException ( )
{
return false ;
}
/**
* Returns <code>true</code> if the expression should be considered a value
* in the big and small step interpreters and must thereby not be evaluated
* any further. The default implementation in the <code>Expression</code>
* class simply returns <code>false</code>, so derived classes will need to
* override this method if their instances should be considered values under
* certain circumstances.
*
* @return <code>true</code> if the expression is a value,
* <code>false</code> otherwise.
*/
public boolean isValue ( )
{
return false ;
}
/**
* Returns an {@link Enumeration} that enumerates the expression within the
* expression hierarchy starting at this expression in level order (that is
* breadth first enumeration).
*
* @return a breadth first enumeration of all expressions within the
* expression hierarchy starting at this item.
*/
public Enumeration < Expression > levelOrderEnumeration ( )
{
return new LevelOrderEnumeration ( this ) ;
}
/**
* Sets the parent of this {@link Expression}.
*
* @param pParent The parent to set.
* @see #parent
* @see #getParent()
*/
public final void setParent ( PrettyPrintable pParent )
{
this.parent = pParent ;
}
/**
* Sets the parser end offset.
*
* @param pParserEndOffset The new parser end offset.
* @see #getParserEndOffset()
* @see #parserEndOffset
*/
public void setParserEndOffset ( int pParserEndOffset )
{
this.parserEndOffset = pParserEndOffset ;
}
/**
* Sets the parser start offset.
*
* @param pParserStartOffset The new parser start offset.
* @see #getParserStartOffset()
* @see #parserStartOffset
*/
public void setParserStartOffset ( int pParserStartOffset )
{
this.parserStartOffset = pParserStartOffset ;
}
/**
* Substitutes the expression <code>e</code> for the identifier
* <code>id</code> in this expression, and returns the resulting expression.
* The resulting expression may be a new <code>Expression</code> object or
* if no substitution took place, the same object. The method operates
* recursively.
*
* @param pId the name of the identifier.
* @param pExpression the <code>Expression</code> to substitute.
* @return the resulting expression.
* @throws NullPointerException if <code>id</code> or </code>e</code> is
* <code>null</code>.
*/
public abstract Expression substitute ( Identifier pId ,
Expression pExpression ) ;
/**
* Applies the type <code>substitution</code> to this expression, to be
* exact, to the types within this expression, and returns the new expression
* with the new types. If the expression does not contain any types, this
* method simply returns a reference to this expression.
*
* @param pTypeSubstitution the type substitution to apply.
* @return the resulting expression.
* @throws NullPointerException if <code>substitution</code> is
* <code>null</code>.
*/
public Expression substitute ( @ SuppressWarnings ( UNUSED )
TypeSubstitution pTypeSubstitution )
{
return this ;
}
/**
* {@inheritDoc}
*
* @see LatexPrintable#toLatexString()
*/
public final LatexString toLatexString ( )
{
return toLatexStringBuilder ( LatexStringBuilderFactory.newInstance ( ) , 0 )
.toLatexString ( ) ;
}
/**
* {@inheritDoc}
*
* @see LatexPrintable#toLatexStringBuilder(LatexStringBuilderFactory,int)
*/
public abstract LatexStringBuilder toLatexStringBuilder (
LatexStringBuilderFactory pLatexStringBuilderFactory , int pIndent ) ;
/**
* {@inheritDoc}
*
* @see PrettyPrintable#toPrettyString()
*/
public final PrettyString toPrettyString ( )
{
return toPrettyStringBuilder ( PrettyStringBuilderFactory.newInstance ( ) )
.toPrettyString ( ) ;
}
/**
* {@inheritDoc}
*
* @see PrettyPrintable#toPrettyStringBuilder(PrettyStringBuilderFactory)
*/
public abstract PrettyStringBuilder toPrettyStringBuilder (
PrettyStringBuilderFactory pPrettyStringBuilderFactory ) ;
/**
* Returns the string representation for this expression. This method is
* mainly used for debugging.
*
* @return The pretty printed string representation for this expression.
* @see #toPrettyString()
* @see Object#toString()
*/
@ Override
public final String toString ( )
{
return toPrettyString ( ).toString ( ) ;
}
}