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 ();