ソースを参照

meta refactor

Simon Krajewski 12 年 前
コミット
b59f384f1a
6 ファイル変更488 行追加488 行削除
  1. 0 469
      ast.ml
  2. 156 0
      common.ml
  3. 3 3
      genxml.ml
  4. 6 6
      interp.ml
  5. 1 1
      main.ml
  6. 322 9
      parser.ml

+ 0 - 469
ast.ml

@@ -26,17 +26,6 @@ type pos = {
 	pmax : int;
 }
 
-type platform =
-	| Cross
-	| Flash8
-	| Js
-	| Neko
-	| Flash
-	| Php
-	| Cpp
-	| Cs
-	| Java
-
 module Meta = struct
 	type strict_meta =
 		| Abstract
@@ -145,151 +134,6 @@ module Meta = struct
 		| Dollar of string
 		| Custom of string
 
-	type meta_usage =
-		| TClass
-		| TClassField
-		| TAbstract
-		| TAbstractField
-		| TEnum
-		| TTypedef
-
-	type meta_parameter =
-		| HasParam of string
-		| Platform of platform
-		| Platforms of platform list
-		| UsedOn of meta_usage
-		| UsedOnEither of meta_usage list
-
-	let to_string = function
-		| Abstract -> ":abstract",("",[Platforms [Java;Cs]])
-		| Access -> ":access",("Forces private access to package, type or field",[HasParam "Target path";UsedOnEither [TClass;TClassField]])
-		| Alias -> ":alias",("",[Platforms [Java;Cs]])
-		| Allow -> ":allow",("Allows private access from package, type or field",[HasParam "Target path";UsedOnEither [TClass;TClassField]])
-		| Annotation -> ":annotation",("",[Platforms [Java;Cs]])
-		| ArrayAccess -> ":arrayAccess",("Allows [] access on an abstract",[UsedOnEither [TAbstract;TAbstractField]])
-		| AutoBuild -> ":autoBuild",("Extends @:build metadata to all extending and implementing classes",[HasParam "Build macro call";UsedOn TClass])
-		| BaseInterface -> ":baseInterface",("",[Platforms [Java;Cs]])
-		| Bind -> ":bind",("Override Swf class declaration",[Platform Flash;UsedOn TClass])
-		| Bitmap -> ":bitmap",("Embeds given bitmap data into the class (must extend flash.display.BitmapData)",[HasParam "Bitmap file path";UsedOn TClass;Platform Flash])
-		| Build -> ":build",("Builds a class or enum from a macro",[HasParam "Build macro call";UsedOnEither [TClass;TEnum]])
-		| BuildXml -> ":buildXml",("",[Platform Cpp])
-		| Class -> ":class",("",[Platforms [Java;Cs]])
-		| ClassCode -> ":classCode",("",[Platforms [Java;Cs]])
-		| Commutative -> ":commutative",("Declares an abstract operator as commutative",[UsedOn TAbstractField])
-		| CompilerGenerated -> ":compilerGenerated",("Marks a field as generated by the compiler. Shouldn't be used by the end user",[Platforms [Java;Cs]])
-		| CoreApi -> ":coreApi",("Identifies this class as a core api class (forces Api check)",[UsedOnEither [TClass;TEnum;TTypedef;TAbstract]])
-		| CoreType -> ":coreType",("Identifies an abstract as core type so that it requires no implementation",[UsedOn TAbstract])
-		| CppFileCode -> ":cppFileCode",("",[Platform Cpp])
-		| CppNamespaceCode -> ":cppNamespaceCode",("",[Platform Cpp])
-		| Debug -> ":debug",("Forces debug information to be generated into the Swf even without -debug",[UsedOnEither [TClass;TClassField]; Platform Flash])
-		| Decl -> ":decl",("",[Platform Cpp])
-		| DefParam -> ":defParam",("?",[])
-		| Depend -> ":depend",("",[Platform Cpp])
-		| Deprecated -> ":deprecated",("",[Platforms [Java;Cs]])
-		| DynamicObject -> ":dynamicObject",("",[Platforms [Java;Cs]])
-		| Enum -> ":enum",("",[Platforms [Java;Cs]])
-		| Expose -> ":expose",("Makes the class available on the window object",[HasParam "?Name=Class path";UsedOn TClass;Platform Js])
-		| Extern -> ":extern",("Marks the field as extern so it is not generated",[UsedOn TClassField])
-		| FakeEnum -> ":fakeEnum",("Treat enum as collection of values of the specified type",[HasParam "Type name";UsedOn TEnum])
-		| File -> ":file",("Includes a given binary file into the target Swf and associates it with the class (must extend flash.utils.ByteArray)",[HasParam "File path";UsedOn TClass;Platform Flash])
-		| Final -> ":final",("Prevents a class from being extended",[UsedOn TClass])
-		| Font -> ":font",("Embeds the given TrueType font into the class (must extend flash.text.Font)",[HasParam "TTF path";HasParam "Range String";UsedOn TClass])
-		| From -> ":from",("Specifies that the field of the abstract is a cast operation from the type identified in the function",[UsedOn TAbstractField])
-		| FunctionCode -> ":functionCode",("",[Platform Cpp])
-		| FunctionTailCode -> ":functionTailCode",("",[Platform Cpp])
-		| Generic -> ":generic",("Marks a class or class field as generic so each type parameter combination generates its own type/field",[UsedOnEither [TClass;TClassField]])
-		| Getter -> ":getter",("Generates a native getter function on the given field",[HasParam "Class field name";UsedOn TClassField;Platform Flash])
-		| Hack -> ":hack",("Allows extending classes marked as @:final",[UsedOn TClass])
-		| HaxeGeneric -> ":haxeGeneric",("",[Platforms [Java;Cs]])
-		| HeaderClassCode -> ":headerClassCode",("",[Platform Cpp])
-		| HeaderCode -> ":headerCode",("",[Platform Cpp])
-		| HeaderNamespaceCode -> ":headerNamespaceCode",("",[Platform Cpp])
-		| HxGen -> ":hxGen",("Annotates that an extern class was generated by Haxe",[Platforms [Java;Cs]; UsedOnEither [TClass;TEnum]])
-		| IfFeature -> ":ifFeature",("Causes a field to be kept by DCE if the given feature is part of the compilation",[HasParam "Feature name";UsedOn TClassField])
-		| Impl -> ":impl",("Used internally to mark abstract implementation fields",[UsedOn TAbstractField])
-		| Include -> ":include",("",[Platform Cpp])
-		| InitPackage -> ":initPackage",("?",[])
-		| Internal -> ":internal",("Generates the annotated field/class with 'internal' access",[Platforms [Java;Cs]; UsedOnEither[TClass;TEnum;TClassField]])
-		| IsVar -> ":isVar",("Forces a physical field to be generated for properties that otherwise would not require one",[UsedOn TClassField])
-		| JavaNative -> ":javaNative",("",[Platforms [Java;Cs]])
-		| Keep -> ":keep",("Causes a field or type to be kept by DCE",[])
-		| KeepInit -> ":keepInit",("Causes a class to be kept by DCE even if all its field are removed",[UsedOn TClass])
-		| KeepSub -> ":keepSub",("Extends @:keep metadata to all implementing and extending classes",[UsedOn TClass])
-		| Meta -> ":meta",("Internally used to mark a class field as being the metadata field",[])
-		| Macro -> ":macro",("(deprecated)",[])
-		| MaybeUsed -> ":maybeUsed",("Internally used by DCE to mark fields that might be kept",[])
-		| MultiType -> ":multiType",("Specifies that an abstract chooses its this-type from its @:to functions",[UsedOn TAbstract])
-		| Native -> ":native",("Rewrites the path of a class or enum during generation",[HasParam "Output type path";UsedOnEither [TClass;TEnum]])
-		| NativeGen -> ":nativeGen",("",[Platforms [Java;Cs]])
-		| NativeGeneric -> ":nativeGeneric",("",[Platforms [Java;Cs]])
-		| NoCompletion -> ":noCompletion",("Prevents the compiler from suggesting completion on this field",[UsedOn TClassField])
-		| NoDebug -> ":noDebug",("Does not generate debug information into the Swf even if -debug is set",[UsedOnEither [TClass;TClassField];Platform Flash])
-		| NoDoc -> ":noDoc",("Prevents a type from being included in documentation generation",[])
-		| NoPackageRestrict -> ":noPackageRestrict",("?",[])
-		| NoStack -> ":noStack",("",[Platform Cpp])
-		| NotNull -> ":notNull",("Declares an abstract type as not accepting null values",[UsedOn TAbstract])
-		| NoUsing -> ":noUsing",("Prevents a field from being used with 'using'",[UsedOn TClassField])
-		| Ns -> ":ns",("Internally used by the Swf generator to handle namespaces",[Platform Flash])
-		| Op -> ":op",("Declares an abstract field as being an operator overload",[HasParam "The operation";UsedOn TAbstractField])
-		| Optional -> ":optional",("Marks the field of a structure as optional",[UsedOn TClassField])
-		| Overload -> ":overload",("Allows the field to be called with different argument types",[HasParam "Function specification (no expression)";UsedOn TClassField])
-		| Public -> ":public",("Marks a class field as being public",[UsedOn TClassField])
-		| PublicFields -> ":publicFields",("Forces all class fields of inheriting classes to be public",[UsedOn TClass])
-		| PrivateAccess -> ":privateAccess",("Internally used by the typer to allow context-sensitive private access",[])
-		| Protected -> ":protected",("Marks a class field as being protected",[UsedOn TClassField])
-		| ReadOnly -> ":readOnly",("",[Platforms [Java;Cs]])
-		| RealPath -> ":realPath",("Internally used on @:native types to retain original path information",[])
-		| Remove -> ":remove",("Causes an interface to be removed from all implementing classes before generation",[UsedOn TClass])
-		| Require -> ":require",("Allows access to a field only if the specified compiler flag is set",[HasParam "Compiler flag to check";UsedOn TClassField])
-		| ReplaceReflection -> ":replaceReflection",("",[Platforms [Java;Cs]])
-		| Rtti -> ":rtti",("Adds runtime type informations",[UsedOn TClass])
-		| Runtime -> ":runtime",("?",[])
-		| RuntimeValue -> ":runtimeValue",("Marks an abstract as being a runtime value",[UsedOn TAbstract])
-		| Setter -> ":setter",("Generates a native getter function on the given field",[HasParam "Class field name";UsedOn TClassField;Platform Flash])
-		| SkipCtor -> ":skipCtor",("",[Platforms [Java;Cs]])
-		| SkipReflection -> ":skipReflection",("",[Platforms [Java;Cs]])
-		| Sound -> ":sound",( "Includes a given .wav or .mp3 file into the target Swf and associates it with the class (must extend flash.media.Sound)",[HasParam "File path";UsedOn TClass;Platform Flash])
-		| Struct -> ":struct",("",[Platforms [Java;Cs]])
-		| SuppressWarnings -> ":suppressWarnings",("",[Platforms [Java;Cs]])
-		| Synchronized -> ":synchronized",("",[Platforms [Java;Cs]])
-		| Throws -> ":throws",("",[Platforms [Java;Cs]])
-		| To -> ":to",("Specifies that the field of the abstract is a cast operation to the type identified in the function",[UsedOn TAbstractField])
-		| Transient -> ":transient",("",[Platforms [Java;Cs]])
-		| ValueUsed -> ":valueUsed",("Internally used by DCE to mark an abstract value as used",[])
-		| VarArgs -> ":varArgs",("",[Platforms [Java;Cs]])
-		| Volatile -> ":volatile",("",[Platforms [Java;Cs]])
-		| UnifyMinDynamic -> ":unifyMinDynamic",("Allows a collection of types to unify to Dynamic",[UsedOn TClassField])
-		| Unreflective -> ":unreflective",("",[Platform Cpp])
-		| Unsafe -> ":unsafe",("",[Platforms [Java;Cs]])
-		| Usage -> ":usage",("?",[])
-		| Used -> ":used",("Internally used by DCE to mark a class or field as used",[])
-		| Last -> assert false
-		| Dollar s -> "$" ^ s,("",[])
-		| Custom s -> s,("",[])
-
-	let hmeta =
-		let h = Hashtbl.create 0 in
-		let rec loop i =
-			let m = Obj.magic i in
-			if m <> Last then begin
-				Hashtbl.add h (fst (to_string m)) m;
-				loop (i + 1);
-			end;
-		in
-		loop 0;
-		h
-
-	let parse s = try Hashtbl.find hmeta (":" ^ s) with Not_found -> Custom (":" ^ s)
-
-	let from_string s =
-		if s = "" then Custom "" else match s.[0] with
-		| ':' -> (try Hashtbl.find hmeta s with Not_found -> Custom s)
-		| '$' -> Dollar (String.sub s 1 (String.length s - 1))
-		| _ -> Custom s
-
-	(* removed
-	:functionBody -> :functionCode
-	*)
 	let has m ml = List.exists (fun (m2,_,_) -> m = m2) ml
 	let get m ml = List.find (fun (m2,_,_) -> m = m2) ml
 end
