Browse Source

more sanitize/beautify

Nicolas Cannasse 14 years ago
parent
commit
995a1dc12f
5 changed files with 78 additions and 72 deletions
  1. 40 30
      genjs.ml
  2. 33 20
      optimizer.ml
  3. 2 8
      std/js/_std/Hash.hx
  4. 1 4
      std/js/_std/IntHash.hx
  5. 2 10
      std/js/_std/Reflect.hx

+ 40 - 30
genjs.ml

@@ -71,6 +71,11 @@ let newline ctx =
 	| '}' | '{' | ':' when not ctx.separator -> print ctx "\n%s" ctx.tabs	
 	| _ -> print ctx ";\n%s" ctx.tabs
 
+let semicolon ctx =	
+	match Buffer.nth ctx.buf (Buffer.length ctx.buf - 1) with
+	| '}' when not ctx.separator -> ()
+	| _ -> spr ctx ";"
+
 let rec concat ctx s f = function
 	| [] -> ()
 	| [x] -> f x
@@ -89,12 +94,7 @@ let fun_block ctx f p =
 	if ctx.com.debug then
 		Codegen.stack_block ctx.stack ctx.current (fst ctx.curmethod) e
 	else
-		mk_block e
-
-let parent e =
-	match e.eexpr with
-	| TParenthesis _ -> e
-	| _ -> mk (TParenthesis e) e.etype e.epos
+		e
 
 let open_block ctx =
 	let oldt = ctx.tabs in
@@ -298,14 +298,14 @@ and gen_expr ctx e =
 		spr ctx ")"
 	| TIf (cond,e,eelse) ->
 		spr ctx "if";
-		gen_value ctx (parent cond);
+		gen_value ctx cond;
 		spr ctx " ";
 		gen_expr ctx e;
 		(match eelse with
 		| None -> ()
 		| Some e ->
-			newline ctx;
-			spr ctx "else ";
+			semicolon ctx;
+			spr ctx " else ";
 			gen_expr ctx e);
 	| TUnop (op,Ast.Prefix,e) ->
 		spr ctx (Ast.s_unop op);
@@ -316,7 +316,7 @@ and gen_expr ctx e =
 	| TWhile (cond,e,Ast.NormalWhile) ->
 		let handle_break = handle_break ctx e in
 		spr ctx "while";
-		gen_value ctx (parent cond);
+		gen_value ctx cond;
 		spr ctx " ";
 		gen_expr ctx e;
 		handle_break();
@@ -325,7 +325,7 @@ and gen_expr ctx e =
 		spr ctx "do ";
 		gen_expr ctx e;
 		spr ctx " while";
-		gen_value ctx (parent cond);
+		gen_value ctx cond;
 		handle_break();
 	| TObjectDecl fields ->
 		spr ctx "{ ";
@@ -356,14 +356,13 @@ and gen_expr ctx e =
 		handle_break();
 	| TTry (e,catchs) ->
 		spr ctx "try ";
-		gen_expr ctx (mk_block e);
-		newline ctx;
+		gen_expr ctx e;
 		let vname = (match catchs with [(v,_,_)] -> v | _ ->
 			let id = ctx.id_counter in
 			ctx.id_counter <- ctx.id_counter + 1;
 			"$e" ^ string_of_int id
 		) in
