View Javadoc

1   ////////////////////////////////////////////////////////////////////////////////
2   // MillScript: an Open Spice interpreter and batch website creation tool
3   // Copyright (C) 2001-2004 Open World Ltd
4   //
5   // This file is part of MillScript.
6   //
7   // MillScript is free software; you can redistribute it and/or modify it under
8   // the terms of the GNU General Public License as published by the Free
9   // Software Foundation; either version 2 of the License, or (at your option)
10  // any later version.
11  //
12  // MillScript is distributed in the hope that it will be useful, but WITHOUT
13  // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15  // more details.
16  //
17  // You should have received a copy of the GNU General Public License along with
18  // MillScript; if not, write to the Free Software Foundation, Inc., 59 Temple
19  // Place, Suite 330, Boston, MA  02111-1307  USA
20  ////////////////////////////////////////////////////////////////////////////////
21  package org.millscript.millscript.expr;
22  
23  import org.millscript.commons.util.list.ELinkedList;
24  import org.millscript.millscript.action.Action;
25  import org.millscript.millscript.action.RelationalOperationChainAction;
26  import org.millscript.millscript.vm.CompilerState;
27  
28  /**
29   * This class implements a relation operation expression.
30   */
31  public final class RelationalOperationExpr extends Expr< Action > implements OneResult {
32  
33      /**
34       * The expression generating a function to apply.
35       */
36      private final Expr< ? > fun;
37  
38      /**
39       * The expression generating the left hand side for the relational
40       * expression.
41       */
42      private final Expr< ? > lhs;
43  
44      /**
45       * The expression generating the right hand side for the relational
46       * expression.
47       */
48      private final Expr< ? > rhs;
49  
50      /**
51       * Creates a new relation operation expression for the specified relational
52       * operation function and argument expressions.
53       *
54       * @param   f   the relation operation function expression, which must
55       * return a function as a single result
56       * @param   l   the left hand side expression, which must return a single
57       * result
58       * @param   r   the right hand side expression, which must return a single
59       * result
60       */
61      public RelationalOperationExpr( final Expr< ? > f, final Expr< ? > l, final Expr< ? > r ) {
62          this.fun = CheckExpr.make( f );
63          this.lhs = CheckExpr.make( l );
64          this.rhs = CheckExpr.make( r );
65      }
66  
67      /**
68       * @see org.millscript.millscript.expr.Expr#compileIt()
69       */
70      @Override
71      @SuppressWarnings("unchecked")
72      public Action compileIt() {
73          // We always compile this type as a chain of relational operations
74          // First make the temporary lists to store the set of comparisons and
75          // right hand side expressions
76          final ELinkedList< Expr< ? > > comparisons = new ELinkedList< Expr< ? > >();
77          final ELinkedList< Expr< ? > > expressions = new ELinkedList< Expr< ? > >();
78          // add this comparison
79          comparisons.addLast( fun );
80          // FIXME - When Sun fix their java compiler the following parameter can be
81          // made Expr< ? > and the suppress warnings can be removed
82          Expr rightExpr = this.getRhs();
83          while( rightExpr instanceof RelationalOperationExpr ) {
84              RelationalOperationExpr rightRelOpExpr = (RelationalOperationExpr) rightExpr;
85              expressions.addLast( rightRelOpExpr.getLhs() );
86              comparisons.addLast( rightRelOpExpr.getFun() );
87              rightExpr = rightRelOpExpr.getRhs();
88          }
89          // finally add the trailing right hand side expression
90          expressions.addLast( rightExpr );
91          // Now perform the compilation of the components.
92          // This will hold all the compiled expression for the right hand side
93          // of each relational operation in the chain
94          final Action[] exprs = new Action[ expressions.size() ];
95          // and compile each expression
96          for ( int i = 0; i < expressions.size(); i++ ) {
97              Expr< ? > e = expressions.get0( i );
98              exprs[ i ] = e.compile();
99          }
100         // This will hold all the compiled symbols for each relational
101         // operation in the chain
102         final Action[] syms = new Action[ comparisons.size() ];
103         // and compile each expression
104         for ( int i = 0; i < comparisons.size(); i++ ) {
105             Expr< ? > e = comparisons.get0( i );
106             syms[ i ] = e.compile();
107         }
108         return new RelationalOperationChainAction( this.lhs.compile(), syms, exprs );
109     }
110 
111     /**
112      * Returns the function expression this apply expression will apply.
113      *
114      * @return  the expression returning a single function
115      */
116     public Expr getFun() {
117         return fun;
118     }
119 
120     /**
121      * Returns the left hand side argument expression for this relational
122      * operation.
123      *
124      * @return  the left hand side expression for the relation operation
125      */
126     public Expr getLhs() {
127         return this.lhs;
128     }
129 
130     /**
131      * Returns the right hand side argument expression for this relational
132      * operation.
133      *
134      * @return  the right hand side expression for the relation operation
135      */
136     public Expr getRhs() {
137         return this.rhs;
138     }
139 
140     /**
141      * @see org.millscript.millscript.expr.Expr#resolve(org.millscript.millscript.vm.CompilerState)
142      */
143     @Override
144     public void resolve( final CompilerState state ) {
145         this.fun.resolve( state );
146         this.lhs.resolve( state );
147         this.rhs.resolve( state );
148     }
149 
150     /**
151      * @see org.millscript.millscript.expr.Expr#showComponents(int)
152      */
153     @Override
154     void showComponents( final int n ) {
155         this.fun.show( n );
156         this.lhs.show( n );
157         this.rhs.show( n );
158     }
159 
160 }