View Javadoc

1   ////////////////////////////////////////////////////////////////////////////////
2   // MillScript: an Open Spice interpreter and batch website creation tool
3   // Copyright (C) 2001-2004 Open World Ltd
4   // Copyright (C) 2005 Kevin Rogers
5   //
6   // This file is part of MillScript.
7   //
8   // MillScript is free software; you can redistribute it and/or modify it under
9   // the terms of the GNU General Public License as published by the Free
10  // Software Foundation; either version 2 of the License, or (at your option)
11  // any later version.
12  //
13  // MillScript is distributed in the hope that it will be useful, but WITHOUT
14  // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16  // more details.
17  //
18  // You should have received a copy of the GNU General Public License along with
19  // MillScript; if not, write to the Free Software Foundation, Inc., 59 Temple
20  // Place, Suite 330, Boston, MA  02111-1307  USA
21  ////////////////////////////////////////////////////////////////////////////////
22  package org.millscript.millscript.expr;
23  
24  import org.millscript.millscript.action.Action;
25  import org.millscript.millscript.action.BinaryOpAction;
26  import org.millscript.millscript.action.arithmetic.AddAction;
27  import org.millscript.millscript.action.arithmetic.DivAction;
28  import org.millscript.millscript.action.arithmetic.ModAction;
29  import org.millscript.millscript.action.arithmetic.MulAction;
30  import org.millscript.millscript.action.arithmetic.SubAction;
31  import org.millscript.millscript.alert.Alerts;
32  import org.millscript.millscript.tools.IntegerTools;
33  
34  /**
35   * This class implements an arithmetic expression. This expression always
36   * returns one result.
37   *
38   * @see IntegerTools
39   */
40  public final class ArithExpr extends BinaryOpExpr< BinaryOpAction > {
41  
42      /**
43       * The arithmetic symbol this expression is for.
44       */
45      private final String sym;
46  
47      /**
48       * Creates a new arithmetic expression for the specified symbol and left and
49       * right hand side expressions.
50       *
51       * @param   s   the arithmetic symbol to make an expression for
52       * @param   a   the left hand side expression, which should return a single
53       *              result
54       * @param   b   the right hand side expression, which should return a single
55       *              result
56       */
57      public ArithExpr( final String s, final Expr< ? > a, final Expr< ? > b ) {
58          super( a, b );
59          this.sym = s;
60      }
61  
62      /**
63       * Returns an expression for the specified arithmetic expression. The
64       * arithmetic expression is composed of a symbol and left and right hand
65       * side expressions. This method provides some compile-time optimisation, as
66       * it avoids creating additional unnecessary objects in the expression tree.
67       * If the specified left and right hand side expressions are for constant
68       * integers, the specified operation is performed and a new constant
69       * expression returned.
70       *
71       * @param   s   the arithmetic symbol to make an expression for
72       * @param   a   the left hand side expression, which should return a single
73       *              result
74       * @param   b   the right hand side expression, which should return a single
75       *              result
76       * @return  a {@link ConstantExpr} if the left and right hand side are
77       *          constant integers, otherwise an anonymous {@link Action} for
78       *          the specified symbol
79       */
80      public static Expr make( final String s, final Expr a, final Expr b ) {
81          Integer x = isIntegerExpr( a );
82          Integer y = isIntegerExpr( b );
83          if ( x != null && y != null ) {
84              return new ConstantExpr( IntegerTools.op( s, x, y ) );
85          } else if ( x != null ) {
86              return new ConstantLeftArithExpr( s, x, b );
87          } else if ( y != null ) {
88              return new ConstantRightArithExpr( s, a, y );
89          } else {
90              return new ArithExpr( s, a, b );
91          }
92      }
93  
94      /**
95       * @see org.millscript.millscript.expr.BinaryOpExpr#newAction(org.millscript.millscript.action.Action, org.millscript.millscript.action.Action)
96       */
97      @Override
98      public BinaryOpAction newAction( final Action a, final Action b ) {
99          if ( sym == "+" ) {
100             return new AddAction( a, b );
101         } else if ( sym == "-" ) {
102             return new SubAction( a, b );
103         } else if ( sym == "*" ) {
104             return new MulAction( a, b );
105         } else if ( sym == "div" ) {
106             return new DivAction( a, b );
107         } else if ( sym == "mod" ) {
108             return new ModAction( a, b );
109         } else {
110             throw(
111                 Alerts.fault(
112                     "Unrecognized arithmetic symbol: " + sym
113                 ).mishap()
114             );
115         }
116     }
117 
118 }