1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
74
75
76 final ELinkedList< Expr< ? > > comparisons = new ELinkedList< Expr< ? > >();
77 final ELinkedList< Expr< ? > > expressions = new ELinkedList< Expr< ? > >();
78
79 comparisons.addLast( fun );
80
81
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
90 expressions.addLast( rightExpr );
91
92
93
94 final Action[] exprs = new Action[ expressions.size() ];
95
96 for ( int i = 0; i < expressions.size(); i++ ) {
97 Expr< ? > e = expressions.get0( i );
98 exprs[ i ] = e.compile();
99 }
100
101
102 final Action[] syms = new Action[ comparisons.size() ];
103
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 }