@@ -716,62 +716,135 @@ def visit_comprehension(self, node):
716
716
self ._unify_collection (element = node .target , collection = node .iter )
717
717
718
718
def visit_builtin_call (self , node ):
719
- if types .is_mono (node .func .type ):
720
- func_name = "function " + node .func .type .find ().name
721
- elif builtins .is_function (node .func .type ):
722
- func_name = node .func .type .find ().name
719
+ typ = node .func .type .find ()
723
720
724
721
def valid_form (signature ):
725
722
return diagnostic .Diagnostic ("note" ,
726
723
"{func} can be invoked as: {signature}" ,
727
- {"func" : func_name },
724
+ {"func" : typ . name , "signature" : signature },
728
725
node .func .loc )
729
726
730
727
def diagnose (valid_forms ):
731
728
diag = diagnostic .Diagnostic ("error" ,
732
729
"{func} cannot be invoked with these arguments" ,
733
- {"func" : func_name },
730
+ {"func" : typ . name },
734
731
node .func .loc , notes = valid_forms )
732
+ self .engine .process (diag )
735
733
736
- if builtins .is_bool ( node . type ):
734
+ if builtins .is_builtin ( typ , "class bool" ):
737
735
valid_forms = lambda : [
738
736
valid_form ("bool() -> bool" ),
739
- valid_form ("bool(x:'a) -> bool where 'a is numeric " )
737
+ valid_form ("bool(x:'a) -> bool" )
740
738
]
741
- elif builtins .is_int (node .type ):
739
+
740
+ if len (node .args ) == 0 and len (node .keywords ) == 0 :
741
+ pass # False
742
+ elif len (node .args ) == 1 and len (node .keywords ) == 0 :
743
+ arg , = node .args
744
+ pass # anything goes
745
+ else :
746
+ diagnose (valid_forms ())
747
+
748
+ self ._unify (node .type , builtins .TBool (),
749
+ node .loc , None )
750
+ elif builtins .is_builtin (typ , "class int" ):
742
751
valid_forms = lambda : [
743
752
valid_form ("int() -> int(width='a)" ),
744
753
valid_form ("int(x:'a) -> int(width='b) where 'a is numeric" ),
745
- valid_form ("int(x:'a, width='b <int literal>) -> int(width='b) where 'a is numeric" )
754
+ valid_form ("int(x:'a, width='b: <int literal>) -> int(width='b) where 'a is numeric" )
746
755
]
747
- elif builtins .is_float (node .type ):
756
+
757
+ self ._unify (node .type , builtins .TInt (),
758
+ node .loc , None )
759
+
760
+ if len (node .args ) == 0 and len (node .keywords ) == 0 :
761
+ pass # 0
762
+ elif len (node .args ) == 1 and len (node .keywords ) == 0 and \
763
+ builtins .is_numeric (node .args [0 ].type ):
764
+ pass
765
+ elif len (node .args ) == 1 and len (node .keywords ) == 1 and \
766
+ builtins .is_numeric (node .args [0 ].type ) and \
767
+ node .keywords [0 ].arg == 'width' :
768
+ width = node .keywords [0 ].value
769
+ if not (isinstance (width , asttyped .NumT ) and isinstance (width .n , int )):
770
+ diag = diagnostic .Diagnostic ("error" ,
771
+ "the width argument of int() must be an integer literal" , {},
772
+ node .keywords [0 ].loc )
773
+
774
+ self ._unify (node .type , builtins .TInt (types .TValue (width .n )),
775
+ node .loc , None )
776
+ else :
777
+ diagnose (valid_forms ())
778
+ elif builtins .is_builtin (typ , "class float" ):
748
779
valid_forms = lambda : [
749
780
valid_form ("float() -> float" ),
750
781
valid_form ("float(x:'a) -> float where 'a is numeric" )
751
782
]
752
- elif builtins .is_list (node .type ):
783
+
784
+ self ._unify (node .type , builtins .TFloat (),
785
+ node .loc , None )
786
+
787
+ if len (node .args ) == 0 and len (node .keywords ) == 0 :
788
+ pass # 0.0
789
+ elif len (node .args ) == 1 and len (node .keywords ) == 0 and \
790
+ builtins .is_numeric (node .args [0 ].type ):
791
+ pass
792
+ else :
793
+ diagnose (valid_forms ())
794
+ elif builtins .is_builtin (typ , "class list" ):
753
795
valid_forms = lambda : [
754
796
valid_form ("list() -> list(elt='a)" ),
755
797
# TODO: add this form when adding iterators
756
798
# valid_form("list(x) -> list(elt='a)")
757
799
]
758
- elif builtins .is_function (node .type , "len" ):
800
+
801
+ self ._unify (node .type , builtins .TList (),
802
+ node .loc , None )
803
+
804
+ if len (node .args ) == 0 and len (node .keywords ) == 0 :
805
+ pass # []
806
+ else :
807
+ diagnose (valid_forms ())
808
+ elif builtins .is_builtin (typ , "function len" ):
759
809
valid_forms = lambda : [
760
810
valid_form ("len(x:list(elt='a)) -> int(width='b)" ),
761
811
]
762
- elif builtins .is_function (node .type , "round" ):
812
+
813
+ # TODO: should be ssize_t-sized
814
+ self ._unify (node .type , builtins .TInt (types .TValue (32 )),
815
+ node .loc , None )
816
+
817
+ if len (node .args ) == 1 and len (node .keywords ) == 0 :
818
+ arg , = node .args
819
+
820
+ self ._unify (arg .type , builtins .TList (),
821
+ arg .loc , None )
822
+ else :
823
+ diagnose (valid_forms ())
824
+ elif builtins .is_builtin (typ , "function round" ):
763
825
valid_forms = lambda : [
764
826
valid_form ("round(x:float) -> int(width='a)" ),
765
827
]
828
+
829
+ self ._unify (node .type , builtins .TInt (),
830
+ node .loc , None )
831
+
832
+ if len (node .args ) == 1 and len (node .keywords ) == 0 :
833
+ arg , = node .args
834
+
835
+ self ._unify (arg .type , builtins .TFloat (),
836
+ arg .loc , None )
837
+ else :
838
+ diagnose (valid_forms ())
766
839
# TODO: add when there are range types
767
- # elif builtins.is_function(node.type , "range"):
840
+ # elif builtins.is_builtin(typ , "function range"):
768
841
# valid_forms = lambda: [
769
842
# valid_form("range(max:'a) -> range(elt='a)"),
770
843
# valid_form("range(min:'a, max:'a) -> range(elt='a)"),
771
844
# valid_form("range(min:'a, max:'a, step:'a) -> range(elt='a)"),
772
845
# ]
773
846
# TODO: add when it is clear what interface syscall() has
774
- # elif builtins.is_function(node.type , "syscall"):
847
+ # elif builtins.is_builtin(typ , "function syscall"):
775
848
# valid_Forms = lambda: [
776
849
# ]
777
850
@@ -790,7 +863,7 @@ def visit_CallT(self, node):
790
863
if types .is_var (node .func .type ):
791
864
return # not enough info yet
792
865
elif types .is_mono (node .func .type ) or types .is_builtin (node .func .type ):
793
- return self .visit_builtin_call (self , node )
866
+ return self .visit_builtin_call (node )
794
867
elif not types .is_function (node .func .type ):
795
868
diag = diagnostic .Diagnostic ("error" ,
796
869
"cannot call this expression of type {type}" ,
0 commit comments