**** Merged from MCS ****
[mono-project.git] / mcs / class / Microsoft.JScript / Microsoft.JScript / Relational.cs
blob454861d80999ebcfd4490589a11c9b4fa366baf7
1 //
2 // Relational.cs:
3 //
4 // Author:
5 // Cesar Lopez Nataren (cesar@ciencias.unam.mx)
6 //
7 // (C) 2003, Cesar Lopez Nataren
8 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 //
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 //
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System;
32 using System.Text;
33 using System.Reflection;
34 using System.Reflection.Emit;
36 namespace Microsoft.JScript {
38 public class Relational : BinaryOp {
40 internal Relational (AST parent, AST left, AST right, JSToken op)
41 : base (left, right, op)
43 this.parent = parent;
46 public Relational (int operatorTok)
47 : base (null, null, (JSToken) operatorTok)
51 public double EvaluateRelational (object v1, object v2)
53 return -1;
57 public static double JScriptCompare (object v1, object v2)
59 throw new NotImplementedException ();
62 public override string ToString ()
64 StringBuilder sb = new StringBuilder ();
66 sb.Append (left.ToString ());
68 if (op != JSToken.None)
69 sb.Append (op + " ");
71 if (right != null)
72 sb.Append (right.ToString ());
74 return sb.ToString ();
77 internal override bool Resolve (IdentificationTable context)
79 if (left != null)
80 left.Resolve (context);
82 if (right != null)
83 right.Resolve (context);
85 return true;
88 internal override bool Resolve (IdentificationTable context, bool no_effect)
90 this.no_effect = no_effect;
91 return Resolve (context);
94 internal override void Emit (EmitContext ec)
96 ILGenerator ig = ec.ig;
98 if (op == JSToken.None && right == null) {
99 left.Emit (ec);
100 return;
101 } else if (op == JSToken.InstanceOf) {
102 if (left != null)
103 left.Emit (ec);
104 if (right != null)
105 right.Emit (ec);
106 ig.Emit (OpCodes.Call, typeof (InstanceOf).GetMethod ("JScriptInstanceof"));
107 return;
108 } else if (op == JSToken.In) {
109 if (left != null)
110 left.Emit (ec);
111 if (right != null)
112 right.Emit (ec);
113 ig.Emit (OpCodes.Call, typeof (In).GetMethod ("JScriptIn"));
114 return;
116 Type t = typeof (Relational);
117 LocalBuilder loc = ig.DeclareLocal (t);
118 ConstructorInfo ctr_info;
120 switch (op) {
121 case JSToken.GreaterThan:
122 ig.Emit (OpCodes.Ldc_I4_S, (byte) 57);
123 break;
124 case JSToken.LessThan:
125 ig.Emit (OpCodes.Ldc_I4_S, (byte) 58);
126 break;
127 case JSToken.LessThanEqual:
128 ig.Emit (OpCodes.Ldc_I4_S, (byte) 59);
129 break;
130 case JSToken.GreaterThanEqual:
131 ig.Emit (OpCodes.Ldc_I4_S, (byte) 60);
132 break;
135 ctr_info = typeof (Relational).GetConstructor (new Type [] { typeof (Int32) });
136 ig.Emit (OpCodes.Newobj, ctr_info);
137 ig.Emit (OpCodes.Stloc, loc);
138 ig.Emit (OpCodes.Ldloc, loc);
140 if (left != null)
141 left.Emit (ec);
142 if (right != null)
143 right.Emit (ec);
145 ig.Emit (OpCodes.Call, t.GetMethod ("EvaluateRelational"));
147 if (no_effect) {
148 ig.Emit (OpCodes.Ldc_I4_0);
149 ig.Emit (OpCodes.Conv_R8);
151 Label a, b;
152 a = ig.DefineLabel ();
153 b = ig.DefineLabel ();
155 switch (op) {
156 case JSToken.GreaterThan:
157 ig.Emit (OpCodes.Bgt_S, a);
158 break;
159 case JSToken.LessThan:
160 ig.Emit (OpCodes.Blt_S, a);
161 break;
162 case JSToken.LessThanEqual:
163 ig.Emit (OpCodes.Ble_S, a);
164 break;
165 case JSToken.GreaterThanEqual:
166 ig.Emit (OpCodes.Bge_S, a);
167 break;
170 ig.Emit (OpCodes.Ldc_I4_0);
171 ig.Emit (OpCodes.Br_S, b);
172 ig.MarkLabel (a);
173 ig.Emit (OpCodes.Ldc_I4_1);
174 ig.MarkLabel (b);
176 if (no_effect)
177 ig.Emit (OpCodes.Pop);
178 else
179 ig.Emit (OpCodes.Box, typeof (bool));