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; } }