Browse Source

more macro refactoring, renamed macro api primitives to match context name

Nicolas Cannasse 8 years ago
parent
commit
7d601f4a27

+ 3 - 0
src/generators/hlinterp.ml

@@ -52,6 +52,9 @@ and vabstract =
 	| AReg of regexp
 	| ARandom
 	| APos of Globals.pos
+	| ATDecl of Type.module_type
+	| AUnsafe of Obj.t
+	| ALazyType of ((unit -> Type.t) ref) * (unit -> value)
 
 and vfunction =
 	| FFun of fundecl

+ 209 - 167
src/macro/hlmacro.ml

@@ -21,71 +21,31 @@ open Type
 open Ast
 open Hlcode
 open Hlinterp
+open MacroApi
 
 type value = Hlinterp.value
 
-type extern_api = {
-	pos : Globals.pos;
-	get_com : unit -> Common.context;
-	get_type : string -> Type.t option;
-	get_module : string -> Type.t list;
-	after_typing : (module_type list -> unit) -> unit;
-	on_generate : (Type.t list -> unit) -> unit;
-	after_generate : (unit -> unit) -> unit;
-	on_type_not_found : (string -> value) -> unit;
-	parse_string : string -> Globals.pos -> bool -> Ast.expr;
-	type_expr : Ast.expr -> Type.texpr;
-	resolve_type  : Ast.complex_type -> Globals.pos -> t;
-	type_macro_expr : Ast.expr -> Type.texpr;
-	store_typed_expr : Type.texpr -> Ast.expr;
-	allow_package : string -> unit;
-	type_patch : string -> string -> bool -> string option -> unit;
-	meta_patch : string -> string -> string option -> bool -> unit;
-	set_js_generator : (value -> unit) -> unit;
-	get_local_type : unit -> t option;
-	get_expected_type : unit -> t option;
-	get_call_arguments : unit -> Ast.expr list option;
-	get_local_method : unit -> string;
-	get_local_imports : unit -> Ast.import list;
-	get_local_using : unit -> tclass list;
-	get_local_vars : unit -> (string, Type.tvar) PMap.t;
-	get_build_fields : unit -> value;
-	get_pattern_locals : Ast.expr -> Type.t -> (string,Type.tvar * Globals.pos) PMap.t;
-	define_type : value -> unit;
-	define_module : string -> value list -> ((string * Globals.pos) list * Ast.import_mode) list -> Ast.type_path list -> unit;
-	module_dependency : string -> string -> bool -> unit;
-	current_module : unit -> module_def;
-	mutable current_macro_module : unit -> module_def;
-	delayed_macro : int -> (unit -> (unit -> value));
-	use_cache : unit -> bool;
-	format_string : string -> Globals.pos -> Ast.expr;
-	cast_or_unify : Type.t -> texpr -> Globals.pos -> Type.texpr;
-	add_global_metadata : string -> string -> (bool * bool * bool) -> unit;
-	add_module_check_policy : string list -> int list -> bool -> int -> unit;
-}
-
 type context = {
 	com : Common.context; (* macro one *)
 	mutable gen : Genhl.context option;
 	interp : Hlinterp.context;
 	types : (Type.path,int) Hashtbl.t;
-	mutable is_reused : bool;
-	mutable curapi : extern_api;
-	mutable on_reused : (unit -> bool) list;
+	mutable curapi : value MacroApi.compiler_api;
 	mutable has_error : bool;
 }
 
-exception Invalid_expr
-exception Abort
 exception Error of string * Globals.pos list
 
 let debug = true (* TODO !!! set to false for speed++ ! *)
 
-let resolve_macro_api_ref = ref (fun _ _ -> None)
 let get_ctx_ref = ref (fun() -> assert false)
 let get_ctx() : context = (!get_ctx_ref)()
+let macro_lib = Hashtbl.create 0
+let interp() = (get_ctx()).interp
 
-let setup() =
+let setup get_api =
+	let api = get_api (fun() -> (get_ctx()).curapi.get_com()) (fun() -> (get_ctx()).curapi) in
+	List.iter (fun (n,v) -> Hashtbl.replace macro_lib n (match v with VClosure (FNativeFun (_,v,_),None) -> v | _ -> assert false)) api;
 	Globals.macro_platform := Globals.Hl
 
 let select ctx =
@@ -122,13 +82,11 @@ let create com api =
 		interp = Hlinterp.create debug;
 		curapi = api;
 		types = Hashtbl.create 0;
-		on_reused = [];
-		is_reused = true;
 		has_error = false;
 	} in
 	select ctx;
 	Hlinterp.set_error_handler ctx.interp (error_handler ctx);
-	Hlinterp.set_macro_api ctx.interp ((!resolve_macro_api_ref) ctx);
+	Hlinterp.set_macro_api ctx.interp (fun name -> try Some (Hashtbl.find macro_lib name) with Not_found -> None);
 	ctx
 
 let init ctx =
@@ -170,7 +128,6 @@ let add_types ctx types ready =
 		Hlinterp.add_code ctx.interp code
 
 let do_reuse ctx api =
-	ctx.is_reused <- false;
 	ctx.curapi <- api
 
 let can_reuse ctx types =
@@ -181,16 +138,7 @@ let can_reuse ctx types =
 		with Not_found ->
 			false
 	in
