11using System . Globalization ;
2- using System . Reflection . Metadata ;
2+ using System . Numerics ;
33using CritLang . Content ;
44
55namespace CritLang ;
@@ -38,10 +38,17 @@ public CritVisitor(string version)
3838 Variables [ "CritVersion" ] = _version ;
3939 Variables [ "Split" ] = new Func < object ? [ ] , object ? > ( Split ) ;
4040 Variables [ "Len" ] = new Func < object ? [ ] , object ? > ( Len ) ;
41+ Variables [ "Type" ] = new Func < object ? [ ] , object ? > ( GetTypeOf ) ;
4142
4243 }
4344
44-
45+ public static object ? GetTypeOf ( object ? [ ] args )
46+ {
47+ if ( args . Length == 0 || args . Length > 1 )
48+ throw new Exception ( "Type only takes 1 argument." ) ;
49+
50+ return args [ 0 ] ! . GetType ( ) ;
51+ }
4552
4653 public static object ? Split ( object ? [ ] args )
4754 {
@@ -52,13 +59,13 @@ public CritVisitor(string version)
5259
5360 public static object ? Delay ( object ? [ ] args )
5461 {
55- if ( args . Length != 1 ) throw new Exception ( "Delay takes 1 argument" ) ;
62+ if ( args . Length != 1 ) throw new Exception ( "Delay takes 1 argument that is the number of milliseconds to delay. " ) ;
5663 Task . Delay ( ( int ) args [ 0 ] ! ) . Wait ( ) ;
5764 return null ;
5865
5966 }
6067
61- //TODO FIX THIS
68+ //TODO FIX THIS; UPDATE SHOULD NOW BE POSSIBLE WITH THE NEW BIG NUMBERS
6269 //public static object? Time(object?[] args)
6370 //{
6471 // if (args.Length != 0) throw new Exception("Time takes no arguments");
@@ -95,7 +102,7 @@ public CritVisitor(string version)
95102 string [ ] typeOptions = new [ ] { "int" , "float" , "string" , "bool" } ;
96103 if ( ! typeOptions . Contains ( args [ 1 ] ! . ToString ( ) ! ) )
97104 throw new Exception ( $ "Invalid type...\n Must be one of the following types: { string . Join ( ", " , typeOptions ) } ") ;
98-
105+ //TODO ADD THE REST OF THE TYPES AUTOMATICALLY
99106 return args [ 1 ] ! . ToString ( ) switch
100107 {
101108 "int" => Convert . ToInt32 ( args [ 0 ] ) ,
@@ -405,10 +412,25 @@ public CritVisitor(string version)
405412 {
406413
407414 if ( context . INTEGER ( ) is { } i )
408- return int . Parse ( ( i . GetText ( ) ) ) ;
415+ {
416+ string text = i . GetText ( ) ;
417+
418+ if ( int . TryParse ( text , out int inT ) )
419+ return inT ;
420+
421+ if ( long . TryParse ( text , out long lo ) )
422+ return lo ;
423+
424+ if ( BigInteger . TryParse ( text , out var biggie ) )
425+ return biggie ;
426+ }
409427
410428 if ( context . FLOAT ( ) is { } f )
411- return float . Parse ( f . GetText ( ) , CultureInfo . InvariantCulture ) ;
429+ {
430+ string text = f . GetText ( ) ;
431+
432+ return text . Split ( '.' ) [ 0 ] . Length >= 40 ? double . Parse ( text , CultureInfo . InvariantCulture ) : float . Parse ( text , CultureInfo . InvariantCulture ) ;
433+ }
412434
413435 if ( context . STRING ( ) is { } s )
414436 return s . GetText ( ) [ 1 ..^ 1 ] ;
@@ -448,8 +470,8 @@ public CritVisitor(string version)
448470
449471 public override object ? VisitAdditiveExpression ( CritParser . AdditiveExpressionContext context )
450472 {
451- var left = Visit ( context . expression ( 0 ) ) ;
452- var right = Visit ( context . expression ( 1 ) ) ;
473+ var left = Visit ( context . expression ( 0 ) ) ! ;
474+ var right = Visit ( context . expression ( 1 ) ) ! ;
453475
454476
455477 var op = context . addOp ( ) . GetText ( ) ;
@@ -469,6 +491,10 @@ public CritVisitor(string version)
469491 var right = Visit ( context . expression ( 1 ) ) ;
470492
471493
494+ left = TypeDispatcher ( left ! ) ;
495+ right = TypeDispatcher ( right ! ) ;
496+
497+
472498 var op = context . multOp ( ) . GetText ( ) ;
473499
474500 return op switch
@@ -480,54 +506,15 @@ public CritVisitor(string version)
480506 } ;
481507 }
482508
483- private static object ? Add ( object ? left , object ? right ) => ( left , right ) switch
484- {
485- ( int l , int r ) => l + r ,
486- ( float lf , float rf ) => lf + rf ,
487- ( int lInt , float rf ) => lInt + rf ,
488- ( float lf , int rInt ) => lf + rInt ,
489- ( string , _) => $ "{ left } { right } ",
490- ( _, string ) => $ "{ left } { right } ",
491- ( _, _) => throw new Exception ( $ "Cannot add values of type { left ? . GetType ( ) } and { right ? . GetType ( ) } .")
492- } ;
493-
494-
495- private static object ? Subtract ( object ? left , object ? right ) => ( left , right ) switch
496- {
497- ( int l , int r ) => l - r ,
498- ( float lf , float rf ) => lf - rf ,
499- ( int lInt , float rf ) => lInt - rf ,
500- ( float lf , int rInt ) => lf - rInt ,
501- ( _, _) => throw new Exception ( $ "Cannot subtract values of type { left ? . GetType ( ) } and { right ? . GetType ( ) } .")
502- } ;
509+ private static object ? Add ( dynamic left , dynamic right ) => left + right ;
503510
511+ private static object ? Subtract ( dynamic left , dynamic right ) => left - right ;
512+
513+ private static object ? Multiply ( dynamic left , dynamic right ) => left * right ;
504514
505- private static object ? Multiply ( object ? left , object ? right ) => ( left , right ) switch
506- {
507- ( int l , int r ) => l * r ,
508- ( float lf , float rf ) => lf * rf ,
509- ( int lInt , float rf ) => lInt * rf ,
510- ( float lf , int rInt ) => lf * rInt ,
511- ( _, _) => throw new Exception ( $ "Cannot multiply values of type { left ? . GetType ( ) } and { right ? . GetType ( ) } .")
512- } ;
515+ private static object ? Divide ( dynamic left , dynamic right ) => left / right ;
513516
514- private static object ? Divide ( object ? left , object ? right ) => ( left , right ) switch
515- {
516- ( int l , int r ) => l / r ,
517- ( float lf , float rf ) => lf / rf ,
518- ( int lInt , float rf ) => lInt / rf ,
519- ( float lf , int rInt ) => lf / rInt ,
520- ( _, _) => throw new Exception ( $ "Cannot divide values of type { left ? . GetType ( ) } and { right ? . GetType ( ) } .")
521- } ;
522-
523- private static object ? Modulus ( object ? left , object ? right ) => ( left , right ) switch
524- {
525- ( int l , int r ) => l % r ,
526- ( float lf , float rf ) => lf % rf ,
527- ( int lInt , float rf ) => lInt % rf ,
528- ( float lf , int rInt ) => lf % rInt ,
529- ( _, _) => throw new Exception ( $ "Cannot modulus values of type { left ? . GetType ( ) } and { right ? . GetType ( ) } .")
530- } ;
517+ private static object ? Modulus ( dynamic left , dynamic right ) => left % right ;
531518
532519
533520
@@ -601,12 +588,61 @@ public CritVisitor(string version)
601588
602589 }
603590
591+ //TODO OPTIMIZE THIS SHIT
592+ private static dynamic TypeDispatcher ( dynamic variable )
593+ {
594+ if ( variable == null ) throw new ArgumentNullException ( nameof ( variable ) ) ;
595+
596+ string variableText = variable . ToString ( ) ! ;
597+
598+ if ( variableText . Contains ( '.' ) || variableText . Contains ( ',' ) )
599+ {
600+ return variableText . Split ( '.' ) [ 0 ] . Length >= 40
601+ ? double . Parse ( variableText , CultureInfo . InvariantCulture )
602+ : float . Parse ( variableText , CultureInfo . InvariantCulture ) ;
603+ }
604+
605+
606+ if ( int . TryParse ( variableText , out int variableTextInt ) )
607+ return variableTextInt ;
608+
609+ if ( long . TryParse ( variableText , out long variableTextLong ) )
610+ return variableTextLong ;
611+
612+ return BigInteger . TryParse ( variableText , out var variableTextBiggie ) ? variableTextBiggie : variable ;
613+
614+ //TODO MAKE A ERROR MESSAGE HERE OF THE TYPE OF VARIABLE
615+ //throw new Exception($"Something when wrong when trying to figure out the type of {variableText}.");
616+ }
617+
604618
605619 public override object ? VisitComparisonExpression ( CritParser . ComparisonExpressionContext context )
606620 {
607621 var left = Visit ( context . expression ( 0 ) ) ;
608622 var right = Visit ( context . expression ( 1 ) ) ;
609623
624+ if ( left is null || right is null ) return null ;
625+
626+ string leftText = left ! . ToString ( ) ! ;
627+ string rightText = right ! . ToString ( ) ! ;
628+
629+ left = TypeDispatcher ( left ) ;
630+ right = TypeDispatcher ( right ) ;
631+
632+
633+
634+
635+ if ( left is BigInteger && right is float or double )
636+ {
637+ object obj = left ; BigInteger biggie = ( BigInteger ) obj ; left = ( double ) biggie ;
638+ }
639+
640+ else if ( right is BigInteger && left is float or double )
641+ {
642+ object obj = right ; BigInteger biggie = ( BigInteger ) obj ; right = ( double ) biggie ;
643+ }
644+
645+
610646 var op = context . compareOp ( ) . GetText ( ) ;
611647
612648 return op switch
@@ -622,97 +658,37 @@ public CritVisitor(string version)
622658 } ;
623659 }
624660
625-
626-
627-
628- private static bool IsEquals ( object ? left , object ? right )
661+ private static bool IsEquals ( dynamic left , dynamic right )
629662 {
630- switch ( left , right )
631- {
632- case ( int l , int r ) :
633- return l == r ;
634- case ( float lf , float rf ) :
635- return lf == rf ;
636- case ( int lInt , float rFloat ) :
637- return lInt == rFloat ;
638- case ( float lFloat , int rInt ) :
639- return lFloat == rInt ;
640- }
641- if ( left is string || right is string )
642- return left ? . ToString ( ) == right ? . ToString ( ) ;
663+
643664
644665 if ( left is bool || right is bool )
645666 return left ? . ToString ( ) == right ? . ToString ( ) ;
646667
647- throw new Exception ( $ "Cannot compare values of type { left ? . GetType ( ) } and { right ? . GetType ( ) } .") ;
648- }
649-
650-
651- private static bool NotEquals ( object ? left , object ? right )
652- {
653- switch ( left , right )
654- {
655- case ( int l , int r ) :
656- return l != r ;
657- case ( float lf , float rf ) :
658- return lf != rf ;
659- case ( int lInt , float rFloat ) :
660- return lInt != rFloat ;
661- case ( float lFloat , int rInt ) :
662- return lFloat != rInt ;
663- }
664-
665668 if ( left is string || right is string )
666- return left ? . ToString ( ) ! = right ? . ToString ( ) ;
669+ return left ? . ToString ( ) = = right ? . ToString ( ) ;
667670
668- throw new Exception ( $ "Cannot compare values of type { left ? . GetType ( ) } and { right ? . GetType ( ) } ." ) ;
671+ return left == right ;
669672 }
670673
671- private static bool GreaterThanOrEqual ( object ? left , object ? right ) => ( left , right ) switch
672- {
673- ( int l , int r ) => l >= r ,
674- ( float lf , float rf ) => lf >= rf ,
675- ( int lInt , float rFloat ) => lInt >= rFloat ,
676- ( float lFloat , int rInt ) => lFloat >= rInt ,
677- _ => throw new Exception ( $ "Cannot compare values of type { left ? . GetType ( ) } and { right ? . GetType ( ) } .") ,
678- } ;
679-
680-
681- private static bool LessThanOrEqual ( object ? left , object ? right ) => ( left , right ) switch
682- {
683- ( int l , int r ) => l <= r ,
684- ( float lf , float rf ) => lf <= rf ,
685- ( int lInt , float rFloat ) => lInt <= rFloat ,
686- ( float lFloat , int rInt ) => lFloat <= rInt ,
687- _ => throw new Exception ( $ "Cannot compare values of type { left ? . GetType ( ) } and { right ? . GetType ( ) } .") ,
688- } ;
689-
690-
691-
692- private static bool GreaterThan ( object ? left , object ? right ) => ( left , right ) switch
693- {
694- ( int l , int r ) => l > r ,
695- ( float lf , float rf ) => lf > rf ,
696- ( int lInt , float rFloat ) => lInt > rFloat ,
697- ( float lFloat , int rInt ) => lFloat > rInt ,
698- _ => throw new Exception ( $ "Cannot compare values of type { left ? . GetType ( ) } and { right ? . GetType ( ) } .") ,
699- } ;
700-
674+ private static bool NotEquals ( dynamic left , dynamic right ) => left != right ;
675+
676+ private static bool GreaterThanOrEqual ( dynamic left , dynamic right ) => left >= right ;
701677
702- private static bool LessThan ( object ? left , object ? right ) => ( left , right ) switch
703- {
704- ( int l , int r ) => l < r ,
705- ( float lf , float rf ) => lf < rf ,
706- ( int lInt , float rFloat ) => lInt < rFloat ,
707- ( float lFloat , int rInt ) => lFloat < rInt ,
708- _ => throw new Exception ( $ "Cannot compare values of type { left ? . GetType ( ) } and { right ? . GetType ( ) } .")
709- } ;
678+ private static bool LessThanOrEqual ( dynamic left , dynamic right ) => left <= right ;
679+
680+ private static bool GreaterThan ( dynamic left , dynamic right ) => left > right ;
681+
682+ private static bool LessThan ( dynamic left , dynamic right ) => left < right ;
710683
711684 private static bool IsTrue ( object ? value ) => value switch
712685 {
713686 bool b => b ,
714687 int i => i != 0 ,
715688 float f => f != 0 ,
689+ long l => l != 0 ,
690+ double d => d != 0 ,
691+ BigInteger bi => bi != 0 ,
716692 string s => s . Length != 0 ,
717693 _ => throw new Exception ( $ "Value is not boolean.")
718694 } ;
0 commit comments