4 // (C) 2008 Mainsoft, Inc. (http://www.mainsoft.com)
5 // (C) 2008 db4objects, Inc. (http://www.db4o.com)
7 // Permission is hereby granted, free of charge, to any person obtaining
8 // a copy of this software and associated documentation files (the
9 // "Software"), to deal in the Software without restriction, including
10 // without limitation the rights to use, copy, modify, merge, publish,
11 // distribute, sublicense, and/or sell copies of the Software, and to
12 // permit persons to whom the Software is furnished to do so, subject to
13 // the following conditions:
15 // The above copyright notice and this permission notice shall be
16 // included in all copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 using System.Globalization;
29 using System.Linq.Expressions;
31 namespace System.Linq.jvm {
34 public static object Evaluate (object a, object b, Type t, ExpressionType et)
36 TypeCode tc = Type.GetTypeCode (t);
37 if (tc == TypeCode.Object) {
38 if (!t.IsNullable ()) {
39 throw new NotImplementedException (
41 "Expression with Node type {0} for type {1}",
46 return EvaluateNullable (a, b, Type.GetTypeCode (t.GetGenericArguments () [0]), et);
48 return Evaluate (a, b, tc, et);
51 public static object EvaluateNullable (object a, object b, TypeCode tc, ExpressionType et)
54 if (a == null || b == null) {
55 if (tc != TypeCode.Boolean) {
59 case ExpressionType.And:
62 case ExpressionType.Or:
65 case ExpressionType.ExclusiveOr:
66 o = ExclusiveOr (a, b);
70 o = Evaluate (a, b, tc, et);
73 return Convert2Nullable (o, tc);
77 private static object ExclusiveOr (object a, object b)
79 if (a == null || b == null) {
82 return (bool) a ^ (bool) b;
85 public static object Or (object a, object b)
88 if (b == null || !((bool) b)) {
95 if (a == null || !((bool) a)) {
101 return (bool) a || (bool) b;
104 public static object And (object a, object b)
107 if (b == null || (bool) b) {
114 if (a == null || (bool) a) {
120 return (bool) a && (bool) b;
123 private static object Convert2Nullable (object o, TypeCode tc)
130 return new Nullable<Char> ((Char) o);
132 return new Nullable<Byte> ((Byte) o);
133 case TypeCode.Decimal:
134 return new Nullable<Decimal> ((Decimal) o);
135 case TypeCode.Double:
136 return new Nullable<Double> ((Double) o);
138 return new Nullable<Int16> ((Int16) o);
140 return new Nullable<Int32> ((Int32) o);
142 return new Nullable<Int64> ((Int64) o);
143 case TypeCode.UInt16:
144 return new Nullable<UInt16> ((UInt16) o);
145 case TypeCode.UInt32:
146 return new Nullable<UInt32> ((UInt32) o);
148 return new Nullable<SByte> ((SByte) o);
149 case TypeCode.Single:
150 return new Nullable<Single> ((Single) o);
151 case TypeCode.Boolean:
152 return new Nullable<Boolean> ((Boolean) o);
155 throw new NotImplementedException ();
158 public static object Evaluate (object a, object b, TypeCode tc, ExpressionType et)
161 case TypeCode.Boolean:
162 return Evaluate (Convert.ToBoolean (a), Convert.ToBoolean (b), et);
164 return Evaluate (Convert.ToChar (a), Convert.ToChar (b), et);
166 return unchecked ((Byte) Evaluate (Convert.ToByte (a), Convert.ToByte (b), et));
167 case TypeCode.Decimal:
168 return Evaluate (Convert.ToDecimal (a), Convert.ToDecimal (b), et);
169 case TypeCode.Double:
170 return Evaluate (Convert.ToDouble (a), Convert.ToDouble (b), et);
172 return unchecked ((Int16) Evaluate (Convert.ToInt16 (a), Convert.ToInt16 (b), et));
174 return Evaluate (Convert.ToInt32 (a), Convert.ToInt32 (b), et);
176 return Evaluate (Convert.ToInt64 (a), Convert.ToInt64 (b), et);
177 case TypeCode.UInt16:
178 return unchecked ((UInt16) Evaluate (Convert.ToUInt16 (a), Convert.ToUInt16 (b), et));
179 case TypeCode.UInt32:
180 return Evaluate (Convert.ToUInt32 (a), Convert.ToUInt32 (b), et);
181 case TypeCode.UInt64:
182 return Evaluate (Convert.ToUInt64 (a), Convert.ToUInt64 (b), et);
184 return unchecked ((SByte) Evaluate (Convert.ToSByte (a), Convert.ToSByte (b), et));
185 case TypeCode.Single:
186 return Evaluate (Convert.ToSingle (a), Convert.ToSingle (b), et);
190 throw new NotImplementedException ();
193 public static object NegateChecked (object a, TypeCode tc)
197 return checked (-Convert.ToChar (a));
199 return checked (-Convert.ToByte (a));
200 case TypeCode.Decimal:
201 return checked (-Convert.ToDecimal (a));
202 case TypeCode.Double:
203 return checked (-Convert.ToDouble (a));
205 return checked (-Convert.ToInt16 (a));
207 return checked (-Convert.ToInt32 (a));
209 return checked (-Convert.ToInt64 (a));
210 case TypeCode.UInt16:
211 return checked (-Convert.ToUInt16 (a));
212 case TypeCode.UInt32:
213 return checked (-Convert.ToUInt32 (a));
215 return checked (-Convert.ToSByte (a));
216 case TypeCode.Single:
217 return checked (-Convert.ToSingle (a));
220 throw new NotImplementedException ();
223 static object CreateInstance (Type type, params object [] arguments)
225 return type.GetConstructor (
226 (from argument in arguments select argument.GetType ()).ToArray ()).Invoke (arguments);
229 public static object ConvertToTypeChecked (object a, Type fromType, Type toType)
231 if (toType.IsNullable ())
232 return a == null ? a : CreateInstance (toType,
233 ConvertToTypeChecked (a, fromType.GetNotNullableType (), toType.GetNotNullableType ()));
236 if (!toType.IsValueType)
238 if (fromType.IsNullable ())
239 throw new InvalidOperationException ("Nullable object must have a value");
242 if (IsType (toType, a)) {
246 if (Expression.IsPrimitiveConversion (fromType, toType))
247 return Convert.ChangeType (a, toType, CultureInfo.CurrentCulture);
249 throw new NotImplementedException (
250 string.Format ("No Convert defined for type {0} ", toType));
253 public static object ConvertToTypeUnchecked (object a, Type fromType, Type toType)
255 if (toType.IsNullable ())
256 return a == null ? a : CreateInstance (toType,
257 ConvertToTypeUnchecked (a, fromType.GetNotNullableType (), toType.GetNotNullableType ()));
260 if (!toType.IsValueType)
262 if (fromType.IsNullable ())
263 throw new InvalidOperationException ("Nullable object must have a value");
266 if (IsType (toType, a))
269 if (Expression.IsPrimitiveConversion (fromType, toType))
270 return Conversion.ConvertPrimitiveUnChecked (fromType, toType, a);
272 throw new NotImplementedException (
273 string.Format ("No Convert defined for type {0} ", toType));
276 public static bool IsType (Type t, Object o)
278 return t.IsInstanceOfType (o);
281 public static object Negate (object a, TypeCode tc)
285 return unchecked (-Convert.ToChar (a));
287 return unchecked (-Convert.ToByte (a));
288 case TypeCode.Decimal:
289 return unchecked (-Convert.ToDecimal (a));
290 case TypeCode.Double:
291 return unchecked (-Convert.ToDouble (a));
293 return unchecked (-Convert.ToInt16 (a));
295 return unchecked (-Convert.ToInt32 (a));
297 return unchecked (-Convert.ToInt64 (a));
298 case TypeCode.UInt16:
299 return unchecked (-Convert.ToUInt16 (a));
300 case TypeCode.UInt32:
301 return unchecked (-Convert.ToUInt32 (a));
303 return unchecked (-Convert.ToSByte (a));
304 case TypeCode.Single:
305 return unchecked (-Convert.ToSingle (a));
308 throw new NotImplementedException ();
311 public static object RightShift (object a, int n, TypeCode tc)
315 return Convert.ToInt16 (a) >> n;
317 return Convert.ToInt32 (a) >> n;
319 return Convert.ToInt64 (a) >> n;
320 case TypeCode.UInt16:
321 return Convert.ToUInt16 (a) >> n;
322 case TypeCode.UInt32:
323 return Convert.ToUInt32 (a) >> n;
324 case TypeCode.UInt64:
325 return Convert.ToUInt64 (a) >> n;
328 throw new NotImplementedException ();
331 public static object LeftShift (object a, int n, TypeCode tc)
335 return Convert.ToInt16 (a) << n;
337 return Convert.ToInt32 (a) << n;
339 return Convert.ToInt64 (a) << n;
340 case TypeCode.UInt16:
341 return Convert.ToUInt16 (a) << n;
342 case TypeCode.UInt32:
343 return Convert.ToUInt32 (a) << n;
344 case TypeCode.UInt64:
345 return Convert.ToUInt64 (a) << n;
348 throw new NotImplementedException ();
351 private static Decimal Evaluate (Decimal a, Decimal b, ExpressionType et)
354 case ExpressionType.Add:
355 return unchecked (a + b);
356 case ExpressionType.AddChecked:
357 return checked (a + b);
358 case ExpressionType.Subtract:
359 return unchecked (a - b);
360 case ExpressionType.SubtractChecked:
361 return checked (a - b);
362 case ExpressionType.Multiply:
363 return unchecked (a * b);
364 case ExpressionType.MultiplyChecked:
365 return checked (a * b);
366 case ExpressionType.Divide:
368 case ExpressionType.Modulo:
373 throw new NotImplementedException ();
376 private static Double Evaluate (Double a, Double b, ExpressionType et)
379 case ExpressionType.Add:
380 return unchecked (a + b);
381 case ExpressionType.AddChecked:
382 return checked (a + b);
383 case ExpressionType.Subtract:
384 return unchecked (a - b);
385 case ExpressionType.SubtractChecked:
386 return checked (a - b);
387 case ExpressionType.Multiply:
388 return unchecked (a * b);
389 case ExpressionType.MultiplyChecked:
390 return checked (a * b);
391 case ExpressionType.Divide:
393 case ExpressionType.Modulo:
395 case ExpressionType.Power:
396 return System.Math.Pow (a, b);
399 throw new NotImplementedException ();
403 private static Int32 Evaluate (Int16 a, Int16 b, ExpressionType et)
406 case ExpressionType.Add:
407 return unchecked (a + b);
408 case ExpressionType.AddChecked:
409 return checked (a + b);
410 case ExpressionType.Subtract:
411 return unchecked (a - b);
412 case ExpressionType.SubtractChecked:
413 return checked (a - b);
414 case ExpressionType.Multiply:
415 return unchecked (a * b);
416 case ExpressionType.MultiplyChecked:
417 return checked (a * b);
418 case ExpressionType.Divide:
420 case ExpressionType.Modulo:
422 case ExpressionType.ExclusiveOr:
424 case ExpressionType.And:
426 case ExpressionType.Or:
430 throw new NotImplementedException ();
433 private static Int32 Evaluate (Int32 a, Int32 b, ExpressionType et)
436 case ExpressionType.Add:
437 return unchecked (a + b);
438 case ExpressionType.AddChecked:
439 return checked (a + b);
440 case ExpressionType.Subtract:
441 return unchecked (a - b);
442 case ExpressionType.SubtractChecked:
443 return checked (a - b);
444 case ExpressionType.Multiply:
445 return unchecked (a * b);
446 case ExpressionType.MultiplyChecked:
447 return checked (a * b);
448 case ExpressionType.Divide:
450 case ExpressionType.Modulo:
452 case ExpressionType.ExclusiveOr:
454 case ExpressionType.And:
456 case ExpressionType.Or:
460 throw new NotImplementedException ();
463 private static Int64 Evaluate (Int64 a, Int64 b, ExpressionType et)
466 case ExpressionType.Add:
467 return unchecked (a + b);
468 case ExpressionType.AddChecked:
469 return checked (a + b);
470 case ExpressionType.Subtract:
471 return unchecked (a - b);
472 case ExpressionType.SubtractChecked:
473 return checked (a - b);
474 case ExpressionType.Multiply:
475 return unchecked (a * b);
476 case ExpressionType.MultiplyChecked:
477 return checked (a * b);
478 case ExpressionType.Divide:
480 case ExpressionType.Modulo:
482 case ExpressionType.ExclusiveOr:
484 case ExpressionType.And:
486 case ExpressionType.Or:
490 throw new NotImplementedException ();
493 private static Int32 Evaluate (UInt16 a, UInt16 b, ExpressionType et)
496 case ExpressionType.Add:
497 return unchecked (a + b);
498 case ExpressionType.AddChecked:
499 return checked (a + b);
500 case ExpressionType.Subtract:
501 return unchecked (a - b);
502 case ExpressionType.SubtractChecked:
503 return checked ((UInt16) (a - b));
504 case ExpressionType.Multiply:
505 return unchecked (a * b);
506 case ExpressionType.MultiplyChecked:
507 return checked (a * b);
508 case ExpressionType.Divide:
510 case ExpressionType.Modulo:
512 case ExpressionType.ExclusiveOr:
514 case ExpressionType.And:
516 case ExpressionType.Or:
520 throw new NotImplementedException ();
523 private static UInt32 Evaluate (UInt32 a, UInt32 b, ExpressionType et)
526 case ExpressionType.Add:
527 return unchecked (a + b);
528 case ExpressionType.AddChecked:
529 return checked (a + b);
530 case ExpressionType.Subtract:
531 return unchecked (a - b);
532 case ExpressionType.SubtractChecked:
533 return checked (a - b);
534 case ExpressionType.Multiply:
535 return unchecked (a * b);
536 case ExpressionType.MultiplyChecked:
537 return checked (a * b);
538 case ExpressionType.Divide:
540 case ExpressionType.Modulo:
542 case ExpressionType.ExclusiveOr:
544 case ExpressionType.And:
546 case ExpressionType.Or:
550 throw new NotImplementedException ();
553 private static UInt64 Evaluate (UInt64 a, UInt64 b, ExpressionType et)
556 case ExpressionType.Add:
557 return unchecked (a + b);
558 case ExpressionType.AddChecked:
559 return checked (a + b);
560 case ExpressionType.Subtract:
561 return unchecked (a - b);
562 case ExpressionType.SubtractChecked:
563 return checked (a - b);
564 case ExpressionType.Multiply:
565 return unchecked (a * b);
566 case ExpressionType.MultiplyChecked:
567 return checked (a * b);
568 case ExpressionType.Divide:
570 case ExpressionType.Modulo:
572 case ExpressionType.ExclusiveOr:
574 case ExpressionType.And:
576 case ExpressionType.Or:
580 throw new NotImplementedException ();
583 private static object Evaluate (Char a, Char b, ExpressionType et)
586 case ExpressionType.ExclusiveOr:
588 case ExpressionType.And:
590 case ExpressionType.Or:
594 throw new NotImplementedException ();
597 private static Int32 Evaluate (SByte a, SByte b, ExpressionType et)
600 case ExpressionType.Add:
601 return unchecked (a + b);
602 case ExpressionType.AddChecked:
603 return checked (a + b);
604 case ExpressionType.Subtract:
605 return unchecked (a - b);
606 case ExpressionType.SubtractChecked:
607 return checked (a - b);
608 case ExpressionType.Multiply:
609 return unchecked (a * b);
610 case ExpressionType.MultiplyChecked:
611 return checked (a * b);
612 case ExpressionType.Divide:
614 case ExpressionType.Modulo:
616 case ExpressionType.ExclusiveOr:
618 case ExpressionType.And:
620 case ExpressionType.Or:
624 throw new NotImplementedException ();
627 private static Int32 Evaluate (Byte a, Byte b, ExpressionType et)
630 case ExpressionType.Add:
631 return unchecked (a + b);
632 case ExpressionType.AddChecked:
633 return checked (a + b);
634 case ExpressionType.Subtract:
635 return unchecked (a - b);
636 case ExpressionType.SubtractChecked:
637 return checked (a - b);
638 case ExpressionType.Multiply:
639 return unchecked (a * b);
640 case ExpressionType.MultiplyChecked:
641 return checked (a * b);
642 case ExpressionType.Divide:
644 case ExpressionType.Modulo:
646 case ExpressionType.ExclusiveOr:
648 case ExpressionType.And:
650 case ExpressionType.Or:
654 throw new NotImplementedException ();
657 private static Single Evaluate (Single a, Single b, ExpressionType et)
660 case ExpressionType.Add:
661 return unchecked (a + b);
662 case ExpressionType.AddChecked:
663 return checked (a + b);
664 case ExpressionType.Subtract:
665 return unchecked (a - b);
666 case ExpressionType.SubtractChecked:
667 return checked (a - b);
668 case ExpressionType.Multiply:
669 return unchecked (a * b);
670 case ExpressionType.MultiplyChecked:
671 return checked (a * b);
672 case ExpressionType.Divide:
674 case ExpressionType.Modulo:
678 throw new NotImplementedException ();
681 private static bool Evaluate (bool a, bool b, ExpressionType et)
684 case ExpressionType.ExclusiveOr:
686 case ExpressionType.And:
688 case ExpressionType.Or:
692 throw new NotImplementedException ();