-	if List.exists has_old_version types then
-		false
-	else if ctx.is_reused then
-		true
-	else if not (List.for_all (fun f -> f()) ctx.on_reused) then
-		false
-	else begin
-		ctx.is_reused <- true;
-		true;
-	end
+	not (List.exists has_old_version types)
 
 let catch_errors ctx ?(final=(fun() -> ())) f =
 	let prev = get_ctx() in (* switch context in case we have an older one, see #5676 *)
@@ -226,37 +174,116 @@ let call_path ctx cpath (f:string) args api =
 
 let vnull = VNull
 let vbool b = VBool b
-let fun1 f : value = assert false
+let vint i = VInt (Int32.of_int i)
+let vint32 i = VInt i
+let vfloat f = VFloat f
+
+let vfun0 f =
+	let callb args = match args with [] -> f() | _ -> assert false in
+	VClosure(FNativeFun ("fun0",callb,HVoid), None)
+
+let vfun1 f =
+	let callb args = match args with [a] -> f a | _ -> assert false in
+	VClosure(FNativeFun ("fun1",callb,HVoid), None)
+
+let vfun2 f =
+	let callb args = match args with [a;b] -> f a b | _ -> assert false in
+	VClosure(FNativeFun ("fun2",callb,HVoid), None)
+
+let vfun3 f =
+	let callb args = match args with [a;b;c] -> f a b c | _ -> assert false in
+	VClosure(FNativeFun ("fun3",callb,HVoid), None)
+
+let vfun4 f =
+	let callb args = match args with [a;b;c;d] -> f a b c d | _ -> assert false in
+	VClosure(FNativeFun ("fun4",callb,HVoid), None)
+
+let vfun5 f =
+	let callb args = match args with [a;b;c;d;e] -> f a b c d e | _ -> assert false in
+	VClosure(FNativeFun ("fun5",callb,HVoid), None)
 
 let exc_string msg =
-	Hlinterp.throw_msg (get_ctx()).interp msg
+	Hlinterp.throw_msg (interp()) msg
 
 let compiler_error msg pos =
 	assert false (* TODO : raise haxe.macro.Error(msg,pos) *)
 
-let call ctx _ callb args pos =
-	assert false
-
 let eval_expr ctx (e:texpr) =
 	assert false
 
 let eval_delayed _ _ =
 	assert false (* macro - in - macro *)
 
-let make_const e =
+let prepare_callback f n =
 	assert false
 
-let dec_string (e:value) : string = assert false
+let encode_pos p = VAbstract (APos p)
+
+let decode_pos = function
+	| VAbstract (APos p) -> p
+	| _ -> raise Invalid_expr
+
+let encode_enum _ pos tag pl =
+	match pos with
+	| None -> VEnum (tag,Array.of_list pl)
+	| Some p -> VEnum (tag,Array.of_list (List.rev (encode_pos p :: List.rev pl)))
+
+let decode_enum = function
+	| VEnum (tag,arr) -> tag, Array.to_list arr
+	| _ -> raise Invalid_expr
+
+let decode_enum_with_pos = function
+	| VEnum (tag,arr) when Array.length arr > 0 ->
+		let rec loop i =
+			if i = Array.length arr - 1 then [] else arr.(i) :: loop (i + 1)
+		in
+		(tag, loop 0), decode_pos arr.(Array.length arr - 1)
+	| _ ->
+		raise Invalid_expr
+
+
+let encode_tdecl t = VAbstract (ATDecl t)
+let encode_unsafe o = VAbstract (AUnsafe o)
+
+let decode_unsafe = function
+	| VAbstract (AUnsafe v) -> v
+	| _ -> raise Invalid_expr
+
+let decode_tdecl = function
+	| VAbstract (ATDecl t) -> t
+	| _ -> raise Invalid_expr
+
+let dec_int = function
+	| VInt i -> Int32.to_int i
+	| _ -> raise Invalid_expr
+
+let dec_i32 = function
+	| VInt i -> i
+	| _ -> raise Invalid_expr
+
+let dec_bool = function
+	| VBool b -> b
+	| _ -> raise Invalid_expr
+
+let field o n =
+	match o with
+	| VDynObj _ | VVirtual _ | VObj _ -> Hlinterp.dyn_get_field (interp()) o n HDyn
+	| _ -> raise Invalid_expr
+
+let dec_string = function
+	| VObj { ofields = [|VBytes s;VInt _|] } -> Hlinterp.hl_to_caml s
+	| _ -> raise Invalid_expr
+
 let dec_array (e:value) = assert false
-let decode_type_def (td:value) = assert false
-let decode_tdecl (td:value) = assert false
-let decode_expr (e:value) : Ast.expr = assert false
-let decode_texpr (e:value) : texpr = assert false
-let decode_field (f:value) = assert false
-let decode_ctype (c:value) = assert false
-let decode_type (t:value) = assert false
 
-let enc_enum tag pl = VEnum (tag,Array.of_list pl)
+let encode_lazytype f t = VAbstract (ALazyType (f,t))
+
+let decode_lazytype = function
+	| VAbstract (ALazyType (t,_)) -> t
+	| _ -> raise Invalid_expr
+
+let enc_obj fields =
+	assert false
 
 let enc_inst path fields =
 	let ctx = get_ctx() in
@@ -271,95 +298,110 @@ let enc_inst path fields =
 let enc_string s =
 	enc_inst ([],"String") [|VBytes (caml_to_hl s);VInt (Int32.of_int (String.length s))|]
 
-let enc_string s : value = assert false
-let enc_array ar : value = assert false
-let enc_obj fl : value = assert false
-let encode_type t : value = assert false
-let encode_expr e = assert false
-let encode_texpr e : value = assert false
-let encode_field f : value = assert false
-
-
-let resolve_macro_api ctx name =
-	match name with
-	| "make_expr" ->
-		Some (function
-		| [v;VAbstract (APos p)] ->
-			let error v = failwith ("Unsupported value " ^ vstr ctx.interp v Hlcode.HDyn) in
-			(*
-			let h_enum = hash "__enum__" and h_et = hash "__et__" and h_ct = hash "__ct__" in
-			let h_tag = hash "tag" and h_args = hash "args" in
-			let h_length = hash "length" in
-			let ctx = get_ctx() in
-			let make_path t =
-				let rec loop = function
-					| [] -> assert false
-					| [name] -> (Ast.EConst (Ast.Ident name),p)
-					| name :: l -> (Ast.EField (loop l,name),p)
-				in
-				let t = t_infos t in
-				loop (List.rev (if t.mt_module.m_path = t.mt_path then fst t.mt_path @ [snd t.mt_path] else fst t.mt_module.m_path @ [snd t.mt_module.m_path;snd t.mt_path]))
-			in*)
-			let rec loop = function
-				| VNull -> (Ast.EConst (Ast.Ident "null"),p)
-				| VBool b -> (Ast.EConst (Ast.Ident (if b then "true" else "false")),p)
-				| VInt i -> (Ast.EConst (Ast.Int (Int32.to_string i)),p)
-				| VFloat f ->
-					let std = (Ast.EConst (Ast.Ident "std"), p) in
-					let math = (Ast.EField (std, "Math"), p) in
-					if (f = infinity) then
-						(Ast.EField (math, "POSITIVE_INFINITY"), p)
-					else if (f = neg_infinity) then
-						(Ast.EField (math, "NEGATIVE_INFINITY"), p)
-					else if (f <> f) then
-						(Ast.EField (math, "NaN"), p)
-					else
-						(Ast.EConst (Ast.Float (Common.float_repres f)), p)
-				| VAbstract (APos p) ->
-					(Ast.EObjectDecl (
-						(("fileName",Globals.null_pos) , (Ast.EConst (Ast.String p.Globals.pfile) , p)) ::
-						(("lineNumber",Globals.null_pos) , (Ast.EConst (Ast.Int (string_of_int (Lexer.get_error_line p))),p)) ::
-						(("className",Globals.null_pos) , (Ast.EConst (Ast.String ("")),p)) ::
-						[]
-					), p)
-				| VObj { oproto = { pclass = { pname = "String" } }; ofields = [|VBytes content;VInt _|] } ->
-					(Ast.EConst (Ast.String (hl_to_caml content)),p)
-				| v ->
-					error v
-				(*
-				| VObject o as v ->
-					match o.oproto with
-					| None ->
-						(match get_field_opt o h_ct with
-						| Some (VAbstract (ATDecl t)) ->
-							make_path t
-						| _ ->
-							let fields = List.fold_left (fun acc (fid,v) -> ((field_name ctx fid,Globals.null_pos), loop v) :: acc) [] (Array.to_list o.ofields) in
-							(Ast.EObjectDecl fields, p))
-					| Some proto ->
-						match get_field_opt proto h_enum, get_field_opt o h_a, get_field_opt o h_s, get_field_opt o h_length with
-						| _, Some (VArray a), _, Some (VInt len) ->
-							(Ast.EArrayDecl (List.map loop (Array.to_list (Array.sub a 0 len))),p)
-						| Some (VObject en), _, _, _ ->
-							(match get_field en h_et, get_field o h_tag with
-							| VAbstract (ATDecl t), VString tag ->
-								let e = (Ast.EField (make_path t,tag),p) in
-								(match get_field_opt o h_args with
-								| Some (VArray args) ->
-									let args = List.map loop (Array.to_list args) in
-									(Ast.ECall (e,args),p)
-								| _ -> e)
-							| _ ->
-								error v)
-						| _ ->
-							error v
-					*)
-			in
-			encode_expr (loop v)
-		| _ ->
-			assert false)
-	| _ ->
-		None
+let enc_array vl =
+	let arr = Array.of_list vl in
+	enc_inst (["hl";"types"],"ArrayObj") [|VInt (Int32.of_int (Array.length arr));VArray (arr,HDyn)|]
 
-;;
-resolve_macro_api_ref := resolve_macro_api
+let encode_bytes s =
+	enc_inst (["haxe";"io"],"Bytes") [|VInt (Int32.of_int (String.length s)); VBytes s|]
+
+let encode_string_map convert pmap =
+	let h = Hashtbl.create 0 in
+	PMap.iter (fun k v -> Hashtbl.add h k (convert v)) pmap;
+	enc_inst (["haxe";"ds"],"StringMap") [|VAbstract (AHashBytes h)|]
+
+let decode_bytes = function
+	| VObj { ofields = [|VInt _;VBytes s|] } -> s
+	| _ -> raise Invalid_expr
+
+let encode_ref v convert tostr =
+	enc_obj [
+		"get", vfun0 (fun() -> convert v);
+		"__string", vfun0 (fun() -> VBytes (caml_to_hl (tostr())));
+		"toString", vfun0 (fun() -> enc_string (tostr()));
+		"$", VAbstract (AUnsafe (Obj.repr v));
+	]
+
+let decode_ref v : 'a =
+	match field v "$" with
+	| VAbstract (AUnsafe t) -> Obj.obj t
+	| _ -> raise Invalid_expr
+
+let value_string v =
+	Hlinterp.vstr (get_ctx()).interp v HDyn
+
+let value_signature v =
+	failwith "signature() not supported in HL macros"
+
+let value_to_expr v p =
+	let ctx = get_ctx() in
+	let error v = failwith ("Unsupported value " ^ vstr ctx.interp v Hlcode.HDyn) in
+	(*
+	let h_enum = hash "__enum__" and h_et = hash "__et__" and h_ct = hash "__ct__" in
+	let h_tag = hash "tag" and h_args = hash "args" in
+	let h_length = hash "length" in
+	let make_path t =
+		let rec loop = function
+			| [] -> assert false
+			| [name] -> (Ast.EConst (Ast.Ident name),p)
+			| name :: l -> (Ast.EField (loop l,name),p)
+		in
+		let t = t_infos t in
+		loop (List.rev (if t.mt_module.m_path = t.mt_path then fst t.mt_path @ [snd t.mt_path] else fst t.mt_module.m_path @ [snd t.mt_module.m_path;snd t.mt_path]))
+	in*)
+	let rec loop = function
+		| VNull -> (Ast.EConst (Ast.Ident "null"),p)
+		| VBool b -> (Ast.EConst (Ast.Ident (if b then "true" else "false")),p)
+		| VInt i -> (Ast.EConst (Ast.Int (Int32.to_string i)),p)
+		| VFloat f ->
+			let std = (Ast.EConst (Ast.Ident "std"), p) in
+			let math = (Ast.EField (std, "Math"), p) in
+			if (f = infinity) then
+				(Ast.EField (math, "POSITIVE_INFINITY"), p)
+			else if (f = neg_infinity) then
+				(Ast.EField (math, "NEGATIVE_INFINITY"), p)
+			else if (f <> f) then
+				(Ast.EField (math, "NaN"), p)
+			else
+				(Ast.EConst (Ast.Float (Common.float_repres f)), p)
+		| VAbstract (APos p) ->
+			(Ast.EObjectDecl (
+				(("fileName",Globals.null_pos) , (Ast.EConst (Ast.String p.Globals.pfile) , p)) ::
+				(("lineNumber",Globals.null_pos) , (Ast.EConst (Ast.Int (string_of_int (Lexer.get_error_line p))),p)) ::
+				(("className",Globals.null_pos) , (Ast.EConst (Ast.String ("")),p)) ::
+				[]
+			), p)
+		| VObj { oproto = { pclass = { pname = "String" } }; ofields = [|VBytes content;VInt _|] } ->
+			(Ast.EConst (Ast.String (hl_to_caml content)),p)
+		| v ->
+			error v
+		(*
+		| VObject o as v ->
+			match o.oproto with
+			| None ->
+				(match get_field_opt o h_ct with
+				| Some (VAbstract (ATDecl t)) ->
+					make_path t
+				| _ ->
+					let fields = List.fold_left (fun acc (fid,v) -> ((field_name ctx fid,Globals.null_pos), loop v) :: acc) [] (Array.to_list o.ofields) in
+					(Ast.EObjectDecl fields, p))
+			| Some proto ->
+				match get_field_opt proto h_enum, get_field_opt o h_a, get_field_opt o h_s, get_field_opt o h_length with
+				| _, Some (VArray a), _, Some (VInt len) ->
+					(Ast.EArrayDecl (List.map loop (Array.to_list (Array.sub a 0 len))),p)
+				| Some (VObject en), _, _, _ ->
+					(match get_field en h_et, get_field o h_tag with
+					| VAbstract (ATDecl t), VString tag ->
+						let e = (Ast.EField (make_path t,tag),p) in
+						(match get_field_opt o h_args with
+						| Some (VArray args) ->
+							let args = List.map loop (Array.to_list args) in
+							(Ast.ECall (e,args),p)
+						| _ -> e)
+					| _ ->
+						error v)
+				| _ ->
+					error v
+			*)
+	in
+	loop v

+ 0 - 4
src/macro/interp.ml

@@ -3229,10 +3229,6 @@ let decode_pos = function
 	| VAbstract (APos p) -> p
 	| _ -> raise Invalid_expr
 
-let maybe_decode_pos v = match v with
-	| VAbstract (APos p) -> p
-	| _ -> Globals.null_pos
-
 let decode_enum v =
 	match field v "index", field v "args" with
 	| VInt i, VNull -> i, []

+ 27 - 24
src/macro/macroApi.ml

@@ -98,8 +98,9 @@ module type InterpApi = sig
 
 	val encode_pos : Globals.pos -> value
 	val encode_enum : enum_index -> Globals.pos option -> int -> value list -> value
-	val encode_tdecl : Type.module_type -> value
 	val encode_string_map : ('a -> value) -> (string, 'a) PMap.t -> value
+
+	val encode_tdecl : Type.module_type -> value
 	val encode_lazytype : (unit -> Type.t) ref -> (unit -> value) -> value
 	val encode_unsafe : Obj.t -> value
 
@@ -117,7 +118,6 @@ module type InterpApi = sig
 	val decode_lazytype : value -> (unit -> Type.t) ref
 	val decode_unsafe : value -> Obj.t
 
-	val maybe_decode_pos : value -> Globals.pos
 	val decode_enum_with_pos : value -> (int * value list) * Globals.pos
 
 	val encode_ref : 'a -> ('a -> value) -> (unit -> string) -> value
