Ver código fonte

rearchitecture

Nicolas Cannasse 17 anos atrás
pai
commit
2c73faf587
18 arquivos alterados com 1968 adições e 1285 exclusões
  1. 28 17
      Makefile.win
  2. 561 0
      codegen.ml
  3. 46 1
      common.ml
  4. 25 10
      doc/install.ml
  5. 11 13
      genas3.ml
  6. 15 17
      genjs.ml
  7. 1 4
      genneko.ml
  8. 22 19
      genswf8.ml
  9. 14 14
      genswf9.ml
  10. 4 6
      genxml.ml
  11. 8 2
      haxe.vcproj
  12. 19 17
      main.ml
  13. 1 1
      std/haxe/io/Bytes.hx
  14. 0 331
      transform.ml
  15. 69 5
      type.ml
  16. 184 0
      typecore.ml
  17. 925 0
      typeload.ml
  18. 35 828
      typer.ml

+ 28 - 17
Makefile.win

@@ -1,4 +1,4 @@
-# Makefile generated by OCamake 
+# Makefile generated by OCamake
 # http://tech.motion-twin.com
 .SUFFIXES : .ml .mli .cmo .cmi .cmx .mll .mly
 
@@ -7,47 +7,58 @@ LIBS=extLib.cmxa extc.cmxa swfLib.cmxa unix.cmxa xml-light.cmxa
 LFLAGS=-g -o haxe.exe -I ../neko/libs/include/ocaml
 OUTPUT=sed 's/File "\([^"]\+\)", line \([0-9]\+\), \(.*\)/\1(\2): \3/' tmp.cmi
 
-FILES = ../neko/libs/include/ocaml/nast.cmx ast.cmx common.cmx ../neko/libs/include/ocaml/nxml.cmx ../neko/libs/include/ocaml/binast.cmx lexer.cmx type.cmx parser.cmx transform.cmx typer.cmx genswf9.cmx genswf8.cmx genneko.cmx genjs.cmx genswf.cmx genxml.cmx genas3.cmx main.cmx
-
+FILES = ast.cmx lexer.cmx type.cmx common.cmx parser.cmx typecore.cmx \
+	genxml.cmx typeload.cmx codegen.cmx typer.cmx \
+	../neko/libs/include/ocaml/nast.cmx ../neko/libs/include/ocaml/binast.cmx ../neko/libs/include/ocaml/nxml.cmx \
+	genneko.cmx genas3.cmx genjs.cmx genswf8.cmx genswf9.cmx genswf.cmx \
+	main.cmx
+	
 all: haxe.exe
 
 haxe.exe: $(FILES)
 	ocamlopt $(LFLAGS) $(LIBS) $(FILES)
 
-genneko.cmx: typer.cmx type.cmx common.cmx ../neko/libs/include/ocaml/binast.cmx ../neko/libs/include/ocaml/nast.cmx lexer.cmx ast.cmx
-
 ../neko/libs/include/ocaml/binast.cmx: ../neko/libs/include/ocaml/nast.cmx
 
+genneko.cmx: type.cmx ../neko/libs/include/ocaml/nxml.cmx ../neko/libs/include/ocaml/nast.cmx lexer.cmx common.cmx ../neko/libs/include/ocaml/binast.cmx ast.cmx
+
 ../neko/libs/include/ocaml/nxml.cmx: ../neko/libs/include/ocaml/nast.cmx
 
-genjs.cmx: typer.cmx type.cmx transform.cmx ast.cmx
+../../mtcvs/swflib/as3hl.cmi: ../../mtcvs/swflib/as3.cmi
+
+codegen.cmx: typeload.cmx typecore.cmx type.cmx genxml.cmx common.cmx ast.cmx
+
+common.cmx: type.cmx ast.cmx
 
-genas3.cmx: typer.cmx type.cmx transform.cmx ast.cmx
+genas3.cmx: type.cmx codegen.cmx ../../mtcvs/swflib/swfParser.cmx ../../mtcvs/swflib/swf.cmx common.cmx ast.cmx ../../mtcvs/swflib/as3parse.cmx ../../mtcvs/swflib/as3code.cmx ../../mtcvs/swflib/as3.cmi
 
-genswf.cmx: typer.cmx type.cmx common.cmx genswf8.cmx genswf9.cmx
+genjs.cmx: type.cmx codegen.cmx lexer.cmx common.cmx ast.cmx
 
-genswf8.cmx: typer.cmx type.cmx transform.cmx common.cmx ast.cmx
+genswf.cmx: type.cmx ../../mtcvs/swflib/swfZip.cmx ../../mtcvs/swflib/swfParser.cmx ../../mtcvs/swflib/swf.cmx genswf9.cmx genswf8.cmx common.cmx ast.cmx ../../mtcvs/swflib/as3hlparse.cmx ../../mtcvs/swflib/as3hl.cmi ../../mtcvs/swflib/as3.cmi
 
-genswf9.cmx: type.cmx ast.cmx typer.cmx transform.cmx common.cmx
+genswf8.cmx: type.cmx codegen.cmx ../../mtcvs/swflib/swf.cmx lexer.cmx common.cmx ast.cmx ../../mtcvs/swflib/actionScript.cmx
 
-genxml.cmx: typer.cmx type.cmx lexer.cmx ast.cmx
+genswf9.cmx: type.cmx codegen.cmx lexer.cmx common.cmx ast.cmx ../../mtcvs/swflib/as3hlparse.cmx ../../mtcvs/swflib/as3hl.cmi ../../mtcvs/swflib/as3.cmi
+
+genxml.cmx: type.cmx lexer.cmx common.cmx ast.cmx
 
 lexer.cmx: lexer.ml
 
 lexer.cmx: ast.cmx
 
-main.cmx: typer.cmx common.cmx parser.cmx lexer.cmx genxml.cmx genswf.cmx genneko.cmx genjs.cmx genas3.cmx ast.cmx
+main.cmx: typer.cmx typeload.cmx typecore.cmx type.cmx parser.cmx lexer.cmx genxml.cmx genswf.cmx genneko.cmx genjs.cmx genas3.cmx common.cmx ast.cmx
 
-parser.cmx: parser.ml common.cmx lexer.cmx ast.cmx
+parser.cmx: lexer.cmx common.cmx ast.cmx
 	(ocamlopt -pp camlp4o $(CFLAGS) -c parser.ml 2>tmp.cmi && $(OUTPUT)) || ($(OUTPUT) && exit 1)
 
-transform.cmx: type.cmx
-
 type.cmx: ast.cmx
 
-typer.cmx: type.cmx common.cmx parser.cmx lexer.cmx ast.cmx transform.cmx
+typecore.cmx: type.cmx common.cmx ast.cmx
+
+typeload.cmx: typecore.cmx type.cmx parser.cmx common.cmx ast.cmx
+
+typer.cmx: typeload.cmx typecore.cmx type.cmx parser.cmx lexer.cmx common.cmx ast.cmx codegen.cmx
 
-common.cmx: type.cmx
 
 clean:
 	rm -f haxe.exe

+ 561 - 0
codegen.ml