@@ -832,316 +676,3 @@ let map_expr loop (e,p) =
 	| EMeta (m,e) -> EMeta(m, loop e)
 	) in
 	(e,p)
-
-let reify in_macro =
-	let cur_pos = ref None in
-	let mk_enum ename n vl p =
-		let constr = (EConst (Ident n),p) in
-		match vl with
-		| [] -> constr
-		| _ -> (ECall (constr,vl),p)
-	in
-	let to_const c p =
-		let cst n v = mk_enum "Constant" n [EConst (String v),p] p in
-		match c with
-		| Int i -> cst "CInt" i
-		| String s -> cst "CString" s
-		| Float s -> cst "CFloat" s
-		| Ident s -> cst "CIdent" s
-		| Regexp (r,o) -> mk_enum "Constant" "CRegexp" [(EConst (String r),p);(EConst (String o),p)] p
-	in
-	let rec to_binop o p =
-		let op n = mk_enum "Binop" n [] p in
-		match o with
-		| OpAdd -> op "OpAdd"
-		| OpMult -> op "OpMult"
-		| OpDiv -> op "OpDiv"
-		| OpSub -> op "OpSub"
-		| OpAssign -> op "OpAssign"
-		| OpEq -> op "OpEq"
-		| OpNotEq -> op "OpNotEq"
-		| OpGt -> op "OpGt"
-		| OpGte -> op "OpGte"
-		| OpLt -> op "OpLt"
-		| OpLte -> op "OpLte"
-		| OpAnd -> op "OpAnd"
-		| OpOr -> op "OpOr"
-		| OpXor -> op "OpXor"
-		| OpBoolAnd -> op "OpBoolAnd"
-		| OpBoolOr -> op "OpBoolOr"
-		| OpShl -> op "OpShl"
-		| OpShr -> op "OpShr"
-		| OpUShr -> op "OpUShr"
-		| OpMod -> op "OpMod"
-		| OpAssignOp o -> mk_enum "Binop" "OpAssignOp" [to_binop o p] p
-		| OpInterval -> op "OpInterval"
-		| OpArrow -> op "OpArrow"
-	in
-	let to_string s p =
-		let len = String.length s in
-		if len > 1 && s.[0] = '$' then
-			(EConst (Ident (String.sub s 1 (len - 1))),p)
-		else
-			(EConst (String s),p)
-	in
-	let to_array f a p =
-		(EArrayDecl (List.map (fun s -> f s p) a),p)
-	in
-	let to_null p =
-		(EConst (Ident "null"),p)
-	in
-	let to_opt f v p =
-		match v with
-		| None -> to_null p
-		| Some v -> f v p
-	in
-	let to_bool o p =
-		(EConst (Ident (if o then "true" else "false")),p)
-	in
-	let to_obj fields p =
-		(EObjectDecl fields,p)
-	in
-	let rec to_tparam t p =
-		let n, v = (match t with
-			| TPType t -> "TPType", to_ctype t p
-			| TPExpr e -> "TPExpr", to_expr e p
-		) in
-		mk_enum "TypeParam" n [v] p
-	and to_tpath t p =
-		let fields = [
-			("pack", to_array to_string t.tpackage p);
-			("name", to_string t.tname p);
-			("params", to_array to_tparam t.tparams p);
-		] in
-		to_obj (match t.tsub with None -> fields | Some s -> fields @ ["sub",to_string s p]) p
-	and to_ctype t p =
-		let ct n vl = mk_enum "ComplexType" n vl p in
-		match t with
-		| CTPath { tpackage = []; tparams = []; tsub = None; tname = n } when n.[0] = '$' ->
-			to_string n p
-		| CTPath t -> ct "TPath" [to_tpath t p]
-		| CTFunction (args,ret) -> ct "TFunction" [to_array to_ctype args p; to_ctype ret p]
-		| CTAnonymous fields -> ct "TAnonymous" [to_array to_cfield fields p]
-		| CTParent t -> ct "TParent" [to_ctype t p]
-		| CTExtend (t,fields) -> ct "TExtend" [to_tpath t p; to_array to_cfield fields p]
-		| CTOptional t -> ct "TOptional" [to_ctype t p]
-	and to_fun f p =
-		let farg (n,o,t,e) p =
-			let fields = [
-				"name", to_string n p;
-				"opt", to_bool o p;
-				"type", to_opt to_ctype t p;
-			] in
-			to_obj (match e with None -> fields | Some e -> fields @ ["value",to_expr e p]) p
-		in
-		let rec fparam t p =
-			let fields = [
-				"name", to_string t.tp_name p;
-				"constraints", to_array to_ctype t.tp_constraints p;
-				"params", to_array fparam t.tp_params p;
-			] in
-			to_obj fields p
-		in
-		let fields = [
-			("args",to_array farg f.f_args p);
-			("ret",to_opt to_ctype f.f_type p);
-			("expr",to_opt to_expr f.f_expr p);
-			("params",to_array fparam f.f_params p);
-		] in
-		to_obj fields p
-	and to_cfield f p =
-		let p = f.cff_pos in
-		let to_access a p =
-			let n = (match a with
-			| APublic -> "APublic"
-			| APrivate -> "APrivate"
-			| AStatic -> "AStatic"
-			| AOverride -> "AOverride"
-			| ADynamic -> "ADynamic"
-			| AInline -> "AInline"
-			| AMacro -> "AMacro"
-			) in
-			mk_enum "Access" n [] p
-		in
-		let to_kind k =
-			let n, vl = (match k with
-				| FVar (ct,e) -> "FVar", [to_opt to_ctype ct p;to_opt to_expr e p]
-				| FFun f -> "FFun", [to_fun f p]
-				| FProp (get,set,t,e) -> "FProp", [to_string get p; to_string set p; to_opt to_ctype t p; to_opt to_expr e p]
-			) in
-			mk_enum "FieldType" n vl p
-		in
-		let fields = [
-			Some ("name", to_string f.cff_name p);
-			(match f.cff_doc with None -> None | Some s -> Some ("doc", to_string s p));
-			(match f.cff_access with [] -> None | l -> Some ("access", to_array to_access l p));
-			Some ("kind", to_kind f.cff_kind);
-			Some ("pos", to_pos f.cff_pos);
-			(match f.cff_meta with [] -> None | l -> Some ("meta", to_meta f.cff_meta p));
-		] in
-		let fields = List.rev (List.fold_left (fun acc v -> match v with None -> acc | Some e -> e :: acc) [] fields) in
-		to_obj fields p
-	and to_meta m p =
-		to_array (fun (m,el,p) _ ->
-			let fields = [
-				"name", to_string (fst (Meta.to_string m)) p;
-				"params", to_expr_array el p;
-				"pos", to_pos p;
-			] in
-			to_obj fields p
-		) m p
-	and to_pos p =
-		match !cur_pos with
-		| Some p ->
-			p
-		| None ->
-		let file = (EConst (String p.pfile),p) in
-		let pmin = (EConst (Int (string_of_int p.pmin)),p) in
-		let pmax = (EConst (Int (string_of_int p.pmax)),p) in
-		if in_macro then
-			(EUntyped (ECall ((EConst (Ident "$mk_pos"),p),[file;pmin;pmax]),p),p)
-		else
-			to_obj [("file",file);("min",pmin);("max",pmax)] p
-	and to_expr_array a p = match a with
-		| [EMeta ((Meta.Dollar "a",[],_),e1),_] -> (match fst e1 with EArrayDecl el -> to_expr_array el p | _ -> e1)
-		| _ -> to_array to_expr a p
-	and to_expr e _ =
-		let p = snd e in
-		let expr n vl =
-			let e = mk_enum "ExprDef" n vl p in
-			to_obj [("expr",e);("pos",to_pos p)] p
-		in
-		let loop e = to_expr e (snd e) in
-		match fst e with
-		| EConst (Ident n) when n.[0] = '$' && String.length n > 1 ->
-			to_string n p
-		| EConst c ->
-			expr "EConst" [to_const c p]
-		| EArray (e1,e2) ->
-			expr "EArray" [loop e1;loop e2]
-		| EBinop (op,e1,e2) ->
-			expr "EBinop" [to_binop op p; loop e1; loop e2]
-		| EField (e,s) ->
-			expr "EField" [loop e; to_string s p]
-		| EParenthesis e ->
-			expr "EParenthesis" [loop e]
-		| EObjectDecl fl ->
-			expr "EObjectDecl" [to_array (fun (f,e) -> to_obj [("field",to_string f p);("expr",loop e)]) fl p]
-		| EArrayDecl el ->
-			expr "EArrayDecl" [to_expr_array el p]
-		| ECall (e,el) ->
-			expr "ECall" [loop e;to_expr_array el p]
-		| ENew (t,el) ->
-			expr "ENew" [to_tpath t p;to_expr_array el p]
-		| EUnop (op,flag,e) ->
-			let op = mk_enum "Unop" (match op with
-				| Increment -> "OpIncrement"
-				| Decrement -> "OpDecrement"
-				| Not -> "OpNot"
-				| Neg -> "OpNeg"
-				| NegBits -> "OpNegBits"
-			) [] p in
-			expr "EUnop" [op;to_bool (flag = Postfix) p;loop e]
-		| EVars vl ->
-			expr "EVars" [to_array (fun (v,t,e) p ->
-				let fields = [
-					"name", to_string v p;
-					"type", to_opt to_ctype t p;
-					"expr", to_opt to_expr e p;
-				] in
-				to_obj fields p
-			) vl p]
-		| EFunction (name,f) ->
-			expr "EFunction" [to_opt to_string name p; to_fun f p]
-		| EBlock el ->
-			expr "EBlock" [to_expr_array el p]
-		| EFor (e1,e2) ->
-			expr "EFor" [loop e1;loop e2]
-		| EIn (e1,e2) ->
-			expr "EIn" [loop e1;loop e2]
-		| EIf (e1,e2,eelse) ->
-			expr "EIf" [loop e1;loop e2;to_opt to_expr eelse p]
-		| EWhile (e1,e2,flag) ->
-			expr "EWhile" [loop e1;loop e2;to_bool (flag = NormalWhile) p]
-		| ESwitch (e1,cases,def) ->
-			let scase (el,eg,e) p =
-				to_obj [("values",to_expr_array el p);"guard",to_opt to_expr eg p;"expr",to_opt to_expr e p] p
-			in
-			expr "ESwitch" [loop e1;to_array scase cases p;to_opt (to_opt to_expr) def p]
-		| ETry (e1,catches) ->
-			let scatch (n,t,e) p =
-				to_obj [("name",to_string n p);("type",to_ctype t p);("expr",loop e)] p
-			in
-			expr "ETry" [loop e1;to_array scatch catches p]
-		| EReturn eo ->
-			expr "EReturn" [to_opt to_expr eo p]
-		| EBreak ->
-			expr "EBreak" []
-		| EContinue ->
-			expr "EContinue" []
-		| EUntyped e ->
-			expr "EUntyped" [loop e]
-		| EThrow e ->
-			expr "EThrow" [loop e]
-		| ECast (e,ct) ->
-			expr "ECast" [loop e; to_opt to_ctype ct p]
-		| EDisplay (e,flag) ->
-			expr "EDisplay" [loop e; to_bool flag p]
-		| EDisplayNew t ->
-			expr "EDisplayNew" [to_tpath t p]
-		| ETernary (e1,e2,e3) ->
-			expr "ETernary" [loop e1;loop e2;loop e3]
-		| ECheckType (e1,ct) ->
-			expr "ECheckType" [loop e1; to_ctype ct p]
-		| EMeta ((m,ml,p),e1) ->
-			match m, ml with
-			| Meta.Dollar ("" | "e"), _ ->
-				e1
-			| Meta.Dollar "a", _ ->
-				expr "EArrayDecl" (match fst e1 with EArrayDecl el -> [to_expr_array el p] | _ -> [e1])
-			| Meta.Dollar "b", _ ->
-				expr "EBlock" [e1]
-			(* TODO: can $v and $i be implemented better? *)
-			| Meta.Dollar "v", _ ->
-				(ECall ((EField ((EField ((EField ((EConst (Ident "haxe"),p),"macro"),p),"Context"),p),"makeExpr"),p),[e; to_pos (pos e)]),p)
-			| Meta.Dollar "i", _ ->
-				expr "EConst" [mk_enum "Constant" "CIdent" [e1] (pos e1)]
-			| Meta.Dollar "p", _ ->
-				(ECall ((EField ((EField ((EField ((EConst (Ident "haxe"),p),"macro"),p),"ExprTools"),p),"toFieldExpr"),p),[e]),p)
-			| Meta.Custom ":pos", [pexpr] ->
-				let old = !cur_pos in
-				cur_pos := Some pexpr;
-				let e = loop e1 in
-				cur_pos := old;
-				e
-			| _ ->
-				expr "EMeta" [to_obj [("name",to_string (fst (Meta.to_string m)) p);("params",to_expr_array ml p);("pos",to_pos p)] p;loop e1]
-	and to_tparam_decl p t =
-		to_obj [
-			"name", to_string t.tp_name p;
-			"params", (EArrayDecl (List.map (to_tparam_decl p) t.tp_params),p);
-			"constraints", (EArrayDecl (List.map (fun t -> to_ctype t p) t.tp_constraints),p)
-		] p
-	and to_type_def (t,p) =
-		match t with
-		| EClass d ->
-			let ext = ref None and impl = ref [] and interf = ref false in
-			List.iter (function
-				| HExtern | HPrivate -> ()
-				| HInterface -> interf := true;
-				| HExtends t -> ext := Some (to_tpath t p)
-				| HImplements i -> impl := (to_tpath i p) :: !impl
-			) d.d_flags;
-			to_obj [
-				"pack", (EArrayDecl [],p);
-				"name", to_string d.d_name p;
-				"pos", to_pos p;
-				"meta", to_meta d.d_meta p;
-				"params", (EArrayDecl (List.map (to_tparam_decl p) d.d_params),p);
-				"isExtern", to_bool (List.mem HExtern d.d_flags) p;
-				"kind", mk_enum "TypeDefKind" "TDClass" [(match !ext with None -> (EConst (Ident "null"),p) | Some t -> t);(EArrayDecl (List.rev !impl),p);to_bool !interf p] p;
-				"fields", (EArrayDecl (List.map (fun f -> to_cfield f p) d.d_data),p)
-			] p
-		| _ -> assert false
-	in
-	(fun e -> to_expr e (snd e)), to_ctype, to_type_def

