2 // Permission is hereby granted, free of charge, to any person obtaining
3 // a copy of this software and associated documentation files (the
4 // "Software"), to deal in the Software without restriction, including
5 // without limitation the rights to use, copy, modify, merge, publish,
6 // distribute, sublicense, and/or sell copies of the Software, and to
7 // permit persons to whom the Software is furnished to do so, subject to
8 // the following conditions:
10 // The above copyright notice and this permission notice shall be
11 // included in all copies or substantial portions of the Software.
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
15 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
17 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
18 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
19 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 // Copyright (C) Lluis Sanchez Gual, 2004
25 using System.Reflection;
26 using System.Reflection.Emit;
28 namespace Mono.CodeGeneration
30 public abstract class CodeExpression: CodeItem
32 internal CodeVariableReference var;
34 public abstract Type GetResultType ();
36 public virtual void GenerateAsStatement (ILGenerator gen)
39 gen.Emit (OpCodes.Pop);
42 public CodeExpression CallToString ()
44 return new CodeMethodCall (this, "ToString");
47 public static CodeExpression AreEqual (CodeExpression e1, CodeExpression e2)
49 return new CodeEquals (e1, e2);
52 public static CodeExpression AreNotEqual (CodeExpression e1, CodeExpression e2)
54 return new CodeNotEquals (e1, e2);
57 public static CodeExpression IsGreaterThan (CodeExpression e1, CodeExpression e2)
59 return new CodeGreaterThan (e1, e2);
62 public static CodeExpression IsSmallerThan (CodeExpression e1, CodeExpression e2)
64 return new CodeLessThan (e1, e2);
67 public static CodeExpression IsGreaterEqualThan (CodeExpression e1, CodeExpression e2)
69 return new CodeGreaterEqualThan (e1, e2);
72 public static CodeExpression IsSmallerEqualThan (CodeExpression e1, CodeExpression e2)
74 return new CodeLessEqualThan (e1, e2);
77 public static CodeExpression Not (CodeExpression e)
79 return new CodeNot (e);
82 public static CodeExpression Add (CodeExpression e1, CodeExpression e2)
84 return new CodeAdd (e1, e2);
87 public static CodeExpression Subtract (CodeExpression e1, CodeExpression e2)
89 return new CodeSub (e1, e2);
92 public static CodeExpression Multiply (CodeExpression e1, CodeExpression e2)
94 return new CodeMul (e1, e2);
97 public static CodeExpression Divide (CodeExpression e1, CodeExpression e2)
99 return new CodeDiv (e1, e2);
102 public CodeExpression CastTo (Type type)
104 return new CodeCast (type, this);
107 public CodeExpression And (CodeExpression other)
109 return new CodeAnd (this, other);
112 public CodeExpression Is (Type type)
114 return new CodeIs (type, this);
117 public CodeExpression Call (string name, params CodeExpression[] parameters)
119 return new CodeMethodCall (this, name, parameters);
122 public CodeExpression Call (MethodInfo method, params CodeExpression[] parameters)
124 return new CodeMethodCall (this, method, parameters);
127 public CodeValueReference MemGet (string name)
129 MemberInfo[] mems = GetResultType().GetMember (name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
130 if (mems.Length == 0) throw new InvalidOperationException ("Field '" + name + "' not found in " + GetResultType());
131 return MemGet (mems[0]);
134 public CodeValueReference MemGet (MemberInfo member)
136 if (member is FieldInfo)
137 return new CodeFieldReference (this, (FieldInfo)member);
138 else if (member is PropertyInfo)
139 return new CodePropertyReference (this, (PropertyInfo)member);
141 throw new InvalidOperationException (member.Name + " is not either a field or a property");
144 public CodeValueReference this [CodeExpression index]
146 get { return new CodeArrayItem (this, index); }
149 public CodeValueReference this [string name]
151 get { return MemGet (name); }
154 public CodeValueReference this [FieldInfo field]
156 get { return new CodeFieldReference (this, field); }
159 public CodeValueReference this [PropertyInfo prop]
161 get { return new CodePropertyReference (this, prop); }
164 public CodeExpression ArrayLength
166 get { return new CodeArrayLength (this); }
169 public CodeExpression IsNull
171 get { return new CodeEquals (this, new CodeLiteral (null, this.GetResultType())); }
174 public static CodeExpression NullValue (Type type)
176 return new CodeLiteral (null, type);
182 return CodeGenerationHelper.IsNumber (GetResultType ());
187 public abstract class CodeConditionExpression: CodeExpression
189 public virtual void GenerateForBranch (ILGenerator gen, Label label, bool jumpCase)
193 gen.Emit (OpCodes.Brtrue, label);
195 gen.Emit (OpCodes.Brfalse, label);