Pārlūkot izejas kodu

[java/cs] Int by Int division is now really a Float operation. Fixes Issue #777

Caue Waneck 13 gadi atpakaļ
vecāks
revīzija
6bac5f255a
3 mainītis faili ar 62 papildinājumiem un 1 dzēšanām
  1. 57 0
      gencommon.ml
  2. 2 0
      gencs.ml
  3. 3 1
      genjava.ml

+ 57 - 0
gencommon.ml

@@ -8465,6 +8465,63 @@ struct
   
 end;;
 
+(* ******************************************* *)
+(* Int Division Synf *)
+(* ******************************************* *)
+
+(*
+  
+  On targets that support int division, this module will force a float division to be performed,
+  so compatibility with current haxe targets is ensured.
+  If catch_int_div is set to true, though, it will look for casts to int or use of Std.int() to optimize
+  this kind of operation.
+  
+  dependencies:
+    since it depends on nothing, but many modules might generate division expressions, 
+    it will be one of the last modules to run
+  
+*)
+
+module IntDivisionSynf =
+struct
+
+  let name = "int_division_synf"
+  
+  let priority = solve_deps name [ DAfter ExpressionUnwrap.priority; DAfter ObjectDeclMap.priority; DAfter ArrayDeclSynf.priority ]
+  
+  let is_int t = match follow t with 
+    | TInst( { cl_path = ([], "Int") }, [] ) -> true
+    | _ -> false
+  
+  let default_implementation gen catch_int_div =
+    let basic = gen.gcon.basic in
+    let rec run e =
+      match e.eexpr with 
+        | TBinop((Ast.OpDiv as op), e1, e2)
+        | TBinop(((Ast.OpAssignOp (Ast.OpDiv)) as op), e1, e2) when is_int e1.etype && is_int e2.etype ->
+          { e with eexpr = TBinop(op, mk_cast basic.tfloat (run e1), run e2) }
+        | TCall(
+            { eexpr = TField( { eexpr = TTypeExpr ( TClassDecl ({ cl_path = ([], "Std") }) ) }, "int") },
+            [ ({ eexpr = TBinop((Ast.OpDiv as op), e1, e2) } as ebinop ) ]
+          )
+        | TCall(
+            { eexpr = TField( { eexpr = TTypeExpr ( TClassDecl ({ cl_path = ([], "Std") }) ) }, "int") },
+            [ ({ eexpr = TBinop(((Ast.OpAssignOp (Ast.OpDiv)) as op), e1, e2) } as ebinop ) ]
+          ) when catch_int_div && is_int e1.etype && is_int e2.etype ->
+          { ebinop with eexpr = TBinop(op, run e1, run e2); etype = basic.tint }
+        | TCast( ({ eexpr = TBinop((Ast.OpDiv as op), e1, e2) } as ebinop ), _ )
+        | TCast( ({ eexpr = TBinop(( (Ast.OpAssignOp Ast.OpDiv) as op), e1, e2) } as ebinop ), _ ) when catch_int_div && is_int e1.etype && is_int e2.etype && is_int e.etype ->
+          { ebinop with eexpr = TBinop(op, run e1, run e2); etype = basic.tint }
+        | _ -> Type.map_expr run e
+    in
+    run
+  
+  let configure gen (mapping_func:texpr->texpr) =
+    let map e = Some(mapping_func e) in
+    gen.gsyntax_filters#add ~name:name ~priority:(PCustom priority) map
+  
+end;;
+
 (*
 (* ******************************************* *)
 (* Example *)

+ 2 - 0
gencs.ml

@@ -1447,6 +1447,8 @@ let configure gen =
   
   ExpressionUnwrap.configure gen (ExpressionUnwrap.traverse gen (fun e -> Some { eexpr = TVars([mk_temp gen "expr" e.etype, Some e]); etype = gen.gcon.basic.tvoid; epos = e.epos }));
   
+  IntDivisionSynf.configure gen (IntDivisionSynf.default_implementation gen true);
+  
   ArrayDeclSynf.configure gen (ArrayDeclSynf.default_implementation gen native_arr_cl);
   
   let goto_special = alloc_var "__goto__" t_dynamic in

+ 3 - 1
genjava.ml

@@ -232,7 +232,7 @@ struct
 
   let name = "java_specific"
   
-  let priority = solve_deps name [ DAfter ExpressionUnwrap.priority; DAfter ObjectDeclMap.priority; DAfter ArrayDeclSynf.priority ]
+  let priority = solve_deps name [ DAfter ExpressionUnwrap.priority; DAfter ObjectDeclMap.priority; DAfter ArrayDeclSynf.priority; DBefore IntDivisionSynf.priority ]
   
   let java_hash s =
     let h = ref Int32.zero in
@@ -1694,6 +1694,8 @@ let configure gen =
   
   ExpressionUnwrap.configure gen (ExpressionUnwrap.traverse gen (fun e -> Some { eexpr = TVars([mk_temp gen "expr" e.etype, Some e]); etype = gen.gcon.basic.tvoid; epos = e.epos }));
   
+  IntDivisionSynf.configure gen (IntDivisionSynf.default_implementation gen true);
+  
   UnreachableCodeEliminationSynf.configure gen (UnreachableCodeEliminationSynf.traverse gen true);
   
   ArrayDeclSynf.configure gen (ArrayDeclSynf.default_implementation gen native_arr_cl);