package de.unisiegen.tpml.core.expressions;
import de.unisiegen.tpml.core.exceptions.NotOnlyFreeVariableException;
import de.unisiegen.tpml.core.interfaces.DefaultExpressions;
import de.unisiegen.tpml.core.latex.DefaultLatexCommand;
import de.unisiegen.tpml.core.latex.LatexCommandList;
import de.unisiegen.tpml.core.latex.LatexStringBuilder;
import de.unisiegen.tpml.core.latex.LatexStringBuilderFactory;
import de.unisiegen.tpml.core.prettyprinter.PrettyStringBuilder;
import de.unisiegen.tpml.core.prettyprinter.PrettyStringBuilderFactory;
import de.unisiegen.tpml.core.typechecker.TypeSubstitution;
/**
* Instances of this class represent or expressions, printed as
* <code>e1 || e2</code>. This is syntactic sugar for
* <code>if e1 then true else e2</code>.
*
* @author Benedikt Meurer
* @author Christian Fehler
* @version $Rev:1053 $
* @see And
* @see Condition
* @see Condition1
* @see Expression
*/
public final class Or extends Expression implements DefaultExpressions
{
/**
* The caption of this {@link Expression}.
*/
private static final String CAPTION = Expression.getCaption ( Or.class );
/**
* String for the case that e1 is null.
*/
private static final String E1_NULL = "e1 is null"; //$NON-NLS-1$
/**
* String for the case that e2 is null.
*/
private static final String E2_NULL = "e2 is null"; //$NON-NLS-1$
/**
* Indeces of the child {@link Expression}s.
*/
private static final int [] INDICES_E = new int []
{ 1, 2 };
/**
* 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_KEY_BARBAR, 0,
"\\textbf{\\color{" + LATEX_COLOR_KEYWORD + "}{$\\|$}}" ) ); //$NON-NLS-1$ //$NON-NLS-2$
commands.add ( new DefaultLatexCommand ( LATEX_OR, 2, "\\color{" //$NON-NLS-1$
+ LATEX_COLOR_EXPRESSION + "}#1\\ \\" + LATEX_KEY_BARBAR + "\\ #2", //$NON-NLS-1$ //$NON-NLS-2$
"e1", "e2" ) ); //$NON-NLS-1$ //$NON-NLS-2$
return commands;
}
/**
* The left and right expression.
*/
private Expression [] expressions;
/**
* Allocates a new <code>Or</code> instance with the specified
* <code>e1</code> and <code>e2</code>.
*
* @param pExpression1 the left side expression.
* @param pExpression2 the right side expression.
* @throws NullPointerException if <code>e1</code> or <code>e2</code> is
* <code>null</code>.
*/
public Or ( Expression pExpression1, Expression pExpression2 )
{
if ( pExpression1 == null )
{
throw new NullPointerException ( E1_NULL );
}
if ( pExpression2 == null )
{
throw new NullPointerException ( E2_NULL );
}
this.expressions = new Expression []
{ pExpression1, pExpression2 };
this.expressions [ 0 ].setParent ( this );
this.expressions [ 1 ].setParent ( this );
}
/**
* Allocates a new <code>Or</code> instance with the specified
* <code>e1</code> and <code>e2</code>.
*
* @param pExpression1 the left side expression.
* @param pExpression2 the right side expression.
* @param pParserStartOffset The start offset of this {@link Expression} in
* the source code.
* @param pParserEndOffset The end offset of this {@link Expression} in the
* source code.
* @throws NullPointerException if <code>e1</code> or <code>e2</code> is
* <code>null</code>.
*/
public Or ( Expression pExpression1, Expression pExpression2,
int pParserStartOffset, int pParserEndOffset )
{
this ( pExpression1, pExpression2 );
this.parserStartOffset = pParserStartOffset;
this.parserEndOffset = pParserEndOffset;
}
/**
* {@inheritDoc}
*
* @see Expression#clone()
*/
@Override
public Or clone ()
{
return new Or ( this.expressions [ 0 ].clone (), this.expressions [ 1 ]
.clone () );
}
/**
* {@inheritDoc}
*
* @see Expression#equals(Object)
*/
@Override
public boolean equals ( Object pObject )
{
if ( pObject instanceof Or )
{
Or other = ( Or ) pObject;
return ( ( this.expressions [ 0 ].equals ( other.expressions [ 0 ] ) ) && ( this.expressions [ 1 ]
.equals ( other.expressions [ 1 ] ) ) );
}
return false;
}
/**
* {@inheritDoc}
*/
@Override
public String getCaption ()
{
return CAPTION;
}
/**
* Returns the left side expression.
*
* @return the e1.
*/
public Expression getE1 ()
{
return this.expressions [ 0 ];
}
/**
* Returns the right side expression.
*
* @return the e2.
*/
public Expression getE2 ()
{
return this.expressions [ 1 ];
}
/**
* Returns the sub expressions.
*
* @return the sub expressions.
*/
public Expression [] getExpressions ()
{
return this.expressions;
}
/**
* Returns the indices of the child {@link Expression}s.
*
* @return The indices of the child {@link Expression}s.
*/
public int [] getExpressionsIndex ()
{
return INDICES_E;
}
/**
* Returns a set of needed latex commands for this latex printable object.
*
* @return A set of needed latex commands for this latex printable object.
*/
@Override
public LatexCommandList getLatexCommands ()
{
LatexCommandList commands = super.getLatexCommands ();
commands.add ( getLatexCommandsStatic () );
return commands;
}
/**
* {@inheritDoc}
*
* @see Expression#hashCode()
*/
@Override
public int hashCode ()
{
return this.expressions [ 0 ].hashCode ()
+ this.expressions [ 1 ].hashCode ();
}
/**
* {@inheritDoc}
*
* @see Expression#substitute(Identifier, Expression)
*/
@Override
public Or substitute ( Identifier pId, Expression pExpression )
{
if ( pExpression.getIdentifierFreeNotOnlyVariable () )
{
throw new NotOnlyFreeVariableException ();
}
Expression newE1 = this.expressions [ 0 ].substitute ( pId, pExpression );
Expression newE2 = this.expressions [ 1 ].substitute ( pId, pExpression );
return new Or ( newE1, newE2 );
}
/**
* {@inheritDoc}
*
* @see Expression#substitute(TypeSubstitution)
*/
@Override
public Or substitute ( TypeSubstitution pTypeSubstitution )
{
Expression newE1 = this.expressions [ 0 ].substitute ( pTypeSubstitution );
Expression newE2 = this.expressions [ 1 ].substitute ( pTypeSubstitution );
return new Or ( newE1, newE2 );
}
/**
* {@inheritDoc}
*
* @see Expression#toLatexStringBuilder(LatexStringBuilderFactory,int)
*/
@Override
public LatexStringBuilder toLatexStringBuilder (
LatexStringBuilderFactory pLatexStringBuilderFactory, int pIndent )
{
LatexStringBuilder builder = pLatexStringBuilderFactory.newBuilder (
PRIO_OR, LATEX_OR, pIndent, this.toPrettyString ().toString (),
this.expressions [ 0 ].toPrettyString ().toString (),
this.expressions [ 1 ].toPrettyString ().toString () );
builder.addBuilder ( this.expressions [ 0 ].toLatexStringBuilder (
pLatexStringBuilderFactory, pIndent + LATEX_INDENT ), PRIO_OR_E1 );
builder.addBreak ();
builder.addBuilder ( this.expressions [ 1 ].toLatexStringBuilder (
pLatexStringBuilderFactory, pIndent + LATEX_INDENT ), PRIO_OR_E2 );
return builder;
}
/**
* {@inheritDoc}
*
* @see Expression#toPrettyStringBuilder(PrettyStringBuilderFactory)
*/
@Override
public PrettyStringBuilder toPrettyStringBuilder (
PrettyStringBuilderFactory pPrettyStringBuilderFactory )
{
if ( this.prettyStringBuilder == null )
{
this.prettyStringBuilder = pPrettyStringBuilderFactory.newBuilder ( this,
PRIO_OR );
this.prettyStringBuilder.addBuilder ( this.expressions [ 0 ]
.toPrettyStringBuilder ( pPrettyStringBuilderFactory ), PRIO_OR_E1 );
this.prettyStringBuilder.addText ( PRETTY_SPACE );
this.prettyStringBuilder.addBreak ();
this.prettyStringBuilder.addKeyword ( PRETTY_BARBAR );
this.prettyStringBuilder.addText ( PRETTY_SPACE );
this.prettyStringBuilder.addBuilder ( this.expressions [ 1 ]
.toPrettyStringBuilder ( pPrettyStringBuilderFactory ), PRIO_OR_E2 );
}
return this.prettyStringBuilder;
}
}