001/*
002 * Copyright (c) 2012-2017 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 */
009
010package org.eclipse.golo.runtime;
011
012import java.lang.invoke.*;
013import java.util.HashSet;
014import java.util.Set;
015import java.util.Objects;
016import java.math.BigDecimal;
017import java.math.BigInteger;
018
019import static java.lang.invoke.MethodHandles.*;
020import static java.lang.invoke.MethodType.methodType;
021import static gololang.Messages.message;
022
023public final class OperatorSupport {
024
025  private OperatorSupport() {
026    throw new UnsupportedOperationException("Don't instantiate invokedynamic bootstrap class");
027  }
028
029  static class MonomorphicInlineCache extends MutableCallSite {
030
031    final MethodHandles.Lookup callerLookup;
032    final String name;
033    MethodHandle fallback;
034
035    MonomorphicInlineCache(MethodHandles.Lookup callerLookup, String name, MethodType type) {
036      super(type);
037      this.callerLookup = callerLookup;
038      this.name = name;
039    }
040  }
041
042  private static final MethodHandle FALLBACK_1;
043
044  private static final MethodHandle GUARD_2;
045  private static final MethodHandle FALLBACK_2;
046
047  private static final Set<String> NO_GUARD_OPERATORS = new HashSet<String>() {
048    {
049      add("is");
050      add("isnt");
051      add("oftype");
052    }
053  };
054
055  static {
056    try {
057      MethodHandles.Lookup lookup = MethodHandles.lookup();
058
059      FALLBACK_1 = lookup.findStatic(
060          OperatorSupport.class,
061          "fallback_1",
062          methodType(Object.class, MonomorphicInlineCache.class, Object[].class));
063
064      GUARD_2 = lookup.findStatic(
065          OperatorSupport.class,
066          "guard_2",
067          methodType(boolean.class, Class.class, Class.class, Object.class, Object.class));
068
069      FALLBACK_2 = lookup.findStatic(
070          OperatorSupport.class,
071          "fallback_2",
072          methodType(Object.class, MonomorphicInlineCache.class, Object[].class));
073    } catch (NoSuchMethodException | IllegalAccessException e) {
074      throw new Error("Could not bootstrap the required method handles", e);
075    }
076  }
077
078  public static boolean guard_2(Class<?> expected1, Class<?> expected2, Object arg1, Object arg2) {
079    Class<?> t1 = (arg1 == null) ? Object.class : arg1.getClass();
080    Class<?> t2 = (arg2 == null) ? Object.class : arg2.getClass();
081    return (t1 == expected1) && (t2 == expected2);
082  }
083
084  public static Object fallback_1(MonomorphicInlineCache inlineCache, Object[] args) throws Throwable {
085
086    Class<?> argClass = (args[0] == null) ? Object.class : args[0].getClass();
087    MethodHandle target;
088
089    try {
090      target = inlineCache.callerLookup.findStatic(
091          OperatorSupport.class, inlineCache.name, methodType(Object.class, argClass));
092    } catch (Throwable t1) {
093      try {
094        target = inlineCache.callerLookup.findStatic(
095            OperatorSupport.class, inlineCache.name + "_fallback", methodType(Object.class, Object.class));
096      } catch (Throwable t2) {
097        return reject(args[0], inlineCache.name);
098      }
099    }
100
101    target = target.asType(methodType(Object.class, Object.class));
102    target = catchException(target, ClassCastException.class, inlineCache.fallback);
103    inlineCache.setTarget(target);
104
105    return target.invokeWithArguments(args);
106  }
107
108  public static Object fallback_2(MonomorphicInlineCache inlineCache, Object[] args) throws Throwable {
109
110    Class<?> arg1Class = (args[0] == null) ? Object.class : args[0].getClass();
111    Class<?> arg2Class = (args[1] == null) ? Object.class : args[1].getClass();
112    MethodHandle target;
113
114    try {
115      target = inlineCache.callerLookup.findStatic(
116          OperatorSupport.class, inlineCache.name, methodType(Object.class, arg1Class, arg2Class));
117    } catch (Throwable t1) {
118      try {
119        target = inlineCache.callerLookup.findStatic(
120            OperatorSupport.class, inlineCache.name + "_fallback", methodType(Object.class, Object.class, Object.class));
121      } catch (Throwable t2) {
122        return reject(args[0], args[1], inlineCache.name);
123      }
124    }
125
126    target = target.asType(methodType(Object.class, Object.class, Object.class));
127    if (arg1Class == String.class || arg2Class == String.class) {
128      MethodHandle guard = insertArguments(GUARD_2, 0, arg1Class, arg2Class);
129      target = guardWithTest(guard, target, inlineCache.fallback);
130    } else {
131      target = catchException(target, ClassCastException.class, dropArguments(inlineCache.fallback, 0, ClassCastException.class));
132    }
133    inlineCache.setTarget(target);
134
135    return target.invokeWithArguments(args);
136  }
137
138  public static CallSite bootstrap(MethodHandles.Lookup caller, String name, MethodType type, int arity) throws NoSuchMethodException, IllegalAccessException {
139
140    if (NO_GUARD_OPERATORS.contains(name)) {
141      MethodHandle target = caller.findStatic(OperatorSupport.class, name + "_noguard",
142          methodType(Object.class, Object.class, Object.class));
143      return new ConstantCallSite(target);
144    }
145
146    MonomorphicInlineCache callSite = new MonomorphicInlineCache(caller, name, type);
147    MethodHandle fallback;
148    if (arity == 2) {
149      fallback = FALLBACK_2;
150    } else {
151      fallback = FALLBACK_1;
152    }
153    MethodHandle fallbackHandle = fallback
154        .bindTo(callSite)
155        .asCollector(Object[].class, type.parameterCount())
156        .asType(type);
157    callSite.fallback = fallbackHandle;
158    callSite.setTarget(fallbackHandle);
159    return callSite;
160  }
161
162  // primitive specific arithmetic and comparisons (generated, use generate_math.rb) ......................................................................
163
164  // BEGIN GENERATED
165  public static Object plus(Character a, Character b) {
166    return ((char) a) + ((char) b);
167  }
168
169  public static Object minus(Character a, Character b) {
170    return ((char) a) - ((char) b);
171  }
172
173  public static Object divide(Character a, Character b) {
174    return ((char) a) / ((char) b);
175  }
176
177  public static Object times(Character a, Character b) {
178    return ((char) a) * ((char) b);
179  }
180
181  public static Object modulo(Character a, Character b) {
182    return ((char) a) % ((char) b);
183  }
184
185  public static Object equals(Character a, Character b) {
186    return ((char) a) == ((char) b);
187  }
188
189  public static Object notequals(Character a, Character b) {
190    return ((char) a) != ((char) b);
191  }
192
193  public static Object less(Character a, Character b) {
194    return ((char) a) < ((char) b);
195  }
196
197  public static Object lessorequals(Character a, Character b) {
198    return ((char) a) <= ((char) b);
199  }
200
201  public static Object more(Character a, Character b) {
202    return ((char) a) > ((char) b);
203  }
204
205  public static Object moreorequals(Character a, Character b) {
206    return ((char) a) >= ((char) b);
207  }
208
209  public static Object plus(Integer a, Integer b) {
210    return ((int) a) + ((int) b);
211  }
212
213  public static Object minus(Integer a, Integer b) {
214    return ((int) a) - ((int) b);
215  }
216
217  public static Object divide(Integer a, Integer b) {
218    return ((int) a) / ((int) b);
219  }
220
221  public static Object times(Integer a, Integer b) {
222    return ((int) a) * ((int) b);
223  }
224
225  public static Object modulo(Integer a, Integer b) {
226    return ((int) a) % ((int) b);
227  }
228
229  public static Object equals(Integer a, Integer b) {
230    return ((int) a) == ((int) b);
231  }
232
233  public static Object notequals(Integer a, Integer b) {
234    return ((int) a) != ((int) b);
235  }
236
237  public static Object less(Integer a, Integer b) {
238    return ((int) a) < ((int) b);
239  }
240
241  public static Object lessorequals(Integer a, Integer b) {
242    return ((int) a) <= ((int) b);
243  }
244
245  public static Object more(Integer a, Integer b) {
246    return ((int) a) > ((int) b);
247  }
248
249  public static Object moreorequals(Integer a, Integer b) {
250    return ((int) a) >= ((int) b);
251  }
252
253  public static Object plus(Long a, Long b) {
254    return ((long) a) + ((long) b);
255  }
256
257  public static Object minus(Long a, Long b) {
258    return ((long) a) - ((long) b);
259  }
260
261  public static Object divide(Long a, Long b) {
262    return ((long) a) / ((long) b);
263  }
264
265  public static Object times(Long a, Long b) {
266    return ((long) a) * ((long) b);
267  }
268
269  public static Object modulo(Long a, Long b) {
270    return ((long) a) % ((long) b);
271  }
272
273  public static Object equals(Long a, Long b) {
274    return ((long) a) == ((long) b);
275  }
276
277  public static Object notequals(Long a, Long b) {
278    return ((long) a) != ((long) b);
279  }
280
281  public static Object less(Long a, Long b) {
282    return ((long) a) < ((long) b);
283  }
284
285  public static Object lessorequals(Long a, Long b) {
286    return ((long) a) <= ((long) b);
287  }
288
289  public static Object more(Long a, Long b) {
290    return ((long) a) > ((long) b);
291  }
292
293  public static Object moreorequals(Long a, Long b) {
294    return ((long) a) >= ((long) b);
295  }
296
297  public static Object plus(Double a, Double b) {
298    return ((double) a) + ((double) b);
299  }
300
301  public static Object minus(Double a, Double b) {
302    return ((double) a) - ((double) b);
303  }
304
305  public static Object divide(Double a, Double b) {
306    return ((double) a) / ((double) b);
307  }
308
309  public static Object times(Double a, Double b) {
310    return ((double) a) * ((double) b);
311  }
312
313  public static Object modulo(Double a, Double b) {
314    return ((double) a) % ((double) b);
315  }
316
317  public static Object equals(Double a, Double b) {
318    return ((double) a) == ((double) b);
319  }
320
321  public static Object notequals(Double a, Double b) {
322    return ((double) a) != ((double) b);
323  }
324
325  public static Object less(Double a, Double b) {
326    return ((double) a) < ((double) b);
327  }
328
329  public static Object lessorequals(Double a, Double b) {
330    return ((double) a) <= ((double) b);
331  }
332
333  public static Object more(Double a, Double b) {
334    return ((double) a) > ((double) b);
335  }
336
337  public static Object moreorequals(Double a, Double b) {
338    return ((double) a) >= ((double) b);
339  }
340
341  public static Object plus(Float a, Float b) {
342    return ((float) a) + ((float) b);
343  }
344
345  public static Object minus(Float a, Float b) {
346    return ((float) a) - ((float) b);
347  }
348
349  public static Object divide(Float a, Float b) {
350    return ((float) a) / ((float) b);
351  }
352
353  public static Object times(Float a, Float b) {
354    return ((float) a) * ((float) b);
355  }
356
357  public static Object modulo(Float a, Float b) {
358    return ((float) a) % ((float) b);
359  }
360
361  public static Object equals(Float a, Float b) {
362    return ((float) a) == ((float) b);
363  }
364
365  public static Object notequals(Float a, Float b) {
366    return ((float) a) != ((float) b);
367  }
368
369  public static Object less(Float a, Float b) {
370    return ((float) a) < ((float) b);
371  }
372
373  public static Object lessorequals(Float a, Float b) {
374    return ((float) a) <= ((float) b);
375  }
376
377  public static Object more(Float a, Float b) {
378    return ((float) a) > ((float) b);
379  }
380
381  public static Object moreorequals(Float a, Float b) {
382    return ((float) a) >= ((float) b);
383  }
384
385  public static Object plus(Character a, Integer b) {
386    return ((int) a) + ((int) b);
387  }
388
389  public static Object minus(Character a, Integer b) {
390    return ((int) a) - ((int) b);
391  }
392
393  public static Object divide(Character a, Integer b) {
394    return ((int) a) / ((int) b);
395  }
396
397  public static Object times(Character a, Integer b) {
398    return ((int) a) * ((int) b);
399  }
400
401  public static Object modulo(Character a, Integer b) {
402    return ((int) a) % ((int) b);
403  }
404
405  public static Object equals(Character a, Integer b) {
406    return ((int) a) == ((int) b);
407  }
408
409  public static Object notequals(Character a, Integer b) {
410    return ((int) a) != ((int) b);
411  }
412
413  public static Object less(Character a, Integer b) {
414    return ((int) a) < ((int) b);
415  }
416
417  public static Object lessorequals(Character a, Integer b) {
418    return ((int) a) <= ((int) b);
419  }
420
421  public static Object more(Character a, Integer b) {
422    return ((int) a) > ((int) b);
423  }
424
425  public static Object moreorequals(Character a, Integer b) {
426    return ((int) a) >= ((int) b);
427  }
428
429  public static Object plus(Character a, Long b) {
430    return ((long) a) + ((long) b);
431  }
432
433  public static Object minus(Character a, Long b) {
434    return ((long) a) - ((long) b);
435  }
436
437  public static Object divide(Character a, Long b) {
438    return ((long) a) / ((long) b);
439  }
440
441  public static Object times(Character a, Long b) {
442    return ((long) a) * ((long) b);
443  }
444
445  public static Object modulo(Character a, Long b) {
446    return ((long) a) % ((long) b);
447  }
448
449  public static Object equals(Character a, Long b) {
450    return ((long) a) == ((long) b);
451  }
452
453  public static Object notequals(Character a, Long b) {
454    return ((long) a) != ((long) b);
455  }
456
457  public static Object less(Character a, Long b) {
458    return ((long) a) < ((long) b);
459  }
460
461  public static Object lessorequals(Character a, Long b) {
462    return ((long) a) <= ((long) b);
463  }
464
465  public static Object more(Character a, Long b) {
466    return ((long) a) > ((long) b);
467  }
468
469  public static Object moreorequals(Character a, Long b) {
470    return ((long) a) >= ((long) b);
471  }
472
473  public static Object plus(Character a, Double b) {
474    return ((double) a) + ((double) b);
475  }
476
477  public static Object minus(Character a, Double b) {
478    return ((double) a) - ((double) b);
479  }
480
481  public static Object divide(Character a, Double b) {
482    return ((double) a) / ((double) b);
483  }
484
485  public static Object times(Character a, Double b) {
486    return ((double) a) * ((double) b);
487  }
488
489  public static Object modulo(Character a, Double b) {
490    return ((double) a) % ((double) b);
491  }
492
493  public static Object equals(Character a, Double b) {
494    return ((double) a) == ((double) b);
495  }
496
497  public static Object notequals(Character a, Double b) {
498    return ((double) a) != ((double) b);
499  }
500
501  public static Object less(Character a, Double b) {
502    return ((double) a) < ((double) b);
503  }
504
505  public static Object lessorequals(Character a, Double b) {
506    return ((double) a) <= ((double) b);
507  }
508
509  public static Object more(Character a, Double b) {
510    return ((double) a) > ((double) b);
511  }
512
513  public static Object moreorequals(Character a, Double b) {
514    return ((double) a) >= ((double) b);
515  }
516
517  public static Object plus(Character a, Float b) {
518    return ((float) a) + ((float) b);
519  }
520
521  public static Object minus(Character a, Float b) {
522    return ((float) a) - ((float) b);
523  }
524
525  public static Object divide(Character a, Float b) {
526    return ((float) a) / ((float) b);
527  }
528
529  public static Object times(Character a, Float b) {
530    return ((float) a) * ((float) b);
531  }
532
533  public static Object modulo(Character a, Float b) {
534    return ((float) a) % ((float) b);
535  }
536
537  public static Object equals(Character a, Float b) {
538    return ((float) a) == ((float) b);
539  }
540
541  public static Object notequals(Character a, Float b) {
542    return ((float) a) != ((float) b);
543  }
544
545  public static Object less(Character a, Float b) {
546    return ((float) a) < ((float) b);
547  }
548
549  public static Object lessorequals(Character a, Float b) {
550    return ((float) a) <= ((float) b);
551  }
552
553  public static Object more(Character a, Float b) {
554    return ((float) a) > ((float) b);
555  }
556
557  public static Object moreorequals(Character a, Float b) {
558    return ((float) a) >= ((float) b);
559  }
560
561  public static Object plus(Integer a, Long b) {
562    return ((long) a) + ((long) b);
563  }
564
565  public static Object minus(Integer a, Long b) {
566    return ((long) a) - ((long) b);
567  }
568
569  public static Object divide(Integer a, Long b) {
570    return ((long) a) / ((long) b);
571  }
572
573  public static Object times(Integer a, Long b) {
574    return ((long) a) * ((long) b);
575  }
576
577  public static Object modulo(Integer a, Long b) {
578    return ((long) a) % ((long) b);
579  }
580
581  public static Object equals(Integer a, Long b) {
582    return ((long) a) == ((long) b);
583  }
584
585  public static Object notequals(Integer a, Long b) {
586    return ((long) a) != ((long) b);
587  }
588
589  public static Object less(Integer a, Long b) {
590    return ((long) a) < ((long) b);
591  }
592
593  public static Object lessorequals(Integer a, Long b) {
594    return ((long) a) <= ((long) b);
595  }
596
597  public static Object more(Integer a, Long b) {
598    return ((long) a) > ((long) b);
599  }
600
601  public static Object moreorequals(Integer a, Long b) {
602    return ((long) a) >= ((long) b);
603  }
604
605  public static Object plus(Integer a, Double b) {
606    return ((double) a) + ((double) b);
607  }
608
609  public static Object minus(Integer a, Double b) {
610    return ((double) a) - ((double) b);
611  }
612
613  public static Object divide(Integer a, Double b) {
614    return ((double) a) / ((double) b);
615  }
616
617  public static Object times(Integer a, Double b) {
618    return ((double) a) * ((double) b);
619  }
620
621  public static Object modulo(Integer a, Double b) {
622    return ((double) a) % ((double) b);
623  }
624
625  public static Object equals(Integer a, Double b) {
626    return ((double) a) == ((double) b);
627  }
628
629  public static Object notequals(Integer a, Double b) {
630    return ((double) a) != ((double) b);
631  }
632
633  public static Object less(Integer a, Double b) {
634    return ((double) a) < ((double) b);
635  }
636
637  public static Object lessorequals(Integer a, Double b) {
638    return ((double) a) <= ((double) b);
639  }
640
641  public static Object more(Integer a, Double b) {
642    return ((double) a) > ((double) b);
643  }
644
645  public static Object moreorequals(Integer a, Double b) {
646    return ((double) a) >= ((double) b);
647  }
648
649  public static Object plus(Integer a, Float b) {
650    return ((float) a) + ((float) b);
651  }
652
653  public static Object minus(Integer a, Float b) {
654    return ((float) a) - ((float) b);
655  }
656
657  public static Object divide(Integer a, Float b) {
658    return ((float) a) / ((float) b);
659  }
660
661  public static Object times(Integer a, Float b) {
662    return ((float) a) * ((float) b);
663  }
664
665  public static Object modulo(Integer a, Float b) {
666    return ((float) a) % ((float) b);
667  }
668
669  public static Object equals(Integer a, Float b) {
670    return ((float) a) == ((float) b);
671  }
672
673  public static Object notequals(Integer a, Float b) {
674    return ((float) a) != ((float) b);
675  }
676
677  public static Object less(Integer a, Float b) {
678    return ((float) a) < ((float) b);
679  }
680
681  public static Object lessorequals(Integer a, Float b) {
682    return ((float) a) <= ((float) b);
683  }
684
685  public static Object more(Integer a, Float b) {
686    return ((float) a) > ((float) b);
687  }
688
689  public static Object moreorequals(Integer a, Float b) {
690    return ((float) a) >= ((float) b);
691  }
692
693  public static Object plus(Long a, Double b) {
694    return ((double) a) + ((double) b);
695  }
696
697  public static Object minus(Long a, Double b) {
698    return ((double) a) - ((double) b);
699  }
700
701  public static Object divide(Long a, Double b) {
702    return ((double) a) / ((double) b);
703  }
704
705  public static Object times(Long a, Double b) {
706    return ((double) a) * ((double) b);
707  }
708
709  public static Object modulo(Long a, Double b) {
710    return ((double) a) % ((double) b);
711  }
712
713  public static Object equals(Long a, Double b) {
714    return ((double) a) == ((double) b);
715  }
716
717  public static Object notequals(Long a, Double b) {
718    return ((double) a) != ((double) b);
719  }
720
721  public static Object less(Long a, Double b) {
722    return ((double) a) < ((double) b);
723  }
724
725  public static Object lessorequals(Long a, Double b) {
726    return ((double) a) <= ((double) b);
727  }
728
729  public static Object more(Long a, Double b) {
730    return ((double) a) > ((double) b);
731  }
732
733  public static Object moreorequals(Long a, Double b) {
734    return ((double) a) >= ((double) b);
735  }
736
737  public static Object plus(Long a, Float b) {
738    return ((float) a) + ((float) b);
739  }
740
741  public static Object minus(Long a, Float b) {
742    return ((float) a) - ((float) b);
743  }
744
745  public static Object divide(Long a, Float b) {
746    return ((float) a) / ((float) b);
747  }
748
749  public static Object times(Long a, Float b) {
750    return ((float) a) * ((float) b);
751  }
752
753  public static Object modulo(Long a, Float b) {
754    return ((float) a) % ((float) b);
755  }
756
757  public static Object equals(Long a, Float b) {
758    return ((float) a) == ((float) b);
759  }
760
761  public static Object notequals(Long a, Float b) {
762    return ((float) a) != ((float) b);
763  }
764
765  public static Object less(Long a, Float b) {
766    return ((float) a) < ((float) b);
767  }
768
769  public static Object lessorequals(Long a, Float b) {
770    return ((float) a) <= ((float) b);
771  }
772
773  public static Object more(Long a, Float b) {
774    return ((float) a) > ((float) b);
775  }
776
777  public static Object moreorequals(Long a, Float b) {
778    return ((float) a) >= ((float) b);
779  }
780
781  public static Object plus(Double a, Float b) {
782    return ((double) a) + ((double) b);
783  }
784
785  public static Object minus(Double a, Float b) {
786    return ((double) a) - ((double) b);
787  }
788
789  public static Object divide(Double a, Float b) {
790    return ((double) a) / ((double) b);
791  }
792
793  public static Object times(Double a, Float b) {
794    return ((double) a) * ((double) b);
795  }
796
797  public static Object modulo(Double a, Float b) {
798    return ((double) a) % ((double) b);
799  }
800
801  public static Object equals(Double a, Float b) {
802    return ((double) a) == ((double) b);
803  }
804
805  public static Object notequals(Double a, Float b) {
806    return ((double) a) != ((double) b);
807  }
808
809  public static Object less(Double a, Float b) {
810    return ((double) a) < ((double) b);
811  }
812
813  public static Object lessorequals(Double a, Float b) {
814    return ((double) a) <= ((double) b);
815  }
816
817  public static Object more(Double a, Float b) {
818    return ((double) a) > ((double) b);
819  }
820
821  public static Object moreorequals(Double a, Float b) {
822    return ((double) a) >= ((double) b);
823  }
824
825  public static Object plus(Integer a, Character b) {
826    return ((int) a) + ((int) b);
827  }
828
829  public static Object minus(Integer a, Character b) {
830    return ((int) a) - ((int) b);
831  }
832
833  public static Object divide(Integer a, Character b) {
834    return ((int) a) / ((int) b);
835  }
836
837  public static Object times(Integer a, Character b) {
838    return ((int) a) * ((int) b);
839  }
840
841  public static Object modulo(Integer a, Character b) {
842    return ((int) a) % ((int) b);
843  }
844
845  public static Object equals(Integer a, Character b) {
846    return ((int) a) == ((int) b);
847  }
848
849  public static Object notequals(Integer a, Character b) {
850    return ((int) a) != ((int) b);
851  }
852
853  public static Object less(Integer a, Character b) {
854    return ((int) a) < ((int) b);
855  }
856
857  public static Object lessorequals(Integer a, Character b) {
858    return ((int) a) <= ((int) b);
859  }
860
861  public static Object more(Integer a, Character b) {
862    return ((int) a) > ((int) b);
863  }
864
865  public static Object moreorequals(Integer a, Character b) {
866    return ((int) a) >= ((int) b);
867  }
868
869  public static Object plus(Long a, Character b) {
870    return ((long) a) + ((long) b);
871  }
872
873  public static Object minus(Long a, Character b) {
874    return ((long) a) - ((long) b);
875  }
876
877  public static Object divide(Long a, Character b) {
878    return ((long) a) / ((long) b);
879  }
880
881  public static Object times(Long a, Character b) {
882    return ((long) a) * ((long) b);
883  }
884
885  public static Object modulo(Long a, Character b) {
886    return ((long) a) % ((long) b);
887  }
888
889  public static Object equals(Long a, Character b) {
890    return ((long) a) == ((long) b);
891  }
892
893  public static Object notequals(Long a, Character b) {
894    return ((long) a) != ((long) b);
895  }
896
897  public static Object less(Long a, Character b) {
898    return ((long) a) < ((long) b);
899  }
900
901  public static Object lessorequals(Long a, Character b) {
902    return ((long) a) <= ((long) b);
903  }
904
905  public static Object more(Long a, Character b) {
906    return ((long) a) > ((long) b);
907  }
908
909  public static Object moreorequals(Long a, Character b) {
910    return ((long) a) >= ((long) b);
911  }
912
913  public static Object plus(Double a, Character b) {
914    return ((double) a) + ((double) b);
915  }
916
917  public static Object minus(Double a, Character b) {
918    return ((double) a) - ((double) b);
919  }
920
921  public static Object divide(Double a, Character b) {
922    return ((double) a) / ((double) b);
923  }
924
925  public static Object times(Double a, Character b) {
926    return ((double) a) * ((double) b);
927  }
928
929  public static Object modulo(Double a, Character b) {
930    return ((double) a) % ((double) b);
931  }
932
933  public static Object equals(Double a, Character b) {
934    return ((double) a) == ((double) b);
935  }
936
937  public static Object notequals(Double a, Character b) {
938    return ((double) a) != ((double) b);
939  }
940
941  public static Object less(Double a, Character b) {
942    return ((double) a) < ((double) b);
943  }
944
945  public static Object lessorequals(Double a, Character b) {
946    return ((double) a) <= ((double) b);
947  }
948
949  public static Object more(Double a, Character b) {
950    return ((double) a) > ((double) b);
951  }
952
953  public static Object moreorequals(Double a, Character b) {
954    return ((double) a) >= ((double) b);
955  }
956
957  public static Object plus(Float a, Character b) {
958    return ((float) a) + ((float) b);
959  }
960
961  public static Object minus(Float a, Character b) {
962    return ((float) a) - ((float) b);
963  }
964
965  public static Object divide(Float a, Character b) {
966    return ((float) a) / ((float) b);
967  }
968
969  public static Object times(Float a, Character b) {
970    return ((float) a) * ((float) b);
971  }
972
973  public static Object modulo(Float a, Character b) {
974    return ((float) a) % ((float) b);
975  }
976
977  public static Object equals(Float a, Character b) {
978    return ((float) a) == ((float) b);
979  }
980
981  public static Object notequals(Float a, Character b) {
982    return ((float) a) != ((float) b);
983  }
984
985  public static Object less(Float a, Character b) {
986    return ((float) a) < ((float) b);
987  }
988
989  public static Object lessorequals(Float a, Character b) {
990    return ((float) a) <= ((float) b);
991  }
992
993  public static Object more(Float a, Character b) {
994    return ((float) a) > ((float) b);
995  }
996
997  public static Object moreorequals(Float a, Character b) {
998    return ((float) a) >= ((float) b);
999  }
1000
1001  public static Object plus(Long a, Integer b) {
1002    return ((long) a) + ((long) b);
1003  }
1004
1005  public static Object minus(Long a, Integer b) {
1006    return ((long) a) - ((long) b);
1007  }
1008
1009  public static Object divide(Long a, Integer b) {
1010    return ((long) a) / ((long) b);
1011  }
1012
1013  public static Object times(Long a, Integer b) {
1014    return ((long) a) * ((long) b);
1015  }
1016
1017  public static Object modulo(Long a, Integer b) {
1018    return ((long) a) % ((long) b);
1019  }
1020
1021  public static Object equals(Long a, Integer b) {
1022    return ((long) a) == ((long) b);
1023  }
1024
1025  public static Object notequals(Long a, Integer b) {
1026    return ((long) a) != ((long) b);
1027  }
1028
1029  public static Object less(Long a, Integer b) {
1030    return ((long) a) < ((long) b);
1031  }
1032
1033  public static Object lessorequals(Long a, Integer b) {
1034    return ((long) a) <= ((long) b);
1035  }
1036
1037  public static Object more(Long a, Integer b) {
1038    return ((long) a) > ((long) b);
1039  }
1040
1041  public static Object moreorequals(Long a, Integer b) {
1042    return ((long) a) >= ((long) b);
1043  }
1044
1045  public static Object plus(Double a, Integer b) {
1046    return ((double) a) + ((double) b);
1047  }
1048
1049  public static Object minus(Double a, Integer b) {
1050    return ((double) a) - ((double) b);
1051  }
1052
1053  public static Object divide(Double a, Integer b) {
1054    return ((double) a) / ((double) b);
1055  }
1056
1057  public static Object times(Double a, Integer b) {
1058    return ((double) a) * ((double) b);
1059  }
1060
1061  public static Object modulo(Double a, Integer b) {
1062    return ((double) a) % ((double) b);
1063  }
1064
1065  public static Object equals(Double a, Integer b) {
1066    return ((double) a) == ((double) b);
1067  }
1068
1069  public static Object notequals(Double a, Integer b) {
1070    return ((double) a) != ((double) b);
1071  }
1072
1073  public static Object less(Double a, Integer b) {
1074    return ((double) a) < ((double) b);
1075  }
1076
1077  public static Object lessorequals(Double a, Integer b) {
1078    return ((double) a) <= ((double) b);
1079  }
1080
1081  public static Object more(Double a, Integer b) {
1082    return ((double) a) > ((double) b);
1083  }
1084
1085  public static Object moreorequals(Double a, Integer b) {
1086    return ((double) a) >= ((double) b);
1087  }
1088
1089  public static Object plus(Float a, Integer b) {
1090    return ((float) a) + ((float) b);
1091  }
1092
1093  public static Object minus(Float a, Integer b) {
1094    return ((float) a) - ((float) b);
1095  }
1096
1097  public static Object divide(Float a, Integer b) {
1098    return ((float) a) / ((float) b);
1099  }
1100
1101  public static Object times(Float a, Integer b) {
1102    return ((float) a) * ((float) b);
1103  }
1104
1105  public static Object modulo(Float a, Integer b) {
1106    return ((float) a) % ((float) b);
1107  }
1108
1109  public static Object equals(Float a, Integer b) {
1110    return ((float) a) == ((float) b);
1111  }
1112
1113  public static Object notequals(Float a, Integer b) {
1114    return ((float) a) != ((float) b);
1115  }
1116
1117  public static Object less(Float a, Integer b) {
1118    return ((float) a) < ((float) b);
1119  }
1120
1121  public static Object lessorequals(Float a, Integer b) {
1122    return ((float) a) <= ((float) b);
1123  }
1124
1125  public static Object more(Float a, Integer b) {
1126    return ((float) a) > ((float) b);
1127  }
1128
1129  public static Object moreorequals(Float a, Integer b) {
1130    return ((float) a) >= ((float) b);
1131  }
1132
1133  public static Object plus(Double a, Long b) {
1134    return ((double) a) + ((double) b);
1135  }
1136
1137  public static Object minus(Double a, Long b) {
1138    return ((double) a) - ((double) b);
1139  }
1140
1141  public static Object divide(Double a, Long b) {
1142    return ((double) a) / ((double) b);
1143  }
1144
1145  public static Object times(Double a, Long b) {
1146    return ((double) a) * ((double) b);
1147  }
1148
1149  public static Object modulo(Double a, Long b) {
1150    return ((double) a) % ((double) b);
1151  }
1152
1153  public static Object equals(Double a, Long b) {
1154    return ((double) a) == ((double) b);
1155  }
1156
1157  public static Object notequals(Double a, Long b) {
1158    return ((double) a) != ((double) b);
1159  }
1160
1161  public static Object less(Double a, Long b) {
1162    return ((double) a) < ((double) b);
1163  }
1164
1165  public static Object lessorequals(Double a, Long b) {
1166    return ((double) a) <= ((double) b);
1167  }
1168
1169  public static Object more(Double a, Long b) {
1170    return ((double) a) > ((double) b);
1171  }
1172
1173  public static Object moreorequals(Double a, Long b) {
1174    return ((double) a) >= ((double) b);
1175  }
1176
1177  public static Object plus(Float a, Long b) {
1178    return ((float) a) + ((float) b);
1179  }
1180
1181  public static Object minus(Float a, Long b) {
1182    return ((float) a) - ((float) b);
1183  }
1184
1185  public static Object divide(Float a, Long b) {
1186    return ((float) a) / ((float) b);
1187  }
1188
1189  public static Object times(Float a, Long b) {
1190    return ((float) a) * ((float) b);
1191  }
1192
1193  public static Object modulo(Float a, Long b) {
1194    return ((float) a) % ((float) b);
1195  }
1196
1197  public static Object equals(Float a, Long b) {
1198    return ((float) a) == ((float) b);
1199  }
1200
1201  public static Object notequals(Float a, Long b) {
1202    return ((float) a) != ((float) b);
1203  }
1204
1205  public static Object less(Float a, Long b) {
1206    return ((float) a) < ((float) b);
1207  }
1208
1209  public static Object lessorequals(Float a, Long b) {
1210    return ((float) a) <= ((float) b);
1211  }
1212
1213  public static Object more(Float a, Long b) {
1214    return ((float) a) > ((float) b);
1215  }
1216
1217  public static Object moreorequals(Float a, Long b) {
1218    return ((float) a) >= ((float) b);
1219  }
1220
1221  public static Object plus(Float a, Double b) {
1222    return ((double) a) + ((double) b);
1223  }
1224
1225  public static Object minus(Float a, Double b) {
1226    return ((double) a) - ((double) b);
1227  }
1228
1229  public static Object divide(Float a, Double b) {
1230    return ((double) a) / ((double) b);
1231  }
1232
1233  public static Object times(Float a, Double b) {
1234    return ((double) a) * ((double) b);
1235  }
1236
1237  public static Object modulo(Float a, Double b) {
1238    return ((double) a) % ((double) b);
1239  }
1240
1241  public static Object equals(Float a, Double b) {
1242    return ((double) a) == ((double) b);
1243  }
1244
1245  public static Object notequals(Float a, Double b) {
1246    return ((double) a) != ((double) b);
1247  }
1248
1249  public static Object less(Float a, Double b) {
1250    return ((double) a) < ((double) b);
1251  }
1252
1253  public static Object lessorequals(Float a, Double b) {
1254    return ((double) a) <= ((double) b);
1255  }
1256
1257  public static Object more(Float a, Double b) {
1258    return ((double) a) > ((double) b);
1259  }
1260
1261  public static Object moreorequals(Float a, Double b) {
1262    return ((double) a) >= ((double) b);
1263  }
1264
1265  public static Object equals(BigDecimal a, Integer b) {
1266    return (a).compareTo(new BigDecimal(b)) == 0;
1267  }
1268
1269  public static Object equals(Integer a, BigDecimal b) {
1270    return (new BigDecimal(a)).compareTo(b) == 0;
1271  }
1272
1273  public static Object notequals(BigDecimal a, Integer b) {
1274    return (a).compareTo(new BigDecimal(b)) != 0;
1275  }
1276
1277  public static Object notequals(Integer a, BigDecimal b) {
1278    return (new BigDecimal(a)).compareTo(b) != 0;
1279  }
1280
1281  public static Object less(BigDecimal a, Integer b) {
1282    return (a).compareTo(new BigDecimal(b)) < 0;
1283  }
1284
1285  public static Object less(Integer a, BigDecimal b) {
1286    return (new BigDecimal(a)).compareTo(b) < 0;
1287  }
1288
1289  public static Object lessorequals(BigDecimal a, Integer b) {
1290    return (a).compareTo(new BigDecimal(b)) <= 0;
1291  }
1292
1293  public static Object lessorequals(Integer a, BigDecimal b) {
1294    return (new BigDecimal(a)).compareTo(b) <= 0;
1295  }
1296
1297  public static Object more(BigDecimal a, Integer b) {
1298    return (a).compareTo(new BigDecimal(b)) > 0;
1299  }
1300
1301  public static Object more(Integer a, BigDecimal b) {
1302    return (new BigDecimal(a)).compareTo(b) > 0;
1303  }
1304
1305  public static Object moreorequals(BigDecimal a, Integer b) {
1306    return (a).compareTo(new BigDecimal(b)) >= 0;
1307  }
1308
1309  public static Object moreorequals(Integer a, BigDecimal b) {
1310    return (new BigDecimal(a)).compareTo(b) >= 0;
1311  }
1312
1313  public static Object plus(BigDecimal a, Integer b) {
1314    return (a).add(new BigDecimal(b));
1315  }
1316
1317  public static Object plus(Integer a, BigDecimal b) {
1318    return (new BigDecimal(a)).add(b);
1319  }
1320
1321  public static Object minus(BigDecimal a, Integer b) {
1322    return (a).subtract(new BigDecimal(b));
1323  }
1324
1325  public static Object minus(Integer a, BigDecimal b) {
1326    return (new BigDecimal(a)).subtract(b);
1327  }
1328
1329  public static Object times(BigDecimal a, Integer b) {
1330    return (a).multiply(new BigDecimal(b));
1331  }
1332
1333  public static Object times(Integer a, BigDecimal b) {
1334    return (new BigDecimal(a)).multiply(b);
1335  }
1336
1337  public static Object divide(BigDecimal a, Integer b) {
1338    return (a).divide(new BigDecimal(b));
1339  }
1340
1341  public static Object divide(Integer a, BigDecimal b) {
1342    return (new BigDecimal(a)).divide(b);
1343  }
1344
1345  public static Object modulo(BigDecimal a, Integer b) {
1346    return (a).remainder(new BigDecimal(b));
1347  }
1348
1349  public static Object modulo(Integer a, BigDecimal b) {
1350    return (new BigDecimal(a)).remainder(b);
1351  }
1352
1353  public static Object equals(BigDecimal a, Long b) {
1354    return (a).compareTo(new BigDecimal(b)) == 0;
1355  }
1356
1357  public static Object equals(Long a, BigDecimal b) {
1358    return (new BigDecimal(a)).compareTo(b) == 0;
1359  }
1360
1361  public static Object notequals(BigDecimal a, Long b) {
1362    return (a).compareTo(new BigDecimal(b)) != 0;
1363  }
1364
1365  public static Object notequals(Long a, BigDecimal b) {
1366    return (new BigDecimal(a)).compareTo(b) != 0;
1367  }
1368
1369  public static Object less(BigDecimal a, Long b) {
1370    return (a).compareTo(new BigDecimal(b)) < 0;
1371  }
1372
1373  public static Object less(Long a, BigDecimal b) {
1374    return (new BigDecimal(a)).compareTo(b) < 0;
1375  }
1376
1377  public static Object lessorequals(BigDecimal a, Long b) {
1378    return (a).compareTo(new BigDecimal(b)) <= 0;
1379  }
1380
1381  public static Object lessorequals(Long a, BigDecimal b) {
1382    return (new BigDecimal(a)).compareTo(b) <= 0;
1383  }
1384
1385  public static Object more(BigDecimal a, Long b) {
1386    return (a).compareTo(new BigDecimal(b)) > 0;
1387  }
1388
1389  public static Object more(Long a, BigDecimal b) {
1390    return (new BigDecimal(a)).compareTo(b) > 0;
1391  }
1392
1393  public static Object moreorequals(BigDecimal a, Long b) {
1394    return (a).compareTo(new BigDecimal(b)) >= 0;
1395  }
1396
1397  public static Object moreorequals(Long a, BigDecimal b) {
1398    return (new BigDecimal(a)).compareTo(b) >= 0;
1399  }
1400
1401  public static Object plus(BigDecimal a, Long b) {
1402    return (a).add(new BigDecimal(b));
1403  }
1404
1405  public static Object plus(Long a, BigDecimal b) {
1406    return (new BigDecimal(a)).add(b);
1407  }
1408
1409  public static Object minus(BigDecimal a, Long b) {
1410    return (a).subtract(new BigDecimal(b));
1411  }
1412
1413  public static Object minus(Long a, BigDecimal b) {
1414    return (new BigDecimal(a)).subtract(b);
1415  }
1416
1417  public static Object times(BigDecimal a, Long b) {
1418    return (a).multiply(new BigDecimal(b));
1419  }
1420
1421  public static Object times(Long a, BigDecimal b) {
1422    return (new BigDecimal(a)).multiply(b);
1423  }
1424
1425  public static Object divide(BigDecimal a, Long b) {
1426    return (a).divide(new BigDecimal(b));
1427  }
1428
1429  public static Object divide(Long a, BigDecimal b) {
1430    return (new BigDecimal(a)).divide(b);
1431  }
1432
1433  public static Object modulo(BigDecimal a, Long b) {
1434    return (a).remainder(new BigDecimal(b));
1435  }
1436
1437  public static Object modulo(Long a, BigDecimal b) {
1438    return (new BigDecimal(a)).remainder(b);
1439  }
1440
1441  public static Object equals(BigDecimal a, BigInteger b) {
1442    return (a).compareTo(new BigDecimal(b)) == 0;
1443  }
1444
1445  public static Object equals(BigInteger a, BigDecimal b) {
1446    return (new BigDecimal(a)).compareTo(b) == 0;
1447  }
1448
1449  public static Object notequals(BigDecimal a, BigInteger b) {
1450    return (a).compareTo(new BigDecimal(b)) != 0;
1451  }
1452
1453  public static Object notequals(BigInteger a, BigDecimal b) {
1454    return (new BigDecimal(a)).compareTo(b) != 0;
1455  }
1456
1457  public static Object less(BigDecimal a, BigInteger b) {
1458    return (a).compareTo(new BigDecimal(b)) < 0;
1459  }
1460
1461  public static Object less(BigInteger a, BigDecimal b) {
1462    return (new BigDecimal(a)).compareTo(b) < 0;
1463  }
1464
1465  public static Object lessorequals(BigDecimal a, BigInteger b) {
1466    return (a).compareTo(new BigDecimal(b)) <= 0;
1467  }
1468
1469  public static Object lessorequals(BigInteger a, BigDecimal b) {
1470    return (new BigDecimal(a)).compareTo(b) <= 0;
1471  }
1472
1473  public static Object more(BigDecimal a, BigInteger b) {
1474    return (a).compareTo(new BigDecimal(b)) > 0;
1475  }
1476
1477  public static Object more(BigInteger a, BigDecimal b) {
1478    return (new BigDecimal(a)).compareTo(b) > 0;
1479  }
1480
1481  public static Object moreorequals(BigDecimal a, BigInteger b) {
1482    return (a).compareTo(new BigDecimal(b)) >= 0;
1483  }
1484
1485  public static Object moreorequals(BigInteger a, BigDecimal b) {
1486    return (new BigDecimal(a)).compareTo(b) >= 0;
1487  }
1488
1489  public static Object plus(BigDecimal a, BigInteger b) {
1490    return (a).add(new BigDecimal(b));
1491  }
1492
1493  public static Object plus(BigInteger a, BigDecimal b) {
1494    return (new BigDecimal(a)).add(b);
1495  }
1496
1497  public static Object minus(BigDecimal a, BigInteger b) {
1498    return (a).subtract(new BigDecimal(b));
1499  }
1500
1501  public static Object minus(BigInteger a, BigDecimal b) {
1502    return (new BigDecimal(a)).subtract(b);
1503  }
1504
1505  public static Object times(BigDecimal a, BigInteger b) {
1506    return (a).multiply(new BigDecimal(b));
1507  }
1508
1509  public static Object times(BigInteger a, BigDecimal b) {
1510    return (new BigDecimal(a)).multiply(b);
1511  }
1512
1513  public static Object divide(BigDecimal a, BigInteger b) {
1514    return (a).divide(new BigDecimal(b));
1515  }
1516
1517  public static Object divide(BigInteger a, BigDecimal b) {
1518    return (new BigDecimal(a)).divide(b);
1519  }
1520
1521  public static Object modulo(BigDecimal a, BigInteger b) {
1522    return (a).remainder(new BigDecimal(b));
1523  }
1524
1525  public static Object modulo(BigInteger a, BigDecimal b) {
1526    return (new BigDecimal(a)).remainder(b);
1527  }
1528
1529  public static Object equals(BigDecimal a, Float b) {
1530    return (a).compareTo(new BigDecimal(b)) == 0;
1531  }
1532
1533  public static Object equals(Float a, BigDecimal b) {
1534    return (new BigDecimal(a)).compareTo(b) == 0;
1535  }
1536
1537  public static Object notequals(BigDecimal a, Float b) {
1538    return (a).compareTo(new BigDecimal(b)) != 0;
1539  }
1540
1541  public static Object notequals(Float a, BigDecimal b) {
1542    return (new BigDecimal(a)).compareTo(b) != 0;
1543  }
1544
1545  public static Object less(BigDecimal a, Float b) {
1546    return (a).compareTo(new BigDecimal(b)) < 0;
1547  }
1548
1549  public static Object less(Float a, BigDecimal b) {
1550    return (new BigDecimal(a)).compareTo(b) < 0;
1551  }
1552
1553  public static Object lessorequals(BigDecimal a, Float b) {
1554    return (a).compareTo(new BigDecimal(b)) <= 0;
1555  }
1556
1557  public static Object lessorequals(Float a, BigDecimal b) {
1558    return (new BigDecimal(a)).compareTo(b) <= 0;
1559  }
1560
1561  public static Object more(BigDecimal a, Float b) {
1562    return (a).compareTo(new BigDecimal(b)) > 0;
1563  }
1564
1565  public static Object more(Float a, BigDecimal b) {
1566    return (new BigDecimal(a)).compareTo(b) > 0;
1567  }
1568
1569  public static Object moreorequals(BigDecimal a, Float b) {
1570    return (a).compareTo(new BigDecimal(b)) >= 0;
1571  }
1572
1573  public static Object moreorequals(Float a, BigDecimal b) {
1574    return (new BigDecimal(a)).compareTo(b) >= 0;
1575  }
1576
1577  public static Object plus(BigDecimal a, Float b) {
1578    return (a).add(new BigDecimal(b));
1579  }
1580
1581  public static Object plus(Float a, BigDecimal b) {
1582    return (new BigDecimal(a)).add(b);
1583  }
1584
1585  public static Object minus(BigDecimal a, Float b) {
1586    return (a).subtract(new BigDecimal(b));
1587  }
1588
1589  public static Object minus(Float a, BigDecimal b) {
1590    return (new BigDecimal(a)).subtract(b);
1591  }
1592
1593  public static Object times(BigDecimal a, Float b) {
1594    return (a).multiply(new BigDecimal(b));
1595  }
1596
1597  public static Object times(Float a, BigDecimal b) {
1598    return (new BigDecimal(a)).multiply(b);
1599  }
1600
1601  public static Object divide(BigDecimal a, Float b) {
1602    return (a).divide(new BigDecimal(b));
1603  }
1604
1605  public static Object divide(Float a, BigDecimal b) {
1606    return (new BigDecimal(a)).divide(b);
1607  }
1608
1609  public static Object modulo(BigDecimal a, Float b) {
1610    return (a).remainder(new BigDecimal(b));
1611  }
1612
1613  public static Object modulo(Float a, BigDecimal b) {
1614    return (new BigDecimal(a)).remainder(b);
1615  }
1616
1617  public static Object equals(BigDecimal a, Double b) {
1618    return (a).compareTo(new BigDecimal(b)) == 0;
1619  }
1620
1621  public static Object equals(Double a, BigDecimal b) {
1622    return (new BigDecimal(a)).compareTo(b) == 0;
1623  }
1624
1625  public static Object notequals(BigDecimal a, Double b) {
1626    return (a).compareTo(new BigDecimal(b)) != 0;
1627  }
1628
1629  public static Object notequals(Double a, BigDecimal b) {
1630    return (new BigDecimal(a)).compareTo(b) != 0;
1631  }
1632
1633  public static Object less(BigDecimal a, Double b) {
1634    return (a).compareTo(new BigDecimal(b)) < 0;
1635  }
1636
1637  public static Object less(Double a, BigDecimal b) {
1638    return (new BigDecimal(a)).compareTo(b) < 0;
1639  }
1640
1641  public static Object lessorequals(BigDecimal a, Double b) {
1642    return (a).compareTo(new BigDecimal(b)) <= 0;
1643  }
1644
1645  public static Object lessorequals(Double a, BigDecimal b) {
1646    return (new BigDecimal(a)).compareTo(b) <= 0;
1647  }
1648
1649  public static Object more(BigDecimal a, Double b) {
1650    return (a).compareTo(new BigDecimal(b)) > 0;
1651  }
1652
1653  public static Object more(Double a, BigDecimal b) {
1654    return (new BigDecimal(a)).compareTo(b) > 0;
1655  }
1656
1657  public static Object moreorequals(BigDecimal a, Double b) {
1658    return (a).compareTo(new BigDecimal(b)) >= 0;
1659  }
1660
1661  public static Object moreorequals(Double a, BigDecimal b) {
1662    return (new BigDecimal(a)).compareTo(b) >= 0;
1663  }
1664
1665  public static Object plus(BigDecimal a, Double b) {
1666    return (a).add(new BigDecimal(b));
1667  }
1668
1669  public static Object plus(Double a, BigDecimal b) {
1670    return (new BigDecimal(a)).add(b);
1671  }
1672
1673  public static Object minus(BigDecimal a, Double b) {
1674    return (a).subtract(new BigDecimal(b));
1675  }
1676
1677  public static Object minus(Double a, BigDecimal b) {
1678    return (new BigDecimal(a)).subtract(b);
1679  }
1680
1681  public static Object times(BigDecimal a, Double b) {
1682    return (a).multiply(new BigDecimal(b));
1683  }
1684
1685  public static Object times(Double a, BigDecimal b) {
1686    return (new BigDecimal(a)).multiply(b);
1687  }
1688
1689  public static Object divide(BigDecimal a, Double b) {
1690    return (a).divide(new BigDecimal(b));
1691  }
1692
1693  public static Object divide(Double a, BigDecimal b) {
1694    return (new BigDecimal(a)).divide(b);
1695  }
1696
1697  public static Object modulo(BigDecimal a, Double b) {
1698    return (a).remainder(new BigDecimal(b));
1699  }
1700
1701  public static Object modulo(Double a, BigDecimal b) {
1702    return (new BigDecimal(a)).remainder(b);
1703  }
1704
1705  public static Object equals(BigDecimal a, BigDecimal b) {
1706    return (a).compareTo(b) == 0;
1707  }
1708
1709  public static Object notequals(BigDecimal a, BigDecimal b) {
1710    return (a).compareTo(b) != 0;
1711  }
1712
1713  public static Object less(BigDecimal a, BigDecimal b) {
1714    return (a).compareTo(b) < 0;
1715  }
1716
1717  public static Object lessorequals(BigDecimal a, BigDecimal b) {
1718    return (a).compareTo(b) <= 0;
1719  }
1720
1721  public static Object more(BigDecimal a, BigDecimal b) {
1722    return (a).compareTo(b) > 0;
1723  }
1724
1725  public static Object moreorequals(BigDecimal a, BigDecimal b) {
1726    return (a).compareTo(b) >= 0;
1727  }
1728
1729  public static Object plus(BigDecimal a, BigDecimal b) {
1730    return (a).add(b);
1731  }
1732
1733  public static Object minus(BigDecimal a, BigDecimal b) {
1734    return (a).subtract(b);
1735  }
1736
1737  public static Object times(BigDecimal a, BigDecimal b) {
1738    return (a).multiply(b);
1739  }
1740
1741  public static Object divide(BigDecimal a, BigDecimal b) {
1742    return (a).divide(b);
1743  }
1744
1745  public static Object modulo(BigDecimal a, BigDecimal b) {
1746    return (a).remainder(b);
1747  }
1748
1749  public static Object equals(BigInteger a, Integer b) {
1750    return (a).compareTo(BigInteger.valueOf(b.longValue())) == 0;
1751  }
1752
1753  public static Object equals(Integer a, BigInteger b) {
1754    return (BigInteger.valueOf(a.longValue())).compareTo(b) == 0;
1755  }
1756
1757  public static Object notequals(BigInteger a, Integer b) {
1758    return (a).compareTo(BigInteger.valueOf(b.longValue())) != 0;
1759  }
1760
1761  public static Object notequals(Integer a, BigInteger b) {
1762    return (BigInteger.valueOf(a.longValue())).compareTo(b) != 0;
1763  }
1764
1765  public static Object less(BigInteger a, Integer b) {
1766    return (a).compareTo(BigInteger.valueOf(b.longValue())) < 0;
1767  }
1768
1769  public static Object less(Integer a, BigInteger b) {
1770    return (BigInteger.valueOf(a.longValue())).compareTo(b) < 0;
1771  }
1772
1773  public static Object lessorequals(BigInteger a, Integer b) {
1774    return (a).compareTo(BigInteger.valueOf(b.longValue())) <= 0;
1775  }
1776
1777  public static Object lessorequals(Integer a, BigInteger b) {
1778    return (BigInteger.valueOf(a.longValue())).compareTo(b) <= 0;
1779  }
1780
1781  public static Object more(BigInteger a, Integer b) {
1782    return (a).compareTo(BigInteger.valueOf(b.longValue())) > 0;
1783  }
1784
1785  public static Object more(Integer a, BigInteger b) {
1786    return (BigInteger.valueOf(a.longValue())).compareTo(b) > 0;
1787  }
1788
1789  public static Object moreorequals(BigInteger a, Integer b) {
1790    return (a).compareTo(BigInteger.valueOf(b.longValue())) >= 0;
1791  }
1792
1793  public static Object moreorequals(Integer a, BigInteger b) {
1794    return (BigInteger.valueOf(a.longValue())).compareTo(b) >= 0;
1795  }
1796
1797  public static Object plus(BigInteger a, Integer b) {
1798    return (a).add(BigInteger.valueOf(b.longValue()));
1799  }
1800
1801  public static Object plus(Integer a, BigInteger b) {
1802    return (BigInteger.valueOf(a.longValue())).add(b);
1803  }
1804
1805  public static Object minus(BigInteger a, Integer b) {
1806    return (a).subtract(BigInteger.valueOf(b.longValue()));
1807  }
1808
1809  public static Object minus(Integer a, BigInteger b) {
1810    return (BigInteger.valueOf(a.longValue())).subtract(b);
1811  }
1812
1813  public static Object times(BigInteger a, Integer b) {
1814    return (a).multiply(BigInteger.valueOf(b.longValue()));
1815  }
1816
1817  public static Object times(Integer a, BigInteger b) {
1818    return (BigInteger.valueOf(a.longValue())).multiply(b);
1819  }
1820
1821  public static Object divide(BigInteger a, Integer b) {
1822    return (a).divide(BigInteger.valueOf(b.longValue()));
1823  }
1824
1825  public static Object divide(Integer a, BigInteger b) {
1826    return (BigInteger.valueOf(a.longValue())).divide(b);
1827  }
1828
1829  public static Object modulo(BigInteger a, Integer b) {
1830    return (a).remainder(BigInteger.valueOf(b.longValue()));
1831  }
1832
1833  public static Object modulo(Integer a, BigInteger b) {
1834    return (BigInteger.valueOf(a.longValue())).remainder(b);
1835  }
1836
1837  public static Object equals(BigInteger a, Long b) {
1838    return (a).compareTo(BigInteger.valueOf(b.longValue())) == 0;
1839  }
1840
1841  public static Object equals(Long a, BigInteger b) {
1842    return (BigInteger.valueOf(a.longValue())).compareTo(b) == 0;
1843  }
1844
1845  public static Object notequals(BigInteger a, Long b) {
1846    return (a).compareTo(BigInteger.valueOf(b.longValue())) != 0;
1847  }
1848
1849  public static Object notequals(Long a, BigInteger b) {
1850    return (BigInteger.valueOf(a.longValue())).compareTo(b) != 0;
1851  }
1852
1853  public static Object less(BigInteger a, Long b) {
1854    return (a).compareTo(BigInteger.valueOf(b.longValue())) < 0;
1855  }
1856
1857  public static Object less(Long a, BigInteger b) {
1858    return (BigInteger.valueOf(a.longValue())).compareTo(b) < 0;
1859  }
1860
1861  public static Object lessorequals(BigInteger a, Long b) {
1862    return (a).compareTo(BigInteger.valueOf(b.longValue())) <= 0;
1863  }
1864
1865  public static Object lessorequals(Long a, BigInteger b) {
1866    return (BigInteger.valueOf(a.longValue())).compareTo(b) <= 0;
1867  }
1868
1869  public static Object more(BigInteger a, Long b) {
1870    return (a).compareTo(BigInteger.valueOf(b.longValue())) > 0;
1871  }
1872
1873  public static Object more(Long a, BigInteger b) {
1874    return (BigInteger.valueOf(a.longValue())).compareTo(b) > 0;
1875  }
1876
1877  public static Object moreorequals(BigInteger a, Long b) {
1878    return (a).compareTo(BigInteger.valueOf(b.longValue())) >= 0;
1879  }
1880
1881  public static Object moreorequals(Long a, BigInteger b) {
1882    return (BigInteger.valueOf(a.longValue())).compareTo(b) >= 0;
1883  }
1884
1885  public static Object plus(BigInteger a, Long b) {
1886    return (a).add(BigInteger.valueOf(b.longValue()));
1887  }
1888
1889  public static Object plus(Long a, BigInteger b) {
1890    return (BigInteger.valueOf(a.longValue())).add(b);
1891  }
1892
1893  public static Object minus(BigInteger a, Long b) {
1894    return (a).subtract(BigInteger.valueOf(b.longValue()));
1895  }
1896
1897  public static Object minus(Long a, BigInteger b) {
1898    return (BigInteger.valueOf(a.longValue())).subtract(b);
1899  }
1900
1901  public static Object times(BigInteger a, Long b) {
1902    return (a).multiply(BigInteger.valueOf(b.longValue()));
1903  }
1904
1905  public static Object times(Long a, BigInteger b) {
1906    return (BigInteger.valueOf(a.longValue())).multiply(b);
1907  }
1908
1909  public static Object divide(BigInteger a, Long b) {
1910    return (a).divide(BigInteger.valueOf(b.longValue()));
1911  }
1912
1913  public static Object divide(Long a, BigInteger b) {
1914    return (BigInteger.valueOf(a.longValue())).divide(b);
1915  }
1916
1917  public static Object modulo(BigInteger a, Long b) {
1918    return (a).remainder(BigInteger.valueOf(b.longValue()));
1919  }
1920
1921  public static Object modulo(Long a, BigInteger b) {
1922    return (BigInteger.valueOf(a.longValue())).remainder(b);
1923  }
1924
1925  public static Object equals(BigInteger a, BigInteger b) {
1926    return (a).compareTo(b) == 0;
1927  }
1928
1929  public static Object notequals(BigInteger a, BigInteger b) {
1930    return (a).compareTo(b) != 0;
1931  }
1932
1933  public static Object less(BigInteger a, BigInteger b) {
1934    return (a).compareTo(b) < 0;
1935  }
1936
1937  public static Object lessorequals(BigInteger a, BigInteger b) {
1938    return (a).compareTo(b) <= 0;
1939  }
1940
1941  public static Object more(BigInteger a, BigInteger b) {
1942    return (a).compareTo(b) > 0;
1943  }
1944
1945  public static Object moreorequals(BigInteger a, BigInteger b) {
1946    return (a).compareTo(b) >= 0;
1947  }
1948
1949  public static Object plus(BigInteger a, BigInteger b) {
1950    return (a).add(b);
1951  }
1952
1953  public static Object minus(BigInteger a, BigInteger b) {
1954    return (a).subtract(b);
1955  }
1956
1957  public static Object times(BigInteger a, BigInteger b) {
1958    return (a).multiply(b);
1959  }
1960
1961  public static Object divide(BigInteger a, BigInteger b) {
1962    return (a).divide(b);
1963  }
1964
1965  public static Object modulo(BigInteger a, BigInteger b) {
1966    return (a).remainder(b);
1967  }
1968
1969  public static Object equals(BigInteger a, Float b) {
1970    return (new BigDecimal(a)).compareTo(new BigDecimal(b)) == 0;
1971  }
1972
1973  public static Object equals(Float a, BigInteger b) {
1974    return (new BigDecimal(a)).compareTo(new BigDecimal(b)) == 0;
1975  }
1976
1977  public static Object notequals(BigInteger a, Float b) {
1978    return (new BigDecimal(a)).compareTo(new BigDecimal(b)) != 0;
1979  }
1980
1981  public static Object notequals(Float a, BigInteger b) {
1982    return (new BigDecimal(a)).compareTo(new BigDecimal(b)) != 0;
1983  }
1984
1985  public static Object less(BigInteger a, Float b) {
1986    return (new BigDecimal(a)).compareTo(new BigDecimal(b)) < 0;
1987  }
1988
1989  public static Object less(Float a, BigInteger b) {
1990    return (new BigDecimal(a)).compareTo(new BigDecimal(b)) < 0;
1991  }
1992
1993  public static Object lessorequals(BigInteger a, Float b) {
1994    return (new BigDecimal(a)).compareTo(new BigDecimal(b)) <= 0;
1995  }
1996
1997  public static Object lessorequals(Float a, BigInteger b) {
1998    return (new BigDecimal(a)).compareTo(new BigDecimal(b)) <= 0;
1999  }
2000
2001  public static Object more(BigInteger a, Float b) {
2002    return (new BigDecimal(a)).compareTo(new BigDecimal(b)) > 0;
2003  }
2004
2005  public static Object more(Float a, BigInteger b) {
2006    return (new BigDecimal(a)).compareTo(new BigDecimal(b)) > 0;
2007  }
2008
2009  public static Object moreorequals(BigInteger a, Float b) {
2010    return (new BigDecimal(a)).compareTo(new BigDecimal(b)) >= 0;
2011  }
2012
2013  public static Object moreorequals(Float a, BigInteger b) {
2014    return (new BigDecimal(a)).compareTo(new BigDecimal(b)) >= 0;
2015  }
2016
2017  public static Object plus(BigInteger a, Float b) {
2018    return (new BigDecimal(a)).add(new BigDecimal(b));
2019  }
2020
2021  public static Object plus(Float a, BigInteger b) {
2022    return (new BigDecimal(a)).add(new BigDecimal(b));
2023  }
2024
2025  public static Object minus(BigInteger a, Float b) {
2026    return (new BigDecimal(a)).subtract(new BigDecimal(b));
2027  }
2028
2029  public static Object minus(Float a, BigInteger b) {
2030    return (new BigDecimal(a)).subtract(new BigDecimal(b));
2031  }
2032
2033  public static Object times(BigInteger a, Float b) {
2034    return (new BigDecimal(a)).multiply(new BigDecimal(b));
2035  }
2036
2037  public static Object times(Float a, BigInteger b) {
2038    return (new BigDecimal(a)).multiply(new BigDecimal(b));
2039  }
2040
2041  public static Object divide(BigInteger a, Float b) {
2042    return (new BigDecimal(a)).divide(new BigDecimal(b));
2043  }
2044
2045  public static Object divide(Float a, BigInteger b) {
2046    return (new BigDecimal(a)).divide(new BigDecimal(b));
2047  }
2048
2049  public static Object modulo(BigInteger a, Float b) {
2050    return (new BigDecimal(a)).remainder(new BigDecimal(b));
2051  }
2052
2053  public static Object modulo(Float a, BigInteger b) {
2054    return (new BigDecimal(a)).remainder(new BigDecimal(b));
2055  }
2056
2057  public static Object equals(BigInteger a, Double b) {
2058    return (new BigDecimal(a)).compareTo(new BigDecimal(b)) == 0;
2059  }
2060
2061  public static Object equals(Double a, BigInteger b) {
2062    return (new BigDecimal(a)).compareTo(new BigDecimal(b)) == 0;
2063  }
2064
2065  public static Object notequals(BigInteger a, Double b) {
2066    return (new BigDecimal(a)).compareTo(new BigDecimal(b)) != 0;
2067  }
2068
2069  public static Object notequals(Double a, BigInteger b) {
2070    return (new BigDecimal(a)).compareTo(new BigDecimal(b)) != 0;
2071  }
2072
2073  public static Object less(BigInteger a, Double b) {
2074    return (new BigDecimal(a)).compareTo(new BigDecimal(b)) < 0;
2075  }
2076
2077  public static Object less(Double a, BigInteger b) {
2078    return (new BigDecimal(a)).compareTo(new BigDecimal(b)) < 0;
2079  }
2080
2081  public static Object lessorequals(BigInteger a, Double b) {
2082    return (new BigDecimal(a)).compareTo(new BigDecimal(b)) <= 0;
2083  }
2084
2085  public static Object lessorequals(Double a, BigInteger b) {
2086    return (new BigDecimal(a)).compareTo(new BigDecimal(b)) <= 0;
2087  }
2088
2089  public static Object more(BigInteger a, Double b) {
2090    return (new BigDecimal(a)).compareTo(new BigDecimal(b)) > 0;
2091  }
2092
2093  public static Object more(Double a, BigInteger b) {
2094    return (new BigDecimal(a)).compareTo(new BigDecimal(b)) > 0;
2095  }
2096
2097  public static Object moreorequals(BigInteger a, Double b) {
2098    return (new BigDecimal(a)).compareTo(new BigDecimal(b)) >= 0;
2099  }
2100
2101  public static Object moreorequals(Double a, BigInteger b) {
2102    return (new BigDecimal(a)).compareTo(new BigDecimal(b)) >= 0;
2103  }
2104
2105  public static Object plus(BigInteger a, Double b) {
2106    return (new BigDecimal(a)).add(new BigDecimal(b));
2107  }
2108
2109  public static Object plus(Double a, BigInteger b) {
2110    return (new BigDecimal(a)).add(new BigDecimal(b));
2111  }
2112
2113  public static Object minus(BigInteger a, Double b) {
2114    return (new BigDecimal(a)).subtract(new BigDecimal(b));
2115  }
2116
2117  public static Object minus(Double a, BigInteger b) {
2118    return (new BigDecimal(a)).subtract(new BigDecimal(b));
2119  }
2120
2121  public static Object times(BigInteger a, Double b) {
2122    return (new BigDecimal(a)).multiply(new BigDecimal(b));
2123  }
2124
2125  public static Object times(Double a, BigInteger b) {
2126    return (new BigDecimal(a)).multiply(new BigDecimal(b));
2127  }
2128
2129  public static Object divide(BigInteger a, Double b) {
2130    return (new BigDecimal(a)).divide(new BigDecimal(b));
2131  }
2132
2133  public static Object divide(Double a, BigInteger b) {
2134    return (new BigDecimal(a)).divide(new BigDecimal(b));
2135  }
2136
2137  public static Object modulo(BigInteger a, Double b) {
2138    return (new BigDecimal(a)).remainder(new BigDecimal(b));
2139  }
2140
2141  public static Object modulo(Double a, BigInteger b) {
2142    return (new BigDecimal(a)).remainder(new BigDecimal(b));
2143  }
2144
2145  // END GENERATED
2146
2147  // arithmetic fallbacks .............................................................................................
2148
2149  public static Object plus(String a, String b) {
2150    return a + b;
2151  }
2152
2153  public static Object plus_fallback(Object a, Object b) {
2154    if (isNotNullAndString(a) || isNotNullAndString(b)) {
2155      return String.valueOf(a) + b;
2156    }
2157    return reject(a, b, "+");
2158  }
2159
2160  public static Object times_fallback(Object a, Object b) {
2161    if (isInteger(a) && isString(b)) {
2162      return repeat((String) b, (Integer) a);
2163    }
2164    if (isString(a) && isInteger(b)) {
2165      return repeat((String) a, (Integer) b);
2166    }
2167    return reject(a, b, "*");
2168  }
2169
2170  private static String repeat(String string, int n) {
2171    StringBuilder builder = new StringBuilder();
2172    for (int i = 0; i < n; i++) {
2173      builder.append(string);
2174    }
2175    return builder.toString();
2176  }
2177
2178  // comparisons fallback .............................................................................................
2179
2180  public static Object equals_fallback(Object a, Object b) {
2181    return Objects.equals(a, b);
2182  }
2183
2184  public static Object notequals_fallback(Object a, Object b) {
2185    return !Objects.equals(a, b);
2186  }
2187
2188  @SuppressWarnings("unchecked")
2189  public static Object less_fallback(Object a, Object b) {
2190    if (bothNotNull(a, b) && isComparable(a) && isComparable(b)) {
2191      return ((Comparable) a).compareTo(b) < 0;
2192    }
2193    return reject(a, b, "<");
2194  }
2195
2196  @SuppressWarnings("unchecked")
2197  public static Object lessorequals_fallback(Object a, Object b) {
2198    if (bothNotNull(a, b) && isComparable(a) && isComparable(b)) {
2199      return ((Comparable) a).compareTo(b) <= 0;
2200    }
2201    return reject(a, b, "<=");
2202  }
2203
2204  @SuppressWarnings("unchecked")
2205  public static Object more_fallback(Object a, Object b) {
2206    if (bothNotNull(a, b) && isComparable(a) && isComparable(b)) {
2207      return ((Comparable) a).compareTo(b) > 0;
2208    }
2209    return reject(a, b, ">");
2210  }
2211
2212  @SuppressWarnings("unchecked")
2213  public static Object moreorequals_fallback(Object a, Object b) {
2214    if (bothNotNull(a, b) && isComparable(a) && isComparable(b)) {
2215      return ((Comparable) a).compareTo(b) >= 0;
2216    }
2217    return reject(a, b, ">=");
2218  }
2219
2220  // logic ............................................................................................................
2221
2222  public static Object not(Boolean a) {
2223    return !a;
2224  }
2225
2226  public static Object oftype_noguard(Object a, Object b) {
2227    if (isClass(b)) {
2228      return ((Class<?>) b).isInstance(a);
2229    }
2230    return reject(a, b, "oftype");
2231  }
2232
2233  public static Object is_noguard(Object a, Object b) {
2234    return a == b;
2235  }
2236
2237  public static Object isnt_noguard(Object a, Object b) {
2238    return a != b;
2239  }
2240
2241  // helpers ..........................................................................................................
2242
2243  private static boolean isNotNullAndString(Object obj) {
2244    return (obj != null) && (obj.getClass() == String.class);
2245  }
2246
2247  private static boolean bothNotNull(Object a, Object b) {
2248    return (a != null) && (b != null);
2249  }
2250
2251  private static boolean isString(Object obj) {
2252    return obj.getClass() == String.class;
2253  }
2254
2255  private static boolean isInteger(Object obj) {
2256    return obj.getClass() == Integer.class;
2257  }
2258
2259  private static boolean isComparable(Object obj) {
2260    return obj instanceof Comparable<?>;
2261  }
2262
2263  private static boolean isClass(Object obj) {
2264    return (obj != null) && (obj.getClass() == Class.class);
2265  }
2266
2267  private static Object reject(Object a, String symbol) throws IllegalArgumentException {
2268    throw new IllegalArgumentException(
2269        message("invalid_unary_operator", symbol, a.getClass().getName()));
2270  }
2271
2272  private static Object reject(Object a, Object b, String symbol) throws IllegalArgumentException {
2273    throw new IllegalArgumentException(
2274        message("invalid_binary_operator", symbol, a.getClass().getName(), b.getClass().getName()));
2275  }
2276}