@@ -0,0 +1,561 @@
+(*
+ *  Haxe Compiler
+ *  Copyright (c)2005-2008 Nicolas Cannasse
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *)
+ 
+open Ast
+open Type
+open Common
+open Typecore
+
+(* -------------------------------------------------------------------------- *)
+(* REMOTING PROXYS *)
+
+let rec reverse_type t =
+	match t with
+	| TEnum (e,params) ->
+		TPNormal { tpackage = fst e.e_path; tname = snd e.e_path; tparams = List.map reverse_param params }
+	| TInst (c,params) ->
+		TPNormal { tpackage = fst c.cl_path; tname = snd c.cl_path; tparams = List.map reverse_param params }
+	| TType (t,params) ->
+		TPNormal { tpackage = fst t.t_path; tname = snd t.t_path; tparams = List.map reverse_param params }
+	| TFun (params,ret) ->
+		TPFunction (List.map (fun (_,_,t) -> reverse_type t) params,reverse_type ret)
+	| TAnon a ->
+		TPAnonymous (PMap.fold (fun f acc ->
+			(f.cf_name , Some f.cf_public, AFVar (reverse_type f.cf_type), null_pos) :: acc
+		) a.a_fields [])
+	| TDynamic t2 ->
+		TPNormal { tpackage = []; tname = "Dynamic"; tparams = if t == t2 then [] else [TPType (reverse_type t2)] }
+	| _ ->
+		raise Exit
+
+and reverse_param t =
+	TPType (reverse_type t)
+
+(*/*
+let extend_remoting ctx c t p async prot =
+	if c.cl_super <> None then error "Cannot extend several classes" p;
+	if ctx.isproxy then
+		() (* skip this proxy generation, we shouldn't need it anyway *)
+	else
+	let ctx2 = context ctx.com in
+	(* remove forbidden packages *)
+	let rules = ctx.com.package_rules in
+	ctx.com.package_rules <- PMap.foldi (fun key r acc -> match r with Forbidden -> acc | _ -> PMap.add key r acc) rules PMap.empty;
+	ctx2.isproxy <- true;
+	let ct = (try load_normal_type ctx2 t p false with e -> ctx.com.package_rules <- rules; raise e) in
+	ctx.com.package_rules <- rules;
+	let tvoid = TPNormal { tpackage = []; tname = "Void"; tparams = [] } in
+	let make_field name args ret =
+		try
+			let targs = List.map (fun (a,o,t) -> a, o, Some (reverse_type t)) args in
+			let tret = reverse_type ret in
+			let eargs = [EArrayDecl (List.map (fun (a,_,_) -> (EConst (Ident a),p)) args),p] in
+			let targs , tret , eargs = if async then
+				match tret with
+				| TPNormal { tpackage = []; tname = "Void" } -> targs , tvoid , eargs @ [EConst (Ident "null"),p]
+				| _ -> targs @ ["__callb",true,Some (TPFunction ([tret],tvoid))] , tvoid , eargs @ [EUntyped (EConst (Ident "__callb"),p),p]
+			else
+				targs, tret , eargs
+			in
+			let idname = EConst (String name) , p in
+			(FFun (name,None,[APublic],[], {
+				f_args = targs;
+				f_type = Some tret;
+				f_expr = (EBlock [
+					(EReturn (Some (EUntyped (ECall (
+						(EField (
+							(ECall (
+								(EField ((EConst (Ident "__cnx"),p),"resolve"),p),
+								[if prot then idname else ECall ((EConst (Ident "__unprotect__"),p),[idname]),p]
+							),p)
+						,"call"),p),eargs
+					),p),p)),p)
+				],p);
+			}),p)
+		with
+			Exit -> error ("Field " ^ name ^ " type is not complete and cannot be used by RemotingProxy") p
+	in
+	let class_fields = (match ct with
+		| TInst (c,params) ->
+			(FVar ("__cnx",None,[],Some (TPNormal { tpackage = ["haxe";"remoting"]; tname = if async then "AsyncConnection" else "Connection"; tparams = [] }),None),p) ::
+			(FFun ("new",None,[APublic],[],{ f_args = ["c",false,None]; f_type = None; f_expr = (EBinop (OpAssign,(EConst (Ident "__cnx"),p),(EConst (Ident "c"),p)),p) }),p) ::
+			PMap.fold (fun f acc ->
+				if not f.cf_public then
+					acc
+				else match follow f.cf_type with
+				| TFun (args,ret) when f.cf_get = NormalAccess && (f.cf_set = NormalAccess || f.cf_set = MethodCantAccess) && f.cf_params = [] ->
+					make_field f.cf_name args ret :: acc
+				| _ -> acc
+			) c.cl_fields []
+		| _ ->
+			error "Remoting type parameter should be a class" p
+	) in
+	let class_decl = (EClass {
+		d_name = t.tname;
+		d_doc = None;
+		d_params = [];
+		d_flags = [];
+		d_data = class_fields;
+	},p) in
+	let m = (try Hashtbl.find ctx2.modules (t.tpackage,t.tname) with Not_found -> assert false) in
+	let mdecl = (List.map (fun (m,t) -> (EImport (fst m.mpath, snd m.mpath, t),p)) m.mimports) @ [class_decl] in
+	let m = (!type_module_ref) ctx ("Remoting" :: t.tpackage,t.tname) mdecl p in
+	c.cl_super <- Some (match m.mtypes with
+		| [TClassDecl c] -> (c,[])
+		| _ -> assert false
+	)
+*/*)
+
+(* -------------------------------------------------------------------------- *)
+(* HAXE.RTTI.GENERIC *)
+
+let build_generic ctx c p tl =
+	let pack = fst c.cl_path in
+	let recurse = ref false in
+	let rec check_recursive t =
+		match follow t with
+		| TInst (c,tl) ->
+			if c.cl_kind = KTypeParameter then recurse := true;
+			List.iter check_recursive tl;
+		| _ ->
+			()
+	in
+	let name = String.concat "_" (snd c.cl_path :: (List.map (fun t ->
+		check_recursive t;
+		let path = (match follow t with
+			| TInst (c,_) -> c.cl_path
+			| TEnum (e,_) -> e.e_path
+			| _ -> error "Type parameter must be a class or enum instance" p
+		) in
+		match path with
+		| [] , name -> name
+		| l , name -> String.concat "_" l ^ "_" ^ name
+	) tl)) in
+	if !recurse then begin
+		TInst (c,tl)
+	end else try
+		Typeload.load_normal_type ctx { tpackage = pack; tname = name; tparams = [] } p false
+	with Error(Module_not_found path,_) when path = (pack,name) ->
+		(* try to find the module in which the generic class was originally defined *)
+		let mpath = (if c.cl_private then match List.rev (fst c.cl_path) with [] -> assert false | x :: l -> List.rev l, String.sub x 1 (String.length x - 1) else c.cl_path) in
+		let mtypes = try (Hashtbl.find ctx.modules mpath).mtypes with Not_found -> [] in
+		let ctx = { ctx with local_types = mtypes @ ctx.local_types } in
+		let cg = mk_class (pack,name) c.cl_pos None false in
+		let mg = {
+			mpath = cg.cl_path;
+			mtypes = [TClassDecl cg];
+			mimports = [];
+		} in
+		Hashtbl.add ctx.modules mg.mpath mg;
+		let rec loop l1 l2 =
+			match l1, l2 with
+			| [] , [] -> []
+			| (x,TLazy f) :: l1, _ -> loop ((x,(!f)()) :: l1) l2
+			| (_,t1) :: l1 , t2 :: l2 -> (t1,t2) :: loop l1 l2
+			| _ -> assert false
+		in
+		let subst = loop c.cl_types tl in
+		let rec build_type t =
+			match t with
+			| TInst ({ cl_kind = KGeneric } as c,tl) ->
+				(* maybe loop, or generate cascading generics *)
+				Typeload.load_type ctx p (reverse_type (TInst (c,List.map build_type tl)))
+			| _ ->
+				try List.assq t subst with Not_found -> Type.map build_type t
+		in
+		let rec build_expr e =
+			let t = build_type e.etype in
+			match e.eexpr with
+			| TFunction f ->
+				{
+					eexpr = TFunction {
+						tf_args = List.map (fun (n,o,t) -> n, o, build_type t) f.tf_args;
+						tf_type = build_type f.tf_type;
+						tf_expr = build_expr f.tf_expr;
+					};
+					etype = t;
+					epos = e.epos;
+				}
+			| TNew (c,tl,el) ->
+				let c, tl = (match follow t with TInst (c,tl) -> c, tl | _ -> assert false) in
+				{
+					eexpr = TNew (c,tl,List.map build_expr el);
+					etype = t;
+					epos = e.epos;
+				};
+			| TVars vl ->
+				{
+					eexpr = TVars (List.map (fun (v,t,eo) ->
+						v, build_type t, (match eo with None -> None | Some e -> Some (build_expr e))
+					) vl);
+					etype = t;
+					epos = e.epos;
+				}
+			(* there's still some 't' lefts in TFor, TMatch and TTry *)
+			| _ ->
+				Type.map_expr build_expr { e with etype = t }
+		in
+		let build_field f =
+			let t = build_type f.cf_type in
+			{ f with cf_type = t; cf_expr = (match f.cf_expr with None -> None | Some e -> Some (build_expr e)) }
+		in
+		if c.cl_super <> None || c.cl_init <> None || c.cl_dynamic <> None then error "This class can't be generic" p;
+		if c.cl_ordered_statics <> [] then error "A generic class can't have static fields" p;
+		cg.cl_kind <- KGenericInstance (c,tl);
+		cg.cl_constructor <- (match c.cl_constructor with None -> None | Some c -> Some (build_field c));
+		cg.cl_implements <- List.map (fun (i,tl) -> i, List.map build_type tl) c.cl_implements;
+		cg.cl_ordered_fields <- List.map (fun f ->
+			let f = build_field f in
+			cg.cl_fields <- PMap.add f.cf_name f cg.cl_fields;
+			f
+		) c.cl_ordered_fields;
+		TInst (cg,[])
+
+(* -------------------------------------------------------------------------- *)
+(* HAXE.XML.PROXY *)
+
+let extend_xml_proxy ctx c t file p =
+	let t = Typeload.load_type ctx p t in
+	let file = (try Common.find_file ctx.com file with Not_found -> file) in
+	try
+		let rec loop = function
+			| Xml.Element (_,attrs,childs) ->
+				(try
+					let id = List.assoc "id" attrs in
+					if PMap.mem id c.cl_fields then error ("Duplicate id " ^ id) p;
+					let f = {
+						cf_name = id;
+						cf_type = t;
+						cf_public = true;
+						cf_doc = None;
+						cf_get = ResolveAccess;
+						cf_set = NoAccess;
+						cf_params = [];
+						cf_expr = None;
+					} in
+					c.cl_fields <- PMap.add id f c.cl_fields;
+				with
+					Not_found -> ());
+				List.iter loop childs;
+			| Xml.PCData _ -> ()
+		in
+		loop (Xml.parse_file file)
+	with
+		| Xml.Error e -> error ("XML error " ^ Xml.error e) p
+		| Xml.File_not_found f -> error ("XML File not found : " ^ f) p
+
+(* -------------------------------------------------------------------------- *)
+(* API EVENTS *)
+
+let build_instance ctx mtype p =
+	match mtype with
+	| TClassDecl c ->
+		c.cl_types , c.cl_path , (match c.cl_kind with KGeneric -> build_generic ctx c p | _ -> (fun t -> TInst (c,t)))
+	| TEnumDecl e ->
+		e.e_types , e.e_path , (fun t -> TEnum (e,t))
+	| TTypeDecl t ->
+		t.t_types , t.t_path , (fun tl -> TType(t,tl))
+
+let on_inherit ctx c p h =
+	match h with
+(*/*
+	| HExtends { tpackage = ["haxe";"remoting"]; tname = "Proxy"; tparams = [TPType(TPNormal t)] } ->
+		extend_remoting ctx c t p false true;
+		false
+	| HExtends { tpackage = ["haxe";"remoting"]; tname = "AsyncProxy"; tparams = [TPType(TPNormal t)] } ->
+		extend_remoting ctx c t p true true;
+		false
+	| HExtends { tpackage = ["mt"]; tname = "AsyncProxy"; tparams = [TPType(TPNormal t)] } ->
+		extend_remoting ctx c t p true false;
+		false
+*/*)
+	| HImplements { tpackage = ["haxe";"rtti"]; tname = "Generic"; tparams = [] } ->
+		c.cl_kind <- KGeneric;
+		false
+	| HExtends { tpackage = ["haxe";"xml"]; tname = "Proxy"; tparams = [TPConst(String file);TPType t] } ->
+		extend_xml_proxy ctx c t file p;
+		true
+	| _ ->
+		true
+
+let rec has_rtti c =
+	List.exists (function (t,pl) ->
+		match t, pl with
+		| { cl_path = ["haxe";"rtti"],"Infos" },[] -> true
+		| _ -> false
+	) c.cl_implements || (match c.cl_super with None -> false | Some (c,_) -> has_rtti c)
+
+let on_generate ctx t =
+	match t with
+	| TClassDecl c when has_rtti c ->
+		let f = mk_field "__rtti" ctx.api.tstring in
+		let str = Genxml.gen_type_string ctx.com t in
+		f.cf_expr <- Some (mk (TConst (TString str)) f.cf_type c.cl_pos);
+		c.cl_ordered_statics <- f :: c.cl_ordered_statics;
+		c.cl_statics <- PMap.add f.cf_name f c.cl_statics;
+	| _ ->
+		()
+
+(* -------------------------------------------------------------------------- *)
+(* PER-BLOCK VARIABLES *)
+
+(*
+	This algorithm ensure that variables used in loop sub-functions are captured
+	by value. It transforms the following expression :
+
+	for( x in array )
+		funs.push(function() return x);
+
+	Into the following :
+
+	for( x in array )
+		funs.push(function(x) { function() return x; }(x));
+
+	This way, each value is captured independantly.	
+*)
+
+let block_vars e =
+	let add_var map v d = map := PMap.add v d (!map) in
+	let wrap e used =
+		match PMap.foldi (fun v _ acc -> v :: acc) used [] with
+		| [] -> e
+		| vars ->
+			mk (TCall (
+				(mk (TFunction {
+					tf_args = List.map (fun v -> v , false, t_dynamic) vars;
+					tf_type = t_dynamic;
+					tf_expr = mk (TReturn (Some e)) t_dynamic e.epos;
+				}) t_dynamic e.epos),
+				List.map (fun v -> mk (TLocal v) t_dynamic e.epos) vars)
+			) t_dynamic e.epos
+	in
+	let rec in_fun vars depth used_locals e =
+		match e.eexpr with
+		| TLocal v ->
+			(try
+				if PMap.find v vars = depth then add_var used_locals v depth;				
+			with
+				Not_found -> ())
+		| _ ->
+			iter (in_fun vars depth used_locals) e
+
+	and in_loop vars depth e =
+		match e.eexpr with
+		| TVars l ->
+			{ e with eexpr = TVars (List.map (fun (v,t,e) ->
+				let e = (match e with None -> None | Some e -> Some (in_loop vars depth e)) in
+				add_var vars v depth;
+				v, t, e
+			) l) }
+		| TFor (v,t,i,e1) ->
+			let new_vars = PMap.add v depth (!vars) in
+			{ e with eexpr = TFor (v,t,in_loop vars depth i,in_loop (ref new_vars) depth e1) }
+		| TTry (e1,cases) ->
+			let e1 = in_loop vars depth e1 in
+			let cases = List.map (fun (v,t,e) ->
+				let new_vars = PMap.add v depth (!vars) in
+				v , t, in_loop (ref new_vars) depth e
+			) cases in
+			{ e with eexpr = TTry (e1,cases) }
+		| TMatch (e1,t,cases,def) ->
+			let e1 = in_loop vars depth e1 in
+			let cases = List.map (fun (cl,params,e) ->
+				let e = (match params with
+					| None -> in_loop vars depth e
+					| Some l ->
+						let new_vars = List.fold_left (fun acc (v,t) ->
+							match v with
+							| None -> acc
+							| Some name -> PMap.add name depth acc
+						) (!vars) l in
+						in_loop (ref new_vars) depth e
+				) in
+				cl , params, e
+			) cases in
+			let def = (match def with None -> None | Some e -> Some (in_loop vars depth e)) in
+			{ e with eexpr = TMatch (e1, t, cases, def) }
+		| TBlock l ->
+			let new_vars = (ref !vars) in
+			map_expr (in_loop new_vars depth) e
+		| TFunction _ ->
+			let new_vars = !vars in
+			let used = ref PMap.empty in
+			iter (in_fun new_vars depth used) e;
+			let e = wrap e (!used) in
+			let new_vars = ref (PMap.foldi (fun v _ acc -> PMap.remove v acc) (!used) new_vars) in
+			map_expr (in_loop new_vars (depth + 1)) e
+		| _ ->
+			map_expr (in_loop vars depth) e
+	and out_loop e =
+		match e.eexpr with
+		| TFor _ | TWhile _ ->
+			in_loop (ref PMap.empty) 0 e
+		| _ ->
+			map_expr out_loop e
+	in
+	out_loop e
+
+(* -------------------------------------------------------------------------- *)
+(* STACK MANAGEMENT EMULATION *)
+
+let emk e = mk e (mk_mono()) null_pos
+
+let stack_var = "$s"
+let exc_stack_var = "$e"
+let stack_var_pos = "$spos"
+let stack_e = emk (TLocal stack_var)
+let stack_pop = emk (TCall (emk (TField (stack_e,"pop")),[]))
+
+let stack_push useadd (c,m) =
+	emk (TCall (emk (TField (stack_e,"push")),[
+		if useadd then
+			emk (TBinop (
+				OpAdd,
+				emk (TConst (TString (s_type_path c.cl_path ^ "::"))),
+				emk (TConst (TString m))
+			))
+		else
+			emk (TConst (TString (s_type_path c.cl_path ^ "::" ^ m)))
+	]))
+
+let stack_save_pos =
+	emk (TVars [stack_var_pos, t_dynamic, Some (emk (TField (stack_e,"length")))])
+
+let stack_restore_pos =
+	let ev = emk (TLocal exc_stack_var) in
+	[
+	emk (TBinop (OpAssign, ev, emk (TArrayDecl [])));
+	emk (TWhile (
+		emk (TBinop (OpGte,
+			emk (TField (stack_e,"length")),
+			emk (TLocal stack_var_pos)
+		)),
+		emk (TCall (
+			emk (TField (ev,"unshift")),
+			[emk (TCall (
+				emk (TField (stack_e,"pop")),
+				[]
+			))]
+		)),
+		NormalWhile
+	));
+	emk (TCall (emk (TField (stack_e,"push")),[ emk (TArray (ev,emk (TConst (TInt 0l)))) ]))
+	]
+
+let rec stack_block_loop e =
+	match e.eexpr with
+	| TFunction _ ->
+		e
+	| TReturn None | TReturn (Some { eexpr = TConst _ }) | TReturn (Some { eexpr = TLocal _ }) ->
+		mk (TBlock [
+			stack_pop;
+			e;
+		]) e.etype e.epos
+	| TReturn (Some e) ->
+		mk (TBlock [
+			mk (TVars ["$tmp", t_dynamic, Some (stack_block_loop e)]) t_dynamic e.epos;
+			stack_pop;
+			mk (TReturn (Some (mk (TLocal "$tmp") t_dynamic e.epos))) t_dynamic e.epos
+		]) e.etype e.epos
+	| TTry (v,cases) ->
+		let v = stack_block_loop v in
+		let cases = List.map (fun (n,t,e) ->
+			let e = stack_block_loop e in
+			let e = (match (mk_block e).eexpr with
+				| TBlock l -> mk (TBlock (stack_restore_pos @ l)) e.etype e.epos
+				| _ -> assert false
+			) in
+			n , t , e
+		) cases in
+		mk (TTry (v,cases)) e.etype e.epos
+	| _ ->
+		map_expr stack_block_loop e
+
+let stack_block ?(useadd=false) ctx e =	
+	match (mk_block e).eexpr with
+	| TBlock l -> mk (TBlock (stack_push useadd ctx :: stack_save_pos :: List.map stack_block_loop l @ [stack_pop])) e.etype e.epos
+	| _ -> assert false
+
+(* -------------------------------------------------------------------------- *)
+(* MISC FEATURES *)
+
+let local_find flag vname e =
+	let rec loop2 e =
+		match e.eexpr with
+		| TFunction f ->
+			if not flag && not (List.exists (fun (a,_,_) -> a = vname) f.tf_args) then loop2 f.tf_expr
+		| TBlock _ ->
+			(try
+				Type.iter loop2 e;
+			with
+				Not_found -> ())
+		| TVars vl ->
+			List.iter (fun (v,t,e) ->
+				(match e with
+				| None -> ()
+				| Some e -> loop2 e);
+				if v = vname then raise Not_found;
+			) vl
+		| TConst TSuper ->
+			if vname = "super" then raise Exit
+		| TLocal v ->
+			if v = vname then raise Exit
+		| _ ->
+			iter loop2 e
+	in
+	let rec loop e =
+		match e.eexpr with
+		| TFunction f ->
+			if not (List.exists (fun (a,_,_) -> a = vname) f.tf_args) then loop2 f.tf_expr
+		| TBlock _ ->
+			(try
+				iter loop e;
+			with
+				Not_found -> ())
+		| TVars vl ->
+			List.iter (fun (v,t,e) ->
+				(match e with
+				| None -> ()
+				| Some e -> loop e);
+				if v = vname then raise Not_found;
+			) vl
+		| _ ->
+			iter loop e
+	in
+	try
+		(if flag then loop2 else loop) e;
+		false
+	with
+		Exit ->
+			true
+
+let rec is_volatile t =
+	match t with
+	| TMono r ->
+		(match !r with
+		| Some t -> is_volatile t
+		| _ -> false)
+	| TLazy f ->
+		is_volatile (!f())
+	| TType (t,tl) ->
+		(match t.t_path with
+		| ["mt";"flash"],"Volatile" -> true
+		| _ -> is_volatile (apply_params t.t_types tl t.t_type))
+	| _ ->
+		false

+ 46 - 1
common.ml

@@ -16,6 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *)
+open Type
 
 type package_rule =
 	| Forbidden
@@ -29,23 +30,49 @@ type platform =
 	| Flash9
 	| Php
 
+type pos = Ast.pos
+
+type context_type_api = {
+	(* basic types *)
+	mutable tvoid : t;
+	mutable tint : t;
+	mutable tfloat : t;
+	mutable tbool : t;
+	mutable tnull : t -> t;
+	mutable tstring : t;
+	mutable tarray : t -> t;
+	(* api *)
+	mutable load_module : path -> pos -> module_def;
+	mutable build_instance : module_type -> pos -> ((string * t) list * path * (t list -> t));
+	mutable on_inherit : tclass -> pos -> Ast.class_flag -> bool;
+	mutable on_generate : module_type -> unit;
+	mutable get_type_module : module_type -> module_def;
+}
+
 type context = {
 	(* config *)
 	mutable debug : bool;
 	mutable verbose : bool;
 	mutable platform : platform;
 	mutable class_path : string list;
-	mutable main_class : Type.module_path option; 
+	mutable main_class : Type.path option; 
 	mutable defines : (string,unit) PMap.t;
 	mutable package_rules : (string,package_rule) PMap.t;
+	mutable error : string -> pos -> unit;
+	mutable warning : string -> pos -> unit;
 	(* output *)
 	mutable file : string;
 	mutable flash_version : int;
 	mutable types : Type.module_type list;
 	mutable resources : (string,string) Hashtbl.t;
+	(* typing *)
+	mutable type_api : context_type_api;
 }
 
+exception Abort of string * Ast.pos
+
 let create() =
+	let m = Type.mk_mono() in
 	{
 		debug = false;
 		verbose = false;
@@ -58,11 +85,29 @@ let create() =
 		types = [];
 		flash_version = 8;
 		resources = Hashtbl.create 0;
+		warning = (fun _ _ -> assert false);
+		error = (fun _ _ -> assert false);
+		type_api = {
+			tvoid = m;
+			tint = m;
+			tfloat = m;
+			tbool = m;
+			tnull = (fun _ -> assert false);
+			tstring = m;
+			tarray = (fun _ -> assert false);
+			load_module = (fun _ _ -> assert false);
+			build_instance = (fun _ _ -> assert false);
+			on_inherit = (fun _ _ _ -> true);
+			on_generate = (fun _ -> ());
+			get_type_module = (fun _ -> assert false);
+		};
 	}
 
 let defined ctx v = PMap.mem v ctx.defines
 let define ctx v = ctx.defines <- PMap.add v () ctx.defines
 
