Browse Source

added __setfield.

Nicolas Cannasse 19 năm trước cách đây
mục cha
commit
50f2df9573
1 tập tin đã thay đổi với 12 bổ sung2 xóa
  1. 12 2
      typer.ml

+ 12 - 2
typer.ml

@@ -64,6 +64,7 @@ type access_kind =
 	| AccNo of string
 	| AccExpr of texpr
 	| AccSet of texpr * string * t * string
+	| AccSetField of texpr * string * t
 
 type switch_mode =
 	| CMatch of (string * (string option * t) list option)
@@ -267,7 +268,7 @@ let acc_get g p =
 	match g with
 	| AccNo f -> error ("Field " ^ f ^ " cannot be accessed for reading") p
 	| AccExpr e -> e
-	| AccSet _ -> assert false
+	| AccSet _ | AccSetField _ -> assert false
 
 (** since load_type is used in PASS2 , it cannot access the structure of a type **)
 
@@ -973,8 +974,10 @@ let type_field ctx e i p get =
 			match c.cl_dynamic with
 			| Some t ->
 				let t = apply_params c.cl_types params t in
-				if PMap.mem "__resolve" c.cl_fields then
+				if get && PMap.mem "__resolve" c.cl_fields then
 					AccExpr (mk (TCall (mk (TField (e,"__resolve")) (mk_mono()) p,[type_constant ctx (String i) p])) t p)
+				else if not get && PMap.mem "__setfield" c.cl_fields then
+					AccSetField (e,i,t)
 				else
 					AccExpr (mk (TField (e,i)) t p)
 			| None ->
@@ -1049,6 +1052,9 @@ let rec type_binop ctx op e1 e2 p =
 				error "Assigning a value to itself" p
 			| _ , _ -> ());
 			mk (TBinop (op,e1,e2)) e1.etype p
+		| AccSetField (e,f,t) ->
+			unify ctx e2.etype t p;
+			mk (TCall (mk (TField (e,"__setfield")) (mk_mono()) p,[mk (TConst (TString f)) (mk_mono()) p; e2])) t p
 		| AccSet (e,m,t,_) ->
 			unify ctx e2.etype t p;
 			mk (TCall (mk (TField (e,m)) (mk_mono()) p,[e2])) t p)
@@ -1064,6 +1070,8 @@ let rec type_binop ctx op e1 e2 p =
 				mk (TBinop (OpAssignOp op,e,e2)) e.etype p;
 			| _ ->
 				assert false)
+		| AccSetField _ ->
+			error "This kind of operation is not supported" p
 		| AccSet (e,m,t,f) ->
 			let l = save_locals ctx in
 			let v = gen_local ctx e.etype in
@@ -1193,6 +1201,8 @@ and type_unop ctx op flag e p =
 		| _ -> mk (TUnop (op,flag,e)) t p)
 	| AccNo s ->
 		error ("The field or identifier " ^ s ^ " is not accessible for " ^ (if set then "writing" else "reading")) p
+	| AccSetField _ ->
+		error "This kind of operation is not supported" p
 	| AccSet (e,m,t,f) ->
 		let l = save_locals ctx in
 		let v = gen_local ctx e.etype in