+ 156 - 0
common.ml

@@ -47,6 +47,17 @@ type stats = {
 	s_macros_called : int ref;
 }
 
+type platform =
+	| Cross
+	| Flash8
+	| Js
+	| Neko
+	| Flash
+	| Php
+	| Cpp
+	| Cs
+	| Java
+
 (**
 	The capture policy tells which handling we make of captured locals
 	(the locals which are referenced in local functions)
@@ -256,6 +267,151 @@ module Define = struct
 		| Last -> assert false
 end
 
+module MetaInfo = struct
+	open Meta
+	type meta_usage =
+		| TClass
+		| TClassField
+		| TAbstract
+		| TAbstractField
+		| TEnum
+		| TTypedef
+
+	type meta_parameter =
+		| HasParam of string
+		| Platform of platform
+		| Platforms of platform list
+		| UsedOn of meta_usage
+		| UsedOnEither of meta_usage list
+
+	let to_string = function
+		| Abstract -> ":abstract",("",[Platforms [Java;Cs]])
+		| Access -> ":access",("Forces private access to package, type or field",[HasParam "Target path";UsedOnEither [TClass;TClassField]])
+		| Alias -> ":alias",("",[Platforms [Java;Cs]])
+		| Allow -> ":allow",("Allows private access from package, type or field",[HasParam "Target path";UsedOnEither [TClass;TClassField]])
+		| Annotation -> ":annotation",("",[Platforms [Java;Cs]])
+		| ArrayAccess -> ":arrayAccess",("Allows [] access on an abstract",[UsedOnEither [TAbstract;TAbstractField]])
+		| AutoBuild -> ":autoBuild",("Extends @:build metadata to all extending and implementing classes",[HasParam "Build macro call";UsedOn TClass])
+		| BaseInterface -> ":baseInterface",("",[Platforms [Java;Cs]])
+		| Bind -> ":bind",("Override Swf class declaration",[Platform Flash;UsedOn TClass])
+		| Bitmap -> ":bitmap",("Embeds given bitmap data into the class (must extend flash.display.BitmapData)",[HasParam "Bitmap file path";UsedOn TClass;Platform Flash])
+		| Build -> ":build",("Builds a class or enum from a macro",[HasParam "Build macro call";UsedOnEither [TClass;TEnum]])
+		| BuildXml -> ":buildXml",("",[Platform Cpp])
+		| Class -> ":class",("",[Platforms [Java;Cs]])
+		| ClassCode -> ":classCode",("",[Platforms [Java;Cs]])
+		| Commutative -> ":commutative",("Declares an abstract operator as commutative",[UsedOn TAbstractField])
+		| CompilerGenerated -> ":compilerGenerated",("Marks a field as generated by the compiler. Shouldn't be used by the end user",[Platforms [Java;Cs]])
+		| CoreApi -> ":coreApi",("Identifies this class as a core api class (forces Api check)",[UsedOnEither [TClass;TEnum;TTypedef;TAbstract]])
+		| CoreType -> ":coreType",("Identifies an abstract as core type so that it requires no implementation",[UsedOn TAbstract])
+		| CppFileCode -> ":cppFileCode",("",[Platform Cpp])
+		| CppNamespaceCode -> ":cppNamespaceCode",("",[Platform Cpp])
+		| Debug -> ":debug",("Forces debug information to be generated into the Swf even without -debug",[UsedOnEither [TClass;TClassField]; Platform Flash])
+		| Decl -> ":decl",("",[Platform Cpp])
+		| DefParam -> ":defParam",("?",[])
+		| Depend -> ":depend",("",[Platform Cpp])
+		| Deprecated -> ":deprecated",("",[Platforms [Java;Cs]])
+		| DynamicObject -> ":dynamicObject",("",[Platforms [Java;Cs]])
+		| Enum -> ":enum",("",[Platforms [Java;Cs]])
+		| Expose -> ":expose",("Makes the class available on the window object",[HasParam "?Name=Class path";UsedOn TClass;Platform Js])
+		| Extern -> ":extern",("Marks the field as extern so it is not generated",[UsedOn TClassField])
+		| FakeEnum -> ":fakeEnum",("Treat enum as collection of values of the specified type",[HasParam "Type name";UsedOn TEnum])
+		| File -> ":file",("Includes a given binary file into the target Swf and associates it with the class (must extend flash.utils.ByteArray)",[HasParam "File path";UsedOn TClass;Platform Flash])
+		| Final -> ":final",("Prevents a class from being extended",[UsedOn TClass])
+		| Font -> ":font",("Embeds the given TrueType font into the class (must extend flash.text.Font)",[HasParam "TTF path";HasParam "Range String";UsedOn TClass])
+		| From -> ":from",("Specifies that the field of the abstract is a cast operation from the type identified in the function",[UsedOn TAbstractField])
+		| FunctionCode -> ":functionCode",("",[Platform Cpp])
+		| FunctionTailCode -> ":functionTailCode",("",[Platform Cpp])
+		| Generic -> ":generic",("Marks a class or class field as generic so each type parameter combination generates its own type/field",[UsedOnEither [TClass;TClassField]])
+		| Getter -> ":getter",("Generates a native getter function on the given field",[HasParam "Class field name";UsedOn TClassField;Platform Flash])
+		| Hack -> ":hack",("Allows extending classes marked as @:final",[UsedOn TClass])
+		| HaxeGeneric -> ":haxeGeneric",("",[Platforms [Java;Cs]])
+		| HeaderClassCode -> ":headerClassCode",("",[Platform Cpp])
+		| HeaderCode -> ":headerCode",("",[Platform Cpp])
+		| HeaderNamespaceCode -> ":headerNamespaceCode",("",[Platform Cpp])
+		| HxGen -> ":hxGen",("Annotates that an extern class was generated by Haxe",[Platforms [Java;Cs]; UsedOnEither [TClass;TEnum]])
+		| IfFeature -> ":ifFeature",("Causes a field to be kept by DCE if the given feature is part of the compilation",[HasParam "Feature name";UsedOn TClassField])
+		| Impl -> ":impl",("Used internally to mark abstract implementation fields",[UsedOn TAbstractField])
+		| Include -> ":include",("",[Platform Cpp])
+		| InitPackage -> ":initPackage",("?",[])
+		| Internal -> ":internal",("Generates the annotated field/class with 'internal' access",[Platforms [Java;Cs]; UsedOnEither[TClass;TEnum;TClassField]])
+		| IsVar -> ":isVar",("Forces a physical field to be generated for properties that otherwise would not require one",[UsedOn TClassField])
+		| JavaNative -> ":javaNative",("",[Platforms [Java;Cs]])
+		| Keep -> ":keep",("Causes a field or type to be kept by DCE",[])
+		| KeepInit -> ":keepInit",("Causes a class to be kept by DCE even if all its field are removed",[UsedOn TClass])
+		| KeepSub -> ":keepSub",("Extends @:keep metadata to all implementing and extending classes",[UsedOn TClass])
+		| Meta -> ":meta",("Internally used to mark a class field as being the metadata field",[])
+		| Macro -> ":macro",("(deprecated)",[])
+		| MaybeUsed -> ":maybeUsed",("Internally used by DCE to mark fields that might be kept",[])
+		| MultiType -> ":multiType",("Specifies that an abstract chooses its this-type from its @:to functions",[UsedOn TAbstract])
+		| Native -> ":native",("Rewrites the path of a class or enum during generation",[HasParam "Output type path";UsedOnEither [TClass;TEnum]])
+		| NativeGen -> ":nativeGen",("",[Platforms [Java;Cs]])
+		| NativeGeneric -> ":nativeGeneric",("",[Platforms [Java;Cs]])
+		| NoCompletion -> ":noCompletion",("Prevents the compiler from suggesting completion on this field",[UsedOn TClassField])
+		| NoDebug -> ":noDebug",("Does not generate debug information into the Swf even if -debug is set",[UsedOnEither [TClass;TClassField];Platform Flash])
+		| NoDoc -> ":noDoc",("Prevents a type from being included in documentation generation",[])
+		| NoPackageRestrict -> ":noPackageRestrict",("?",[])
+		| NoStack -> ":noStack",("",[Platform Cpp])
+		| NotNull -> ":notNull",("Declares an abstract type as not accepting null values",[UsedOn TAbstract])
+		| NoUsing -> ":noUsing",("Prevents a field from being used with 'using'",[UsedOn TClassField])
+		| Ns -> ":ns",("Internally used by the Swf generator to handle namespaces",[Platform Flash])
+		| Op -> ":op",("Declares an abstract field as being an operator overload",[HasParam "The operation";UsedOn TAbstractField])
+		| Optional -> ":optional",("Marks the field of a structure as optional",[UsedOn TClassField])
+		| Overload -> ":overload",("Allows the field to be called with different argument types",[HasParam "Function specification (no expression)";UsedOn TClassField])
+		| Public -> ":public",("Marks a class field as being public",[UsedOn TClassField])
+		| PublicFields -> ":publicFields",("Forces all class fields of inheriting classes to be public",[UsedOn TClass])
+		| PrivateAccess -> ":privateAccess",("Internally used by the typer to allow context-sensitive private access",[])
+		| Protected -> ":protected",("Marks a class field as being protected",[UsedOn TClassField])
+		| ReadOnly -> ":readOnly",("",[Platforms [Java;Cs]])
+		| RealPath -> ":realPath",("Internally used on @:native types to retain original path information",[])
+		| Remove -> ":remove",("Causes an interface to be removed from all implementing classes before generation",[UsedOn TClass])
+		| Require -> ":require",("Allows access to a field only if the specified compiler flag is set",[HasParam "Compiler flag to check";UsedOn TClassField])
+		| ReplaceReflection -> ":replaceReflection",("",[Platforms [Java;Cs]])
+		| Rtti -> ":rtti",("Adds runtime type informations",[UsedOn TClass])
+		| Runtime -> ":runtime",("?",[])
+		| RuntimeValue -> ":runtimeValue",("Marks an abstract as being a runtime value",[UsedOn TAbstract])
+		| Setter -> ":setter",("Generates a native getter function on the given field",[HasParam "Class field name";UsedOn TClassField;Platform Flash])
+		| SkipCtor -> ":skipCtor",("",[Platforms [Java;Cs]])
+		| SkipReflection -> ":skipReflection",("",[Platforms [Java;Cs]])
+		| Sound -> ":sound",( "Includes a given .wav or .mp3 file into the target Swf and associates it with the class (must extend flash.media.Sound)",[HasParam "File path";UsedOn TClass;Platform Flash])
+		| Struct -> ":struct",("",[Platforms [Java;Cs]])
+		| SuppressWarnings -> ":suppressWarnings",("",[Platforms [Java;Cs]])
+		| Synchronized -> ":synchronized",("",[Platforms [Java;Cs]])
+		| Throws -> ":throws",("",[Platforms [Java;Cs]])
+		| To -> ":to",("Specifies that the field of the abstract is a cast operation to the type identified in the function",[UsedOn TAbstractField])
+		| Transient -> ":transient",("",[Platforms [Java;Cs]])
+		| ValueUsed -> ":valueUsed",("Internally used by DCE to mark an abstract value as used",[])
+		| VarArgs -> ":varArgs",("",[Platforms [Java;Cs]])
+		| Volatile -> ":volatile",("",[Platforms [Java;Cs]])
+		| UnifyMinDynamic -> ":unifyMinDynamic",("Allows a collection of types to unify to Dynamic",[UsedOn TClassField])
+		| Unreflective -> ":unreflective",("",[Platform Cpp])
+		| Unsafe -> ":unsafe",("",[Platforms [Java;Cs]])
+		| Usage -> ":usage",("?",[])
+		| Used -> ":used",("Internally used by DCE to mark a class or field as used",[])
+		| Last -> assert false
+		| Dollar s -> "$" ^ s,("",[])
+		| Custom s -> s,("",[])
+
+	let hmeta =
+		let h = Hashtbl.create 0 in
+		let rec loop i =
+			let m = Obj.magic i in
+			if m <> Last then begin
+				Hashtbl.add h (fst (to_string m)) m;
+				loop (i + 1);
+			end;
+		in
+		loop 0;
+		h
+
+	let parse s = try Hashtbl.find hmeta (":" ^ s) with Not_found -> Custom (":" ^ s)
+
+	let from_string s =
+		if s = "" then Custom "" else match s.[0] with
+		| ':' -> (try Hashtbl.find hmeta s with Not_found -> Custom s)
+		| '$' -> Dollar (String.sub s 1 (String.length s - 1))
+		| _ -> Custom s
+end
+
 let stats =
 	{
 		s_files_parsed = ref 0;

+ 3 - 3
genxml.ml

@@ -95,7 +95,7 @@ let gen_meta meta =
 	| [] -> []
 	| _ ->
 		let nodes = List.map (fun (m,el,_) ->
-			node "m" ["n",fst (Meta.to_string m)] (List.map (fun e -> node "e" [] [gen_string (sexpr e)]) el)
+			node "m" ["n",fst (MetaInfo.to_string m)] (List.map (fun e -> node "e" [] [gen_string (sexpr e)]) el)
 		) meta in
 		[node "meta" [] nodes]
 
@@ -341,8 +341,8 @@ let generate_type com t =
 			| Meta.DefParam | Meta.CoreApi | Meta.Used | Meta.MaybeUsed -> ()
 			| _ ->
 			match pl with
-			| [] -> p "@%s " (fst (Meta.to_string m))
-			| l -> p "@%s(%s) " (fst (Meta.to_string m)) (String.concat "," (List.map sexpr pl))
+			| [] -> p "@%s " (fst (MetaInfo.to_string m))
+			| l -> p "@%s(%s) " (fst (MetaInfo.to_string m)) (String.concat "," (List.map sexpr pl))
 		) ml
 	in
 	let access a =

+ 6 - 6
interp.ml

@@ -2373,7 +2373,7 @@ let macro_lib =
 			| VString file ->
 				let com = ccom() in
 				(match com.platform with
-				| Ast.Flash -> Genswf.add_swf_lib com file false
+				| Flash -> Genswf.add_swf_lib com file false
 				| _ -> failwith "Unsupported platform");
 				VNull
 			| _ ->
@@ -3545,7 +3545,7 @@ and encode_access a =
 
 and encode_meta_entry (m,ml,p) =
 	enc_obj [
-		"name", enc_string (fst (Meta.to_string m));
+		"name", enc_string (fst (MetaInfo.to_string m));
 		"params", enc_array (List.map encode_expr ml);
 		"pos", encode_pos p;
 	]
@@ -3837,7 +3837,7 @@ and decode_access v =
 	| _ -> raise Invalid_expr
 
 and decode_meta_entry v =
-	Meta.from_string (dec_string (field v "name")), List.map decode_expr (dec_array (field v "params")), decode_pos (field v "pos")
+	MetaInfo.from_string (dec_string (field v "name")), List.map decode_expr (dec_array (field v "params")), decode_pos (field v "pos")
 
 and decode_meta_content v =
 	List.map decode_meta_entry (dec_array v)
@@ -4008,20 +4008,20 @@ let encode_meta m set =
 		"add", VFunction (Fun3 (fun k vl p ->
 			(try
 				let el = List.map decode_expr (dec_array vl) in
-				meta := (Meta.from_string (dec_string k), el, decode_pos p) :: !meta;
+				meta := (MetaInfo.from_string (dec_string k), el, decode_pos p) :: !meta;
 				set (!meta)
 			with Invalid_expr ->
 				failwith "Invalid expression");
 			VNull
 		));
 		"remove", VFunction (Fun1 (fun k ->
-			let k = Meta.from_string (try dec_string k with Invalid_expr -> raise Builtin_error) in
+			let k = MetaInfo.from_string (try dec_string k with Invalid_expr -> raise Builtin_error) in
 			meta := List.filter (fun (m,_,_) -> m <> k) (!meta);
 			set (!meta);
 			VNull
 		));
 		"has", VFunction (Fun1 (fun k ->
-			let k = Meta.from_string (try dec_string k with Invalid_expr -> raise Builtin_error) in
+			let k = MetaInfo.from_string (try dec_string k with Invalid_expr -> raise Builtin_error) in
 			VBool (List.exists (fun (m,_,_) -> m = k) (!meta));
 		));
 	]