-		print ctx "catch( %s ) {" vname;
+		print ctx " catch( %s ) {" vname;
 		let bend = open_block ctx in
 		let last = ref false in
 		List.iter (fun (v,t,e) ->
@@ -411,10 +410,23 @@ and gen_expr ctx e =
 		newline ctx;
 		spr ctx "}";
 	| TMatch (e,(estruct,_),cases,def) ->
-		spr ctx "var $e = ";
-		gen_value ctx e;
-		newline ctx;
-		spr ctx "switch( $e[1] ) {";
+		let evar = (if List.for_all (fun (_,pl,_) -> pl = None) cases then begin
+			spr ctx "switch( ";
+			gen_value ctx (if Optimizer.need_parent e then Codegen.mk_parent e else e);
+			spr ctx "[1] ) {";
+			"???"
+		end else begin
+			let v = (match e.eexpr with
+				| TLocal v -> v
+				| _ ->
+					spr ctx "var $e = ";
+					gen_value ctx e;
+					newline ctx;
+					"$e"
+			) in
+			print ctx "switch( %s[1] ) {" v;
+			v
+		end) in
 		List.iter (fun (cl,params,e) ->
 			List.iter (fun c ->
 				newline ctx;
@@ -422,18 +434,15 @@ and gen_expr ctx e =
 			) cl;
 			let bend = open_block ctx in
 			(match params with
-			| None | Some [] -> ()
+			| None -> ()
 			| Some l ->
 				let n = ref 1 in
 				let l = List.fold_left (fun acc (v,_) -> incr n; match v with None -> acc | Some v -> (v,!n) :: acc) [] l in
-				match l with
-				| [] -> ()
-				| l ->
-					newline ctx;
-					spr ctx "var ";
-					concat ctx ", " (fun (v,n) ->
-						print ctx "%s = $e[%d]" v n;
-					) l);
+				newline ctx;
+				spr ctx "var ";
+				concat ctx ", " (fun (v,n) ->
+					print ctx "%s = %s[%d]" v evar n;
+				) l);
 			gen_block ctx e;
 			if not (has_return e) then begin
 				newline ctx;
@@ -454,7 +463,7 @@ and gen_expr ctx e =
 		spr ctx "}"
 	| TSwitch (e,cases,def) ->
 		spr ctx "switch";
-		gen_value ctx (parent e);
+		gen_value ctx e;
 		spr ctx " {";
 		newline ctx;
 		List.iter (fun (el,e2) ->
@@ -608,8 +617,9 @@ and gen_value ctx e =
 		v()
 	| TTry (b,catchs) ->
 		let v = value true in
-		gen_expr ctx (mk (TTry (assign b,
-			List.map (fun (v,t,e) -> v, t , assign e) catchs
+		let block e = mk (TBlock [e]) e.etype e.epos in
+		gen_expr ctx (mk (TTry (block (assign b),
+			List.map (fun (v,t,e) -> v, t , block (assign e)) catchs
 		)) e.etype e.epos);
 		v()
 

+ 33 - 20
optimizer.ml

@@ -373,24 +373,39 @@ let standard_precedence op =
 	| OpAssignOp OpAssign -> 16, right (* mimics ?: *)
 	| OpAssign | OpAssignOp _ -> 17, right
 
+let need_parent e =
+	match e.eexpr with
+	| TConst _ | TLocal _ | TEnumField _ | TArray _ | TField _ | TParenthesis _ | TCall _ | TClosure _ | TNew _ | TTypeExpr _ | TObjectDecl _ | TArrayDecl _ -> false
+	| TCast _ | TThrow _ | TReturn _ | TTry _ | TMatch _ | TSwitch _ | TFor _ | TIf _ | TWhile _ | TBinop _ | TContinue | TBreak
+	| TBlock _ | TVars _ | TFunction _ | TUnop _ -> true
+
 let sanitize_expr e =
 	let parent e =
-		mk (TParenthesis e) e.etype e.epos
+		match e.eexpr with
+		| TParenthesis _ -> e
+		| _ -> mk (TParenthesis e) e.etype e.epos
 	in
 	let block e =
-		mk (TBlock [e]) e.etype e.epos
+		match e.eexpr with
+		| TBlock _ -> e
+		| _ -> mk (TBlock [e]) e.etype e.epos
 	in
 	let complex e =
 		(* complex expressions are the one that once generated to source consists in several expressions *)
 		match e.eexpr with
-		| TFor _ -> block e (* a temp var is needed for holding iterator *)
+		| TFor _ (* a temp var is needed for holding iterator *)
+		| TMatch _ (* a temp var is needed for holding enum *)
+		| TCall ({ eexpr = TLocal "__js__" },_) (* we never know *)
+			-> block e
 		| _ -> e
 	in
-	let need_parent e =
+	(* tells if the printed expresssion ends with an if without else *)
+	let rec has_if e =
 		match e.eexpr with
-		| TConst _ | TLocal _ | TEnumField _ | TArray _ | TField _ | TParenthesis _ | TCall _ | TClosure _ | TNew _ | TTypeExpr _ | TObjectDecl _ | TArrayDecl _ -> false
-		| TCast _ | TThrow _ | TReturn _ | TTry _ | TMatch _ | TSwitch _ | TFor _ | TIf _ | TWhile _ | TBinop _ | TContinue | TBreak
-		| TBlock _ | TVars _ | TFunction _ | TUnop _ -> true
+		| TIf (_,_,None) -> true
+		| TWhile (_,e,NormalWhile) -> has_if e
+		| TFor (_,_,_,e) -> has_if e
+		| _ -> false
 	in
 	match e.eexpr with
 	| TBinop (op,e1,e2) ->
@@ -418,21 +433,12 @@ let sanitize_expr e =
 		in
 		{ e with eexpr = TUnop (op,mode,loop e2) }
 	| TIf (e1,e2,eelse) ->
-		let e1 = (match e1.eexpr with
-			| TParenthesis _ -> e1
-			| _ -> parent e1
-		) in
-		let e2 = (match e2.eexpr, eelse with
-			| TIf (_,_,Some _) , _ | TIf (_,_,None), Some _ -> block e2
-			| _ -> complex e2
-		) in
+		let e1 = parent e1 in
+		let e2 = (if (eelse <> None && has_if e2) || (match e2.eexpr with TIf _ -> true | _ -> false) then block e2 else complex e2) in
 		let eelse = (match eelse with None -> None | Some e -> Some (complex e)) in
 		{ e with eexpr = TIf (e1,e2,eelse) }
 	| TWhile (e1,e2,flag) ->
-		let e1 = (match e1.eexpr with
-			| TParenthesis _ -> e1
-			| _ -> parent e1
-		) in
+		let e1 = parent e1 in
 		let e2 = complex e2 in
 		{ e with eexpr = TWhile (e1,e2,flag) }
 	| TFor (v,t,e1,e2) ->
@@ -448,6 +454,13 @@ let sanitize_expr e =
 		if need_parent e2 then { e with eexpr = TField(parent e2,f) } else e
 	| TArray (e1,e2) ->
 		if need_parent e1 then { e with eexpr = TArray(parent e1,e2) } else e
+	| TTry (e1,catches) ->
+		let e1 = block e1 in
+		let catches = List.map (fun (v,t,e) -> v, t, block e) catches in
+		{ e with eexpr = TTry (e1,catches) }
+	| TSwitch (e1,cases,def) ->
+		let e1 = parent e1 in
+		{ e with eexpr = TSwitch (e1,cases,def) }
 	| _ ->
 		e
 
@@ -462,7 +475,7 @@ let reduce_expr ctx e =
 			) cl
 		) cases;
 		e
-	| TBlock [{ eexpr = TConst _ } as ec] ->
+	| TBlock [ec] ->
 		{ ec with epos = e.epos }
 	| TParenthesis ec ->
 		{ ec with epos = e.epos }

+ 2 - 8
std/js/_std/Hash.hx

@@ -50,10 +50,7 @@
 			key = "$"+key;
 			return untyped this.hasOwnProperty.call(h,key);
 		}catch(e:Dynamic){
-			untyped __js__("
-				for(var i in this.h)
-					if( i == key ) return true;
-			");
+			untyped __js__("for(var i in this.h) if( i == key ) return true");
 			return false;
 		}
 	}
@@ -67,10 +64,7 @@
 
 	public function keys() : Iterator<String> {
 		var a = new Array<String>();
-		untyped __js__("
-			for(var i in this.h)
-				a.push(i.substr(1));
-		");
+		untyped __js__("for(var i in this.h) a.push(i.substr(1))");
 		return a.iterator();
 	}
 

+ 1 - 4
std/js/_std/IntHash.hx

@@ -55,10 +55,7 @@
 
 	public function keys() : Iterator<Int> {
 		var a = new Array();
-		untyped __js__("
-			for( x in this.h )
-				a.push(x);
-		");
+		untyped __js__("for( x in this.h ) a.push(x)");
 		return a.iterator();
 	}
 

+ 2 - 10
std/js/_std/Reflect.hx

@@ -55,21 +55,13 @@
 		if( o == null ) return new Array();
 		var a = new Array();
 		if( o.hasOwnProperty ) {
-			__js__("
-				for(var i in o)
-					if( o.hasOwnProperty(i) )
-						a.push(i);
-			");
+			__js__("for(var i in o) if( o.hasOwnProperty(i) ) a.push(i)");
 		} else {
 			var t;
 			try{ t = o.__proto__; } catch( e : Dynamic ) { t = null; }
 			if( t != null )
 				o.__proto__ = null;
-			__js__("
-				for(var i in o)
-					if( i != \"__proto__\" )
-						a.push(i);
-			");
+			__js__("for(var i in o) if( i != \"__proto__\" ) a.push(i)");
 			if( t != null )
 				o.__proto__ = t;
 		}