+let error msg p = raise (Abort (msg,p))
+
 let platform ctx p = ctx.platform = p
 
 let find_file ctx f =

+ 25 - 10
doc/install.ml

@@ -130,16 +130,31 @@ let compile() =
 	(* HAXE *)
 	Sys.chdir "haxe";
 	command "ocamllex lexer.mll";
-	ocamlc "-I ../ocaml ast.ml type.ml common.ml lexer.ml";
-	ocamlc "-I ../ocaml -pp camlp4o parser.ml";
-	ocamlc "-I ../ocaml -I ../ocaml/swflib -I ../ocaml/xml-light transform.ml typer.ml genswf9.ml genswf8.ml genswf.ml genxml.ml genjs.ml genas3.ml";
-	ocamlc "-I ../ocaml -I ../neko/libs/include/ocaml ../neko/libs/include/ocaml/nast.ml ../neko/libs/include/ocaml/nxml.ml ../neko/libs/include/ocaml/binast.ml genneko.ml";
-	ocamlc "-I ../ocaml -I ../ocaml/extc main.ml";
-	let mlist = ["ast";"type";"common";"lexer";"parser";"transform";"typer";"genswf9";"genswf8";"genswf";"../neko/libs/include/ocaml/nast";"../neko/libs/include/ocaml/nxml";"../neko/libs/include/ocaml/binast";"genneko";"genxml";"genjs";"genas3";"main"] in
-	let libs = ["../ocaml/extLib";"../ocaml/extc/extc";"../ocaml/swflib/swflib";"../ocaml/xml-light/xml-light";"unix"] in
-	let makelibs ext = " " ^ String.concat " " (List.map (fun l -> l ^ ext) libs) ^ " " in
-	if bytecode then command ("ocamlc -custom -o ../bin/haxe-byte" ^ exe_ext ^ makelibs ".cma" ^ modules mlist ".cmo");
-	if native then command ("ocamlopt -o ../bin/haxe" ^ exe_ext ^ makelibs ".cmxa" ^ modules mlist ".cmx");
+	let libs = [
+		"../ocaml/extLib";
+		"../ocaml/extc/extc";
+		"../ocaml/swflib/swflib";
+		"../ocaml/xml-light/xml-light";
+		"unix"
+	] in
+	let paths = [
+		"../ocaml";
+		"../ocaml/swflib";
+		"../ocaml/xml-light";
+		"../neko/libs/include/ocaml"
+	] in
+	let mlist = [
+		"ast";"lexer";"type";"common";"parser";"typecore";
+		"genxml";"typeload";"codegen";"typer";
+		"nast";"binast";"nxml";
+		"genneko";"genas3";"genjs";"genswf8";"genswf9";"genswf";
+		"main";
+	] in
+	let path_str = String.concat " " (List.map (fun s -> "-I " ^ s) paths) in
+	let libs_str ext = " " ^ String.concat " " (List.map (fun l -> l ^ ext) libs) ^ " " in
+	ocamlc (path_str ^ " " ^ modules mlist ".ml");
+	if bytecode then command ("ocamlc -custom -o ../bin/haxe-byte" ^ exe_ext ^ libs_str ".cma" ^ modules mlist ".cmo");
+	if native then command ("ocamlopt -o ../bin/haxe" ^ exe_ext ^ libs_str ".cmxa" ^ modules mlist ".cmx");
 
 in
 let startdir = Sys.getcwd() in

+ 11 - 13
genas3.ml

@@ -22,7 +22,7 @@ open Common
 type context = {
 	ch : out_channel;
 	buf : Buffer.t;
-	path : module_path;
+	path : path;
 	mutable get_sets : (string * bool,string) Hashtbl.t;
 	mutable curclass : tclass;
 	mutable tabs : string;
@@ -135,7 +135,7 @@ let define_local ctx l =
 let spr ctx s = Buffer.add_string ctx.buf s
 let print ctx = Printf.kprintf (fun s -> Buffer.add_string ctx.buf s)
 
-let unsupported = Typer.error "This expression cannot be generated to AS3"
+let unsupported p = error "This expression cannot be generated to AS3" p
 
 let newline ctx =
 	match Buffer.nth ctx.buf (Buffer.length ctx.buf - 1) with
@@ -155,8 +155,6 @@ let open_block ctx =
 	ctx.tabs <- "\t" ^ ctx.tabs;
 	(fun() -> ctx.tabs <- oldt)
 
-let block = Transform.block
-
 let parent e =
 	match e.eexpr with
 	| TParenthesis _ -> e
@@ -375,7 +373,7 @@ and gen_expr ctx e =
 	| TConst c ->
 		gen_constant ctx e.epos c
 	| TLocal s ->
-		spr ctx (try PMap.find s ctx.locals with Not_found -> Typer.error ("Unknown local " ^ s) e.epos)
+		spr ctx (try PMap.find s ctx.locals with Not_found -> error ("Unknown local " ^ s) e.epos)
 	| TEnumField (en,s) ->
 		print ctx "%s.%s" (s_path ctx en.e_path e.epos) (s_ident s)
 	| TArray ({ eexpr = TLocal "__global__" },{ eexpr = TConst (TString s) }) ->
@@ -450,7 +448,7 @@ and gen_expr ctx e =
 		let h = gen_function_header ctx None f [] e.epos in
 		let old = ctx.in_static in
 		ctx.in_static <- true;
-		gen_expr ctx (block f.tf_expr);
+		gen_expr ctx (mk_block f.tf_expr);
 		ctx.in_static <- old;
 		h();
 	| TCall (e,el) ->
@@ -531,13 +529,13 @@ and gen_expr ctx e =
 		handle_break();
 	| TTry (e,catchs) ->
 		spr ctx "try ";
-		gen_expr ctx (block e);
+		gen_expr ctx (mk_block e);
 		List.iter (fun (v,t,e) ->
 			newline ctx;
 			let b = save_locals ctx in
 			let v = define_local ctx v in
 			print ctx "catch( %s : %s )" v (type_str ctx t e.epos);
-			gen_expr ctx (block e);
+			gen_expr ctx (mk_block e);
 			b();
 		) catchs;
 	| TMatch (e,_,cases,def) ->
@@ -568,7 +566,7 @@ and gen_expr ctx e =
 						print ctx "%s : %s = %s.params[%d]" v (type_str ctx t e.epos) tmp n;
 					) l;
 					newline ctx);
-			gen_expr ctx (block e);
+			gen_expr ctx (mk_block e);
 			print ctx "break";
 			newline ctx;
 			b()
@@ -577,7 +575,7 @@ and gen_expr ctx e =
 		| None -> ()
 		| Some e ->
 			spr ctx "default:";
-			gen_expr ctx (block e);
+			gen_expr ctx (mk_block e);
 			print ctx "break";
 			newline ctx;
 		);
@@ -594,7 +592,7 @@ and gen_expr ctx e =
 				gen_value ctx e;
 				spr ctx ":";
 			) el;
-			gen_expr ctx (block e2);
+			gen_expr ctx (mk_block e2);
 			print ctx "break";
 			newline ctx;
 		) cases;
@@ -602,7 +600,7 @@ and gen_expr ctx e =
 		| None -> ()
 		| Some e ->
 			spr ctx "default:";
-			gen_expr ctx (block e);
+			gen_expr ctx (mk_block e);
 			print ctx "break";
 			newline ctx;
 		);
@@ -757,7 +755,7 @@ let generate_field ctx static f =
 		in
 		if not static then loop ctx.curclass;
 		let h = gen_function_header ctx (Some (s_ident f.cf_name)) fd f.cf_params p in
-		gen_expr ctx (block fd.tf_expr);
+		gen_expr ctx (mk_block fd.tf_expr);
 		h()
 	| _ ->
 		if ctx.curclass.cl_path = (["flash"],"Boot") && f.cf_name = "init" then

+ 15 - 17
genjs.ml

@@ -55,7 +55,7 @@ let ident s = if Hashtbl.mem kwds s then "$" ^ s else s
 let spr ctx s = Buffer.add_string ctx.buf s
 let print ctx = Printf.kprintf (fun s -> Buffer.add_string ctx.buf s)
 
-let unsupported = Typer.error "This expression cannot be compiled to Javascript"
+let unsupported p = error "This expression cannot be compiled to Javascript" p
 
 let newline ctx =
 	match Buffer.nth ctx.buf (Buffer.length ctx.buf - 1) with
@@ -70,13 +70,11 @@ let rec concat ctx s f = function
 		spr ctx s;
 		concat ctx s f l
 
-let block = Transform.block
-
 let fun_block ctx f =
 	if ctx.com.debug then
-		Transform.stack_block (ctx.current,fst ctx.curmethod) f.tf_expr
+		Codegen.stack_block (ctx.current,fst ctx.curmethod) f.tf_expr
 	else
-		block f.tf_expr
+		mk_block f.tf_expr
 
 let parent e =
 	match e.eexpr with
@@ -120,7 +118,7 @@ let gen_constant ctx p = function
 	| TInt i -> print ctx "%ld" i
 	| TFloat s -> spr ctx s
 	| TString s ->
-		if String.contains s '\000' then Typer.error "A String cannot contain \\0 characters" p;
+		if String.contains s '\000' then error "A String cannot contain \\0 characters" p;
 		print ctx "\"%s\"" (Ast.s_escape s)
 	| TBool b -> spr ctx (if b then "true" else "false")
 	| TNull -> spr ctx "null"
@@ -332,7 +330,7 @@ and gen_expr ctx e =
 		handle_break();
 	| TTry (e,catchs) ->
 		spr ctx "try ";
-		gen_expr ctx (block e);
+		gen_expr ctx (mk_block e);
 		newline ctx;
 		let id = ctx.id_counter in
 		ctx.id_counter <- ctx.id_counter + 1;
@@ -407,7 +405,7 @@ and gen_expr ctx e =
 						print ctx "%s = $e[%d]" v n;
 					) l;
 					newline ctx);
-			gen_expr ctx (block e);
+			gen_expr ctx (mk_block e);
 			print ctx "break";
 			newline ctx
 		) cases;
@@ -415,7 +413,7 @@ and gen_expr ctx e =
 		| None -> ()
 		| Some e ->
 			spr ctx "default:";
-			gen_expr ctx (block e);
+			gen_expr ctx (mk_block e);
 			print ctx "break";
 			newline ctx;
 		);
@@ -431,7 +429,7 @@ and gen_expr ctx e =
 				gen_value ctx e;
 				spr ctx ":";
 			) el;
-			gen_expr ctx (block e2);
+			gen_expr ctx (mk_block e2);
 			print ctx "break";
 			newline ctx;
 		) cases;
@@ -439,7 +437,7 @@ and gen_expr ctx e =
 		| None -> ()
 		| Some e ->
 			spr ctx "default:";
-			gen_expr ctx (block e);
+			gen_expr ctx (mk_block e);
 			print ctx "break";
 			newline ctx;
 		);
@@ -575,7 +573,7 @@ let gen_class_static_field ctx c f =
 		print ctx "%s%s = null" (s_path c.cl_path) (field f.cf_name);
 		newline ctx
 	| Some e ->
-		let e = Transform.block_vars e in
+		let e = Codegen.block_vars e in
 		match e.eexpr with
 		| TFunction _ ->
 			ctx.curmethod <- (f.cf_name,false);
@@ -593,7 +591,7 @@ let gen_class_field ctx c f =
 		newline ctx
 	| Some e ->
 		ctx.curmethod <- (f.cf_name,false);
-		gen_value ctx (Transform.block_vars e);
+		gen_value ctx (Codegen.block_vars e);
 		newline ctx
 
 let generate_class ctx c =
