|
@@ -27,6 +27,7 @@ type context = {
|
|
delays : (unit -> unit) list list ref;
|
|
delays : (unit -> unit) list list ref;
|
|
warn : string -> pos -> unit;
|
|
warn : string -> pos -> unit;
|
|
mutable std : module_def;
|
|
mutable std : module_def;
|
|
|
|
+ mutable untyped : bool;
|
|
(* per-module *)
|
|
(* per-module *)
|
|
current : module_def;
|
|
current : module_def;
|
|
mutable local_types : (module_path * module_type) list;
|
|
mutable local_types : (module_path * module_type) list;
|
|
@@ -63,17 +64,25 @@ let load_ref : (context -> module_path -> pos -> module_def) ref = ref (fun _ _
|
|
|
|
|
|
let load ctx m p = (!load_ref) ctx m p
|
|
let load ctx m p = (!load_ref) ctx m p
|
|
|
|
|
|
-let unify t1 t2 p =
|
|
|
|
- if not (unify t1 t2) then raise (Error (Cannot_unify (t1,t2),p))
|
|
|
|
|
|
+let unify ctx t1 t2 p =
|
|
|
|
+ if not (unify t1 t2) && not ctx.untyped then raise (Error (Cannot_unify (t1,t2),p))
|
|
|
|
|
|
(** since load_type is used in PASS2 , it cannot access the structure of a type **)
|
|
(** since load_type is used in PASS2 , it cannot access the structure of a type **)
|
|
|
|
|
|
let load_type_def ctx p tpath =
|
|
let load_type_def ctx p tpath =
|
|
|
|
+ let no_pack = fst tpath = [] in
|
|
try
|
|
try
|
|
- snd (List.find (fun (tp,_) -> tp = tpath || (fst tpath = [] && snd tp = snd tpath)) ctx.local_types)
|
|
|
|
|
|
+ snd (List.find (fun (tp,_) -> tp = tpath || (no_pack && snd tp = snd tpath)) ctx.local_types)
|
|
with
|
|
with
|
|
Not_found ->
|
|
Not_found ->
|
|
- let m = load ctx tpath p in
|
|
|
|
|
|
+ let tpath, m = (try
|
|
|
|
+ if not no_pack || fst ctx.current.mpath = [] then raise Exit;
|
|
|
|
+ let tpath2 = fst ctx.current.mpath , snd tpath in
|
|
|
|
+ tpath2, load ctx tpath2 p
|
|
|
|
+ with
|
|
|
|
+ | Error (Module_not_found _,p2) when p == p2 -> tpath, load ctx tpath p
|
|
|
|
+ | Exit -> tpath, load ctx tpath p
|
|
|
|
+ ) in
|
|
try
|
|
try
|
|
snd (List.find (fun (tp,_) -> tp = tpath) m.mtypes)
|
|
snd (List.find (fun (tp,_) -> tp = tpath) m.mtypes)
|
|
with
|
|
with
|
|
@@ -106,9 +115,9 @@ let rec load_normal_type ctx t p allow_no_params =
|
|
(match c.cl_super with
|
|
(match c.cl_super with
|
|
| None -> ()
|
|
| None -> ()
|
|
| Some (c,params) ->
|
|
| Some (c,params) ->
|
|
- unify t (TInst (c,params)) p);
|
|
|
|
|
|
+ unify ctx t (TInst (c,params)) p);
|
|
List.iter (fun (i,params) ->
|
|
List.iter (fun (i,params) ->
|
|
- unify t (TInst (i,params)) p
|
|
|
|
|
|
+ unify ctx t (TInst (i,params)) p
|
|
) c.cl_implements
|
|
) c.cl_implements
|
|
| TEnum (c,[]) -> ()
|
|
| TEnum (c,[]) -> ()
|
|
| _ -> assert false);
|
|
| _ -> assert false);
|
|
@@ -146,7 +155,7 @@ let load_type_opt ctx p t =
|
|
|
|
|
|
let set_heritance ctx c herits p =
|
|
let set_heritance ctx c herits p =
|
|
let rec loop = function
|
|
let rec loop = function
|
|
- | HNative ->
|
|
|
|
|
|
+ | HExtern | HInterface ->
|
|
()
|
|
()
|
|
| HExtends t ->
|
|
| HExtends t ->
|
|
if c.cl_super <> None then error "Cannot extend several classes" p;
|
|
if c.cl_super <> None then error "Cannot extend several classes" p;
|
|
@@ -183,7 +192,8 @@ let type_type_params ctx path p (n,flags) =
|
|
(* build a phantom class *)
|
|
(* build a phantom class *)
|
|
let c = {
|
|
let c = {
|
|
cl_path = (fst path @ [snd path],n);
|
|
cl_path = (fst path @ [snd path],n);
|
|
- cl_native = false;
|
|
|
|
|
|
+ cl_extern = false;
|
|
|
|
+ cl_interface = false;
|
|
cl_types = [];
|
|
cl_types = [];
|
|
cl_super = None;
|
|
cl_super = None;
|
|
cl_implements = [];
|
|
cl_implements = [];
|
|
@@ -308,8 +318,10 @@ let type_ident ctx i p =
|
|
in
|
|
in
|
|
loop ctx.local_types
|
|
loop ctx.local_types
|
|
with Not_found ->
|
|
with Not_found ->
|
|
- if ctx.in_static && PMap.mem i ctx.curclass.cl_fields then error ("Cannot access " ^ i ^ " in static function") p;
|
|
|
|
- error ("Unknown identifier " ^ i) p
|
|
|
|
|
|
+ if ctx.untyped then mk (TLocal i) t_dynamic p else begin
|
|
|
|
+ if ctx.in_static && PMap.mem i ctx.curclass.cl_fields then error ("Cannot access " ^ i ^ " in static function") p;
|
|
|
|
+ error ("Unknown identifier " ^ i) p
|
|
|
|
+ end
|
|
|
|
|
|
let type_type ctx tpath p =
|
|
let type_type ctx tpath p =
|
|
match load_type_def ctx p tpath with
|
|
match load_type_def ctx p tpath with
|
|
@@ -333,7 +345,7 @@ let type_constant ctx c p =
|
|
| Ident "true" -> mk (TConst (TBool true)) (t_bool ctx) p
|
|
| Ident "true" -> mk (TConst (TBool true)) (t_bool ctx) p
|
|
| Ident "false" -> mk (TConst (TBool false)) (t_bool ctx) p
|
|
| Ident "false" -> mk (TConst (TBool false)) (t_bool ctx) p
|
|
| Ident "this" ->
|
|
| Ident "this" ->
|
|
- if ctx.in_static then error "Cannot access this from a static function" p;
|
|
|
|
|
|
+ if not ctx.untyped && ctx.in_static then error "Cannot access this from a static function" p;
|
|
mk (TConst TThis) (TInst (ctx.curclass,List.map snd ctx.curclass.cl_types)) p
|
|
mk (TConst TThis) (TInst (ctx.curclass,List.map snd ctx.curclass.cl_types)) p
|
|
| Ident "super" ->
|
|
| Ident "super" ->
|
|
let t = (match ctx.curclass.cl_super with
|
|
let t = (match ctx.curclass.cl_super with
|
|
@@ -348,10 +360,12 @@ let type_constant ctx c p =
|
|
| Type s ->
|
|
| Type s ->
|
|
type_type ctx ([],s) p
|
|
type_type ctx ([],s) p
|
|
|
|
|
|
-let check_assign e =
|
|
|
|
|
|
+let check_assign ctx e =
|
|
match e.eexpr with
|
|
match e.eexpr with
|
|
| TLocal _ | TMember _ | TArray _ | TField _ ->
|
|
| TLocal _ | TMember _ | TArray _ | TField _ ->
|
|
()
|
|
()
|
|
|
|
+ | TType _ when ctx.untyped ->
|
|
|
|
+ ()
|
|
| _ ->
|
|
| _ ->
|
|
error "Invalid assign" e.epos
|
|
error "Invalid assign" e.epos
|
|
|
|
|
|
@@ -399,7 +413,7 @@ let type_matching ctx (enum,params) (e,p) ecases =
|
|
|
|
|
|
let type_field ctx t i p =
|
|
let type_field ctx t i p =
|
|
let no_field() =
|
|
let no_field() =
|
|
- error (s_type (print_context()) t ^ " have no field " ^ i) p
|
|
|
|
|
|
+ if ctx.untyped then t_dynamic else error (s_type (print_context()) t ^ " have no field " ^ i) p
|
|
in
|
|
in
|
|
match follow t with
|
|
match follow t with
|
|
| TInst (c,params) ->
|
|
| TInst (c,params) ->
|
|
@@ -432,8 +446,7 @@ let type_field ctx t i p =
|
|
| TDynamic t ->
|
|
| TDynamic t ->
|
|
t
|
|
t
|
|
| TAnon fl ->
|
|
| TAnon fl ->
|
|
- let f = (try PMap.find i fl with Not_found -> no_field()) in
|
|
|
|
- f.cf_type
|
|
|
|
|
|
+ (try (PMap.find i fl).cf_type with Not_found -> no_field())
|
|
| t ->
|
|
| t ->
|
|
no_field()
|
|
no_field()
|
|
|
|
|
|
@@ -459,8 +472,8 @@ let rec type_binop ctx op e1 e2 p =
|
|
| OpShr
|
|
| OpShr
|
|
| OpUShr ->
|
|
| OpUShr ->
|
|
let i = t_int ctx in
|
|
let i = t_int ctx in
|
|
- unify e1.etype i e1.epos;
|
|
|
|
- unify e2.etype i e2.epos;
|
|
|
|
|
|
+ unify ctx e1.etype i e1.epos;
|
|
|
|
+ unify ctx e2.etype i e2.epos;
|
|
mk_op i
|
|
mk_op i
|
|
| OpMod
|
|
| OpMod
|
|
| OpMult
|
|
| OpMult
|
|
@@ -469,8 +482,8 @@ let rec type_binop ctx op e1 e2 p =
|
|
let i = t_int ctx in
|
|
let i = t_int ctx in
|
|
let f1 = is_float e1.etype in
|
|
let f1 = is_float e1.etype in
|
|
let f2 = is_float e2.etype in
|
|
let f2 = is_float e2.etype in
|
|
- if not f1 then unify e1.etype i e1.epos;
|
|
|
|
- if not f2 then unify e2.etype i e2.epos;
|
|
|
|
|
|
+ if not f1 then unify ctx e1.etype i e1.epos;
|
|
|
|
+ if not f2 then unify ctx e2.etype i e2.epos;
|
|
if op <> OpDiv && not f1 && not f2 then
|
|
if op <> OpDiv && not f1 && not f2 then
|
|
mk_op i
|
|
mk_op i
|
|
else
|
|
else
|
|
@@ -484,24 +497,24 @@ let rec type_binop ctx op e1 e2 p =
|
|
| OpLt
|
|
| OpLt
|
|
| OpLte ->
|
|
| OpLte ->
|
|
(try
|
|
(try
|
|
- unify e1.etype e2.etype p
|
|
|
|
|
|
+ unify ctx e1.etype e2.etype p
|
|
with
|
|
with
|
|
- Error (Cannot_unify _,_) -> unify e2.etype e1.etype p);
|
|
|
|
|
|
+ Error (Cannot_unify _,_) -> unify ctx e2.etype e1.etype p);
|
|
mk_op (t_bool ctx)
|
|
mk_op (t_bool ctx)
|
|
| OpBoolAnd
|
|
| OpBoolAnd
|
|
| OpBoolOr ->
|
|
| OpBoolOr ->
|
|
let b = t_bool ctx in
|
|
let b = t_bool ctx in
|
|
- unify e1.etype b p;
|
|
|
|
- unify e2.etype b p;
|
|
|
|
|
|
+ unify ctx e1.etype b p;
|
|
|
|
+ unify ctx e2.etype b p;
|
|
mk_op b
|
|
mk_op b
|
|
| OpInterval ->
|
|
| OpInterval ->
|
|
let i = t_int ctx in
|
|
let i = t_int ctx in
|
|
- unify e1.etype i p;
|
|
|
|
- unify e2.etype i p;
|
|
|
|
|
|
+ unify ctx e1.etype i p;
|
|
|
|
+ unify ctx e2.etype i p;
|
|
mk_op (TFun ([],i))
|
|
mk_op (TFun ([],i))
|
|
| OpAssign ->
|
|
| OpAssign ->
|
|
- unify e2.etype e1.etype p;
|
|
|
|
- check_assign e1;
|
|
|
|
|
|
+ unify ctx e2.etype e1.etype p;
|
|
|
|
+ check_assign ctx e1;
|
|
mk_op e1.etype
|
|
mk_op e1.etype
|
|
| OpAssignOp op ->
|
|
| OpAssignOp op ->
|
|
let e = loop op in
|
|
let e = loop op in
|
|
@@ -518,17 +531,17 @@ and type_unop ctx op flag e p =
|
|
let t = (match op with
|
|
let t = (match op with
|
|
| Not ->
|
|
| Not ->
|
|
let b = t_bool ctx in
|
|
let b = t_bool ctx in
|
|
- unify e.etype b e.epos;
|
|
|
|
|
|
+ unify ctx e.etype b e.epos;
|
|
b
|
|
b
|
|
| Increment
|
|
| Increment
|
|
| Decrement
|
|
| Decrement
|
|
| Neg
|
|
| Neg
|
|
| NegBits ->
|
|
| NegBits ->
|
|
- if op = Increment || op = Decrement then check_assign e;
|
|
|
|
|
|
+ if op = Increment || op = Decrement then check_assign ctx e;
|
|
if is_float e.etype then
|
|
if is_float e.etype then
|
|
t_float ctx
|
|
t_float ctx
|
|
else begin
|
|
else begin
|
|
- unify e.etype (t_int ctx) e.epos;
|
|
|
|
|
|
+ unify ctx e.etype (t_int ctx) e.epos;
|
|
t_int ctx
|
|
t_int ctx
|
|
end
|
|
end
|
|
) in
|
|
) in
|
|
@@ -562,10 +575,10 @@ and type_switch ctx e cases def need_val p =
|
|
let locals = ctx.locals in
|
|
let locals = ctx.locals in
|
|
let e1 = (match enum with Some e -> type_matching ctx e e1 ecases | None -> type_expr ctx e1) in
|
|
let e1 = (match enum with Some e -> type_matching ctx e e1 ecases | None -> type_expr ctx e1) in
|
|
(* this inversion is needed *)
|
|
(* this inversion is needed *)
|
|
- unify e.etype e1.etype e1.epos;
|
|
|
|
|
|
+ unify ctx e.etype e1.etype e1.epos;
|
|
let e2 = type_expr ctx e2 in
|
|
let e2 = type_expr ctx e2 in
|
|
ctx.locals <- locals;
|
|
ctx.locals <- locals;
|
|
- if need_val then unify e2.etype t e2.epos;
|
|
|
|
|
|
+ if need_val then unify ctx e2.etype t e2.epos;
|
|
(e1,e2)
|
|
(e1,e2)
|
|
) cases in
|
|
) cases in
|
|
let def = (match def with
|
|
let def = (match def with
|
|
@@ -583,7 +596,7 @@ and type_switch ctx e cases def need_val p =
|
|
None
|
|
None
|
|
| Some e ->
|
|
| Some e ->
|
|
let e = type_expr ctx e in
|
|
let e = type_expr ctx e in
|
|
- if need_val then unify e.etype t e.epos;
|
|
|
|
|
|
+ if need_val then unify ctx e.etype t e.epos;
|
|
Some e
|
|
Some e
|
|
) in
|
|
) in
|
|
mk (TSwitch (e,cases,def)) t p
|
|
mk (TSwitch (e,cases,def)) t p
|
|
@@ -596,9 +609,9 @@ and type_expr ctx ?(need_val=true) (e,p) =
|
|
| EArray (e1,e2) ->
|
|
| EArray (e1,e2) ->
|
|
let e1 = type_expr ctx e1 in
|
|
let e1 = type_expr ctx e1 in
|
|
let e2 = type_expr ctx e2 in
|
|
let e2 = type_expr ctx e2 in
|
|
- unify e2.etype (t_int ctx) e2.epos;
|
|
|
|
|
|
+ unify ctx e2.etype (t_int ctx) e2.epos;
|
|
let t , pt = t_array ctx in
|
|
let t , pt = t_array ctx in
|
|
- unify e1.etype t e1.epos;
|
|
|
|
|
|
+ unify ctx e1.etype t e1.epos;
|
|
mk (TArray (e1,e2)) pt p
|
|
mk (TArray (e1,e2)) pt p
|
|
| EBinop (op,e1,e2) ->
|
|
| EBinop (op,e1,e2) ->
|
|
type_binop ctx op e1 e2 p
|
|
type_binop ctx op e1 e2 p
|
|
@@ -649,7 +662,7 @@ and type_expr ctx ?(need_val=true) (e,p) =
|
|
let t , pt = t_array ctx in
|
|
let t , pt = t_array ctx in
|
|
let el = List.map (fun e ->
|
|
let el = List.map (fun e ->
|
|
let e = type_expr ctx e in
|
|
let e = type_expr ctx e in
|
|
- unify e.etype pt e.epos;
|
|
|
|
|
|
+ unify ctx e.etype pt e.epos;
|
|
e
|
|
e
|
|
) el in
|
|
) el in
|
|
mk (TArrayDecl el) t p
|
|
mk (TArrayDecl el) t p
|
|
@@ -660,7 +673,7 @@ and type_expr ctx ?(need_val=true) (e,p) =
|
|
| None -> None
|
|
| None -> None
|
|
| Some e ->
|
|
| Some e ->
|
|
let e = type_expr ctx e in
|
|
let e = type_expr ctx e in
|
|
- unify e.etype t p;
|
|
|
|
|
|
+ unify ctx e.etype t p;
|
|
Some e
|
|
Some e
|
|
) in
|
|
) in
|
|
ctx.locals <- PMap.add v t ctx.locals;
|
|
ctx.locals <- PMap.add v t ctx.locals;
|
|
@@ -675,9 +688,9 @@ and type_expr ctx ?(need_val=true) (e,p) =
|
|
| TAnon _
|
|
| TAnon _
|
|
| TInst _ ->
|
|
| TInst _ ->
|
|
let ft = type_field ctx e1.etype "iterator" e1.epos in
|
|
let ft = type_field ctx e1.etype "iterator" e1.epos in
|
|
- unify ft t e1.epos
|
|
|
|
|
|
+ unify ctx ft t e1.epos
|
|
| _ ->
|
|
| _ ->
|
|
- unify e1.etype t e1.epos;
|
|
|
|
|
|
+ unify ctx e1.etype t e1.epos;
|
|
);
|
|
);
|
|
let locals = ctx.locals in
|
|
let locals = ctx.locals in
|
|
ctx.locals <- PMap.add i pt ctx.locals;
|
|
ctx.locals <- PMap.add i pt ctx.locals;
|
|
@@ -686,24 +699,24 @@ and type_expr ctx ?(need_val=true) (e,p) =
|
|
mk (TFor (i,e1,e2)) (t_void ctx) p
|
|
mk (TFor (i,e1,e2)) (t_void ctx) p
|
|
| EIf (e,e1,e2) ->
|
|
| EIf (e,e1,e2) ->
|
|
let e = type_expr ctx e in
|
|
let e = type_expr ctx e in
|
|
- unify e.etype (t_bool ctx) e.epos;
|
|
|
|
|
|
+ unify ctx e.etype (t_bool ctx) e.epos;
|
|
let e1 = type_expr ctx ~need_val e1 in
|
|
let e1 = type_expr ctx ~need_val e1 in
|
|
(match e2 with
|
|
(match e2 with
|
|
| None -> mk (TIf (e,e1,None)) (t_void ctx) p
|
|
| None -> mk (TIf (e,e1,None)) (t_void ctx) p
|
|
| Some e2 ->
|
|
| Some e2 ->
|
|
let e2 = type_expr ctx ~need_val e2 in
|
|
let e2 = type_expr ctx ~need_val e2 in
|
|
let t = if not need_val then t_void ctx else (try
|
|
let t = if not need_val then t_void ctx else (try
|
|
- unify e1.etype e2.etype p;
|
|
|
|
|
|
+ unify ctx e1.etype e2.etype p;
|
|
e2.etype
|
|
e2.etype
|
|
with
|
|
with
|
|
Error (Cannot_unify _,_) ->
|
|
Error (Cannot_unify _,_) ->
|
|
- unify e2.etype e1.etype p;
|
|
|
|
|
|
+ unify ctx e2.etype e1.etype p;
|
|
e1.etype
|
|
e1.etype
|
|
) in
|
|
) in
|
|
mk (TIf (e,e1,Some e2)) t p)
|
|
mk (TIf (e,e1,Some e2)) t p)
|
|
| EWhile (cond,e,flag) ->
|
|
| EWhile (cond,e,flag) ->
|
|
let cond = type_expr ctx cond in
|
|
let cond = type_expr ctx cond in
|
|
- unify cond.etype (t_bool ctx) cond.epos;
|
|
|
|
|
|
+ unify ctx cond.etype (t_bool ctx) cond.epos;
|
|
let e = type_expr ctx e in
|
|
let e = type_expr ctx e in
|
|
mk (TWhile (cond,e,flag)) (t_void ctx) p
|
|
mk (TWhile (cond,e,flag)) (t_void ctx) p
|
|
| ESwitch (e,cases,def) ->
|
|
| ESwitch (e,cases,def) ->
|
|
@@ -712,11 +725,11 @@ and type_expr ctx ?(need_val=true) (e,p) =
|
|
let e , t = (match e with
|
|
let e , t = (match e with
|
|
| None ->
|
|
| None ->
|
|
let v = t_void ctx in
|
|
let v = t_void ctx in
|
|
- unify v ctx.ret p;
|
|
|
|
|
|
+ unify ctx v ctx.ret p;
|
|
None , v
|
|
None , v
|
|
| Some e ->
|
|
| Some e ->
|
|
let e = type_expr ctx e in
|
|
let e = type_expr ctx e in
|
|
- unify e.etype ctx.ret e.epos;
|
|
|
|
|
|
+ unify ctx e.etype ctx.ret e.epos;
|
|
Some e , e.etype
|
|
Some e , e.etype
|
|
) in
|
|
) in
|
|
mk (TReturn e) (t_void ctx) p
|
|
mk (TReturn e) (t_void ctx) p
|
|
@@ -732,11 +745,11 @@ and type_expr ctx ?(need_val=true) (e,p) =
|
|
ctx.locals <- PMap.add v t ctx.locals;
|
|
ctx.locals <- PMap.add v t ctx.locals;
|
|
let e = type_expr ctx ~need_val e in
|
|
let e = type_expr ctx ~need_val e in
|
|
ctx.locals <- locals;
|
|
ctx.locals <- locals;
|
|
- if not need_val then unify e.etype e1.etype e.epos;
|
|
|
|
|
|
+ if not need_val then unify ctx e.etype e1.etype e.epos;
|
|
v , t , e
|
|
v , t , e
|
|
) catches in
|
|
) catches in
|
|
mk (TTry (e1,catches)) (if not need_val then t_void ctx else e1.etype) p
|
|
mk (TTry (e1,catches)) (if not need_val then t_void ctx else e1.etype) p
|
|
- | ECall ((EConst (Ident "throw"),_),[e]) ->
|
|
|
|
|
|
+ | EThrow e ->
|
|
let e = type_expr ctx e in
|
|
let e = type_expr ctx e in
|
|
mk (TThrow e) (mk_mono()) p
|
|
mk (TThrow e) (mk_mono()) p
|
|
| ECall ((EConst (Ident "type"),_),[e]) ->
|
|
| ECall ((EConst (Ident "type"),_),[e]) ->
|
|
@@ -753,7 +766,7 @@ and type_expr ctx ?(need_val=true) (e,p) =
|
|
(match apply_params c.cl_types params f.cf_type with
|
|
(match apply_params c.cl_types params f.cf_type with
|
|
| TFun (args,r) ->
|
|
| TFun (args,r) ->
|
|
if List.length args <> List.length el then error "Invalid number of constructor parameters" p;
|
|
if List.length args <> List.length el then error "Invalid number of constructor parameters" p;
|
|
- List.iter2 (fun e t -> unify e.etype t e.epos) el args;
|
|
|
|
|
|
+ List.iter2 (fun e t -> unify ctx e.etype t e.epos) el args;
|
|
| _ ->
|
|
| _ ->
|
|
error "Constructor is not a function" p);
|
|
error "Constructor is not a function" p);
|
|
);
|
|
);
|
|
@@ -765,12 +778,12 @@ and type_expr ctx ?(need_val=true) (e,p) =
|
|
| TFun (args,r) ->
|
|
| TFun (args,r) ->
|
|
if List.length args <> List.length el then error "Invalid number of arguments" p;
|
|
if List.length args <> List.length el then error "Invalid number of arguments" p;
|
|
List.iter2 (fun e t ->
|
|
List.iter2 (fun e t ->
|
|
- unify e.etype t e.epos;
|
|
|
|
|
|
+ unify ctx e.etype t e.epos;
|
|
) el args;
|
|
) el args;
|
|
r
|
|
r
|
|
| TMono _ ->
|
|
| TMono _ ->
|
|
let t = mk_mono() in
|
|
let t = mk_mono() in
|
|
- unify (TFun (List.map (fun e -> e.etype) el,t)) e.etype e.epos;
|
|
|
|
|
|
+ unify ctx (TFun (List.map (fun e -> e.etype) el,t)) e.etype e.epos;
|
|
t
|
|
t
|
|
| t ->
|
|
| t ->
|
|
if t == t_dynamic then
|
|
if t == t_dynamic then
|
|
@@ -793,7 +806,7 @@ and type_expr ctx ?(need_val=true) (e,p) =
|
|
(match apply_params c.cl_types params f.cf_type with
|
|
(match apply_params c.cl_types params f.cf_type with
|
|
| TFun (args,r) ->
|
|
| TFun (args,r) ->
|
|
if List.length args <> List.length el then error "Invalid number of constructor parameters" p;
|
|
if List.length args <> List.length el then error "Invalid number of constructor parameters" p;
|
|
- List.iter2 (fun e t -> unify e.etype t e.epos) el args;
|
|
|
|
|
|
+ List.iter2 (fun e t -> unify ctx e.etype t e.epos) el args;
|
|
| _ ->
|
|
| _ ->
|
|
error "Constructor is not a function" p);
|
|
error "Constructor is not a function" p);
|
|
c , params , t
|
|
c , params , t
|
|
@@ -814,6 +827,12 @@ and type_expr ctx ?(need_val=true) (e,p) =
|
|
tf_expr = e;
|
|
tf_expr = e;
|
|
} in
|
|
} in
|
|
mk (TFunction f) ft p
|
|
mk (TFunction f) ft p
|
|
|
|
+ | EUntyped e ->
|
|
|
|
+ let old = ctx.untyped in
|
|
|
|
+ ctx.untyped <- true;
|
|
|
|
+ let e = type_expr ctx e in
|
|
|
|
+ ctx.untyped <- old;
|
|
|
|
+ e
|
|
|
|
|
|
and type_function ctx t static constr f p =
|
|
and type_function ctx t static constr f p =
|
|
let locals = ctx.locals in
|
|
let locals = ctx.locals in
|
|
@@ -838,7 +857,7 @@ and type_function ctx t static constr f p =
|
|
if have_ret then
|
|
if have_ret then
|
|
return_flow e
|
|
return_flow e
|
|
else
|
|
else
|
|
- unify r (t_void ctx) p;
|
|
|
|
|
|
+ unify ctx r (t_void ctx) p;
|
|
ctx.locals <- locals;
|
|
ctx.locals <- locals;
|
|
ctx.ret <- old_ret;
|
|
ctx.ret <- old_ret;
|
|
ctx.in_static <- old_static;
|
|
ctx.in_static <- old_static;
|
|
@@ -848,7 +867,7 @@ and type_function ctx t static constr f p =
|
|
let type_static_var ctx t e p =
|
|
let type_static_var ctx t e p =
|
|
ctx.in_static <- true;
|
|
ctx.in_static <- true;
|
|
let e = type_expr ctx e in
|
|
let e = type_expr ctx e in
|
|
- unify e.etype t p;
|
|
|
|
|
|
+ unify ctx e.etype t p;
|
|
e
|
|
e
|
|
|
|
|
|
let check_overloading c p () =
|
|
let check_overloading c p () =
|
|
@@ -885,8 +904,19 @@ let init_class ctx c p types herits fields =
|
|
ctx.type_params <- [];
|
|
ctx.type_params <- [];
|
|
c.cl_types <- List.map (type_type_params ctx c.cl_path p) types;
|
|
c.cl_types <- List.map (type_type_params ctx c.cl_path p) types;
|
|
ctx.type_params <- c.cl_types;
|
|
ctx.type_params <- c.cl_types;
|
|
- c.cl_native <- List.mem HNative herits;
|
|
|
|
|
|
+ c.cl_extern <- List.mem HExtern herits;
|
|
|
|
+ c.cl_interface <- List.mem HInterface herits;
|
|
set_heritance ctx c herits p;
|
|
set_heritance ctx c herits p;
|
|
|
|
+ let is_public access =
|
|
|
|
+ if c.cl_extern || c.cl_interface then not (List.mem APrivate access) else List.mem APublic access
|
|
|
|
+ in
|
|
|
|
+ let type_opt p t =
|
|
|
|
+ match t with
|
|
|
|
+ | None when c.cl_extern || c.cl_interface ->
|
|
|
|
+ error "Type required for extern classes and interfaces" p
|
|
|
|
+ | _ ->
|
|
|
|
+ load_type_opt ctx p t
|
|
|
|
+ in
|
|
let loop_cf f p =
|
|
let loop_cf f p =
|
|
match f with
|
|
match f with
|
|
| FVar (name,access,t,e) ->
|
|
| FVar (name,access,t,e) ->
|
|
@@ -895,7 +925,7 @@ let init_class ctx c p types herits fields =
|
|
cf_name = name;
|
|
cf_name = name;
|
|
cf_type = t;
|
|
cf_type = t;
|
|
cf_expr = None;
|
|
cf_expr = None;
|
|
- cf_public = List.mem APublic access;
|
|
|
|
|
|
+ cf_public = is_public access;
|
|
} in
|
|
} in
|
|
let delay = (match e with
|
|
let delay = (match e with
|
|
| None -> (fun() -> ())
|
|
| None -> (fun() -> ())
|
|
@@ -906,15 +936,15 @@ let init_class ctx c p types herits fields =
|
|
) in
|
|
) in
|
|
List.mem AStatic access, cf, delay
|
|
List.mem AStatic access, cf, delay
|
|
| FFun (name,access,f) ->
|
|
| FFun (name,access,f) ->
|
|
- let r = load_type_opt ctx p f.f_type in
|
|
|
|
- let args = List.map (fun (name,t) -> name , load_type_opt ctx p t) f.f_args in
|
|
|
|
|
|
+ let r = type_opt p f.f_type in
|
|
|
|
+ let args = List.map (fun (name,t) -> name , type_opt p t) f.f_args in
|
|
let t = TFun (List.map snd args,r) in
|
|
let t = TFun (List.map snd args,r) in
|
|
let stat = List.mem AStatic access in
|
|
let stat = List.mem AStatic access in
|
|
let cf = {
|
|
let cf = {
|
|
cf_name = name;
|
|
cf_name = name;
|
|
cf_type = t;
|
|
cf_type = t;
|
|
cf_expr = None;
|
|
cf_expr = None;
|
|
- cf_public = List.mem APublic access;
|
|
|
|
|
|
+ cf_public = is_public access;
|
|
} in
|
|
} in
|
|
let define_fun() =
|
|
let define_fun() =
|
|
ctx.curclass <- c;
|
|
ctx.curclass <- c;
|
|
@@ -926,7 +956,7 @@ let init_class ctx c p types herits fields =
|
|
} in
|
|
} in
|
|
cf.cf_expr <- Some (mk (TFunction f) t p)
|
|
cf.cf_expr <- Some (mk (TFunction f) t p)
|
|
in
|
|
in
|
|
- stat || name = "new", cf , (if c.cl_native then (fun() -> ()) else define_fun)
|
|
|
|
|
|
+ stat || name = "new", cf , (if c.cl_extern || c.cl_interface then (fun() -> ()) else define_fun)
|
|
in
|
|
in
|
|
List.map (fun (f,p) ->
|
|
List.map (fun (f,p) ->
|
|
let static , f , delayed = loop_cf f p in
|
|
let static , f , delayed = loop_cf f p in
|
|
@@ -959,7 +989,8 @@ let type_module ctx m tdecls =
|
|
let c = {
|
|
let c = {
|
|
cl_path = path;
|
|
cl_path = path;
|
|
cl_types = [];
|
|
cl_types = [];
|
|
- cl_native = false;
|
|
|
|
|
|
+ cl_extern = false;
|
|
|
|
+ cl_interface = false;
|
|
cl_super = None;
|
|
cl_super = None;
|
|
cl_implements = [];
|
|
cl_implements = [];
|
|
cl_fields = PMap.empty;
|
|
cl_fields = PMap.empty;
|
|
@@ -996,6 +1027,7 @@ let type_module ctx m tdecls =
|
|
type_params = [];
|
|
type_params = [];
|
|
in_constructor = false;
|
|
in_constructor = false;
|
|
in_static = false;
|
|
in_static = false;
|
|
|
|
+ untyped = false;
|
|
} in
|
|
} in
|
|
let delays = ref [] in
|
|
let delays = ref [] in
|
|
List.iter (fun (d,p) ->
|
|
List.iter (fun (d,p) ->
|
|
@@ -1056,6 +1088,7 @@ let context warn =
|
|
delays = ref [];
|
|
delays = ref [];
|
|
in_constructor = false;
|
|
in_constructor = false;
|
|
in_static = false;
|
|
in_static = false;
|
|
|
|
+ untyped = false;
|
|
ret = mk_mono();
|
|
ret = mk_mono();
|
|
warn = warn;
|
|
warn = warn;
|
|
locals = PMap.empty;
|
|
locals = PMap.empty;
|
|
@@ -1063,7 +1096,8 @@ let context warn =
|
|
type_params = [];
|
|
type_params = [];
|
|
curclass = {
|
|
curclass = {
|
|
cl_path = [] , "";
|
|
cl_path = [] , "";
|
|
- cl_native = false;
|
|
|
|
|
|
+ cl_extern = false;
|
|
|
|
+ cl_interface = false;
|
|
cl_types = [];
|
|
cl_types = [];
|
|
cl_super = None;
|
|
cl_super = None;
|
|
cl_implements = [];
|
|
cl_implements = [];
|