+ 1 - 1
main.ml

@@ -1306,7 +1306,7 @@ with
 	| Typer.DisplayMetadata m ->
 		let b = Buffer.create 0 in
 		List.iter (fun (m,el,p) ->
-			Buffer.add_string b ("<meta name=\"" ^ (fst (Ast.Meta.to_string m)) ^ "\"");
+			Buffer.add_string b ("<meta name=\"" ^ (fst (MetaInfo.to_string m)) ^ "\"");
 			if el = [] then Buffer.add_string b "/>" else begin
 				Buffer.add_string b ">\n";
 				List.iter (fun e -> Buffer.add_string b ((htmlescape (Genxml.sexpr e)) ^ "\n")) el;

+ 322 - 9
parser.ml

@@ -82,6 +82,12 @@ let is_resuming p =
 	let p2 = !resume_display in
 	p.pmax = p2.pmin && Common.unique_full_path p.pfile = p2.pfile
 
+let is_dollar_ident e = match fst e with
+	| EConst (Ident n) when n.[0] = '$' ->
+		true
+	| _ ->
+		false
+
 let precedence op =
 	let left = true and right = false in
 	match op with
@@ -101,12 +107,6 @@ let is_not_assign = function
 	| OpAssign | OpAssignOp _ -> false
 	| _ -> true
 
-let is_dollar_ident e = match fst e with
-	| EConst (Ident n) when n.[0] = '$' ->
-		true
-	| _ ->
-		false
-
 let swap op1 op2 =
 	let p1, left1 = precedence op1 in
 	let p2, _ = precedence op2 in
@@ -137,6 +137,319 @@ let rec make_meta name params ((v,p2) as e) p1 =
 	| _ ->
 		EMeta((name,params,p1),e),punion p1 p2
 
+let reify in_macro =
+	let cur_pos = ref None in
+	let mk_enum ename n vl p =
+		let constr = (EConst (Ident n),p) in
+		match vl with
+		| [] -> constr
+		| _ -> (ECall (constr,vl),p)
+	in
+	let to_const c p =
+		let cst n v = mk_enum "Constant" n [EConst (String v),p] p in
+		match c with
+		| Int i -> cst "CInt" i
+		| String s -> cst "CString" s
+		| Float s -> cst "CFloat" s
+		| Ident s -> cst "CIdent" s
+		| Regexp (r,o) -> mk_enum "Constant" "CRegexp" [(EConst (String r),p);(EConst (String o),p)] p
+	in
+	let rec to_binop o p =
+		let op n = mk_enum "Binop" n [] p in
+		match o with
+		| OpAdd -> op "OpAdd"
+		| OpMult -> op "OpMult"
+		| OpDiv -> op "OpDiv"
+		| OpSub -> op "OpSub"
+		| OpAssign -> op "OpAssign"
+		| OpEq -> op "OpEq"
+		| OpNotEq -> op "OpNotEq"
+		| OpGt -> op "OpGt"
+		| OpGte -> op "OpGte"
+		| OpLt -> op "OpLt"
+		| OpLte -> op "OpLte"
+		| OpAnd -> op "OpAnd"
+		| OpOr -> op "OpOr"
+		| OpXor -> op "OpXor"
+		| OpBoolAnd -> op "OpBoolAnd"
+		| OpBoolOr -> op "OpBoolOr"
+		| OpShl -> op "OpShl"
+		| OpShr -> op "OpShr"
+		| OpUShr -> op "OpUShr"
+		| OpMod -> op "OpMod"
+		| OpAssignOp o -> mk_enum "Binop" "OpAssignOp" [to_binop o p] p
+		| OpInterval -> op "OpInterval"
+		| OpArrow -> op "OpArrow"
+	in
+	let to_string s p =
+		let len = String.length s in
+		if len > 1 && s.[0] = '$' then
+			(EConst (Ident (String.sub s 1 (len - 1))),p)
+		else
+			(EConst (String s),p)
+	in
+	let to_array f a p =
+		(EArrayDecl (List.map (fun s -> f s p) a),p)
+	in
+	let to_null p =
+		(EConst (Ident "null"),p)
+	in
+	let to_opt f v p =
+		match v with
+		| None -> to_null p
+		| Some v -> f v p
+	in
+	let to_bool o p =
+		(EConst (Ident (if o then "true" else "false")),p)
+	in
+	let to_obj fields p =
+		(EObjectDecl fields,p)
+	in
+	let rec to_tparam t p =
+		let n, v = (match t with
+			| TPType t -> "TPType", to_ctype t p
+			| TPExpr e -> "TPExpr", to_expr e p
+		) in
+		mk_enum "TypeParam" n [v] p
+	and to_tpath t p =
+		let fields = [
+			("pack", to_array to_string t.tpackage p);
+			("name", to_string t.tname p);
+			("params", to_array to_tparam t.tparams p);
+		] in
+		to_obj (match t.tsub with None -> fields | Some s -> fields @ ["sub",to_string s p]) p
+	and to_ctype t p =
+		let ct n vl = mk_enum "ComplexType" n vl p in
+		match t with
+		| CTPath { tpackage = []; tparams = []; tsub = None; tname = n } when n.[0] = '$' ->
+			to_string n p
+		| CTPath t -> ct "TPath" [to_tpath t p]
+		| CTFunction (args,ret) -> ct "TFunction" [to_array to_ctype args p; to_ctype ret p]
+		| CTAnonymous fields -> ct "TAnonymous" [to_array to_cfield fields p]
+		| CTParent t -> ct "TParent" [to_ctype t p]
+		| CTExtend (t,fields) -> ct "TExtend" [to_tpath t p; to_array to_cfield fields p]
+		| CTOptional t -> ct "TOptional" [to_ctype t p]
+	and to_fun f p =
+		let farg (n,o,t,e) p =
+			let fields = [
+				"name", to_string n p;
+				"opt", to_bool o p;
+				"type", to_opt to_ctype t p;
+			] in
+			to_obj (match e with None -> fields | Some e -> fields @ ["value",to_expr e p]) p
+		in
+		let rec fparam t p =
+			let fields = [
+				"name", to_string t.tp_name p;
+				"constraints", to_array to_ctype t.tp_constraints p;
+				"params", to_array fparam t.tp_params p;
+			] in
+			to_obj fields p
+		in
+		let fields = [
+			("args",to_array farg f.f_args p);
+			("ret",to_opt to_ctype f.f_type p);
+			("expr",to_opt to_expr f.f_expr p);
+			("params",to_array fparam f.f_params p);
+		] in
+		to_obj fields p
+	and to_cfield f p =
+		let p = f.cff_pos in
+		let to_access a p =
+			let n = (match a with
+			| APublic -> "APublic"
+			| APrivate -> "APrivate"
+			| AStatic -> "AStatic"
+			| AOverride -> "AOverride"
+			| ADynamic -> "ADynamic"
+			| AInline -> "AInline"
+			| AMacro -> "AMacro"
+			) in
+			mk_enum "Access" n [] p
+		in
+		let to_kind k =
+			let n, vl = (match k with
+				| FVar (ct,e) -> "FVar", [to_opt to_ctype ct p;to_opt to_expr e p]
+				| FFun f -> "FFun", [to_fun f p]
+				| FProp (get,set,t,e) -> "FProp", [to_string get p; to_string set p; to_opt to_ctype t p; to_opt to_expr e p]
+			) in
+			mk_enum "FieldType" n vl p
+		in
+		let fields = [
+			Some ("name", to_string f.cff_name p);
+			(match f.cff_doc with None -> None | Some s -> Some ("doc", to_string s p));
+			(match f.cff_access with [] -> None | l -> Some ("access", to_array to_access l p));
+			Some ("kind", to_kind f.cff_kind);
+			Some ("pos", to_pos f.cff_pos);
+			(match f.cff_meta with [] -> None | l -> Some ("meta", to_meta f.cff_meta p));
+		] in
+		let fields = List.rev (List.fold_left (fun acc v -> match v with None -> acc | Some e -> e :: acc) [] fields) in
+		to_obj fields p
+	and to_meta m p =
+		to_array (fun (m,el,p) _ ->
+			let fields = [
+				"name", to_string (fst (Common.MetaInfo.to_string m)) p;
+				"params", to_expr_array el p;
+				"pos", to_pos p;
+			] in
+			to_obj fields p
+		) m p
+	and to_pos p =
+		match !cur_pos with
+		| Some p ->
+			p
+		| None ->
+		let file = (EConst (String p.pfile),p) in
+		let pmin = (EConst (Int (string_of_int p.pmin)),p) in
+		let pmax = (EConst (Int (string_of_int p.pmax)),p) in
+		if in_macro then
+			(EUntyped (ECall ((EConst (Ident "$mk_pos"),p),[file;pmin;pmax]),p),p)
+		else
+			to_obj [("file",file);("min",pmin);("max",pmax)] p
+	and to_expr_array a p = match a with
+		| [EMeta ((Meta.Dollar "a",[],_),e1),_] -> (match fst e1 with EArrayDecl el -> to_expr_array el p | _ -> e1)
+		| _ -> to_array to_expr a p
+	and to_expr e _ =
+		let p = snd e in
+		let expr n vl =
+			let e = mk_enum "ExprDef" n vl p in
+			to_obj [("expr",e);("pos",to_pos p)] p
+		in
+		let loop e = to_expr e (snd e) in
+		match fst e with
+		| EConst (Ident n) when n.[0] = '$' && String.length n > 1 ->
+			to_string n p
+		| EConst c ->
+			expr "EConst" [to_const c p]
+		| EArray (e1,e2) ->
+			expr "EArray" [loop e1;loop e2]
+		| EBinop (op,e1,e2) ->
+			expr "EBinop" [to_binop op p; loop e1; loop e2]
+		| EField (e,s) ->
+			expr "EField" [loop e; to_string s p]
+		| EParenthesis e ->
+			expr "EParenthesis" [loop e]
+		| EObjectDecl fl ->
+			expr "EObjectDecl" [to_array (fun (f,e) -> to_obj [("field",to_string f p);("expr",loop e)]) fl p]
+		| EArrayDecl el ->
+			expr "EArrayDecl" [to_expr_array el p]
+		| ECall (e,el) ->
+			expr "ECall" [loop e;to_expr_array el p]
+		| ENew (t,el) ->
+			expr "ENew" [to_tpath t p;to_expr_array el p]
+		| EUnop (op,flag,e) ->
+			let op = mk_enum "Unop" (match op with
+				| Increment -> "OpIncrement"
+				| Decrement -> "OpDecrement"
+				| Not -> "OpNot"
+				| Neg -> "OpNeg"
+				| NegBits -> "OpNegBits"
+			) [] p in
+			expr "EUnop" [op;to_bool (flag = Postfix) p;loop e]
+		| EVars vl ->
+			expr "EVars" [to_array (fun (v,t,e) p ->
+				let fields = [
+					"name", to_string v p;
+					"type", to_opt to_ctype t p;
+					"expr", to_opt to_expr e p;
+				] in
+				to_obj fields p
+			) vl p]
+		| EFunction (name,f) ->
+			expr "EFunction" [to_opt to_string name p; to_fun f p]
+		| EBlock el ->
+			expr "EBlock" [to_expr_array el p]
+		| EFor (e1,e2) ->
+			expr "EFor" [loop e1;loop e2]
+		| EIn (e1,e2) ->
+			expr "EIn" [loop e1;loop e2]
+		| EIf (e1,e2,eelse) ->
+			expr "EIf" [loop e1;loop e2;to_opt to_expr eelse p]
+		| EWhile (e1,e2,flag) ->
+			expr "EWhile" [loop e1;loop e2;to_bool (flag = NormalWhile) p]
+		| ESwitch (e1,cases,def) ->
+			let scase (el,eg,e) p =
+				to_obj [("values",to_expr_array el p);"guard",to_opt to_expr eg p;"expr",to_opt to_expr e p] p
+			in
+			expr "ESwitch" [loop e1;to_array scase cases p;to_opt (to_opt to_expr) def p]
+		| ETry (e1,catches) ->
+			let scatch (n,t,e) p =
+				to_obj [("name",to_string n p);("type",to_ctype t p);("expr",loop e)] p
+			in
+			expr "ETry" [loop e1;to_array scatch catches p]
+		| EReturn eo ->
+			expr "EReturn" [to_opt to_expr eo p]
+		| EBreak ->
+			expr "EBreak" []
+		| EContinue ->
+			expr "EContinue" []
+		| EUntyped e ->
+			expr "EUntyped" [loop e]
+		| EThrow e ->
+			expr "EThrow" [loop e]
+		| ECast (e,ct) ->
+			expr "ECast" [loop e; to_opt to_ctype ct p]
+		| EDisplay (e,flag) ->
+			expr "EDisplay" [loop e; to_bool flag p]
+		| EDisplayNew t ->
+			expr "EDisplayNew" [to_tpath t p]
+		| ETernary (e1,e2,e3) ->
+			expr "ETernary" [loop e1;loop e2;loop e3]
+		| ECheckType (e1,ct) ->
+			expr "ECheckType" [loop e1; to_ctype ct p]
+		| EMeta ((m,ml,p),e1) ->
+			match m, ml with
+			| Meta.Dollar ("" | "e"), _ ->
+				e1
+			| Meta.Dollar "a", _ ->
+				expr "EArrayDecl" (match fst e1 with EArrayDecl el -> [to_expr_array el p] | _ -> [e1])
+			| Meta.Dollar "b", _ ->
+				expr "EBlock" [e1]
+			(* TODO: can $v and $i be implemented better? *)
+			| Meta.Dollar "v", _ ->
+				(ECall ((EField ((EField ((EField ((EConst (Ident "haxe"),p),"macro"),p),"Context"),p),"makeExpr"),p),[e; to_pos (pos e)]),p)
+			| Meta.Dollar "i", _ ->
+				expr "EConst" [mk_enum "Constant" "CIdent" [e1] (pos e1)]
+			| Meta.Dollar "p", _ ->
+				(ECall ((EField ((EField ((EField ((EConst (Ident "haxe"),p),"macro"),p),"ExprTools"),p),"toFieldExpr"),p),[e]),p)
+			| Meta.Custom ":pos", [pexpr] ->
+				let old = !cur_pos in
+				cur_pos := Some pexpr;
+				let e = loop e1 in
+				cur_pos := old;
+				e
+			| _ ->
+				expr "EMeta" [to_obj [("name",to_string (fst (Common.MetaInfo.to_string m)) p);("params",to_expr_array ml p);("pos",to_pos p)] p;loop e1]
+	and to_tparam_decl p t =
+		to_obj [
+			"name", to_string t.tp_name p;
+			"params", (EArrayDecl (List.map (to_tparam_decl p) t.tp_params),p);
+			"constraints", (EArrayDecl (List.map (fun t -> to_ctype t p) t.tp_constraints),p)
+		] p
+	and to_type_def (t,p) =
+		match t with
+		| EClass d ->
+			let ext = ref None and impl = ref [] and interf = ref false in
+			List.iter (function
+				| HExtern | HPrivate -> ()
+				| HInterface -> interf := true;
+				| HExtends t -> ext := Some (to_tpath t p)
+				| HImplements i -> impl := (to_tpath i p) :: !impl
+			) d.d_flags;
+			to_obj [
+				"pack", (EArrayDecl [],p);
+				"name", to_string d.d_name p;
+				"pos", to_pos p;
+				"meta", to_meta d.d_meta p;
+				"params", (EArrayDecl (List.map (to_tparam_decl p) d.d_params),p);
+				"isExtern", to_bool (List.mem HExtern d.d_flags) p;
+				"kind", mk_enum "TypeDefKind" "TDClass" [(match !ext with None -> (EConst (Ident "null"),p) | Some t -> t);(EArrayDecl (List.rev !impl),p);to_bool !interf p] p;
+				"fields", (EArrayDecl (List.map (fun f -> to_cfield f p) d.d_data),p)
+			] p
+		| _ -> assert false
+	in
+	(fun e -> to_expr e (snd e)), to_ctype, to_type_def
+
 let popt f = parser
 	| [< v = f >] -> Some v
 	| [< >] -> None
@@ -419,8 +732,8 @@ and meta_name = parser
 	| [< '(Const (Ident i),p) >] -> (Meta.Custom i), p
 	| [< '(Kwd k,p) >] -> (Meta.Custom (s_keyword k)),p
 	| [< '(DblDot,_); s >] -> match s with parser
-		| [< '(Const (Ident i),p) >] -> (Meta.parse i), p
-		| [< '(Kwd k,p) >] -> (Meta.parse (s_keyword k)),p
+		| [< '(Const (Ident i),p) >] -> (Common.MetaInfo.parse i), p
+		| [< '(Kwd k,p) >] -> (Common.MetaInfo.parse (s_keyword k)),p
 
 and parse_enum_flags = parser
 	| [< '(Kwd Enum,p) >] -> [] , p
@@ -872,7 +1185,7 @@ and expr = parser
 and expr_next e1 = parser
  	| [< '(BrOpen,p1) when is_dollar_ident e1; eparam = expr; '(BrClose,p2); s >] ->
 		(match fst e1 with
-		| EConst(Ident n) -> expr_next (EMeta((Meta.from_string n,[],snd e1),eparam), punion p1 p2) s
+		| EConst(Ident n) -> expr_next (EMeta((Common.MetaInfo.from_string n,[],snd e1),eparam), punion p1 p2) s
 		| _ -> assert false)
 	| [< '(Dot,p); s >] ->
 		if is_resuming p then display (EDisplay (e1,false),p);