@@ -604,7 +602,7 @@ let generate_class ctx c =
 	print ctx "%s = " p;
 	(match c.cl_constructor with
 	| Some { cf_expr = Some e } ->
-		(match Transform.block_vars e with
+		(match Codegen.block_vars e with
 		| { eexpr = TFunction f } ->
 			let args  = List.map arg_name f.tf_args in
 			let a, args = (match args with [] -> "p" , ["p"] | x :: _ -> x, args) in
@@ -666,7 +664,7 @@ let generate_type ctx = function
 	| TClassDecl c ->
 		(match c.cl_init with
 		| None -> ()
-		| Some e -> ctx.inits <- Transform.block_vars e :: ctx.inits);
+		| Some e -> ctx.inits <- Codegen.block_vars e :: ctx.inits);
 		if not c.cl_extern then generate_class ctx c
 	| TEnumDecl e when e.e_extern ->
 		()
@@ -696,9 +694,9 @@ let generate com =
 	print ctx "js.Boot.__res = {}";
 	newline ctx;
 	if com.debug then begin
-		print ctx "%s = []" Transform.stack_var;
+		print ctx "%s = []" Codegen.stack_var;
 		newline ctx;
-		print ctx "%s = []" Transform.exc_stack_var;
+		print ctx "%s = []" Codegen.exc_stack_var;
 		newline ctx;
 	end;
 	Hashtbl.iter (fun name data ->

+ 1 - 4
genneko.ml

@@ -31,9 +31,6 @@ type context = {
 	mutable inits : texpr list;
 }
 
-let error msg p =
-	raise (Typer.Error (Typer.Custom msg,p))
-
 let files = Hashtbl.create 0
 
 let pos ctx p =
@@ -191,7 +188,7 @@ let rec gen_big_string ctx p s =
 let gen_constant ctx pe c =
 	let p = pos ctx pe in
 	match c with
-	| TInt i -> (try int p (Int32.to_int i) with _ -> Typer.error "This integer is too big to be compiled to a Neko 31-bit integer. Please use a Float instead" pe)
+	| TInt i -> (try int p (Int32.to_int i) with _ -> error "This integer is too big to be compiled to a Neko 31-bit integer. Please use a Float instead" pe)
 	| TFloat f -> (EConst (Float f),p)
 	| TString s -> call p (field p (ident p "String") "new") [gen_big_string ctx p s]
 	| TBool b -> (EConst (if b then True else False),p)

+ 22 - 19
genswf8.ml

@@ -43,7 +43,7 @@ type context = {
 	packages : (string list,unit) Hashtbl.t;
 	flash6 : bool;
 	mutable idents : (string * bool,int) Hashtbl.t;
-	mutable movieclips : module_path list;
+	mutable movieclips : path list;
 	mutable inits : texpr list;
 	mutable statics : (tclass * bool * string * texpr) list;
 	mutable regs : (string,register) PMap.t;
@@ -62,8 +62,8 @@ type context = {
 	mutable in_loop : bool;
 }
 
-let error p = Typer.error "Invalid expression" p
-let stack_error p = Typer.error "Stack error" p
+let invalid_expr p = error "Invalid expression" p
+let stack_error p = error "Stack error" p
 let protect_all = ref true
 let extern_boot = ref false
 let debug_pass = ref ""
@@ -437,7 +437,7 @@ let segment ctx =
 (* Generation Helpers *)
 
 let define_var ctx v ef exprs =
-	if ctx.flash6 || List.exists (Transform.local_find false v) exprs then begin
+	if ctx.flash6 || List.exists (Codegen.local_find false v) exprs then begin
 		push ctx [VStr (v,false)];
 		ctx.regs <- PMap.add v NoReg ctx.regs;
 		match ef with
@@ -531,9 +531,9 @@ let rec gen_big_string ctx s =
 let rec gen_constant ctx c p =
 	match c with
 	| TInt i -> push ctx [VInt32 i]
-	| TFloat s -> push ctx [VFloat (try float_of_string s with _ -> error p)]
+	| TFloat s -> push ctx [VFloat (try float_of_string s with _ -> invalid_expr p)]
 	| TString s ->
-		if String.contains s '\000' then Typer.error "A String cannot contain \\0 characters" p;
+		if String.contains s '\000' then error "A String cannot contain \\0 characters" p;
 		push ctx [VStr (s,true)]
 	| TBool b -> write ctx (APush [PBool b])
 	| TNull -> push ctx [VNull]
@@ -578,7 +578,7 @@ let rec gen_access ctx forcall e =
 		(match follow e.etype with
 		| TFun _ -> VarClosure
 		| _ ->
-			if not !protect_all && Transform.is_volatile e.etype then
+			if not !protect_all && Codegen.is_volatile e.etype then
 				VarVolatile
 			else
 				VarObj)
@@ -598,7 +598,7 @@ let rec gen_access ctx forcall e =
 		| TEnumDecl e -> gen_path ctx e.e_path false
 		| TTypeDecl _ -> assert false)
 	| _ ->
-		if not forcall then error e.epos;
+		if not forcall then invalid_expr e.epos;
 		gen_expr ctx true e;
 		write ctx (APush [PUndefined]);
 		VarObj
@@ -937,7 +937,7 @@ and gen_expr_2 ctx retval e =
 		let block = open_block ctx in
 		let old_in_loop = ctx.in_loop in
 		let old_meth = ctx.curmethod in
-		let reg_super = Transform.local_find true "super" f.tf_expr in
+		let reg_super = Codegen.local_find true "super" f.tf_expr in
 		if snd ctx.curmethod then
 			ctx.curmethod <- (fst ctx.curmethod ^ "@" ^ string_of_int (Lexer.get_error_line e.epos), true)
 		else
@@ -952,7 +952,7 @@ and gen_expr_2 ctx retval e =
 		ctx.in_loop <- false;
 		let pargs = ref [] in
 		let rargs = List.map (fun (a,_,t) ->
-			let no_reg = ctx.flash6 || Transform.local_find false a f.tf_expr in
+			let no_reg = ctx.flash6 || Codegen.local_find false a f.tf_expr in
 			if no_reg then begin
 				ctx.regs <- PMap.add a NoReg ctx.regs;
 				pargs := unprotect a :: !pargs;
@@ -964,14 +964,17 @@ and gen_expr_2 ctx retval e =
 				r , ""
 			end
 		) f.tf_args in
-		let tf = begin_func ctx reg_super (Transform.local_find true "__arguments__" f.tf_expr) rargs in
+		let tf = begin_func ctx reg_super (Codegen.local_find true "__arguments__" f.tf_expr) rargs in
 		ctx.fun_pargs <- (ctx.code_pos, List.rev !pargs) :: ctx.fun_pargs;
 		if ctx.com.debug then begin
+			let cur = (ctx.curclass,fst ctx.curmethod) in
+			gen_expr ctx false (Codegen.stack_push true cur);
+			gen_expr ctx false Codegen.stack_save_pos;
 			let start_try = gen_try ctx in
-			gen_expr ctx false (Transform.stack_block ~useadd:true (ctx.curclass,fst ctx.curmethod) f.tf_expr);
+			gen_expr ctx false (Codegen.stack_block_loop f.tf_expr);
 			let end_try = start_try() in
 			(* if $spos == 1 , then no upper call, so report as uncaught *)
-			getvar ctx (access_local ctx Transform.stack_var_pos);
+			getvar ctx (access_local ctx Codegen.stack_var_pos);
 			push ctx [VInt 1];
 			write ctx AEqual;
 			write ctx ANot;
@@ -1110,7 +1113,7 @@ let gen_class_static_field ctx c flag f =
 		push ctx [VReg 0; VStr (f.cf_name,flag); VNull];
 		setvar ctx VarObj
 	| Some e ->
-		let e = Transform.block_vars e in
+		let e = Codegen.block_vars e in
 		match e.eexpr with
 		| TFunction _ ->
 			push ctx [VReg 0; VStr (f.cf_name,flag)];
@@ -1135,7 +1138,7 @@ let gen_class_field ctx flag f =
 		push ctx [VNull]
 	| Some e ->
 		ctx.curmethod <- (f.cf_name,false);
-		gen_expr ctx true (Transform.block_vars e));
+		gen_expr ctx true (Codegen.block_vars e));
 	setvar ctx VarObj
 
 let gen_enum_field ctx e f =
@@ -1232,7 +1235,7 @@ let gen_type_def ctx t =
 	| TClassDecl c ->
 		(match c.cl_init with
 		| None -> ()
-		| Some e -> ctx.inits <- Transform.block_vars e :: ctx.inits);
+		| Some e -> ctx.inits <- Codegen.block_vars e :: ctx.inits);
 		gen_package ctx c.cl_path c.cl_extern;
 		if c.cl_extern then
 			()
@@ -1255,7 +1258,7 @@ let gen_type_def ctx t =
 		| Some { cf_expr = Some e } ->
 			have_constr := true;
 			ctx.curmethod <- ("new",false);
-			gen_expr ctx true (Transform.block_vars e)
+			gen_expr ctx true (Codegen.block_vars e)
 		| _ ->
 			let f = begin_func ctx true false [] in
 			f());
@@ -1435,10 +1438,10 @@ let generate com =
 	protect_all := not (Common.defined com "swf-mark");
 	extern_boot := true;
 	if com.debug then begin
-		push ctx [VStr (Transform.stack_var,false); VInt 0];
+		push ctx [VStr (Codegen.stack_var,false); VInt 0];
 		write ctx AInitArray;
 		write ctx ASet;
-		push ctx [VStr (Transform.exc_stack_var,false); VInt 0];
+		push ctx [VStr (Codegen.exc_stack_var,false); VInt 0];
 		write ctx AInitArray;
 		write ctx ASet;
 	end;

+ 14 - 14
genswf9.ml

@@ -93,8 +93,8 @@ type context = {
 	mutable for_call : bool;
 }
 
-let error p = Typer.error "Invalid expression" p
-let stack_error p = Typer.error "Stack error" p
+let invalid_expr p = error "Invalid expression" p
+let stack_error p = error "Stack error" p
 
 let index_int (x : int) : 'a index = Obj.magic (x + 1)
 let index_nz_int (x : int) : 'a index_nz = Obj.magic x
@@ -351,7 +351,7 @@ let pop ctx n =
 	ctx.infos.istack <- old
 
 let define_local ctx ?(init=false) name t el =
