2
0
Эх сурвалжийг харах

give prefix unary operators higher priority than ?:

Nicolas Cannasse 14 жил өмнө
parent
commit
a00889c3ad
5 өөрчлөгдсөн 22 нэмэгдсэн , 2 устгасан
  1. 1 0
      doc/CHANGES.txt
  2. 1 0
      genjs.ml
  3. 2 1
      optimizer.ml
  4. 1 0
      parser.ml
  5. 17 1
      tests/unit/TestOps.hx

+ 1 - 0
doc/CHANGES.txt

@@ -49,6 +49,7 @@
 	flash9 : fixed Xml.nodeValue for comments (does not include <!--/-->)
 	all : added named local functions (allow self-recursion)
 	all : use left-assoc for (==,!=,>,>=,<,<=)(==,!=,>,>=,<,<=) (&&)(&&) and (||)(||)
+	all : give prefix unary operators higher priority than ?:
 
 2010-08-14: 2.06
 	neko : change serializer to be able to handle instances of basic classes from other modules

+ 1 - 0
genjs.ml

@@ -546,6 +546,7 @@ and gen_value ctx e =
 		loop el;
 		v();
 	| TIf (cond,e,eo) ->
+		(* remove parenthesis unless it's an operation with higher precedence than ?: *)
 		let cond = (match cond.eexpr with
 			| TParenthesis { eexpr = TBinop ((Ast.OpAssign | Ast.OpAssignOp _),_,_) } -> cond
 			| TParenthesis e -> e

+ 2 - 1
optimizer.ml

@@ -370,6 +370,7 @@ let standard_precedence op =
 	| OpInterval -> 13, right (* haxe specific *)
 	| OpBoolAnd -> 14, left
 	| OpBoolOr -> 15, left
+	| OpAssignOp OpAssign -> 16, right (* mimics ?: *)
 	| OpAssign | OpAssignOp _ -> 17, right
 
 let sanitize_expr e =
@@ -389,7 +390,7 @@ let sanitize_expr e =
 		let rec loop ee left =
 			match ee.eexpr with
 			| TBinop (op2,_,_) -> if left then not (swap op2 op) else swap op op2
-			| TIf _ -> Parser.is_not_assign op
+			| TIf _ -> if left then not (swap (OpAssignOp OpAssign) op) else swap op (OpAssignOp OpAssign)
 			| TCast (e,None) -> loop e left
 			| _ -> false
 		in		

+ 1 - 0
parser.ml

@@ -99,6 +99,7 @@ let rec make_binop op e ((v,p2) as e2) =
 let rec make_unop op ((v,p2) as e) p1 =
 	match v with
 	| EBinop (bop,e,e2) -> EBinop (bop, make_unop op e p1 , e2) , (punion p1 p2)
+	| ETernary (e1,e2,e3) -> ETernary (make_unop op e1 p1 , e2, e3), punion p1 p2
 	| _ ->
 		EUnop (op,Prefix,e), punion p1 p2
 

+ 17 - 1
tests/unit/TestOps.hx

@@ -57,8 +57,24 @@ class TestOps extends Test {
 		eq( false ? 1 : 6 * 5, 30);
 		eq( (true ? 1 : 6) * 5, 5);
 		eq( (false ? 1 : 6) * 5, 30);
-
+		
+		eq( 1 + (5 == 6 ? 4 : 1), 2 );
+		eq( 1 + 1 == 3 ? 1 : 5, 5 );
+		
+		eq( -3 == 3 ? 0 : 1, 1 );
+		t( !true ? true : true );
+	
+		var k = false;
+		f(k = true ? false : true);
+		f(k);
+		f((k = true) ? false : true);
+		t(k);
+		
 		t( true || false && false );
+		
+		var x = 1;
+		eq( -x++, -1);
+		eq( -x--, -2);
 	}
 
 }