Browse Source

allow numerical operations on type parameters constraint by Float

Nicolas Cannasse 17 years ago
parent
commit
d96942b1e1
2 changed files with 36 additions and 8 deletions
  1. 1 0
      doc/CHANGES.txt
  2. 35 8
      typer.ml

+ 1 - 0
doc/CHANGES.txt

@@ -26,6 +26,7 @@ TODO inlining : substitute class+function type parameters in order to have fully
 	fixed completion for packages starting with 'a' or 'z'
 	fixed completion for packages starting with 'a' or 'z'
 	added flash9.Lib.as
 	added flash9.Lib.as
 	prevent double Movieclip class declaration when linking flash9 lib
 	prevent double Movieclip class declaration when linking flash9 lib
+	allow numerical operations on type parameters constraint by Float
 
 
 2008-02-23: 1.18
 2008-02-23: 1.18
 	some optimization and bugfix for as3 codegen
 	some optimization and bugfix for as3 codegen

+ 35 - 8
typer.ml

@@ -1292,12 +1292,14 @@ type type_class =
 	| KUnk
 	| KUnk
 	| KDyn
 	| KDyn
 	| KOther
 	| KOther
+	| KParam of t
 
 
 let classify t =
 let classify t =
 	match follow t with
 	match follow t with
 	| TInst ({ cl_path = ([],"Int") },[]) -> KInt
 	| TInst ({ cl_path = ([],"Int") },[]) -> KInt
 	| TInst ({ cl_path = ([],"Float") },[]) -> KFloat
 	| TInst ({ cl_path = ([],"Float") },[]) -> KFloat
 	| TInst ({ cl_path = ([],"String") },[]) -> KString
 	| TInst ({ cl_path = ([],"String") },[]) -> KString
+	| TInst ({ cl_kind = KTypeParameter; cl_implements = [{ cl_path = ([],"Float")},[]] },[]) -> KParam t
 	| TMono r when !r = None -> KUnk
 	| TMono r when !r = None -> KUnk
 	| TDynamic _ -> KDyn
 	| TDynamic _ -> KDyn
 	| _ -> KOther
 	| _ -> KOther
@@ -1387,6 +1389,14 @@ let rec type_binop ctx op e1 e2 p =
 			unify ctx e1.etype t e1.epos;
 			unify ctx e1.etype t e1.epos;
 			unify ctx e2.etype t e2.epos;
 			unify ctx e2.etype t e2.epos;
 			t
 			t
+		| KParam t1, KParam t2 when t1 == t2 ->
+			t1
+		| KParam t, KInt | KInt, KParam t ->
+			t
+		| KParam _, KFloat | KFloat, KParam _ | KParam _, KParam _ ->
+			t_float ctx
+		| KParam _, _
+		| _, KParam _
 		| KOther, _
 		| KOther, _
 		| _ , KOther ->
 		| _ , KOther ->
 			let pr = print_context() in
 			let pr = print_context() in
@@ -1407,14 +1417,28 @@ let rec type_binop ctx op e1 e2 p =
 	| OpDiv
 	| OpDiv
 	| OpSub ->
 	| OpSub ->
 		let i = t_int ctx in
 		let i = t_int ctx in
-		let f1 = is_float e1.etype in
-		let f2 = is_float e2.etype in
-		if not f1 then unify ctx e1.etype i e1.epos;
-		if not f2 then unify ctx e2.etype i e2.epos;
-		if op <> OpDiv && not f1 && not f2 then
-			mk_op i
-		else
-			mk_op (t_float ctx)
+		let result = ref (if op = OpDiv then t_float ctx else i) in
+		(match classify e1.etype, classify e2.etype with
+		| KFloat, KFloat ->
+			result := t_float ctx
+		| KParam t1, KParam t2 when t1 == t2 ->
+			if op <> OpDiv then result := t1
+		| KParam _, KParam _ ->
+			result := t_float ctx
+		| KParam t, KInt | KInt, KParam t ->
+			if op <> OpDiv then result := t
+		| KParam _, KFloat | KFloat, KParam _ ->
+			result := t_float ctx
+		| KFloat, _ ->
+			unify ctx e2.etype i e2.epos;
+			result := t_float ctx
+		| _, KFloat ->
+			unify ctx e1.etype i e1.epos;
+			result := t_float ctx
+		| _ , _ ->
+			unify ctx e1.etype i e1.epos;
+			unify ctx e2.etype i e2.epos);
+		mk_op !result
 	| OpEq
 	| OpEq
 	| OpPhysEq
 	| OpPhysEq
 	| OpPhysNotEq
 	| OpPhysNotEq
@@ -1439,12 +1463,15 @@ let rec type_binop ctx op e1 e2 p =
 		| KDyn , KInt | KDyn , KFloat | KDyn , KString -> ()
 		| KDyn , KInt | KDyn , KFloat | KDyn , KString -> ()
 		| KInt , KDyn | KFloat , KDyn | KString , KDyn -> ()
 		| KInt , KDyn | KFloat , KDyn | KString , KDyn -> ()
 		| KDyn , KDyn -> ()
 		| KDyn , KDyn -> ()
+		| KParam _ , x | x , KParam _ when x <> KString && x <> KOther -> ()
 		| KDyn , KUnk
 		| KDyn , KUnk
 		| KUnk , KDyn
 		| KUnk , KDyn
 		| KString , KInt
 		| KString , KInt
 		| KString , KFloat
 		| KString , KFloat
 		| KInt , KString
 		| KInt , KString
 		| KFloat , KString
 		| KFloat , KString
+		| KParam _ , _
+		| _ , KParam _
 		| KOther , _
 		| KOther , _
 		| _ , KOther ->
 		| _ , KOther ->
 			let pr = print_context() in
 			let pr = print_context() in