@@ -527,6 +527,8 @@ let decode_import_mode t =
 
 let decode_import t = (List.map (fun o -> ((dec_string (field o "name")), (decode_pos (field o "pos")))) (dec_array (field t "path")), decode_import_mode (field t "mode"))
 
+let maybe_decode_pos p = try decode_pos p with Invalid_expr -> Globals.null_pos
+
 let decode_placed_name vp v =
 	dec_string v,maybe_decode_pos vp
 
@@ -1365,7 +1367,7 @@ let rec make_const e =
 
 let macro_api ccom get_api =
 	[
-		"curpos", vfun0 (fun() ->
+		"current_pos", vfun0 (fun() ->
 			encode_pos (get_api()).pos
 		);
 		"error", vfun2 (fun msg p ->
@@ -1388,12 +1390,13 @@ let macro_api ccom get_api =
 		"class_path", vfun0 (fun() ->
 			enc_array (List.map enc_string (ccom()).class_path);
 		);
-		"resolve", vfun1 (fun file ->
+		"resolve_path", vfun1 (fun file ->
 			let file = dec_string file in
 			enc_string (try Common.find_file (ccom()) file with Not_found -> failwith ("File not found '" ^ file ^ "'"))
 		);
-		"define", vfun1 (fun s ->
-			Common.raw_define (ccom()) (dec_string s);
+		"define", vfun2 (fun s v ->
+			let v = if v = vnull then "" else "=" ^ (dec_string v) in
+			Common.raw_define (ccom()) ((dec_string s) ^ v);
 			vnull
 		);
 		"defined", vfun1 (fun s ->
@@ -1414,7 +1417,7 @@ let macro_api ccom get_api =
 		"get_module", vfun1 (fun s ->
 			enc_array (List.map encode_type ((get_api()).get_module (dec_string s)))
 		);
-		"after_typing", vfun1 (fun f ->
+		"on_after_typing", vfun1 (fun f ->
 			let f = prepare_callback f 1 in
 			(get_api()).after_typing (fun tl -> ignore(f [enc_array (List.map encode_module_type tl)]));
 			vnull
@@ -1424,7 +1427,7 @@ let macro_api ccom get_api =
 			(get_api()).on_generate (fun tl -> ignore(f [enc_array (List.map encode_type tl)]));
 			vnull
 		);
-		"after_generate", vfun1 (fun f ->
+		"on_after_generate", vfun1 (fun f ->
 			let f = prepare_callback f 0 in
 			(get_api()).after_generate (fun () -> ignore(f []));
 			vnull
@@ -1434,7 +1437,7 @@ let macro_api ccom get_api =
 			(get_api()).on_type_not_found (fun path -> f [enc_string path]);
 			vnull
 		);
-		"parse", vfun3 (fun s p b ->
+		"do_parse", vfun3 (fun s p b ->
 			let s = dec_string s in
 			if s = "" then raise Invalid_expr;
 			encode_expr ((get_api()).parse_string s (decode_pos p) (dec_bool b))
@@ -1445,7 +1448,7 @@ let macro_api ccom get_api =
 		"signature", vfun1 (fun v ->
 			enc_string (Digest.to_hex (value_signature v))
 		);
-		"to_complex", vfun1 (fun v ->
+		"to_complex_type", vfun1 (fun v ->
 			try	encode_ctype (TExprToExpr.convert_type' (decode_type v))
 			with Exit -> vnull
 		);
@@ -1488,11 +1491,11 @@ let macro_api ccom get_api =
 			(get_api()).meta_patch (dec_string m) (dec_string t) (opt dec_string f) (dec_bool s);
 			vnull
 		);
-		"add_global_metadata", vfun5 (fun s1 s2 b1 b2 b3 ->
+		"add_global_metadata_impl", vfun5 (fun s1 s2 b1 b2 b3 ->
 			(get_api()).add_global_metadata (dec_string s1) (dec_string s2) (dec_bool b1,dec_bool b2,dec_bool b3);
 			vnull
 		);
-		"custom_js", vfun1 (fun f ->
+		"set_custom_js_generator", vfun1 (fun f ->
 			let f = prepare_callback f 1 in
 			(get_api()).set_js_generator (fun js_ctx ->
 				let com = ccom() in
@@ -1548,7 +1551,7 @@ let macro_api ccom get_api =
 			let p = decode_pos p in
 			enc_obj ["min",vint p.Globals.pmin;"max",vint p.Globals.pmax;"file",enc_string p.Globals.pfile]
 		);
-		"make_pos", vfun3 (fun min max file ->
+		"make_position", vfun3 (fun min max file ->
 			encode_pos { Globals.pmin = dec_int min; Globals.pmax = dec_int max; Globals.pfile = dec_string file }
 		);
 		"add_resource", vfun2 (fun name data ->
@@ -1563,32 +1566,32 @@ let macro_api ccom get_api =
 		"get_resources", vfun0 (fun() ->
 			encode_string_map encode_bytes (Hashtbl.fold (fun k v acc -> PMap.add k v acc) (ccom()).resources PMap.empty)
 		);
-		"local_module", vfun0 (fun() ->
+		"get_local_module", vfun0 (fun() ->
 			let m = (get_api()).current_module() in
 			enc_string (s_type_path m.m_path);
 		);
-		"local_type", vfun0 (fun() ->
+		"get_local_type", vfun0 (fun() ->
 			match (get_api()).get_local_type() with
 			| None -> vnull
 			| Some t -> encode_type t
 		);
-		"expected_type", vfun0 (fun() ->
+		"get_expected_type", vfun0 (fun() ->
 			match (get_api()).get_expected_type() with
 			| None -> vnull
 			| Some t -> encode_type t
 		);
-		"call_arguments", vfun0 (fun() ->
+		"get_call_arguments", vfun0 (fun() ->
 			match (get_api()).get_call_arguments() with
 			| None -> vnull
 			| Some el -> enc_array (List.map encode_expr el)
 		);
-		"local_method", vfun0 (fun() ->
+		"get_local_method", vfun0 (fun() ->
 			enc_string ((get_api()).get_local_method())
 		);
-		"local_using", vfun0 (fun() ->
+		"get_local_using", vfun0 (fun() ->
 			enc_array (List.map encode_clref ((get_api()).get_local_using()))
 		);
-		"local_imports", vfun0 (fun() ->
+		"get_local_imports", vfun0 (fun() ->
 			enc_array (List.map encode_import ((get_api()).get_local_imports()))
 		);
 		"local_vars", vfun1 (fun as_var ->
@@ -1632,7 +1635,7 @@ let macro_api ccom get_api =
 			in
 			encode_type (if dec_opt_bool once then follow_once t else follow t)
 		);
-		"build_fields", vfun0 (fun() ->
+		"get_build_fields", vfun0 (fun() ->
 			(get_api()).get_build_fields()
 		);
 		"define_type", vfun1 (fun v ->
@@ -1683,11 +1686,11 @@ let macro_api ccom get_api =
 			| _ -> failwith "Unsupported platform");
 			vnull
 		);
-		"module_dependency", vfun2 (fun m file ->
+		"register_module_dependency", vfun2 (fun m file ->
 			(get_api()).module_dependency (dec_string m) (dec_string file) false;
 			vnull
 		);
-		"module_reuse_call", vfun2 (fun m mcall ->
+		"register_module_reuse_call", vfun2 (fun m mcall ->
 			(get_api()).module_dependency (dec_string m) (dec_string mcall) true;
 			vnull
 		);
@@ -1717,7 +1720,7 @@ let macro_api ccom get_api =
 			let loc = (get_api()).get_pattern_locals (decode_expr e) (decode_type t) in
 			encode_string_map (fun (v,_) -> encode_type v.v_type) loc
 		);
-		"macro_context_reused", vfun1 (fun c ->
+		"on_macro_context_reused", vfun1 (fun c ->
 			let c = prepare_callback c 0 in
 			(get_api()).on_reuse (fun() -> dec_bool (c []));
 			vnull

+ 1 - 2
src/macro/macroContext.ml

@@ -25,9 +25,8 @@ open Typecore
 open Error
 open Globals
 
-(* module Interp = Hlmacro *)
+module InterpImpl = Interp (* Hlmacro *)
 
-module InterpImpl = Interp
 module Interp = struct
 	module BuiltApi = MacroApi.MacroApiImpl(InterpImpl)
 	include InterpImpl

+ 71 - 24
std/haxe/macro/Compiler.hx

@@ -25,6 +25,9 @@ import haxe.macro.Expr;
 /**
 	All these methods can be called for compiler configuration macros.
 **/
+#if hl
+@:hlNative("macro")
+#end
 class Compiler {
 	/**
 		A conditional compiler flag can be set command line using
@@ -44,22 +47,34 @@ class Compiler {
 		return macro $v{haxe.macro.Context.definedValue(key)};
 	}
 
-#if neko
+#if (neko || (macro && hl))
 
 	static var ident = ~/^[A-Za-z_][A-Za-z0-9_]*$/;
 	static var path = ~/^[A-Za-z_][A-Za-z0-9_.]*$/;
 
 	public static function allowPackage( v : String ) {
+		#if neko
 		load("allow_package", 1)(v);
+		#end
 	}
 
 	/**
 		Set a conditional compiler flag.
 	**/
 	public static function define( flag : String, ?value : String ) {
-		var v = flag + (value == null ? "" : "=" + value);
-		load("define", 1)(v);
+		#if neko
+		load("define", 2)(flag,value);
+		#end
+	}
+
+	#if !neko
+	private static function typePatch( cl : String, f : String, stat : Bool, t : String ) {
+	}
+	private static function metaPatch( meta : String, cl : String, f : String, stat : Bool ) {
 	}
+	private static function addGlobalMetadataImpl(pathFilter:String, meta:String, recursive:Bool, toTypes:Bool, toFields:Bool) {
+	}
+	#end
 
 	/**
 		Removes a (static) field from a given class by name.
@@ -67,8 +82,12 @@ class Compiler {
 	**/
 	public static function removeField( className : String, field : String, ?isStatic : Bool ) {
 		if( !path.match(className) ) throw "Invalid "+className;
-		if( !ident.match(field) ) throw "Invalid "+field;
-		load("type_patch",4)(className,field,isStatic == true,null);
+		if( !ident.match(field) ) throw "Invalid " + field;
+		#if neko
+		load("type_patch", 4)(className, field, isStatic == true, null);
+		#else
+		typePatch(className, field, isStatic == true, null);
+		#end
 	}
 
 	/**
@@ -78,7 +97,11 @@ class Compiler {
 	public static function setFieldType( className : String, field : String, type : String, ?isStatic : Bool ) {
 		if( !path.match(className) ) throw "Invalid "+className;
 		if( !ident.match((field.charAt(0) == "$") ? field.substr(1) : field) ) throw "Invalid "+field;
-		load("type_patch",4)(className,field,isStatic == true,type);
+		#if neko
+		load("type_patch", 4)(className, field, isStatic == true, type);
+		#else
+		typePatch(className, field, isStatic == true, type);
+		#end
 	}
 
 	/**
@@ -88,38 +111,57 @@ class Compiler {
 	public static function addMetadata( meta : String, className : String, ?field : String, ?isStatic : Bool ) {
 		if( !path.match(className) ) throw "Invalid "+className;
 		if( field != null && !ident.match(field) ) throw "Invalid "+field;
-		load("meta_patch",4)(meta,className,field,isStatic == true);
+		#if neko
+		load("meta_patch", 4)(meta, className, field, isStatic == true);
+		#else
+		metaPatch(meta, className, field, isStatic == true);
+		#end
 	}
 
 	public static function addClassPath( path : String ) {
-		load("add_class_path",1)(path);
+		#if neko
+		load("add_class_path", 1)(path);
+		#end
 	}
 
 	public static function getOutput() : String {
-		return load("get_output",0)();
+		#if neko
+		return load("get_output", 0)();
+		#else
+		return null;
+		#end
 	}
 
 	public static function setOutput( fileOrDir : String ) {
-		load("set_output",1)(fileOrDir);
+		#if neko
+		load("set_output", 1)(fileOrDir);
+		#end
 	}
 
 	public static function getDisplayPos() : Null<{ file : String, pos : Int }> {
-		return load("get_display_pos",0)();
+		#if neko
+		return load("get_display_pos", 0)();
+		#else
+		return null;
+		#end
 	}
 
 	/**
 		Adds a native library depending on the platform (e.g. `-swf-lib` for Flash).
 	**/
 	public static function addNativeLib( name : String ) {
-		load("add_native_lib",1)(name);
+		#if neko
+		load("add_native_lib", 1)(name);
+		#end
 	}
 
 	/**
 		Adds an argument to be passed to the native compiler (e.g. `-javac-arg` for Java).
 	 **/
-	public static function addNativeArg( argument : String )
-	{
-		load("add_native_arg",1)(argument);
+	public static function addNativeArg( argument : String ) {
+		#if neko
+		load("add_native_arg", 1)(argument);
+		#end
 	}
 
 	/**
@@ -342,23 +384,27 @@ class Compiler {
 		through `Context.getType`.
 	**/
 	public static function addGlobalMetadata(pathFilter:String, meta:String, ?recursive:Bool = true, ?toTypes:Bool = true, ?toFields:Bool = false) {
-		load("add_global_metadata",5)(pathFilter, meta, recursive, toTypes, toFields);
+		#if neko
+		load("add_global_metadata_impl", 5)(pathFilter, meta, recursive, toTypes, toFields);
+		#else
+		addGlobalMetadataImpl(pathFilter, meta, recursive, toTypes, toFields);
+		#end
 	}
 
 	/**
 		Change the default JS output by using a custom generator callback
 	**/
 	public static function setCustomJSGenerator( callb : JSGenApi -> Void ) {
-		load("custom_js",1)(callb);
+		#if neko
+		load("set_custom_js_generator", 1)(callb);
+		#end
 	}
 
-	static function load( f, nargs ) : Dynamic {
-		#if macro
-		return neko.Lib.load("macro", f, nargs);
-		#else
-		return Reflect.makeVarArgs(function(_) return throw "Can't be called outside of macro");
-		#end
+	#if neko
+	static inline function load( f, nargs ) : Dynamic {
+		return @:privateAccess Context.load(f, nargs);
 	}
+	#end
 
 #end
 
@@ -376,12 +422,13 @@ class Compiler {
 				var p = Context.currentPos();
 				{ expr : EUntyped( { expr : ECall( { expr : EConst(CIdent("__js__")), pos : p }, [ { expr : EConst(CString(f)), pos : p } ]), pos : p } ), pos : p };
 			case Top | Closure:
-				load("include_file", 2)(file, position);
+				@:privateAccess Context.includeFile(file, position);
 				macro {};
 			case _:
 				Context.error("unknown includeFile position: " + position, Context.currentPos());
 		}
 	}
+
 	#end
 
 }

+ 26 - 6
std/haxe/macro/Context.hl.hx

@@ -40,7 +40,8 @@ class Context {
 	public static function warning( msg : String, pos : Position ) : Void {
 	}
 
-	public static function resolvePath( file : String ) : Void {
+	public static function resolvePath( file : String ) : String {
+		return null;
 	}
 
 	public static function getClassPath() : Array<String> {
@@ -62,7 +63,12 @@ class Context {
 	}
 
 	public static function getLocalClass() : Null<Type.Ref<Type.ClassType>> {
-		return null;
+		var l = getLocalType();
+		if( l == null ) return null;
+		return switch( l ) {
+		case TInst(c,_): c;
+		default: null;
+		}
 	}
 
 	public static function getLocalModule() : String {
@@ -85,14 +91,18 @@ class Context {
 		return null;
 	}
 
+	private static function localVars(b:Bool) : Map<String,Dynamic> {
+		return null;
+	}
+
 	@:deprecated("Use Context.getLocalTVars() instead")
 	public static function getLocalVars() : Map<String,Type> {
-		return null;
+		return cast localVars(false);
 	}
 
 	@:require(haxe_ver >= 3.102)
 	public static function getLocalTVars() : Map<String,Type.TVar> {
-		return null;
+		return cast localVars(true);
 	}
 
 	public static function defined( s : String ) : Bool {
@@ -115,12 +125,16 @@ class Context {
 		return null;
 	}
 
-	public static function parse( expr : String, pos : Position ) : Expr {
+	static function doParse( expr : String, pos : Position, isInline : Bool ) : Expr {
 		return null;
 	}
 
+	public static function parse( expr : String, pos : Position ) : Expr {
+		return doParse(expr,pos,false);
+	}
+
 	public static function parseInlineString( expr : String, pos : Position ) : Expr {
-		return null;
+		return doParse(expr,pos,true);
 	}
 
 	public static function makeExpr( v : Dynamic, pos : Position ) : Expr {
@@ -217,6 +231,12 @@ class Context {
 	public static function onMacroContextReused( callb : Void -> Bool ) : Void {
 	}
 
+	private static function includeFile( file : String, position : String ) {
+	}
+
+	private static function sExpr( e : TypedExpr, pretty : Bool ) : String {
+	}
+
 #end
 
 }

+ 28 - 20
std/haxe/macro/Context.hx

@@ -72,7 +72,7 @@ class Context {
 		file path. Otherwise it returns the absolute file path.
 	**/
 	public static function resolvePath( file : String ) {
-		return load("resolve",1)(file);
+		return load("resolve_path",1)(file);
 	}
 
 	/**
@@ -90,7 +90,7 @@ class Context {
 		Returns the position at which the macro was called.
 	**/
 	public static function currentPos() : Position {
-		return load("curpos", 0)();
+		return load("current_pos", 0)();
 	}
 
 	/**
@@ -104,7 +104,7 @@ class Context {
 	**/
 	@:require(haxe_ver >= 3.1)
 	public static function getExpectedType():Null<Type> {
-		return load("expected_type", 0)();
+		return load("get_expected_type", 0)();
 	}
 
 	/**
@@ -115,7 +115,7 @@ class Context {
 	**/
 	@:require(haxe_ver >= 3.2)
 	public static function getCallArguments():Null<Array<Expr>> {
-		return load("call_arguments", 0)();
+		return load("get_call_arguments", 0)();
 	}
 
 	/**
@@ -124,7 +124,7 @@ class Context {
 		If no such class exists, null is returned.
 	**/
 	public static function getLocalClass() : Null<Type.Ref<Type.ClassType>> {
-		var l : Type = load("local_type", 0)();
+		var l : Type = load("get_local_type", 0)();
 		if( l == null ) return null;
 		return switch( l ) {
 		case TInst(c,_): c;
@@ -136,7 +136,7 @@ class Context {
 		Returns the current module path in/on which the macro was called.
 	**/
 	public static function getLocalModule() : String {
-		return load("local_module", 0)();
+		return load("get_local_module", 0)();
 	}
 
 	/**
@@ -145,7 +145,7 @@ class Context {
 		If no such type exists, null is returned.
 	**/
 	public static function getLocalType() : Null<Type> {
-		return load("local_type", 0)();
+		return load("get_local_type", 0)();
 	}
 
 	/**
@@ -154,7 +154,7 @@ class Context {
 		If no such method exists, null is returned.
 	**/
 	public static function getLocalMethod() : Null<String> {
-		return load("local_method", 0)();
+		return load("get_local_method", 0)();
 	}
 
 	/**
@@ -164,7 +164,7 @@ class Context {
 		Modifying the returned array has no effect on the compiler.
 	**/
 	public static function getLocalUsing() :  Array<Type.Ref<Type.ClassType>> {
-		return load("local_using", 0)();
+		return load("get_local_using", 0)();
 	}
 
 	/**
@@ -173,7 +173,7 @@ class Context {
 		Modifying the returned array has no effect on the compiler.
 	**/
 	public static function getLocalImports() :  Array<ImportExpr> {
-		return load("local_imports", 0)();
+		return load("get_local_imports", 0)();
 	}
 
 	/**
@@ -269,7 +269,7 @@ class Context {
 		The provided `Position` `pos` is used for all generated inner AST nodes.
 	**/
 	public static function parse( expr : String, pos : Position ) : Expr {
-		return load("parse", 3)(expr, pos, false);
+		return load("do_parse", 3)(expr, pos, false);
 	}
 
 	/**
@@ -277,7 +277,7 @@ class Context {
 		String `expr`.
 	**/
 	public static function parseInlineString( expr : String, pos : Position ) : Expr {
-		return load("parse", 3)(expr, pos, true);
+		return load("do_parse", 3)(expr, pos, true);
 	}
 
 	/**
@@ -321,7 +321,7 @@ class Context {
 	**/
 	@:require(haxe_ver >= 3.1)
 	public static function onAfterGenerate( callback : Void -> Void ) {
-		load("after_generate",1)(callback);
+		load("on_after_generate",1)(callback);
 	}
 
 	/**
@@ -333,7 +333,7 @@ class Context {
 		will be called again with the new types as argument.
 	**/
 	public static function onAfterTyping( callback : Array<haxe.macro.Type.ModuleType> -> Void ) {
-		load("after_typing",1)(callback);
+		load("on_after_typing",1)(callback);
 	}
 
 	/**
@@ -387,7 +387,7 @@ class Context {
 		See `haxe.macro.TypeTools.toComplexType` for details.
 	**/
 	public static function toComplexType( t : Type ) : Null<ComplexType> {
-		return load("to_complex", 1)(t);
+		return load("to_complex_type", 1)(t);
 	}
 
 	/**
@@ -426,7 +426,7 @@ class Context {
 		Builds a `Position` from `inf`.
 	**/
 	public static function makePosition( inf : { min : Int, max : Int, file : String } ) : Position {
-		return load("make_pos",3)(inf.min,inf.max,inf.file);
+		return load("make_position",3)(inf.min,inf.max,inf.file);
 	}
 
 	/**
@@ -461,7 +461,7 @@ class Context {
 		This is only defined for `@:build/@:autoBuild` macros.
 	**/
 	public static function getBuildFields() : Array<Field> {
-		return load("build_fields", 0)();
+		return load("get_build_fields", 0)();
 	}
 
 	/**
@@ -550,7 +550,7 @@ class Context {
 		Has no effect if the compilation cache is not used.
 	**/
 	public static function registerModuleDependency( modulePath : String, externFile : String ) {
-		load("module_dependency", 2)(modulePath,externFile);
+		load("register_module_dependency", 2)(modulePath,externFile);
 	}
 
 	/**
@@ -567,7 +567,7 @@ class Context {
 		but calling this function will still trigger loading of given `modulePath`.
 	**/
 	public static function registerModuleReuseCall( modulePath : String, macroCall : String ) {
-		load("module_reuse_call", 2)(modulePath,macroCall);
+		load("register_module_reuse_call", 2)(modulePath,macroCall);
 	}
 
 	/**
@@ -576,7 +576,7 @@ class Context {
 		returns false, the macro context is discarded and another one is created.
 	**/
 	public static function onMacroContextReused( callb : Void -> Bool ) {
-		load("macro_context_reused", 1)(callb);
+		load("on_macro_context_reused", 1)(callb);
 	}
 
 	@:allow(haxe.macro.TypeTools)
@@ -590,6 +590,14 @@ class Context {
 		#end
 	}
 
+	private static function includeFile( file : String, position : String ) {
+		load("include_file", 2)(file, position);
+	}
+
+	private static function sExpr( e : TypedExpr, pretty : Bool ) : String {
+		return haxe.macro.Context.load("s_expr", 2)(e, pretty);
+	}
+
 #end
 
 }

+ 21 - 1
std/haxe/macro/TypeTools.hx

@@ -33,6 +33,9 @@ using Lambda;
 	best used through 'using haxe.macro.TypeTools' syntax and then provides
 	additional methods on haxe.macro.Type instances.
 **/
+#if hl
+@:hlNative("macro")
+#end
 class TypeTools {
 
 	static function nullable(complexType : ComplexType) : ComplexType return macro : Null<$complexType>;
@@ -243,9 +246,19 @@ class TypeTools {
 			throw 'Incompatible arguments: ${typeParameters.length} type parameters and ${concreteTypes.length} concrete types';
 		else if (typeParameters.length == 0)
 			return t;
+		#if neko
 		return Context.load("apply_params", 3)(typeParameters, concreteTypes, t);
+		#else
+		return applyParams(typeParameters, concreteTypes, t);
+		#end
 	}
 
+	#if !neko
+	private static function applyParams( typeParameters:Array<TypeParameter>, concreteTypes:Array<Type>, t:Type ) {
+	}
+	#end
+
+
 	/**
 		Transforms `t` by calling `f` on each of its subtypes.
 
@@ -328,7 +341,14 @@ class TypeTools {
 	/**
 		Converts type `t` to a human-readable String representation.
 	**/
-	static public function toString( t : Type ) : String return Context.load("s_type", 1)(t);
+	static public function toString( t : Type ) : String {
+		#if neko
+		return Context.load("s_type", 1)(t);
+		#else
+		return null;
+		#end
+	}
+
 	#end
 
 	/**

+ 2 - 2
std/haxe/macro/TypedExprTools.hx

@@ -26,7 +26,7 @@ import haxe.macro.Type;
 
 /**
 	This class provides some utility methods to work with typed expressions.
-	It is best used through 'using haxe.macro.TypedExprTools' syntax and then 
+	It is best used through 'using haxe.macro.TypedExprTools' syntax and then
 	provides additional methods on `haxe.macro.TypedExpr` instances.
 **/
 class TypedExprTools {
@@ -156,7 +156,7 @@ class TypedExprTools {
 
 	#if macro
 	static public function toString(t:TypedExpr, ?pretty = false):String {
-		return haxe.macro.Context.load("s_expr", 2)(t, pretty);
+		return @:privateAccess haxe.macro.Context.sExpr(t, pretty);
 	}
 	#end
 }