-	let l = (if List.exists (Transform.local_find false name) el then begin
+	let l = (if List.exists (Codegen.local_find false name) el then begin
 			let pos = (try
 				let slot , _ , _ = (List.find (fun (_,x,_) -> name = x) ctx.block_vars) in
 				slot
@@ -373,7 +373,7 @@ let define_local ctx ?(init=false) name t el =
 let is_set v = (Obj.magic v) = Write
 
 let gen_local_access ctx name p (forset : 'a)  : 'a access =
-	match (try PMap.find name ctx.locals with Not_found -> Typer.error ("Unbound variable " ^ name) p) with
+	match (try PMap.find name ctx.locals with Not_found -> error ("Unbound variable " ^ name) p) with
 	| LReg r ->
 		VReg r
 	| LScope n ->
@@ -507,7 +507,7 @@ let begin_fun ctx args tret el stat p =
 		match e.eexpr with
 		| TFunction _ -> ()
 		| TConst TThis | TConst TSuper -> raise Exit
-		| _ -> Transform.iter find_this e
+		| _ -> Type.iter find_this e
 	in
 	let this_reg = try List.iter find_this el; false with Exit -> true in
 	ctx.locals <- PMap.foldi (fun name l acc ->
@@ -655,7 +655,7 @@ let gen_constant ctx c t p =
 		write ctx HNull;
 		(match classify ctx t with
 		| KInt | KBool | KUInt | KFloat ->
-			Typer.error ("In Flash9, null can't be used as basic type " ^ s_type (print_context()) t) p
+			error ("In Flash9, null can't be used as basic type " ^ s_type (print_context()) t) p
 		| x -> coerce ctx x)
 	| TThis ->
 		write ctx HThis
@@ -676,7 +676,7 @@ let gen_access ctx e (forset : 'a) : 'a access =
 		gen_local_access ctx i e.epos forset
 	| TField (e1,f) ->
 		let id, k, closure = property f e1.etype in
-		if closure && not ctx.for_call then Typer.error "In Flash9, this method cannot be accessed this way : please define a local function" e1.epos;
+		if closure && not ctx.for_call then error "In Flash9, this method cannot be accessed this way : please define a local function" e1.epos;
 		(match e1.eexpr with
 		| TConst TThis when not ctx.in_static -> write ctx (HFindPropStrict id)
 		| _ -> gen_expr ctx true e1);
@@ -708,7 +708,7 @@ let gen_access ctx e (forset : 'a) : 'a access =
 		if is_set forset then write ctx HGetGlobalScope;
 		VGlobal id
 	| _ ->
-		error e.epos
+		invalid_expr e.epos
 
 let rec gen_expr_content ctx retval e =
 	match e.eexpr with
@@ -819,7 +819,7 @@ let rec gen_expr_content ctx retval e =
 	| TUnop (op,flag,e) ->
 		gen_unop ctx retval op flag e
 	| TTry (e2,cases) ->
-		if ctx.infos.istack <> 0 then Typer.error "Cannot compile try/catch as a right-side expression in Flash9" e.epos;
+		if ctx.infos.istack <> 0 then error "Cannot compile try/catch as a right-side expression in Flash9" e.epos;
 		let branch = begin_branch ctx in
 		let p = ctx.infos.ipos in
 		gen_expr ctx retval e2;
@@ -1349,7 +1349,7 @@ and jump_expr ctx e jif =
 	jump_expr_gen ctx e jif (jump ctx)
 
 let generate_method ctx fdata stat =
-	generate_function ctx { fdata with tf_expr = Transform.block_vars fdata.tf_expr } stat
+	generate_function ctx { fdata with tf_expr = Codegen.block_vars fdata.tf_expr } stat
 
 let generate_construct ctx fdata c =
 	(* make all args optional to allow no-param constructor *)
@@ -1374,7 +1374,7 @@ let generate_construct ctx fdata c =
 			write ctx (HInitProp id);
 		| _ -> ()
 	) c.cl_fields;
-	gen_expr ctx false (Transform.block_vars fdata.tf_expr);
+	gen_expr ctx false (Codegen.block_vars fdata.tf_expr);
 	write ctx HRetVoid;
 	f() , List.length fdata.tf_args
 
@@ -1416,7 +1416,7 @@ let generate_class_statics ctx c =
 				first := false;
 			end;
 			write ctx (HReg r.rid);
-			gen_expr ctx true (Transform.block_vars e);
+			gen_expr ctx true (Codegen.block_vars e);
 			write ctx (HSetSlot !nslot);
 		| _ ->
 			incr nslot
@@ -1537,7 +1537,7 @@ let generate_class ctx c =
 		hlc_interface = c.cl_interface;
 		hlc_namespace = None;
 		hlc_implements = Array.of_list (List.map (fun (c,_) ->
-			if not c.cl_interface then Typer.error "Can't implement class in Flash9" c.cl_pos;
+			if not c.cl_interface then error "Can't implement class in Flash9" c.cl_pos;
 			type_path ctx c.cl_path
 		) c.cl_implements);
 		hlc_construct = cid;
@@ -1720,7 +1720,7 @@ let generate_inits ctx types =
 		| TClassDecl c ->
 			(match c.cl_init with
 			| None -> ()
-			| Some e -> gen_expr ctx false (Transform.block_vars e));
+			| Some e -> gen_expr ctx false (Codegen.block_vars e));
 		| _ -> ()
 	) types;
 	List.iter (fun (t,_) ->

+ 4 - 6
genxml.ml

@@ -117,8 +117,8 @@ let rec exists f c =
 			| None -> true
 			| Some (csup,_) -> exists f csup
 
-let gen_type_decl ctx t =
-	let m = Typer.module_of_type ctx t in
+let gen_type_decl com t =
+	let m = com.type_api.get_type_module t in
 	match t with
 	| TClassDecl c ->
 		let stats = List.map (gen_field ["static","1"]) c.cl_ordered_statics in
@@ -172,9 +172,9 @@ let rec write_xml ch tabs x =
 	| CData s ->
 		IO.printf ch "<![CDATA[%s]]>" s
 
-let generate com ctx file =
+let generate com file =
 	let t = Common.timer "construct xml" in
-	let x = node "haxe" [] (List.map (gen_type_decl ctx) com.types) in
+	let x = node "haxe" [] (List.map (gen_type_decl com) com.types) in
 	t();
 	let t = Common.timer "write xml" in
 	let ch = IO.output_channel (open_out_bin file) in
@@ -188,5 +188,3 @@ let gen_type_string ctx t =
 	write_xml ch "" x;
 	IO.close_out ch
 
-;;
-Typer.generate_meta_data := gen_type_string;

+ 8 - 2
haxe.vcproj

@@ -67,6 +67,9 @@
 		<File
 			RelativePath=".\ast.ml">
 		</File>
+		<File
+			RelativePath=".\codegen.ml">
+		</File>
 		<File
 			RelativePath=".\common.ml">
 		</File>
@@ -98,10 +101,13 @@
 			RelativePath=".\parser.ml">
 		</File>
 		<File
-			RelativePath=".\transform.ml">
+			RelativePath=".\type.ml">
+		</File>
+		<File
+			RelativePath=".\typecore.ml">
 		</File>
 		<File
-			RelativePath=".\type.ml">
+			RelativePath=".\typeload.ml">
 		</File>
 		<File
 			RelativePath=".\typer.ml">

+ 19 - 17
main.ml

@@ -21,7 +21,6 @@ open Genswf
 open Common
 
 let prompt = ref false
-let has_error = ref false
 let display = ref false
 let measure_times = ref false
 
@@ -36,7 +35,7 @@ let normalize_path p =
 		| '\\' | '/' -> p
 		| _ -> p ^ "/"
 
-let warn msg p =
+let message msg p =
 	if p = Ast.null_pos then
 		prerr_endline msg
 	else begin
@@ -54,7 +53,7 @@ let do_exit() =
 	exit 1
 
 let report msg p =
-	warn msg p;
+	message msg p;
 	do_exit()
 
 let htmlescape s =
@@ -69,15 +68,6 @@ let report_list l =
 	) (List.sort (fun (a,_,_) (b,_,_) -> compare a b) l);
 	prerr_endline "</list>"
 
-let type_error e p =
-	warn (Typer.error_msg e) p;
-	has_error := true
-
-let parse_error e p =
-	Lexer.save_lines();
-	warn (Parser.error_msg e) p;
-	has_error := true
-
 let file_extension f =
 	let cl = ExtString.String.nsplit f "." in
 	match List.rev cl with
@@ -186,12 +176,22 @@ try
 	let cmds = ref [] in
 	let excludes = ref [] in
 	let libs = ref [] in
+	let has_error = ref false in
 	let gen_as3 = ref false in
 	let no_output = ref false in
 	let did_something = ref false in
 	let root_packages = ["neko"; "flash"; "flash9"; "js"; "php"] in
 	Common.define com ("haxe_" ^ string_of_int version);
-	Parser.display_error := parse_error;
+	com.warning <- message;
+	com.error <- (fun msg p ->
+		message msg p;
+		has_error := true;
+	);
+	Parser.display_error := (fun e p ->
+		Lexer.save_lines();
+		message (Parser.error_msg e) p;
+		has_error := true;
+	);
 	Parser.use_doc := false;
 	(try
 		let p = Sys.getenv "HAXE_LIBRARY_PATH" in
@@ -391,8 +391,9 @@ try
 	end else begin
 		if com.verbose then print_endline ("Classpath : " ^ (String.concat ";" com.class_path));
 		let t = Common.timer "typing" in
-		let ctx = Typer.context com type_error warn in
-		List.iter (fun cpath -> ignore(Typer.load ctx cpath Ast.null_pos)) (List.rev !classes);
+		Typecore.type_expr_ref := (fun ctx e need_val -> Typer.type_expr ~need_val ctx e);
+		let ctx = Typer.create com in		
+		List.iter (fun cpath -> ignore(com.type_api.load_module cpath Ast.null_pos)) (List.rev !classes);
 		Typer.finalize ctx;
 		t();
 		if !has_error then do_exit();
@@ -421,7 +422,7 @@ try
 		| None -> ()
 		| Some file ->
 			if com.verbose then print_endline ("Generating xml : " ^ com.file);
-			Genxml.generate com ctx file);
+			Genxml.generate com file);
 	end;
 	if not !no_output then List.iter (fun cmd ->
 		let t = Common.timer "command" in
@@ -433,9 +434,10 @@ try
 		t();
 	) (List.rev !cmds)
 with
+	| Common.Abort (m,p) -> report m p
 	| Lexer.Error (m,p) -> report (Lexer.error_msg m) p
 	| Parser.Error (m,p) -> report (Parser.error_msg m) p
-	| Typer.Error (m,p) -> report (Typer.error_msg m) p
+	| Typecore.Error (m,p) -> report (Typecore.error_msg m) p
 	| Failure msg | Arg.Bad msg -> report ("Error : " ^ msg) Ast.null_pos
 	| Arg.Help msg -> print_string msg
 	| Hxml_found -> ()

+ 1 - 1
std/haxe/io/Bytes.hx

@@ -201,7 +201,7 @@ class Bytes {
 		var a = new Array();
 		// utf8-decode
 		for( i in 0...s.length ) {
-			var c : Int = untyped s.cca(i);
+			var c : Int = untyped s["cca"](i);
 			if( c < 0x7F )
 				a.push(c);
 			else if( c < 0x7FF ) {

+ 0 - 331
transform.ml

@@ -1,331 +0,0 @@
-(*
- *  Haxe Compiler
- *  Copyright (c)2005 Nicolas Cannasse
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *)
-open Ast
-open Type
-
-let rec iter f e =
-	match e.eexpr with
-	| TConst _
-	| TLocal _
-	| TEnumField _
-	| TBreak
-	| TContinue
-	| TTypeExpr _ -> ()
-	| TArray (e1,e2)
-	| TBinop (_,e1,e2)
-	| TFor (_,_,e1,e2)
-	| TWhile (e1,e2,_)
-		-> f e1; f e2
-	| TThrow e
-	| TField (e,_)
-	| TParenthesis e
-	| TUnop (_,_,e)
-	| TFunction { tf_expr = e }
-		-> f e
-	| TArrayDecl el 
-	| TNew (_,_,el)
-	| TBlock el
-		-> List.iter f el
-	| TObjectDecl el -> List.iter (fun (_,e) -> f e) el
-	| TCall (e,el) -> f e; List.iter f el
-	| TVars vl -> List.iter (fun (_,_,eo) -> match eo with None -> () | Some e -> f e) vl
-	| TIf (e,e1,e2) -> f e; f e1; (match e2 with None -> () | Some e -> f e)
-	| TSwitch (e,cases,def) -> f e; List.iter (fun (el,e) -> List.iter f el; f e) cases; (match def with None -> () | Some e -> f e)
-	| TMatch (e,_,cases,def) -> f e; List.iter (fun (_,_,e) -> f e) cases; (match def with None -> () | Some e -> f e)
-	| TTry (e,catches) -> f e; List.iter (fun (_,_,e) -> f e) catches
-	| TReturn eo -> (match eo with None -> () | Some e -> f e)
-
-let rec map f e =
-	match e.eexpr with
-	| TConst _
-	| TLocal _
-	| TEnumField _
-	| TBreak
-	| TContinue
-	| TTypeExpr _ ->
-		e
-	| TArray (e1,e2) ->
-		{ e with eexpr = TArray (f e1,f e2) }
-	| TBinop (op,e1,e2) ->
-		{ e with eexpr = TBinop (op,f e1,f e2) }
-	| TFor (v,t,e1,e2) ->
-		{ e with eexpr = TFor (v,t,f e1,f e2) }
-	| TWhile (e1,e2,flag) ->
-		{ e with eexpr = TWhile (f e1,f e2,flag) }
-	| TThrow e1 ->
-		{ e with eexpr = TThrow (f e1) }
-	| TField (e1,v) ->
-		{ e with eexpr = TField (f e1,v) }
-	| TParenthesis e1 ->
-		{ e with eexpr = TParenthesis (f e1) }
-	| TUnop (op,pre,e1) ->
-		{ e with eexpr = TUnop (op,pre,f e1) }
-	| TArrayDecl el ->
-		{ e with eexpr = TArrayDecl (List.map f el) }
-	| TNew (t,pl,el) ->
-		{ e with eexpr = TNew (t,pl,List.map f el) }
-	| TBlock el ->
-		{ e with eexpr = TBlock (List.map f el) }
-	| TObjectDecl el ->
-		{ e with eexpr = TObjectDecl (List.map (fun (v,e) -> v, f e) el) }
-	| TCall (e1,el) ->
-		{ e with eexpr = TCall (f e1, List.map f el) }
-	| TVars vl ->
-		{ e with eexpr = TVars (List.map (fun (v,t,e) -> v , t , match e with None -> None | Some e -> Some (f e)) vl) }
-	| TFunction fu ->
-		{ e with eexpr = TFunction { fu with tf_expr = f fu.tf_expr } }
-	| TIf (ec,e1,e2) ->
-		{ e with eexpr = TIf (f ec,f e1,match e2 with None -> None | Some e -> Some (f e)) }
-	| TSwitch (e1,cases,def) ->
-		{ e with eexpr = TSwitch (f e1, List.map (fun (el,e2) -> List.map f el, f e2) cases, match def with None -> None | Some e -> Some (f e)) }
-	| TMatch (e1,t,cases,def) ->
-		{ e with eexpr = TMatch (f e1, t, List.map (fun (cl,params,e) -> cl, params, f e) cases, match def with None -> None | Some e -> Some (f e)) }
-	| TTry (e1,catches) ->
-		{ e with eexpr = TTry (f e1, List.map (fun (v,t,e) -> v, t, f e) catches) }
-	| TReturn eo ->
-		{ e with eexpr = TReturn (match eo with None -> None | Some e -> Some (f e)) }
-
-let local_find flag vname e =
-	let rec loop2 e =
-		match e.eexpr with
-		| TFunction f ->
-			if not flag && not (List.exists (fun (a,_,_) -> a = vname) f.tf_args) then loop2 f.tf_expr
-		| TBlock _ ->
-			(try
-				iter loop2 e;
-			with
-				Not_found -> ())
-		| TVars vl ->
-			List.iter (fun (v,t,e) ->
-				(match e with
-				| None -> ()
-				| Some e -> loop2 e);
-				if v = vname then raise Not_found;
-			) vl
-		| TConst TSuper ->
-			if vname = "super" then raise Exit
-		| TLocal v ->
-			if v = vname then raise Exit
-		| _ ->
-			iter loop2 e
-	in
-	let rec loop e =
-		match e.eexpr with
-		| TFunction f ->
-			if not (List.exists (fun (a,_,_) -> a = vname) f.tf_args) then loop2 f.tf_expr
-		| TBlock _ ->
-			(try
-				iter loop e;
-			with
-				Not_found -> ())
-		| TVars vl ->
-			List.iter (fun (v,t,e) ->
-				(match e with
-				| None -> ()
-				| Some e -> loop e);
-				if v = vname then raise Not_found;
-			) vl
-		| _ ->
-			iter loop e
-	in
-	try
-		(if flag then loop2 else loop) e;
-		false
-	with
-		Exit ->
-			true
-
-let block_vars e =
-	let add_var map v d = map := PMap.add v d (!map) in
-	let wrap e used =
-		match PMap.foldi (fun v _ acc -> v :: acc) used [] with
-		| [] -> e
-		| vars ->
-			mk (TCall (
-				(mk (TFunction {
-					tf_args = List.map (fun v -> v , false, t_dynamic) vars;
-					tf_type = t_dynamic;
-					tf_expr = mk (TReturn (Some e)) t_dynamic e.epos;
-				}) t_dynamic e.epos),
-				List.map (fun v -> mk (TLocal v) t_dynamic e.epos) vars)
-			) t_dynamic e.epos
-	in
-	let rec in_fun vars depth used_locals e =
-		match e.eexpr with
-		| TLocal v ->
-			(try
-				if PMap.find v vars = depth then add_var used_locals v depth;				
-			with
-				Not_found -> ())
-		| _ ->
-			iter (in_fun vars depth used_locals) e
-
-	and in_loop vars depth e =
-		match e.eexpr with
-		| TVars l ->
-			{ e with eexpr = TVars (List.map (fun (v,t,e) ->
-				let e = (match e with None -> None | Some e -> Some (in_loop vars depth e)) in
-				add_var vars v depth;
-				v, t, e
-			) l) }
-		| TFor (v,t,i,e1) ->
-			let new_vars = PMap.add v depth (!vars) in
-			{ e with eexpr = TFor (v,t,in_loop vars depth i,in_loop (ref new_vars) depth e1) }
-		| TTry (e1,cases) ->
-			let e1 = in_loop vars depth e1 in
-			let cases = List.map (fun (v,t,e) ->
-				let new_vars = PMap.add v depth (!vars) in
-				v , t, in_loop (ref new_vars) depth e
-			) cases in
-			{ e with eexpr = TTry (e1,cases) }
-		| TMatch (e1,t,cases,def) ->
-			let e1 = in_loop vars depth e1 in
-			let cases = List.map (fun (cl,params,e) ->
-				let e = (match params with
-					| None -> in_loop vars depth e
-					| Some l ->
-						let new_vars = List.fold_left (fun acc (v,t) ->
-							match v with
-							| None -> acc
-							| Some name -> PMap.add name depth acc
-						) (!vars) l in
-						in_loop (ref new_vars) depth e
-				) in
-				cl , params, e
-			) cases in
-			let def = (match def with None -> None | Some e -> Some (in_loop vars depth e)) in
-			{ e with eexpr = TMatch (e1, t, cases, def) }
-		| TBlock l ->
-			let new_vars = (ref !vars) in
-			map (in_loop new_vars depth) e
-		| TFunction _ ->
-			let new_vars = !vars in
-			let used = ref PMap.empty in
-			iter (in_fun new_vars depth used) e;
-			let e = wrap e (!used) in
-			let new_vars = ref (PMap.foldi (fun v _ acc -> PMap.remove v acc) (!used) new_vars) in
-			map (in_loop new_vars (depth + 1)) e
-		| _ ->
-			map (in_loop vars depth) e
-	and out_loop e =
-		match e.eexpr with
-		| TFor _ | TWhile _ ->
-			in_loop (ref PMap.empty) 0 e
-		| _ ->
-			map out_loop e
-	in
-	out_loop e
-
-let emk e = mk e (mk_mono()) null_pos
-
-let block e =
-	match e.eexpr with
-	| TBlock (_ :: _) -> e
-	| _ -> mk (TBlock [e]) e.etype e.epos
-
-let stack_var = "$s"
-let exc_stack_var = "$e"
-let stack_var_pos = "$spos"
-let stack_e = emk (TLocal stack_var)
-let stack_pop = emk (TCall (emk (TField (stack_e,"pop")),[]))
-
-let stack_push useadd (c,m) =
-	emk (TCall (emk (TField (stack_e,"push")),[
-		if useadd then
-			emk (TBinop (
-				OpAdd,
-				emk (TConst (TString (s_type_path c.cl_path ^ "::"))),
-				emk (TConst (TString m))
-			))
-		else
-			emk (TConst (TString (s_type_path c.cl_path ^ "::" ^ m)))
-	]))
-
-let stack_save_pos =
-	emk (TVars [stack_var_pos, t_dynamic, Some (emk (TField (stack_e,"length")))])
-
-let stack_restore_pos =
-	let ev = emk (TLocal exc_stack_var) in
-	[
-	emk (TBinop (OpAssign, ev, emk (TArrayDecl [])));
-	emk (TWhile (
-		emk (TBinop (OpGte,
-			emk (TField (stack_e,"length")),
-			emk (TLocal stack_var_pos)
-		)),
-		emk (TCall (
-			emk (TField (ev,"unshift")),
-			[emk (TCall (
-				emk (TField (stack_e,"pop")),
-				[]
-			))]
-		)),
-		NormalWhile
-	));
-	emk (TCall (emk (TField (stack_e,"push")),[ emk (TArray (ev,emk (TConst (TInt 0l)))) ]))
-	]
-
-let stack_block ?(useadd=false) ctx e =
-	let rec loop e =
-		match e.eexpr with
-		| TFunction _ ->
-			e
-		| TReturn None | TReturn (Some { eexpr = TConst _ }) | TReturn (Some { eexpr = TLocal _ }) ->
-			mk (TBlock [
-				stack_pop;
-				e;
-			]) e.etype e.epos
-		| TReturn (Some e) ->
-			mk (TBlock [
-				mk (TVars ["$tmp", t_dynamic, Some (loop e)]) t_dynamic e.epos;
-				stack_pop;
-				mk (TReturn (Some (mk (TLocal "$tmp") t_dynamic e.epos))) t_dynamic e.epos
-			]) e.etype e.epos
-		| TTry (v,cases) ->
-			let v = loop v in
-			let cases = List.map (fun (n,t,e) ->
-				let e = loop e in
-				let e = (match (block e).eexpr with
-					| TBlock l -> mk (TBlock (stack_restore_pos @ l)) e.etype e.epos
-					| _ -> assert false
-				) in
-				n , t , e
-			) cases in
-			mk (TTry (v,cases)) e.etype e.epos
-		| _ ->
-			map loop e
-	in
-	match (block e).eexpr with
-	| TBlock l -> mk (TBlock (stack_push useadd ctx :: stack_save_pos :: List.map loop l @ [stack_pop])) e.etype e.epos
-	| _ -> assert false
-
-let rec is_volatile t =
-	match t with
-	| TMono r ->
-		(match !r with
-		| Some t -> is_volatile t
-		| _ -> false)
-	| TLazy f ->
-		is_volatile (!f())
-	| TType (t,tl) ->
-		(match t.t_path with
-		| ["mt";"flash"],"Volatile" -> true
-		| _ -> is_volatile (apply_params t.t_types tl t.t_type))
-	| _ ->
-		false

+ 69 - 5
type.ml

@@ -18,7 +18,7 @@
  *)
 open Ast
 
-type module_path = string list * string
+type path = string list * string
 
 type field_access =
 	| NormalAccess
@@ -122,7 +122,7 @@ and tclass_kind =
 	| KGenericInstance of tclass * tparams
 
 and tclass = {
-	cl_path : module_path;
+	cl_path : path;
 	cl_pos : Ast.pos;
 	cl_doc : Ast.documentation;
 	cl_private : bool;
@@ -151,7 +151,7 @@ and tenum_field = {
 }
 
 and tenum = {
-	e_path : module_path;
+	e_path : path;
 	e_pos : Ast.pos;
 	e_doc : Ast.documentation;
 	e_private : bool;
@@ -162,7 +162,7 @@ and tenum = {
 }
 
 and tdef = {
-	t_path : module_path;
+	t_path : path;
 	t_pos : Ast.pos;
 	t_doc : Ast.documentation;
 	t_private : bool;
@@ -176,13 +176,18 @@ and module_type =
 	| TTypeDecl of tdef
 
 type module_def = {
-	mpath : module_path;
+	mpath : path;
 	mtypes : module_type list;
 	mutable mimports : (module_def * string option) list;
 }
 
 let mk e t p = { eexpr = e; etype = t; epos = p }
 
+let mk_block e =
+	match e.eexpr with
+	| TBlock (_ :: _) -> e
+	| _ -> mk (TBlock [e]) e.etype e.epos
+
 let not_opened = ref Closed
 let is_closed a = !(a.a_status) <> Opened
 let mk_anon fl = TAnon { a_fields = fl; a_status = not_opened; }
@@ -276,6 +281,15 @@ and s_type_params ctx = function
 	| [] -> ""
 	| l -> "<" ^ String.concat ", " (List.map (s_type ctx) l) ^ ">"
 
+let s_access = function
+	| NormalAccess -> "default"
+	| NoAccess -> "null"
+	| NeverAccess -> "never"
+	| MethodAccess m -> m
+	| MethodCantAccess -> "dynamic"
+	| ResolveAccess -> "resolve"
+	| InlineAccess -> "inline"
+
 let rec is_parent csup c =
 	if c == csup then
 		true
@@ -797,3 +811,53 @@ let rec iter f e =
 		List.iter (fun (_,_,e) -> f e) catches
 	| TReturn eo ->
 		(match eo with None -> () | Some e -> f e)
+
+let rec map_expr f e =
+	match e.eexpr with
+	| TConst _
+	| TLocal _
+	| TEnumField _
+	| TBreak
+	| TContinue
+	| TTypeExpr _ ->
+		e
+	| TArray (e1,e2) ->
+		{ e with eexpr = TArray (f e1,f e2) }
+	| TBinop (op,e1,e2) ->
+		{ e with eexpr = TBinop (op,f e1,f e2) }
+	| TFor (v,t,e1,e2) ->
+		{ e with eexpr = TFor (v,t,f e1,f e2) }
+	| TWhile (e1,e2,flag) ->
+		{ e with eexpr = TWhile (f e1,f e2,flag) }
+	| TThrow e1 ->
+		{ e with eexpr = TThrow (f e1) }
+	| TField (e1,v) ->
+		{ e with eexpr = TField (f e1,v) }
+	| TParenthesis e1 ->
+		{ e with eexpr = TParenthesis (f e1) }
+	| TUnop (op,pre,e1) ->
+		{ e with eexpr = TUnop (op,pre,f e1) }
+	| TArrayDecl el ->
+		{ e with eexpr = TArrayDecl (List.map f el) }
+	| TNew (t,pl,el) ->
+		{ e with eexpr = TNew (t,pl,List.map f el) }
+	| TBlock el ->
+		{ e with eexpr = TBlock (List.map f el) }
+	| TObjectDecl el ->
+		{ e with eexpr = TObjectDecl (List.map (fun (v,e) -> v, f e) el) }
+	| TCall (e1,el) ->
+		{ e with eexpr = TCall (f e1, List.map f el) }
+	| TVars vl ->
+		{ e with eexpr = TVars (List.map (fun (v,t,e) -> v , t , match e with None -> None | Some e -> Some (f e)) vl) }
+	| TFunction fu ->
+		{ e with eexpr = TFunction { fu with tf_expr = f fu.tf_expr } }
+	| TIf (ec,e1,e2) ->
+		{ e with eexpr = TIf (f ec,f e1,match e2 with None -> None | Some e -> Some (f e)) }
+	| TSwitch (e1,cases,def) ->
+		{ e with eexpr = TSwitch (f e1, List.map (fun (el,e2) -> List.map f el, f e2) cases, match def with None -> None | Some e -> Some (f e)) }
+	| TMatch (e1,t,cases,def) ->
+		{ e with eexpr = TMatch (f e1, t, List.map (fun (cl,params,e) -> cl, params, f e) cases, match def with None -> None | Some e -> Some (f e)) }
+	| TTry (e1,catches) ->
+		{ e with eexpr = TTry (f e1, List.map (fun (v,t,e) -> v, t, f e) catches) }
+	| TReturn eo ->
+		{ e with eexpr = TReturn (match eo with None -> None | Some e -> Some (f e)) }

+ 184 - 0
typecore.ml

@@ -0,0 +1,184 @@
+(*
+ *  Haxe Compiler
+ *  Copyright (c)2005-2008 Nicolas Cannasse
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *)
+open Common
+open Type
+
+type typer = {
+	(* shared *)
+	com : context;
+	mutable api : context_type_api;
+	types_module : (path, path) Hashtbl.t;
+	modules : (path , module_def) Hashtbl.t;
+	delays : (unit -> unit) list list ref;
+	constructs : (path , Ast.access list * Ast.type_param list * Ast.func) Hashtbl.t;
+	doinline : bool;
+	mutable std : module_def;
+	mutable untyped : bool;
+	mutable isproxy : bool;
+	mutable super_call : bool;
+	(* per-module *)
+	current : module_def;
+	mutable local_types : module_type list;
+	(* per-class *)
+	mutable curclass : tclass;
+	mutable tthis : t;
+	mutable type_params : (string * t) list;
+	(* per-function *)
+	mutable curmethod : string;
+	mutable in_constructor : bool;
+	mutable in_static : bool;
+	mutable in_loop : bool;
+	mutable in_display : bool;
+	mutable ret : t;
+	mutable locals : (string, t) PMap.t;
+	mutable locals_map : (string, string) PMap.t;
+	mutable locals_map_inv : (string, string) PMap.t;
+	mutable opened : anon_status ref list;
+	mutable param_type : t option;
+}
+
+type error_msg =
+	| Module_not_found of path
+	| Unify of unify_error list
+	| Custom of string
+	| Protect of error_msg
+	| Unknown_ident of string
+	| Stack of error_msg * error_msg
+
+exception Error of error_msg * pos
+
+let type_expr_ref : (typer -> Ast.expr -> bool -> texpr) ref = ref (fun _ _ _ -> assert false)
+
+let unify_error_msg ctx = function
+	| Cannot_unify (t1,t2) ->
+		s_type ctx t1 ^ " should be " ^ s_type ctx t2
+	| Invalid_field_type s ->
+		"Invalid type for field " ^ s ^ " :"
+	| Has_no_field (t,n) ->
+		s_type ctx t ^ " has no field " ^ n
+	| Has_extra_field (t,n) ->
+		s_type ctx t ^ " has extra field " ^ n
+	| Invalid_access (f,get,a,b) ->
+		"Inconsistent " ^ (if get then "getter" else "setter") ^ " for field " ^ f ^ " : " ^ s_access a ^ " should be " ^ s_access b
+	| Invalid_visibility n ->
+		"The field " ^ n ^ " is not public"
+	| Not_matching_optional n ->
+		"Optional attribute of parameter " ^ n ^ " differs"
+	| Cant_force_optional ->
+		"Optional parameters can't be forced"
+
+let rec error_msg = function
+	| Module_not_found m -> "Class not found : " ^ Ast.s_type_path m
+	| Unify l ->
+		let ctx = print_context() in
+		String.concat "\n" (List.map (unify_error_msg ctx) l)
+	| Unknown_ident s -> "Unknown identifier : " ^ s
+	| Custom s -> s
+	| Stack (m1,m2) -> error_msg m1 ^ "\n" ^ error_msg m2
+	| Protect m -> error_msg m
+
+let display_error ctx msg p = ctx.com.error msg p
+
+let type_expr ctx e need_val = (!type_expr_ref) ctx e need_val
+
+let unify ctx t1 t2 p =
+	try
+		Type.unify t1 t2
+	with
+		Unify_error l ->
+			if not ctx.untyped then display_error ctx (error_msg (Unify l)) p
+
+let unify_raise ctx t1 t2 p =
+	try
+		Type.unify t1 t2
+	with
+		Unify_error l ->
+			(* no untyped check *)
+			raise (Error (Unify l,p))
+
+let save_locals ctx =
+	let locals = ctx.locals in
+	let map = ctx.locals_map in
+	let inv = ctx.locals_map_inv in
+	(fun() ->
+		ctx.locals <- locals;
+		ctx.locals_map <- map;
+		ctx.locals_map_inv <- inv;
+	)
+
+let add_local ctx v t =
+	let rec loop n =
+		let nv = (if n = 0 then v else v ^ string_of_int n) in
+		if PMap.mem nv ctx.locals || PMap.mem nv ctx.locals_map_inv then
+			loop (n+1)
+		else begin
+			ctx.locals <- PMap.add v t ctx.locals;
+			if n <> 0 then begin
+				ctx.locals_map <- PMap.add v nv ctx.locals_map;
+				ctx.locals_map_inv <- PMap.add nv v ctx.locals_map_inv;
+			end;
+			nv
+		end
+	in
+	loop 0
+
+let gen_local ctx t =
+	let rec loop n =
+		let nv = (if n = 0 then "_g" else "_g" ^ string_of_int n) in
+		if PMap.mem nv ctx.locals || PMap.mem nv ctx.locals_map_inv then
+			loop (n+1)
+		else
+			nv
+	in
+	add_local ctx (loop 0) t
+
+let rec is_nullable = function
+	| TMono r ->
+		(match !r with None -> true | Some t -> is_nullable t)
+	| TType ({ t_path = ([],"Null") },[_]) ->
+		false
+	| TLazy f ->
+		is_nullable (!f())
+	| TType (t,tl) ->
+		is_nullable (apply_params t.t_types tl t.t_type)
+	| TFun _ ->
+		true
+	| TInst ({ cl_path = (["haxe"],"Int32") },[])
+	| TInst ({ cl_path = ([],"Int") },[])
+	| TInst ({ cl_path = ([],"Float") },[])
+	| TEnum ({ e_path = ([],"Bool") },[]) -> true
+	| _ ->
+		false
+
+let rec is_null = function
+	| TMono r ->
+		(match !r with None -> false | Some t -> is_null t)
+	| TType ({ t_path = ([],"Null") },[t]) ->
+		is_nullable t
+	| TLazy f ->
+		is_null (!f())
+	| TType (t,tl) ->
+		is_null (apply_params t.t_types tl t.t_type)
+	| _ ->
+		false
+
+let null t p = mk (TConst TNull) t p
+
+let tfun pl r = TFun (List.map (fun t -> "",false,t) pl,r)
+

+ 925 - 0
typeload.ml

@@ -0,0 +1,925 @@
+(*
+ *  Haxe Compiler
+ *  Copyright (c)2005-2008 Nicolas Cannasse
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *)
+open Ast
+open Type
+open Common
+open Typecore
+
+let exc_protect f =
+	let rec r = ref (fun() ->
+		try
+			f r
+		with
+			| Error (Protect _,_) as e -> raise e
+			| Error (m,p) -> raise (Error (Protect m,p))
+	) in
+	r
+
+let type_static_var ctx t e p =
+	ctx.in_static <- true;
+	let e = type_expr ctx e true in
+	unify ctx e.etype t p;
+	e
+
+(** since load_type is used in PASS2 , it cannot access the structure of a type **)
+
+let load_type_def ctx p tpath =
+	let no_pack = fst tpath = [] in
+	try
+		List.find (fun t ->
+			let tp = t_path t in
+			tp = tpath || (no_pack && snd tp = snd tpath)
+		) ctx.local_types
+	with
+		Not_found ->
+			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, ctx.api.load_module tpath2 p
+			with
+				| Error (Module_not_found _,p2) when p == p2 -> tpath, ctx.api.load_module tpath p
+				| Exit -> tpath, ctx.api.load_module tpath p
+			) in
+			try
+				List.find (fun t -> not (t_private t) && t_path t = tpath) m.mtypes
+			with
+				Not_found -> error ("Module " ^ s_type_path tpath ^ " does not define type " ^ snd tpath) p
+
+let rec load_normal_type ctx t p allow_no_params =
+	try
+		if t.tpackage <> [] then raise Not_found;
+		let pt = List.assoc t.tname ctx.type_params in
+		if t.tparams <> [] then error ("Class type parameter " ^ t.tname ^ " can't have parameters") p;
+		pt
+	with Not_found ->
+		let types , path , f = ctx.api.build_instance (load_type_def ctx p (t.tpackage,t.tname)) p in
+		if allow_no_params && t.tparams = [] then
+			f (List.map (fun (name,t) ->
+				match follow t with
+				| TInst (c,_) -> if c.cl_implements = [] then mk_mono() else error ("Type parameter " ^ name ^ " need constraint") p
+				| _ -> assert false
+			) types)
+		else if path = ([],"Dynamic") then
+			match t.tparams with
+			| [] -> t_dynamic
+			| [TPType t] -> TDynamic (load_type ctx p t)
+			| _ -> error "Too many parameters for Dynamic" p
+		else begin
+			if List.length types <> List.length t.tparams then error ("Invalid number of type parameters for " ^ s_type_path path) p;
+			let tparams = List.map (fun t ->
+				match t with
+				| TPConst c ->
+					let name, const = (match c with
+						| String s -> "S" ^ s, TString s
+						| Int i -> "I" ^ i, TInt (Int32.of_string i)
+						| Float f -> "F" ^ f, TFloat f
+						| _ -> assert false
+					) in
+					let c = mk_class ([],name) p None false in
+					c.cl_kind <- KConstant const;
+					TInst (c,[])
+				| TPType t -> load_type ctx p t
+			) t.tparams in
+			let params = List.map2 (fun t (name,t2) ->
+				let isconst = (match t with TInst ({ cl_kind = KConstant _ },_) -> true | _ -> false) in
+				if isconst <> (name = "Const") && t != t_dynamic then error (if isconst then "Constant value unexpected here" else "Constant value excepted as type parameter") p;
+				(match follow t2 with
+				| TInst (c,[]) ->
+					List.iter (fun (i,params) ->
+						unify ctx t (apply_params types tparams (TInst (i,params))) p
+					) c.cl_implements
+				| _ -> assert false);
+				t
+			) tparams types in
+			f params
+		end
+
+and load_type ctx p t =
+	match t with
+	| TPParent t -> load_type ctx p t
+	| TPNormal t -> load_normal_type ctx t p false
+	| TPExtend (t,l) ->
+		(match load_type ctx p (TPAnonymous l) with
+		| TAnon a ->
+			let rec loop t =
+				match follow t with
+				| TInst (c,tl) ->
+					let c2 = mk_class (fst c.cl_path,"+" ^ snd c.cl_path) p None true in
+					PMap.iter (fun f _ ->
+						try
+							ignore(class_field c f);
+							error ("Cannot redefine field " ^ f) p
+						with
+							Not_found -> ()
+					) a.a_fields;
+					(* do NOT tag as extern - for protect *)
+					c2.cl_kind <- KExtension (c,tl);
+					c2.cl_super <- Some (c,tl);
+					c2.cl_fields <- a.a_fields;
+					TInst (c2,[])
+				| TMono _ ->
+					error "Please ensure correct initialization of cascading signatures" p
+				| TAnon a2 ->
+					PMap.iter (fun f _ ->
+						if PMap.mem f a2.a_fields then error ("Cannot redefine field " ^ f) p
+					) a.a_fields;
+					mk_anon (PMap.foldi PMap.add a.a_fields a2.a_fields)
+				| _ -> error "Cannot only extend classes and anonymous" p
+			in
+			loop (load_normal_type ctx t p false)
+		| _ -> assert false)
+	| TPAnonymous l ->
+		let rec loop acc (n,pub,f,p) =
+			if PMap.mem n acc then error ("Duplicate field declaration : " ^ n) p;
+			let t , get, set = (match f with
+				| AFVar t ->
+					load_type ctx p t, NormalAccess, NormalAccess
+				| AFFun (tl,t) ->
+					let t = load_type ctx p t in
+					let args = List.map (fun (name,o,t) -> name , o, load_type ctx p t) tl in
+					TFun (args,t), NormalAccess, MethodCantAccess
+				| AFProp (t,i1,i2) ->
+					let access m get =
+						match m with
+						| "null" -> NoAccess
+						| "default" -> NormalAccess
+						| "dynamic" -> MethodAccess ((if get then "get_"  else "set_") ^ n)
+						| _ -> MethodAccess m
+					in
+					load_type ctx p t, access i1 true, access i2 false
+			) in
+			PMap.add n {
+				cf_name = n;
+				cf_type = t;
+				cf_public = (match pub with None -> true | Some p -> p);
+				cf_get = get;
+				cf_set = set;
+				cf_params = [];
+				cf_expr = None;
+				cf_doc = None;
+			} acc
+		in
+		mk_anon (List.fold_left loop PMap.empty l)
+	| TPFunction (args,r) ->
+		match args with
+		| [TPNormal { tpackage = []; tparams = []; tname = "Void" }] ->
+			TFun ([],load_type ctx p r)
+		| _ ->
+			TFun (List.map (fun t -> "",false,load_type ctx p t) args,load_type ctx p r)
+
+let hide_types ctx =
+	let old_locals = ctx.local_types in
+	let old_type_params = ctx.type_params in
+	ctx.local_types <- (try (Hashtbl.find ctx.modules ([],"StdTypes")).mtypes with Not_found -> assert false);
+	ctx.type_params <- [];
+	(fun() ->
+		ctx.local_types <- old_locals;
+		ctx.type_params <- old_type_params;
+	)
+
+let load_core_type ctx name =
+	let show = hide_types ctx in
+	let t = load_normal_type ctx { tpackage = []; tname = name; tparams = [] } null_pos false in
+	show();
+	t
+
+let is_int t =
+	match follow t with
+	| TInst (c,[]) ->
+		c.cl_path = ([],"Int")
+	| _ ->
+		false
+
+let is_float t =
+	match follow t with
+	| TInst (c,[]) ->
+		c.cl_path = ([],"Float")
+	| _ ->
+		false
+
+let t_array ctx =
+	let show = hide_types ctx in
+	match load_type_def ctx null_pos ([],"Array") with
+	| TClassDecl c ->
+		show();
+		if List.length c.cl_types <> 1 then assert false;
+		let pt = mk_mono() in
+		TInst (c,[pt]) , pt
+	| _ ->
+		assert false
+
+let t_array_access ctx =
+	let show = hide_types ctx in
+	match load_type_def ctx null_pos ([],"ArrayAccess") with
+	| TClassDecl c ->
+		show();
+		if List.length c.cl_types <> 1 then assert false;
+		let pt = mk_mono() in
+		TInst (c,[pt]) , pt
+	| _ ->
+		assert false
+
+let t_iterator ctx =
+	let show = hide_types ctx in
+	match load_type_def ctx null_pos ([],"Iterator") with
+	| TTypeDecl t ->
+		show();
+		if List.length t.t_types <> 1 then assert false;
+		let pt = mk_mono() in
+		apply_params t.t_types [pt] t.t_type, pt
+	| _ ->
+		assert false
+
+let load_type_opt ?(opt=false) ctx p t =
+	let t = (match t with None -> mk_mono() | Some t -> load_type ctx p t) in
+	if opt then ctx.api.tnull t else t
+
+(* ---------------------------------------------------------------------- *)
+(* Structure check *)
+
+let valid_redefinition ctx f t =
+	let ft = field_type f in
+	match follow ft , follow t with
+	| TFun (args,r) , TFun (targs,tr) when List.length args = List.length targs ->
+		List.iter2 (fun (n,o1,a1) (_,o2,a2) ->
+			if o1 <> o2 then raise (Unify_error [Not_matching_optional n]);
+			type_eq EqStrict a1 a2
+		) args targs;
+		Type.unify r tr
+	| _ , _ ->
+		type_eq EqStrict ft t
+
+let check_overriding ctx c p () =
+	match c.cl_super with
+	| None -> ()
+	| Some (csup,params) ->
+		PMap.iter (fun i f ->
+			try
+				let t , f2 = class_field csup i in
+				let t = apply_params csup.cl_types params t in
+				ignore(follow f.cf_type); (* force evaluation *)
+				let p = (match f.cf_expr with None -> p | Some e -> e.epos) in
+				if not (List.mem i c.cl_overrides) then
+					display_error ctx ("Field " ^ i ^ " should be declared with 'override' since it is inherited from superclass") p
+				else if f.cf_public <> f2.cf_public then
+					display_error ctx ("Field " ^ i ^ " has different visibility (public/private) than superclass one") p
+				else if f2.cf_get = InlineAccess then
+					display_error ctx ("Field " ^ i ^ " is inlined and cannot be overridden") p
+				else if f2.cf_get <> f.cf_get || f2.cf_set <> f.cf_set then
+					display_error ctx ("Field " ^ i ^ " has different property access than in superclass") p
+				else try
+					valid_redefinition ctx f t
+				with
+					Unify_error l ->
+						display_error ctx ("Field " ^ i ^ " overload parent class with different or incomplete type") p;
+						display_error ctx (error_msg (Unify l)) p;
+			with
+				Not_found ->
+					if List.mem i c.cl_overrides then display_error ctx ("Field " ^ i ^ " is declared 'override' but doesn't override any field") p
+		) c.cl_fields
+
+let class_field_no_interf c i =
+	try
+		let f = PMap.find i c.cl_fields in
+		field_type f , f
+	with Not_found ->
+		match c.cl_super with
+		| None ->
+			raise Not_found
+		| Some (c,tl) ->
+			(* rec over class_field *)
+			let t , f = class_field c i in
+			apply_params c.cl_types tl t , f
+
+let rec check_interface ctx c p intf params =
+	PMap.iter (fun i f ->
+		try
+			let t , f2 = class_field_no_interf c i in
+			ignore(follow f.cf_type); (* force evaluation *)
+			let p = (match f.cf_expr with None -> p | Some e -> e.epos) in
+			if f.cf_public && not f2.cf_public then
+				display_error ctx ("Field " ^ i ^ " should be public as requested by " ^ s_type_path intf.cl_path) p
+			else if not(unify_access f2.cf_get f.cf_get) then
+				display_error ctx ("Field " ^ i ^ " has different property access than in " ^ s_type_path intf.cl_path) p
+			else
+				let t1 = apply_params intf.cl_types params (field_type f) in
+				try
+					valid_redefinition ctx f2 t1
+				with
+					Unify_error l ->
+						display_error ctx ("Field " ^ i ^ " has different type than in " ^ s_type_path intf.cl_path) p;
+						display_error ctx (error_msg (Unify l)) p;
+		with
+			Not_found ->
+				if not c.cl_interface then display_error ctx ("Field " ^ i ^ " needed by " ^ s_type_path intf.cl_path ^ " is missing") p
+	) intf.cl_fields;
+	List.iter (fun (i2,p2) ->
+		check_interface ctx c p i2 (List.map (apply_params intf.cl_types params) p2)
+	) intf.cl_implements
+
+let check_interfaces ctx c p () =
+	match c.cl_path with
+	| "Proxy" :: _ , _ -> ()
+	| _ ->
+	List.iter (fun (intf,params) -> check_interface ctx c p intf params) c.cl_implements
+
+let rec return_flow ctx e =
+	let error() = display_error ctx "A return is missing here" e.epos; raise Exit in
+	let return_flow = return_flow ctx in
+	match e.eexpr with
+	| TReturn _ | TThrow _ -> ()
+	| TParenthesis e ->
+		return_flow e
+	| TBlock el ->
+		let rec loop = function
+			| [] -> error()
+			| [e] -> return_flow e
+			| { eexpr = TReturn _ } :: _ | { eexpr = TThrow _ } :: _ -> ()
+			| _ :: l -> loop l
+		in
+		loop el
+	| TIf (_,e1,Some e2) ->
+		return_flow e1;
+		return_flow e2;
+	| TSwitch (v,cases,Some e) ->
+		List.iter (fun (_,e) -> return_flow e) cases;
+		return_flow e
+	| TSwitch (e,cases,None) when (match follow e.etype with TEnum _ -> true | _ -> false) ->
+		List.iter (fun (_,e) -> return_flow e) cases;
+	| TMatch (_,_,cases,def) ->
+		List.iter (fun (_,_,e) -> return_flow e) cases;
+		(match def with None -> () | Some e -> return_flow e)
+	| TTry (e,cases) ->
+		return_flow e;
+		List.iter (fun (_,_,e) -> return_flow e) cases;
+	| _ ->
+		error()
+
+(* ---------------------------------------------------------------------- *)
+(* PASS 1 & 2 : Module and Class Structure *)
+
+let set_heritance ctx c herits p =
+	let rec loop = function
+		| HPrivate | HExtern | HInterface ->
+			()
+		| HExtends t ->
+			if c.cl_super <> None then error "Cannot extend several classes" p;
+			let t = load_normal_type ctx t p false in
+			(match follow t with
+			| TInst (cl,params) ->
+				if is_parent c cl then error "Recursive class" p;
+				if c.cl_interface then error "Cannot extend an interface" p;
+				if cl.cl_interface then error "Cannot extend by using an interface" p;
+				c.cl_super <- Some (cl,params)
+			| _ -> error "Should extend by using a class" p)
+		| HImplements t ->
+			let t = load_normal_type ctx t p false in
+			(match follow t with
+			| TInst (cl,params) ->
+				if is_parent c cl then error "Recursive class" p;
+				c.cl_implements <- (cl, params) :: c.cl_implements
+			| TDynamic t ->
+				if c.cl_dynamic <> None then error "Cannot have several dynamics" p;
+				c.cl_dynamic <- Some t
+			| _ -> error "Should implement by using an interface or a class" p)
+	in
+	List.iter loop (List.filter (ctx.api.on_inherit c p) herits)
+
+let type_type_params ctx path p (n,flags) =
+	let c = mk_class (fst path @ [snd path],n) p None false in
+	c.cl_kind <- KTypeParameter;
+	let t = TInst (c,[]) in
+	match flags with
+	| [] -> n, t
+	| _ ->
+		let r = exc_protect (fun r ->
+			r := (fun _ -> t);
+			set_heritance ctx c (List.map (fun t -> HImplements t) flags) p;
+			t
+		) in
+		ctx.delays := [(fun () -> ignore(!r()))] :: !(ctx.delays);
+		n, TLazy r
+
+let type_function ctx t static constr f p =
+	let locals = save_locals ctx in
+	let fargs , r = (match t with
+		| TFun (args,r) -> List.map (fun (n,opt,t) -> add_local ctx n t, opt, t) args, r
+		| _ -> assert false
+	) in
+	let old_ret = ctx.ret in
+	let old_static = ctx.in_static in
+	let old_constr = ctx.in_constructor in
+	let old_opened = ctx.opened in
+	ctx.in_static <- static;
+	ctx.in_constructor <- constr;
+	ctx.ret <- r;
+	ctx.opened <- [];
+	let e = type_expr ctx f.f_expr false in
+	let rec loop e =
+		match e.eexpr with
+		| TReturn (Some _) -> raise Exit
+		| TFunction _ -> ()
+		| _ -> Type.iter loop e
+	in
+	let have_ret = (try loop e; false with Exit -> true) in
+	if have_ret then
+		(try return_flow ctx e with Exit -> ())
+	else
+		unify ctx r ctx.api.tvoid p;
+	let rec loop e =
+		match e.eexpr with
+		| TCall ({ eexpr = TConst TSuper },_) -> raise Exit
+		| TFunction _ -> ()
+		| _ -> Type.iter loop e
+	in
+	if constr && (match ctx.curclass.cl_super with None -> false | Some (cl,_) -> cl.cl_constructor <> None) then
+		(try
+			loop e;
+			error "Missing super constructor call" p
+		with
+			Exit -> ());
+	locals();
+	List.iter (fun r -> r := Closed) ctx.opened;
+	ctx.ret <- old_ret;
+	ctx.in_static <- old_static;
+	ctx.in_constructor <- old_constr;
+	ctx.opened <- old_opened;
+	e , fargs
+
+let init_class ctx c p herits fields =
+	ctx.type_params <- c.cl_types;
+	c.cl_extern <- List.mem HExtern herits;
+	c.cl_interface <- List.mem HInterface herits;
+	set_heritance ctx c herits p;
+	let tthis = TInst (c,List.map snd c.cl_types) in
+	let rec extends_public c =
+		List.exists (fun (c,_) -> c.cl_path = (["haxe"],"Public") || extends_public c) c.cl_implements ||
+		match c.cl_super with
+		| None -> false
+		| Some (c,_) -> extends_public c
+	in
+	let extends_public = extends_public c in
+	let is_public access parent =
+		if List.mem APrivate access then
+			false
+		else if List.mem APublic access then
+			true
+		else match parent with
+			| Some { cf_public = p } -> p
+			| _ -> c.cl_extern || c.cl_interface || extends_public
+	in
+	let rec get_parent c name = 
+		match c.cl_super with
+		| None -> None
+		| Some (csup,_) ->
+			try
+				Some (PMap.find name csup.cl_fields)
+			with
+				Not_found -> get_parent csup name
+	in
+	let type_opt ?opt ctx p t =
+		match t with
+		| None when c.cl_extern || c.cl_interface ->
+			display_error ctx "Type required for extern classes and interfaces" p;
+			t_dynamic
+		| _ ->
+			load_type_opt ?opt ctx p t
+	in
+	let rec has_field f = function
+		| None -> false
+		| Some (c,_) ->
+			PMap.exists f c.cl_fields || has_field f c.cl_super || List.exists (fun i -> has_field f (Some i)) c.cl_implements
+	in
+	let loop_cf f p =
+		match f with
+		| FVar (name,doc,access,t,e) ->
+			let stat = List.mem AStatic access in
+			let inline = List.mem AInline access in
+			if not stat && has_field name c.cl_super then error ("Redefinition of variable " ^ name ^ " in subclass is not allowed") p;
+			if inline && not stat then error "Inline variable must be static" p;
+			if inline && e = None then error "Inline variable must be initialized" p;
+			let t = (match t with
+				| None ->
+					if not stat then display_error ctx ("Type required for member variable " ^ name) p;
+					mk_mono()
+				| Some t ->
+					let old = ctx.type_params in
+					if stat then ctx.type_params <- [];
+					let t = load_type ctx p t in
+					if stat then ctx.type_params <- old;
+					t
+			) in
+			let cf = {
+				cf_name = name;
+				cf_doc = doc;
+				cf_type = t;
+				cf_get = if inline then InlineAccess else NormalAccess;
+				cf_set = if inline then NeverAccess else NormalAccess;
+				cf_expr = None;
+				cf_public = is_public access None;
+				cf_params = [];
+			} in
+			let delay = (match e with
+				| None -> (fun() -> ())
+				| Some e ->
+					let ctx = { ctx with curclass = c; tthis = tthis } in
+					let r = exc_protect (fun r ->
+						r := (fun() -> t);
+						if ctx.com.verbose then print_endline ("Typing " ^ s_type_path c.cl_path ^ "." ^ name);
+						cf.cf_expr <- Some (type_static_var ctx t e p);
+						t
+					) in
+					cf.cf_type <- TLazy r;
+					(fun () -> ignore(!r()))
+			) in
+			access, false, cf, delay
+		| FFun (name,doc,access,params,f) ->
+			let params = List.map (fun (n,flags) ->
+				match flags with
+				| [] ->
+					type_type_params ctx ([],name) p (n,[])
+				| _ -> error "This notation is not allowed because it can't be checked" p
+			) params in
+			let stat = List.mem AStatic access in
+			let inline = List.mem AInline access in
+			let parent = (if not stat then get_parent c name else None) in
+			let dynamic = List.mem ADynamic access || (match parent with Some { cf_set = NormalAccess } -> true | _ -> false) in
+			let ctx = { ctx with
+				curclass = c;
+				curmethod = name;
+				tthis = tthis;
+				type_params = if stat then params else params @ ctx.type_params;
+			} in
+			let ret = type_opt ctx p f.f_type in
+			let args = List.map (fun (name,opt,t) -> name , opt, type_opt ~opt ctx p t) f.f_args in
+			let t = TFun (args,ret) in
+			let constr = (name = "new") in
+			if constr && c.cl_interface then error "An interface cannot have a constructor" p;
+			if c.cl_interface && not stat && (match f.f_expr with EBlock [] , _ -> false | _ -> true) then error "An interface method cannot have a body" p;
+			if constr then (match f.f_type with
+				| None | Some (TPNormal { tpackage = []; tname = "Void" }) -> ()
+				| _ -> error "A class constructor can't have a return value" p
+			);
+			let cf = {
+				cf_name = name;
+				cf_doc = doc;
+				cf_type = t;
+				cf_get = if inline then InlineAccess else NormalAccess;
+				cf_set = (if inline then NeverAccess else if dynamic then NormalAccess else MethodCantAccess);
+				cf_expr = None;
+				cf_public = is_public access parent;
+				cf_params = params;
+			} in
+			let r = exc_protect (fun r ->
+				r := (fun() -> t);
+				if ctx.com.verbose then print_endline ("Typing " ^ s_type_path c.cl_path ^ "." ^ name);
+				let e , fargs = type_function ctx t stat constr f p in
+				let f = {
+					tf_args = fargs;
+					tf_type = ret;
+					tf_expr = e;
+				} in
+				if stat && name = "__init__" then c.cl_init <- Some e;
+				cf.cf_expr <- Some (mk (TFunction f) t p);
+				t
+			) in
+			let delay = (
+				if (c.cl_extern || c.cl_interface || ctx.isproxy) && cf.cf_name <> "__init__" then
+					(fun() -> ())
+				else begin
+					cf.cf_type <- TLazy r;
+					(fun() -> ignore((!r)()))
+				end
+			) in
+			access, constr, cf, delay
+		| FProp (name,doc,access,get,set,t) ->
+			let ret = load_type ctx p t in
+			let check_get = ref (fun() -> ()) in
+			let check_set = ref (fun() -> ()) in
+			let check_method m t () =
+				try
+					let t2 = (if List.mem AStatic access then (PMap.find m c.cl_statics).cf_type else fst (class_field c m)) in
+					unify_raise ctx t2 t p;
+				with
+					| Error (Unify l,_) -> raise (Error (Stack (Custom ("In method " ^ m ^ " required by property " ^ name),Unify l),p))
+					| Not_found -> if not c.cl_interface then error ("Method " ^ m ^ " required by property " ^ name ^ " is missing") p
+			in
+			let get = (match get with
+				| "null" -> NoAccess
+				| "dynamic" -> MethodAccess ("get_" ^ name)
+				| "default" -> NormalAccess
+				| _ ->
+					check_get := check_method get (TFun ([],ret));
+					MethodAccess get
+			) in
+			let set = (match set with
+				| "null" ->
+					(* standard flash library read-only variables can't be accessed for writing, even in subclasses *)
+					if c.cl_extern && (match c.cl_path with "flash" :: _  , _ -> true | _ -> false) && Common.defined ctx.com "flash9" then
+						NeverAccess
+					else
+						NoAccess
+				| "dynamic" -> MethodAccess ("set_" ^ name)
+				| "default" -> NormalAccess
+				| _ ->
+					check_set := check_method set (TFun (["",false,ret],ret));
+					MethodAccess set
+			) in
+			if set = NormalAccess && (match get with MethodAccess _ -> true | _ -> false) then error "Unsupported property combination" p;
+			let cf = {
+				cf_name = name;
+				cf_doc = doc;
+				cf_get = get;
+				cf_set = set;
+				cf_expr = None;
+				cf_type = ret;
+				cf_public = is_public access None;
+				cf_params = [];
+			} in
+			access, false, cf, (fun() -> (!check_get)(); (!check_set)())
+	in
+	let fl = List.map (fun (f,p) ->
+		let access , constr, f , delayed = loop_cf f p in
+		let is_static = List.mem AStatic access in
+		if is_static && f.cf_name = "name" && Common.defined ctx.com "js" then error "This identifier cannot be used in Javascript for statics" p;
+		if (is_static || constr) && c.cl_interface && f.cf_name <> "__init__" then error "You can't declare static fields in interfaces" p;
+		if constr then begin
+			if c.cl_constructor <> None then error "Duplicate constructor" p;
+			c.cl_constructor <- Some f;
+		end else if not is_static || f.cf_name <> "__init__" then begin
+			if PMap.mem f.cf_name (if is_static then c.cl_statics else c.cl_fields) then error ("Duplicate class field declaration : " ^ f.cf_name) p;
+			if is_static then begin
+				c.cl_statics <- PMap.add f.cf_name f c.cl_statics;
+				c.cl_ordered_statics <- f :: c.cl_ordered_statics;
+			end else begin
+				c.cl_fields <- PMap.add f.cf_name f c.cl_fields;
+				c.cl_ordered_fields <- f :: c.cl_ordered_fields;
+				if List.mem AOverride access then c.cl_overrides <- f.cf_name :: c.cl_overrides;
+			end;
+		end;
+		delayed
+	) fields in
+	c.cl_ordered_statics <- List.rev c.cl_ordered_statics;
+	c.cl_ordered_fields <- List.rev c.cl_ordered_fields;
+	(*
+		define a default inherited constructor.
+		This is actually pretty tricky since we can't assume that the constructor of the
+		superclass has been defined yet because type structure is not stabilized wrt recursion.
+	*)
+	let rec define_constructor ctx c =
+		try
+			Some (Hashtbl.find ctx.constructs c.cl_path)
+		with Not_found ->
+			match c.cl_super with
+			| None -> None
+			| Some (csuper,_) ->
+				match define_constructor ctx csuper with
+				| None -> None
+				| Some (acc,pl,f) as infos ->
+					let p = c.cl_pos in
+					let esuper = (ECall ((EConst (Ident "super"),p),List.map (fun (n,_,_) -> (EConst (Ident n),p)) f.f_args),p) in
+					let acc = (if csuper.cl_extern && acc = [] then [APublic] else acc) in
+					(* remove types that are superclass type-parameters *)
+					let replace_type = function
+						| Some (TPNormal { tpackage = []; tname = name; tparams = [] }) when List.exists (fun (param,_) -> name = param) csuper.cl_types ->
+							None
+						| t -> t
+					in
+					let fnew = { f with f_expr = esuper; f_args = List.map (fun (a,opt,t) -> a,opt,replace_type t) f.f_args } in
+					let _, _, cf, delayed = loop_cf (FFun ("new",None,acc,pl,fnew)) p in
+					c.cl_constructor <- Some cf;
+					Hashtbl.add ctx.constructs c.cl_path (acc,pl,f);
+					ctx.delays := [delayed] :: !(ctx.delays);
+					infos
+	in
+	ignore(define_constructor ctx c);
+	fl
+
+let type_module ctx m tdecls loadp =
+	(* PASS 1 : build module structure - does not load any module or type - should be atomic ! *)
+	let decls = ref [] in
+	let decl_with_name name p priv =
+		let tpath = if priv then (fst m @ ["_" ^ snd m], name) else (fst m, name) in
+		if priv then begin
+			if List.exists (fun t -> tpath = t_path t) (!decls) then error ("Type name " ^ name ^ " is alreday defined in this module") p;
+			tpath
+		end else try
+			let m2 = Hashtbl.find ctx.types_module tpath in
+			if m <> m2 && String.lowercase (s_type_path m2) = String.lowercase (s_type_path m) then error ("Module " ^ s_type_path m2 ^ " is loaded with a different case than " ^ s_type_path m) loadp;
+			error ("Type name " ^ s_type_path tpath ^ " is redefined from module " ^ s_type_path m2) p
+		with
+			Not_found ->
+				Hashtbl.add ctx.types_module (fst m,name) m;
+				tpath
+	in
+	List.iter (fun (d,p) ->
+		match d with
+		| EImport _ -> ()
+		| EClass d ->
+			let priv = List.mem HPrivate d.d_flags in
+			let path = decl_with_name d.d_name p priv in
+			let c = mk_class path p d.d_doc priv in
+			(* store the constructor for later usage *)
+			List.iter (fun (cf,_) ->
+				match cf with
+				| FFun ("new",_,acc,pl,f) -> Hashtbl.add ctx.constructs path (acc,pl,f)
+				| _ -> ()
+			) d.d_data;
+			decls := TClassDecl c :: !decls
+		| EEnum d ->
+			let priv = List.mem EPrivate d.d_flags in
+			let path = decl_with_name d.d_name p priv in
+			let e = {
+				e_path = path;
+				e_pos = p;
+				e_doc = d.d_doc;
+				e_types = [];
+				e_private = priv;
+				e_extern = List.mem EExtern d.d_flags || d.d_data = [];
+				e_constrs = PMap.empty;
+				e_names = [];
+			} in
+			decls := TEnumDecl e :: !decls
+		| ETypedef d ->
+			let priv = List.mem EPrivate d.d_flags in
+			let path = decl_with_name d.d_name p priv in
+			let t = {
+				t_path = path;
+				t_pos = p;
+				t_doc = d.d_doc;
+				t_private = priv;
+				t_types = [];
+				t_type = mk_mono();
+			} in
+			decls := TTypeDecl t :: !decls
+	) tdecls;
+	let m = {
+		mpath = m;
+		mtypes = List.rev !decls;
+		mimports = [];
+	} in
+	Hashtbl.add ctx.modules m.mpath m;
+	(* PASS 2 : build types structure - does not type any expression ! *)
+	let ctx = {
+		com = ctx.com;
+		api = ctx.api;
+		modules = ctx.modules;
+		delays = ctx.delays;
+		constructs = ctx.constructs;
+		types_module = ctx.types_module;
+		curclass = ctx.curclass;
+		tthis = ctx.tthis;
+		std = ctx.std;
+		ret = ctx.ret;
+		isproxy = ctx.isproxy;
+		doinline = ctx.doinline;
+		current = m;
+		locals = PMap.empty;
+		locals_map = PMap.empty;
+		locals_map_inv = PMap.empty;
+		local_types = ctx.std.mtypes @ m.mtypes;
+		type_params = [];
+		curmethod = "";
+		super_call = false;
+		in_constructor = false;
+		in_static = false;
+		in_display = false;
+		in_loop = false;
+		untyped = false;
+		opened = [];
+		param_type = None;
+	} in
+	let delays = ref [] in
+	let get_class name =
+		let c = List.find (fun d -> match d with TClassDecl { cl_path = _ , n } -> n = name | _ -> false) m.mtypes in
+		match c with TClassDecl c -> c | _ -> assert false
+	in
+	let get_enum name =
+		let e = List.find (fun d -> match d with TEnumDecl { e_path = _ , n } -> n = name | _ -> false) m.mtypes in
+		match e with TEnumDecl e -> e | _ -> assert false
+	in
+	let get_tdef name =
+		let s = List.find (fun d -> match d with TTypeDecl { t_path = _ , n } -> n = name | _ -> false) m.mtypes in
+		match s with TTypeDecl s -> s | _ -> assert false
+	in
+	(* here is an additional PASS 1 phase, which handle the type parameters declaration, with lazy contraints *)
+	List.iter (fun (d,p) ->
+		match d with
+		| EImport _ -> ()
+		| EClass d ->
+			let c = get_class d.d_name in
+			c.cl_types <- List.map (type_type_params ctx c.cl_path p) d.d_params;
+		| EEnum d ->
+			let e = get_enum d.d_name in
+			e.e_types <- List.map (type_type_params ctx e.e_path p) d.d_params;
+		| ETypedef d ->
+			let t = get_tdef d.d_name in
+			t.t_types <- List.map (type_type_params ctx t.t_path p) d.d_params;
+	) tdecls;
+	(* back to PASS2 *)
+	List.iter (fun (d,p) ->
+		match d with
+		| EImport (pack,name,topt) ->
+			let md = ctx.api.load_module (pack,name) p in
+			let types = List.filter (fun t -> not (t_private t)) md.mtypes in
+			(match topt with
+			| None -> ctx.local_types <- ctx.local_types @ types
+			| Some t ->
+				try
+					let t = List.find (fun tdecl -> snd (t_path tdecl) = t) types in
+					ctx.local_types <- ctx.local_types @ [t]
+				with
+					Not_found -> error ("Module " ^ s_type_path (pack,name) ^ " does not define type " ^ t) p
+			);
+			m.mimports <- (md,topt) :: m.mimports;
+		| EClass d ->
+			let c = get_class d.d_name in
+			delays := !delays @ check_overriding ctx c p :: check_interfaces ctx c p :: init_class ctx c p d.d_flags d.d_data
+		| EEnum d ->
+			let e = get_enum d.d_name in
+			ctx.type_params <- e.e_types;
+			let et = TEnum (e,List.map snd e.e_types) in
+			let names = ref [] in
+			let index = ref 0 in
+			List.iter (fun (c,doc,t,p) ->
+				if c = "name" && Common.defined ctx.com "js" then error "This identifier cannot be used in Javascript" p;
+				let t = (match t with
+					| [] -> et
+					| l -> TFun (List.map (fun (s,opt,t) -> s, opt, load_type_opt ~opt ctx p (Some t)) l, et)
+				) in
+				if PMap.mem c e.e_constrs then error ("Duplicate constructor " ^ c) p;
+				e.e_constrs <- PMap.add c {
+					ef_name = c;
+					ef_type = t;
+					ef_pos = p;
+					ef_doc = doc;
+					ef_index = !index;
+				} e.e_constrs;
+				incr index;
+				names := c :: !names;
+			) d.d_data;
+			e.e_names <- List.rev !names;
+		| ETypedef d ->
+			let t = get_tdef d.d_name in
+			ctx.type_params <- t.t_types;
+			let tt = load_type ctx p d.d_data in
+			if t.t_type == follow tt then error "Recursive typedef is not allowed" p;
+			(match t.t_type with
+			| TMono r ->
+				(match !r with
+				| None -> r := Some tt;
+				| Some _ -> assert false);
+			| _ -> assert false);
+	) tdecls;
+	(* PASS 3 : type checking, delayed until all modules and types are built *)
+	ctx.delays := !delays :: !(ctx.delays);
+	m.mimports <- List.rev m.mimports;
+	m
+
+let load_module ctx m p =
+	try
+		Hashtbl.find ctx.modules m
+	with
+		Not_found ->
+			let file = (match m with
+				| [] , name -> name
+				| x :: l , name ->
+					let x = (try
+						match PMap.find x ctx.com.package_rules with
+						| Forbidden -> error ("You can't access the " ^ x ^ " package with current compilation flags") p;
+						| Directory d -> d
+						with Not_found -> x
+					) in
+					String.concat "/" (x :: l) ^ "/" ^ name
+			) ^ ".hx" in
+			let file = (try Common.find_file ctx.com file with Not_found -> raise (Error (Module_not_found m,p))) in
+			let ch = (try open_in_bin file with _ -> error ("Could not open " ^ file) p) in
+			let t = Common.timer "parsing" in
+			let pack , decls = (try Parser.parse ctx.com (Lexing.from_channel ch) file with e -> close_in ch; t(); raise e) in
+			t();
+			close_in ch;
+			if ctx.com.verbose then print_endline ("Parsed " ^ file);
+			if pack <> fst m then begin
+				let spack m = if m = [] then "<empty>" else String.concat "." m in
+				if p == Ast.null_pos then
+					error ("Invalid commandline class : " ^ s_type_path m ^ " should be " ^ s_type_path (pack,snd m)) p
+				else
+					error ("Invalid package : " ^ spack (fst m) ^ " should be " ^ spack pack) p
+			end;
+			type_module ctx m decls p

Diferenças do arquivo suprimidas por serem muito extensas
+ 35 - 828
typer.ml


Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff