View Javadoc

1   ////////////////////////////////////////////////////////////////////////////////
2   // MillScript: an Open Spice interpreter and batch website creation tool
3   // Copyright (C) 2006 Open World Ltd, Kevin Rogers
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.action;
22  
23  import org.millscript.millscript.alert.Alerts;
24  import org.millscript.millscript.functions.Function;
25  import org.millscript.millscript.vm.Machine;
26  
27  
28  /**
29   * 
30   */
31  public class RelationalOperationChainAction extends Action {
32  
33      private final Action[] expressions;
34  
35      /**
36       * The expression generating the left most value in the relational chain
37       * expression.
38       */
39      private final Action first;
40  
41      private final Action[] symbols;
42  
43      /**
44       * 
45       */
46      public RelationalOperationChainAction( final Action act, final Action[] syms, final Action[] exprs ) {
47          this.expressions = exprs;
48          this.first = act;
49          this.symbols = syms;
50      }
51  
52      /**
53       * @see org.millscript.millscript.action.Action#action(org.millscript.millscript.vm.Machine)
54       */
55      @Override
56      public void action( final Machine mc ) {
57          Object lhs = this.first.act1( mc );
58          for ( int i = 0; i < this.symbols.length; i++ ) {
59              Object rhs = this.expressions[ i ].act1( mc );
60              mc.pushObject( lhs );
61              mc.pushObject( rhs );
62              // Perform the symbol action, to get the relation operation
63              // function
64              this.symbols[ i ].act( mc );
65              Function relOp = mc.popFunction();
66              // Record the function entry
67              mc.enterFunction( relOp );
68              // Apply the relational operation, we only ever have two arguments
69              // here, no need to try and calculate it
70              relOp.apply( mc, 2 );
71              // Record the function's exit
72              mc.exitFunction( relOp );
73              // and now check the result of the comparison. If it's true we can
74              // continue to the next comparison, if not we exit early.
75              Object x = mc.popObject();
76              if ( x instanceof Boolean ) {
77                  if ( ((Boolean)x).booleanValue() ) {
78                      lhs = rhs;
79                  } else {
80                      // The result was false, so exit returning false.
81                      mc.pushObject( Boolean.FALSE );
82                      return;
83                  }
84              } else {
85                  throw(
86                      Alerts.eval( "Predicate returned non-boolean", null ).culprit( "object", x ).mishap()
87                  );
88              }
89          }
90          // If we get all the way through the loop, every comparison in the
91          // relation operation chain was true, so the overall result is true!
92          mc.pushObject( Boolean.TRUE );
93      }
94  
95  }