1887e7b5b3856daa335196402c5854c943d1750f
[mono.git] / mcs / class / Microsoft.JScript / Microsoft.JScript / Equality.cs
1 //
2 // Equality.cs:
3 //
4 // Author:
5 //      Cesar Lopez Nataren (cesar@ciencias.unam.mx)
6 //
7 // (C) 2003, 2004 Cesar Lopez Nataren
8 //
9
10 using System;
11 using System.Text;
12 using System.Reflection.Emit;
13
14 namespace Microsoft.JScript {
15
16         public class Equality : BinaryOp {
17
18                 internal Equality (AST parent, AST left, AST right, JSToken op)
19                 {
20                         this.left = left;
21                         this.right = right;
22                         this.current_op = op;
23                 }
24
25                 public Equality (Context context, AST oper1, AST oper2, JSToken operatorTok)
26                 {
27                         throw new NotImplementedException ();
28                 }
29
30                 public Equality (int i)
31                 {
32                         current_op = (JSToken) i;
33                 }
34
35                 public bool EvaluateEquality (object v1, object v2)
36                 {
37                         return false;
38                 }
39
40
41                 public static bool JScriptEquals (object v1, object v2)
42                 {
43                         throw new NotImplementedException ();
44                 }
45
46                 public override string ToString ()
47                 {
48                         StringBuilder sb = new StringBuilder ();
49
50                         sb.Append (left.ToString ());
51
52                         if (current_op != JSToken.None)
53                                 sb.Append (current_op + " ");
54
55                         if (right != null)
56                                 sb.Append (right.ToString ());
57
58                         return sb.ToString ();
59                 }
60
61                 internal override bool Resolve (IdentificationTable context)
62                 {
63                         bool r = true;
64                         if (left != null)
65                                 r &= left.Resolve (context);
66                         if (right != null)
67                                 r &= right.Resolve (context);
68                         return r;
69                 }
70
71                 internal override bool Resolve (IdentificationTable context, bool no_effect)
72                 {
73                         this.no_effect = no_effect;
74                         return  Resolve (context);
75                 }              
76
77                 internal override void Emit (EmitContext ec)
78                 {
79                         ILGenerator ig = ec.ig;
80                         LocalBuilder local_builder;
81
82                         if (current_op != JSToken.None) {
83                                 Type t = typeof (Equality);                             
84                                 local_builder = ig.DeclareLocal (t);
85                                 if (current_op == JSToken.Equal)
86                                         ig.Emit (OpCodes.Ldc_I4_S, (byte) 53);
87                                 else if (current_op == JSToken.NotEqual)
88                                         ig.Emit (OpCodes.Ldc_I4_S, (byte) 54);
89                                 ig.Emit (OpCodes.Newobj, t.GetConstructor (new Type [] {typeof (int)}));
90                                 ig.Emit (OpCodes.Stloc, local_builder);
91                                 ig.Emit (OpCodes.Ldloc, local_builder);
92                         }
93
94                         if (left != null)
95                                 left.Emit (ec);
96                         if (right != null)
97                                 right.Emit (ec);                               
98                         
99                         if (current_op == JSToken.Equal || current_op == JSToken.NotEqual) {
100                                 ig.Emit (OpCodes.Call, typeof (Equality).GetMethod ("EvaluateEquality"));
101
102                                 if (no_effect) {
103                                         Label t_lbl = ig.DefineLabel ();
104                                         Label f_lbl = ig.DefineLabel ();
105
106                                         if (current_op == JSToken.Equal)
107                                                 ig.Emit (OpCodes.Brtrue_S, t_lbl);
108                                         else if (current_op == JSToken.NotEqual)
109                                                 ig.Emit (OpCodes.Brfalse_S, t_lbl);
110                                         
111                                         ig.Emit (OpCodes.Ldc_I4_0);
112                                         ig.Emit (OpCodes.Br_S, f_lbl);
113                                         ig.MarkLabel (t_lbl);
114                                         ig.Emit (OpCodes.Ldc_I4_1);
115                                         ig.MarkLabel (f_lbl);
116                                         ig.Emit (OpCodes.Pop);
117                                 }                               
118                         }
119                 }
120         }
121 }