|
@@ -1824,16 +1824,35 @@ and type_expr ctx ?(need_val=true) (e,p) =
|
|
|
etype = mk_mono();
|
|
|
epos = e.epos;
|
|
|
}
|
|
|
- | ECast (e,t) ->
|
|
|
- match t with
|
|
|
- | None ->
|
|
|
- let e = type_expr ctx e in
|
|
|
- { e with etype = mk_mono() }
|
|
|
- | Some t ->
|
|
|
- type_expr ctx (ETry ((EThrow e,p),[
|
|
|
- ("e",t,(EConst (Ident "e"),p));
|
|
|
- ("e",TPNormal { tpackage = []; tname = "Dynamic"; tparams = [] },(EThrow (EConst (String "Class cast error"),p),p))
|
|
|
- ]),p)
|
|
|
+ | ECast (e,None) ->
|
|
|
+ let e = type_expr ctx e in
|
|
|
+ { e with etype = mk_mono() }
|
|
|
+ | ECast (e, Some t) ->
|
|
|
+ (* // if( Std.is(tmp,T) ) tmp else throw "Class cast error" *)
|
|
|
+ let etmp = (EConst (Ident "tmp"),p) in
|
|
|
+ let t = load_type ctx (pos e) t in
|
|
|
+ let tname = (match follow t with
|
|
|
+ | TInst (_,params) | TEnum (_,params) ->
|
|
|
+ List.iter (fun (_,pt) ->
|
|
|
+ if pt != t_dynamic then error "Cast class parameter must be Dynamic" p;
|
|
|
+ ) params;
|
|
|
+ (match follow t with
|
|
|
+ | TInst (c,_) -> c.cl_path
|
|
|
+ | TEnum (e,_) -> e.e_path
|
|
|
+ | _ -> assert false);
|
|
|
+ | _ ->
|
|
|
+ error "Cast type must be a class" p
|
|
|
+ ) in
|
|
|
+ let make_type (path,name) =
|
|
|
+ match path with
|
|
|
+ | [] -> (EConst (Type name),p)
|
|
|
+ | x :: path -> (EType (List.fold_left (fun acc x -> (EField (acc,x),p)) (EConst (Ident x),p) path,name),p)
|
|
|
+ in
|
|
|
+ let cond = (ECall ((EField ((EConst (Type "Std"),p),"is"),p),[etmp;make_type tname]),p) in
|
|
|
+ type_expr ctx (EBlock [
|
|
|
+ (EVars [("tmp",None,Some e)],p);
|
|
|
+ (EIf (cond,etmp,Some (EThrow (EConst (String "Class cast error"),p),p)),p);
|
|
|
+ ],p)
|
|
|
|
|
|
and type_function ctx t static constr f p =
|
|
|
let locals = save_locals ctx in
|