瀏覽代碼

change DTSwitch structure to have explicit default case

Simon Krajewski 12 年之前
父節點
當前提交
779c2abb9e
共有 7 個文件被更改,包括 39 次插入43 次删除
  1. 0 1
      ast.ml
  2. 15 17
      codegen.ml
  3. 0 1
      common.ml
  4. 4 11
      genneko.ml
  5. 6 5
      matcher.ml
  6. 11 7
      type.ml
  7. 3 1
      typeload.ml

+ 0 - 1
ast.ml

@@ -85,7 +85,6 @@ module Meta = struct
 		| Meta
 		| Macro
 		| MaybeUsed
-		| MatchAny
 		| MultiType
 		| Native
 		| NativeGen

+ 15 - 17
codegen.ml

@@ -934,12 +934,13 @@ let rec local_usage f e =
 				local_usage f e;
 				fdt dt1;
 				(match dt2 with None -> () | Some dt -> fdt dt)
-			| DTSwitch(e,cl) ->
+			| DTSwitch(e,cl,dto) ->
 				local_usage f e;
 				List.iter (fun (e,dt) ->
 					local_usage f e;
 					fdt dt
-				) cl
+				) cl;
+				(match dto with None -> () | Some dt -> fdt dt)
 			| DTGoto _ -> ()
 		in
 		Array.iter fdt dt.dt_dt_lookup
@@ -1259,13 +1260,17 @@ let rename_local_vars com e =
 			) catchs;
 		| TPatMatch dt ->
 			let rec fdt dt = match dt with
-				| DTSwitch(e,cl) ->
+				| DTSwitch(e,cl,dto) ->
 					loop e;
 					List.iter (fun (_,dt) ->
 						let old = save() in
 						fdt dt;
 						old();
 					) cl;
