瀏覽代碼

fixed bugs in for...in optimization with continue.

Nicolas Cannasse 19 年之前
父節點
當前提交
3fbee54431
共有 1 個文件被更改,包括 28 次插入11 次删除
  1. 28 11
      typer.ml

+ 28 - 11
typer.ml

@@ -935,25 +935,42 @@ and type_expr ctx ?(need_val=true) (e,p) =
 		let old_locals = save_locals ctx in
 		let i = add_local ctx i pt in
 		ctx.in_loop <- true;
-		let e2 = type_expr ~need_val:false ctx e2 in
-		ctx.in_loop <- old_loop;
-		old_locals();
-		(match e1.eexpr with
+		let e = (match e1.eexpr with
 		| TNew ({ cl_path = ([],"IntIter") },[],[i1;i2]) -> 
+			let rec loop e =
+				match e.eexpr with
+				| TContinue -> raise Exit
+				| _ -> iter loop e
+			in
+			let max = add_local ctx "max" i2.etype in
+			let n = add_local ctx "n" i1.etype in
+			let e2 = type_expr ~need_val:false ctx e2 in
+			let has_cont = (try loop e2; false with Exit -> true) in
+			let i , block = (if has_cont then begin
+				n , [
+				mk (TVars [i,i1.etype,Some (mk (TLocal n) i1.etype p)]) (t_void ctx) p;
+				mk (TUnop (Increment,Prefix,mk (TLocal n) i1.etype p)) i1.etype p;
+				e2
+			] end else i , [
+				e2;
+				mk (TUnop (Increment,Prefix,mk (TLocal i) i1.etype p)) i1.etype p;
+			]) in
 			let ident = mk (TLocal i) i1.etype p in
 			mk (TBlock [
-				mk (TVars [i,i1.etype,Some i1;"MAX",i2.etype,Some i2]) (t_void ctx) p;
+				mk (TVars [i,i1.etype,Some i1;max,i2.etype,Some i2]) (t_void ctx) p;
 				mk (TWhile (
-					mk (TBinop (OpLt, ident, mk (TLocal "MAX") i2.etype p)) (t_bool ctx) p,
-					mk (TBlock [
-						e2;
-						mk (TUnop (Increment,Prefix,ident)) i1.etype p;
-					]) (t_void ctx) p,
+					mk (TBinop (OpLt, ident, mk (TLocal max) i2.etype p)) (t_bool ctx) p,
+					mk (TBlock block) (t_void ctx) p,
 					NormalWhile
 				)) (t_void ctx) p;
 			]) (t_void ctx) p
 		| _ ->
-			mk (TFor (i,e1,e2)) (t_void ctx) p)
+			let e2 = type_expr ~need_val:false ctx e2 in
+			mk (TFor (i,e1,e2)) (t_void ctx) p
+		) in
+		ctx.in_loop <- old_loop;
+		old_locals();
+		e
 	| EIf (e,e1,e2) ->
 		let e = type_expr ctx e in
 		unify ctx e.etype (t_bool ctx) e.epos;