瀏覽代碼

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;
 	pmax : int;
 }
 }
 
 
-type platform =
-	| Cross
-	| Flash8
-	| Js
-	| Neko
-	| Flash
-	| Php
-	| Cpp
-	| Cs
-	| Java
-
 module Meta = struct
 module Meta = struct
 	type strict_meta =
 	type strict_meta =
 		| Abstract
 		| Abstract
@@ -145,151 +134,6 @@ module Meta = struct
 		| Dollar of string
 		| Dollar of string
 		| Custom 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 has m ml = List.exists (fun (m2,_,_) -> m = m2) ml
 	let get m ml = List.find (fun (m2,_,_) -> m = m2) ml
 	let get m ml = List.find (fun (m2,_,_) -> m = m2) ml
 end
 end
@@ -832,316 +676,3 @@ let map_expr loop (e,p) =
 	| EMeta (m,e) -> EMeta(m, loop e)
 	| EMeta (m,e) -> EMeta(m, loop e)
 	) in
 	) in
 	(e,p)
 	(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;
 	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 capture policy tells which handling we make of captured locals
 	(the locals which are referenced in local functions)
 	(the locals which are referenced in local functions)
@@ -256,6 +267,151 @@ module Define = struct
 		| Last -> assert false
 		| Last -> assert false
 end
 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 =
 let stats =
 	{
 	{
 		s_files_parsed = ref 0;
 		s_files_parsed = ref 0;

+ 3 - 3
genxml.ml

@@ -95,7 +95,7 @@ let gen_meta meta =
 	| [] -> []
 	| [] -> []
 	| _ ->
 	| _ ->
 		let nodes = List.map (fun (m,el,_) ->
 		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
 		) meta in
 		[node "meta" [] nodes]
 		[node "meta" [] nodes]
 
 
@@ -341,8 +341,8 @@ let generate_type com t =
 			| Meta.DefParam | Meta.CoreApi | Meta.Used | Meta.MaybeUsed -> ()
 			| Meta.DefParam | Meta.CoreApi | Meta.Used | Meta.MaybeUsed -> ()
 			| _ ->
 			| _ ->
 			match pl with
 			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
 		) ml
 	in
 	in
 	let access a =
 	let access a =

+ 6 - 6
interp.ml

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

+ 1 - 1
main.ml

@@ -1306,7 +1306,7 @@ with
 	| Typer.DisplayMetadata m ->
 	| Typer.DisplayMetadata m ->
 		let b = Buffer.create 0 in
 		let b = Buffer.create 0 in
 		List.iter (fun (m,el,p) ->
 		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
 			if el = [] then Buffer.add_string b "/>" else begin
 				Buffer.add_string b ">\n";
 				Buffer.add_string b ">\n";
 				List.iter (fun e -> Buffer.add_string b ((htmlescape (Genxml.sexpr e)) ^ "\n")) el;
 				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
 	let p2 = !resume_display in
 	p.pmax = p2.pmin && Common.unique_full_path p.pfile = p2.pfile
 	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 precedence op =
 	let left = true and right = false in
 	let left = true and right = false in
 	match op with
 	match op with
@@ -101,12 +107,6 @@ let is_not_assign = function
 	| OpAssign | OpAssignOp _ -> false
 	| OpAssign | OpAssignOp _ -> false
 	| _ -> true
 	| _ -> true
 
 
-let is_dollar_ident e = match fst e with
-	| EConst (Ident n) when n.[0] = '$' ->
-		true
-	| _ ->
-		false
-
 let swap op1 op2 =
 let swap op1 op2 =
 	let p1, left1 = precedence op1 in
 	let p1, left1 = precedence op1 in
 	let p2, _ = precedence op2 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
 		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
 let popt f = parser
 	| [< v = f >] -> Some v
 	| [< v = f >] -> Some v
 	| [< >] -> None
 	| [< >] -> None
@@ -419,8 +732,8 @@ and meta_name = parser
 	| [< '(Const (Ident i),p) >] -> (Meta.Custom i), p
 	| [< '(Const (Ident i),p) >] -> (Meta.Custom i), p
 	| [< '(Kwd k,p) >] -> (Meta.Custom (s_keyword k)),p
 	| [< '(Kwd k,p) >] -> (Meta.Custom (s_keyword k)),p
 	| [< '(DblDot,_); s >] -> match s with parser
 	| [< '(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
 and parse_enum_flags = parser
 	| [< '(Kwd Enum,p) >] -> [] , p
 	| [< '(Kwd Enum,p) >] -> [] , p
@@ -872,7 +1185,7 @@ and expr = parser
 and expr_next e1 = parser
 and expr_next e1 = parser
  	| [< '(BrOpen,p1) when is_dollar_ident e1; eparam = expr; '(BrClose,p2); s >] ->
  	| [< '(BrOpen,p1) when is_dollar_ident e1; eparam = expr; '(BrClose,p2); s >] ->
 		(match fst e1 with
 		(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)
 		| _ -> assert false)
 	| [< '(Dot,p); s >] ->
 	| [< '(Dot,p); s >] ->
 		if is_resuming p then display (EDisplay (e1,false),p);
 		if is_resuming p then display (EDisplay (e1,false),p);