+					(match dto with None -> () | Some dt ->
+						let old = save() in
+						fdt dt;
+						old())
 				| DTBind(bl,dt) ->
 					List.iter (fun ((v,p),e) ->
 						declare v e.epos
@@ -1400,9 +1405,10 @@ let check_local_vars_init e =
 					loop vars e;
 					restore vars old [];
 					cvars := !vars :: !cvars
-				| DTSwitch(e,cl) ->
+				| DTSwitch(e,cl,dto) ->
 					loop vars e;
-					List.iter (fun (_,dt) -> fdt dt) cl
+					List.iter (fun (_,dt) -> fdt dt) cl;
+					(match dto with None -> () | Some dt -> fdt dt)
 				| DTGuard(e,dt1,dt2) ->
 					fdt dt1;
 					(match dt2 with None -> () | Some dt -> fdt dt)
@@ -1618,19 +1624,11 @@ module PatternMatchConversion = struct
 		| DTGuard(e,dt1,dt2) ->
 			let ethen = convert_dt cctx dt1 in
 			mk (TIf(e,ethen,match dt2 with None -> None | Some dt -> Some (convert_dt cctx dt))) ethen.etype (punion e.epos ethen.epos)
-		| DTSwitch(e_st,cl) ->
-			let def = ref None in
-			let cases = List.filter (fun (e,dt) ->
- 				match e.eexpr with
- 				| TMeta((Meta.MatchAny,_,_),_) ->
-					def := Some (convert_dt cctx dt);
-					false
-				| _ ->
-					true
-			) cl in
-			let cases = group_cases cases in
+		| DTSwitch(e_st,cl,dto) ->
+			let def = match dto with None -> None | Some dt -> Some (convert_dt cctx dt) in
+			let cases = group_cases cl in
 			let cases = List.map (fun (cl,dt) -> cl,convert_dt cctx dt) cases in
-			mk (TSwitch(e_st,cases,!def)) (mk_mono()) e_st.epos
+			mk (TSwitch(e_st,cases,def)) (mk_mono()) e_st.epos
 
 	let to_typed_ast ctx dt p =
 		let first = dt.dt_dt_lookup.(dt.dt_first) in

+ 0 - 1
common.ml

@@ -344,7 +344,6 @@ module MetaInfo = struct
 		| Meta -> ":meta",("Internally used to mark a class field as being the metadata field",[])
 		| Macro -> ":macro",("(deprecated)",[])
 		| MaybeUsed -> ":maybeUsed",("Internally used by DCE to mark fields that might be kept",[Internal])
-		| MatchAny -> ":matchAny",("Internally used to mark the default case when pattern matching",[Internal])
 		| MultiType -> ":multiType",("Specifies that an abstract chooses its this-type from its @:to functions",[UsedOn TAbstract])
 		| Native -> ":native",("Rewrites the path of a class or enum during generation",[HasParam "Output type path";UsedOnEither [TClass;TEnum]])
 		| NativeGen -> ":nativeGen",("Annotates that a type should be treated as if it were an extern definition - platform native",[Platforms [Java;Cs]; UsedOnEither[TClass;TEnum]])

+ 4 - 11
genneko.ml

@@ -409,19 +409,12 @@ and gen_expr ctx e =
 					| Some dt -> (EIf (gen_expr ctx e,loop dt1,Some (loop dt)),p)
 				in
 				(match get_locals e with [] -> eg | el -> EBlock [(EVars(el),p);eg],p)
-			| DTSwitch (e,cl) ->
+			| DTSwitch (e,cl,dto) ->
 				let e = gen_expr ctx e in
-				let def = ref None in
-				let cases = ExtList.List.filter_map (fun (e,dt) ->
-					match e.eexpr with
-	 				| TMeta((Meta.MatchAny,_,_),_) ->
-						def := Some (loop dt);
-						None
-					| _ ->
-						Some (gen_expr ctx e,loop dt)
-				) cl in
+				let def = match dto with None -> None | Some dt -> Some (loop dt) in
+				let cases = List.map (fun (e,dt) -> gen_expr ctx e,loop dt) cl in
 				EBlock [
-					(ESwitch (e,cases,!def),p);
+					(ESwitch (e,cases,def),p);
 					goto num_labels;
 				],p
 		in

+ 6 - 5
matcher.ml

@@ -899,10 +899,7 @@ let convert_con ctx con = match con.c_def with
 	| CExpr e -> e
 	| CEnum(e,ef) -> mk_const ctx con.c_pos (TInt (Int32.of_int ef.ef_index))
 	| CArray i -> mk_const ctx con.c_pos (TInt (Int32.of_int i))
-	| CAny ->
-		let t = mk_mono() in
-		mk (TMeta((Meta.MatchAny,[],con.c_pos),mk (TConst (TNull)) t con.c_pos)) t con.c_pos
-	| CFields _ -> assert false
+	| CAny | CFields _ -> assert false
 
 let convert_switch ctx st cases loop =
 	let e_st = convert_st ctx st in
@@ -926,17 +923,21 @@ let convert_switch ctx st cases loop =
 		e_st
 	in
 	let null = ref None in
+	let def = ref None in
 	let cases = List.filter (fun (con,dt) ->
 		match con.c_def with
 		| CConst TNull ->
 			null := Some (loop dt);
 			false
+		| CAny ->
+			def := Some (loop dt);
+			false
 		| _ ->
 			true
 	) cases in
 	let dt = match cases with
 		| [{c_def = CFields _},dt] -> loop dt
-		| _ -> DTSwitch(e, List.map (fun (c,dt) -> convert_con ctx c, loop dt) cases)
+		| _ -> DTSwitch(e, List.map (fun (c,dt) -> convert_con ctx c, loop dt) cases, !def)
 	in
 	match !null with
 	| None -> dt

+ 11 - 7
type.ml

@@ -293,7 +293,7 @@ and module_kind =
 	| MFake
 
 and dt =
-	| DTSwitch of texpr * (texpr * dt) list
+	| DTSwitch of texpr * (texpr * dt) list * dt option
 	| DTBind of ((tvar * pos) * texpr) list * dt
 	| DTGoto of int
 	| DTExpr of texpr
@@ -1287,7 +1287,9 @@ and unify_with_access t1 f2 =
 
 let iter_dt f dt = match dt with
 	| DTBind(_,dt) -> f dt
-	| DTSwitch(_,cl) -> List.iter (fun (_,dt) -> f dt) cl
+	| DTSwitch(_,cl,dto) ->
+		List.iter (fun (_,dt) -> f dt) cl;
+		(match dto with None -> () | Some dt -> f dt)
 	| DTGuard(_,dt1,dt2) ->
 		f dt1;
 		(match dt2 with None -> () | Some dt -> f dt)
@@ -1340,12 +1342,13 @@ let iter f e =
 		let rec loop dt = match dt with
 			| DTBind(_,dt) -> loop dt
 			| DTGoto _ -> ()
-			| DTSwitch(e,cl) ->
+			| DTSwitch(e,cl,dto) ->
 				f e;
 				List.iter (fun (e,dt) ->
 					f e;
 					loop dt
-				) cl
+				) cl;
+				(match dto with None -> () | Some dt -> loop dt)
 			| DTExpr e -> f e
 			| DTGuard(eg,dt1,dt2) ->
 				f eg;
