Răsfoiți Sursa

added Codegen.add_field_inits (not called yet)

Simon Krajewski 13 ani în urmă
părinte
comite
463c6c0a6f
2 a modificat fișierele cu 46 adăugiri și 7 ștergeri
  1. 40 0
      codegen.ml
  2. 6 7
      typeload.ml

+ 40 - 0
codegen.ml

@@ -1284,6 +1284,46 @@ let fix_abstract_inheritance com t =
 		) c.cl_ordered_fields
 	| _ -> ()
 
+
+(* -------------------------------------------------------------------------- *)
+(* MEMBER FIELD INIT *)
+
+(*
+	Adds member field initializations as assignments to the constructor
+*)
+let add_field_inits ctx c =
+	let inits = List.filter (fun cf ->
+		match cf.cf_kind,cf.cf_expr with
+		| Var _, Some _ -> true
+		| _ -> false
+	) c.cl_ordered_fields in
+	match inits with
+	| [] -> ()
+	| _ ->
+		let ethis = mk (TConst TThis) t_dynamic c.cl_pos in
+		let el = List.map (fun cf ->
+			match cf.cf_expr with None -> assert false | Some e ->
+				let lhs = mk (TField(ethis,cf.cf_name)) e.etype e.epos in
+				mk (TBinop(OpAssign,lhs,e)) lhs.etype e.epos
+		) inits in
+		let ct = (TFun([],ctx.basic.tvoid)) in
+		match c.cl_constructor with
+			| None ->
+				let ce = mk (TFunction {
+					tf_args = [];
+					tf_type = ctx.basic.tvoid;
+					tf_expr = mk (TBlock el) ctx.basic.tvoid c.cl_pos;
+				}) ct c.cl_pos in
+				let ctor = mk_field "new" ct c.cl_pos in
+				c.cl_constructor <- Some ({ctor with cf_expr = Some ce});
+			| Some cf ->
+				(match cf.cf_expr with
+				| Some({eexpr = TFunction(f)}) ->
+					let bl = match f.tf_expr with {eexpr = TBlock b } -> b | x -> [x] in
+					let ce = mk (TFunction {f with tf_expr = mk (TBlock (el @ bl)) ctx.basic.tvoid c.cl_pos }) cf.cf_type cf.cf_pos in
+					c.cl_constructor <- Some ({cf with cf_expr = Some ce})
+				| _ -> assert false)
+
 (* -------------------------------------------------------------------------- *)
 (* MISC FEATURES *)
 

+ 6 - 7
typeload.ml

@@ -43,13 +43,12 @@ let type_function_param ctx t e opt p =
 	else
 		t, e
 
-let type_static_var ctx t e p =
-	ctx.curfun <- FStatic;
+let type_var_field ctx t e stat p =
+	if stat then ctx.curfun <- FStatic;
 	let e = type_expr_with_type ctx e (Some t) false in
 	unify ctx e.etype t p;
-	(* specific case for UInt statics *)
 	match t with
-	| TType ({ t_path = ([],"UInt") },[]) -> { e with etype = t }
+	| TType ({ t_path = ([],"UInt") },[]) when stat -> { e with etype = t }
 	| _ -> e
 
 let apply_macro ctx mode path el p =
@@ -900,13 +899,12 @@ let init_class ctx c p herits fields =
 		| None ->
 			(fun() -> ())
 		| Some e ->
-			if not stat then error "Member variable initialization is not allowed outside of class constructor" p;
 			let r = exc_protect (fun r ->
 				if not !return_partial_type then begin
 					r := (fun() -> t);
 					if ctx.com.verbose then Common.log ctx.com ("Typing " ^ (if ctx.in_macro then "macro " else "") ^ s_type_path c.cl_path ^ "." ^ cf.cf_name);
 					if not inline then mark_used cf;
-					let e = type_static_var ctx t e p in
+					let e = type_var_field ctx t e stat p in
 					let e = (match cf.cf_kind with
 					| Var { v_read = AccInline } ->
 						let e = ctx.g.do_optimize ctx e in
@@ -947,8 +945,9 @@ let init_class ctx c p herits fields =
 			if override then error "You cannot override variables" p;
 
 			let t = (match t with
+				| None when not stat && e = None ->
+					error ("Type required for member variable " ^ name) p;
 				| None ->
-					if not stat then error ("Type required for member variable " ^ name) p;
 					mk_mono()
 				| Some t ->
 					let old = ctx.type_params in