Explorar el Código

fixed + inference.

Nicolas Cannasse hace 19 años
padre
commit
9a9fda914b
Se han modificado 1 ficheros con 49 adiciones y 7 borrados
  1. 49 7
      typer.ml

+ 49 - 7
typer.ml

@@ -594,6 +594,23 @@ let type_field ctx t i p =
 	| t ->
 		no_field()
 
+type type_class =
+	| KInt
+	| KFloat
+	| KString
+	| KUnk
+	| KDyn
+	| KOther
+
+let classify t =
+	match follow t with
+	| TInst ({ cl_path = ([],"Int") },[]) -> KInt
+	| TInst ({ cl_path = ([],"Float") },[]) -> KFloat
+	| TInst ({ cl_path = ([],"String") },[]) -> KString
+	| TMono r when !r = None -> KUnk
+	| TDynamic _ -> KDyn
+	| _ -> KOther
+
 let rec type_binop ctx op e1 e2 p =
 	let e1 = type_expr ctx e1 in
 	let e2 = type_expr ctx e2 in
@@ -601,14 +618,39 @@ let rec type_binop ctx op e1 e2 p =
 	let rec loop op =
 	match op with
 	| OpAdd ->
-		let i1 = is_int e1.etype in
-		let i2 = is_int e2.etype in
-		mk_op (if i1 && i2 then
+		mk_op (match classify e1.etype, classify e2.etype with
+		| KInt , KInt ->
 			t_int ctx
-		else if (i1 || is_float e1.etype) && (i2 || is_float e2.etype) then
-			t_float ctx
-		else
-			t_string ctx)
+		| KFloat , KInt 
+		| KInt, KFloat
+		| KFloat, KFloat ->
+			t_float ctx		
+		| KUnk , KInt
+		| KUnk , KFloat
+		| KUnk , KString  ->
+			unify ctx e1.etype e2.etype e1.epos;
+			e1.etype
+		| KInt , KUnk
+		| KFloat , KUnk 
+		| KString , KUnk ->
+			unify ctx e2.etype e1.etype e2.epos;
+			e2.etype
+		| _ , KString
+		| _ , KDyn ->
+			e2.etype
+		| KString , _
+		| KDyn , _ ->
+			e1.etype
+		| KUnk , KUnk ->
+			let t = t_int ctx in
+			unify ctx e1.etype t e1.epos;
+			unify ctx e2.etype t e2.epos;
+			t
+		| KOther, _
+		| _ , KOther ->
+			let pr = print_context() in
+			error ("Cannot add " ^ s_type pr e1.etype ^ " and " ^ s_type pr e2.etype) p
+		)
 	| OpAnd
 	| OpOr
 	| OpXor