@@ -1408,7 +1411,7 @@ let map_expr f e =
 		let rec loop dt = match dt with
 			| DTBind(vl,dt) -> DTBind(vl, loop dt)
 			| DTGoto _ -> dt
-			| DTSwitch(e,cl) -> DTSwitch(f e, List.map (fun (e,dt) -> f e,loop dt) cl)
+			| DTSwitch(e,cl,dto) -> DTSwitch(f e, List.map (fun (e,dt) -> f e,loop dt) cl,match dto with None -> None | Some dt -> Some (loop dt))
 			| DTExpr e -> DTExpr(f e)
 			| DTGuard(e,dt1,dt2) -> DTGuard(f e,loop dt1,match dt2 with None -> None | Some dt -> Some (loop dt))
 		in
@@ -1480,7 +1483,7 @@ let map_expr_type f ft fv e =
 		let rec loop dt = match dt with
 			| DTBind(vl,dt) -> DTBind(vl, loop dt)
 			| DTGoto _ -> dt
-			| DTSwitch(e,cl) -> DTSwitch(f e, List.map (fun (e,dt) -> f e,loop dt) cl)
+			| DTSwitch(e,cl,dto) -> DTSwitch(f e, List.map (fun (e,dt) -> f e,loop dt) cl,match dto with None -> None | Some dt -> Some (loop dt))
 			| DTExpr e -> DTExpr(f e)
 			| DTGuard (e,dt1,dt2) -> DTGuard(f e, loop dt, match dt2 with None -> None | Some dt -> Some (loop dt))
 		in
@@ -1617,11 +1620,12 @@ let rec s_expr s_type e =
 and s_dt tabs tree =
 	let s_type = s_type (print_context()) in
 	tabs ^ match tree with
-	| DTSwitch (st, cl) ->
+	| DTSwitch (st,cl,dto) ->
 		"switch(" ^ (s_expr s_type st) ^ ") { \n" ^ tabs
 		^ (String.concat ("\n" ^ tabs) (List.map (fun (c,dt) ->
 			"case " ^ (s_expr s_type c) ^ ":\n" ^ (s_dt (tabs ^ "\t") dt)
 		) cl))
+		^ (match dto with None -> "" | Some dt -> tabs ^ "default: " ^ (s_dt (tabs ^ "\t") dt))
 		^ "\n" ^ (if String.length tabs = 0 then "" else (String.sub tabs 0 (String.length tabs - 1))) ^ "}"
 	| DTBind (bl, dt) -> "bind " ^ (String.concat "," (List.map (fun ((v,_),st) -> v.v_name ^ "(" ^ (string_of_int v.v_id) ^ ") =" ^ (s_expr s_type st)) bl)) ^ "\n" ^ (s_dt tabs dt)
 	| DTGoto i ->

+ 3 - 1
typeload.ml

@@ -891,7 +891,9 @@ let rec return_flow ctx e =
 				loop dt1;
 				(match dt2 with None -> () | Some dt -> loop dt)
 			| DTBind (_,d) -> loop d
-			| DTSwitch (_,cl) -> List.iter (fun (_,dt) -> loop dt) cl
+			| DTSwitch (_,cl,dto) ->
+				List.iter (fun (_,dt) -> loop dt) cl;
+				(match dto with None -> () | Some dt -> loop dt)
 			| DTGoto i -> loop (dt.dt_dt_lookup.(i))
 		in
 		loop (dt.dt_dt_lookup.(dt.dt_first))