Browse Source

added _hx_mod for more consistent modulo support on PHP target (fixed issue #830)

Simon Krajewski 13 years ago
parent
commit
b94e441635
3 changed files with 32 additions and 1 deletions
  1. 14 0
      genphp.ml
  2. 11 0
      std/php/Boot.hx
  3. 7 1
      tests/unit/TestOps.hx

+ 14 - 0
genphp.ml

@@ -964,6 +964,12 @@ and gen_expr ctx e =
 				gen_field_op ctx e1;
 				) in
 		(match op with
+		| Ast.OpMod ->
+			spr ctx "_hx_mod(";
+			gen_value_op ctx e1;
+			spr ctx ", ";
+			gen_value_op ctx e2;
+			spr ctx ")";
 		| Ast.OpAssign ->
 			(match e1.eexpr with
 			| TArray(te1, te2) when (match te1.eexpr with | TCall _ | TParenthesis _ -> true | _ -> false) ->
@@ -1003,6 +1009,14 @@ and gen_expr ctx e =
 			spr ctx ", ";
 			gen_value_op ctx e2;
 			spr ctx ")";
+		| Ast.OpAssignOp(Ast.OpMod) ->
+			leftside e1;
+			spr ctx " = ";
+			spr ctx "_hx_mod(";
+			gen_value_op ctx e1;
+			spr ctx ", ";
+			gen_value_op ctx e2;
+			spr ctx ")";
 		| Ast.OpAssignOp(_) ->
 			leftsidec e1;
 			print ctx " %s " (Ast.s_binop op);

+ 11 - 0
std/php/Boot.hx

@@ -236,6 +236,17 @@ function _hx_equal($x, $y) {
 	}
 }
 
+function _hx_mod($x, $y) {
+	if (is_int($x) && is_int($y)) {
+		if ($y == 0) return 0;
+		return $x % $y;
+	}
+	if (!is_nan($x) && !is_nan($y) && !is_finite($y) && is_finite($x)) {
+		return $x;
+	} 
+	return fmod($x, $y);
+}
+
 function _hx_error_handler($errno, $errmsg, $filename, $linenum, $vars) {
 	$msg = $errmsg . ' (errno: ' . $errno . ') in ' . $filename . ' at line #' . $linenum;
 	$e = new HException($msg, $errmsg, $errno, _hx_anonymous(array('fileName' => 'Boot.hx', 'lineNumber' => __LINE__, 'className' => 'php.Boot', 'methodName' => '_hx_error_handler')));

+ 7 - 1
tests/unit/TestOps.hx

@@ -59,10 +59,16 @@ class TestOps extends Test {
 		var x = 101.5;
 		x %= 100;
 		eq( x, 1.5);
+		t(Math.isNaN(5.0 % 0.0));
+		t(Math.isNaN(x %= 0.0));
+		#if !macro
+		//t(Math.isNaN(1 % 0));
+		//t(Math.isNaN(0 % 0));
+		t(Math.isNaN(x %= 0));
+		#end
 		var x:Dynamic = [-101.5];
 		x[0] %= 100;
 		eq( x[0], -1.5);
-
 		eq( true ? 1 : 6 * 5, 1);
 		eq( false ? 1 : 6 * 5, 30);
 		eq( (true ? 1 : 6) * 5, 5);