Skip to content

Commit

Permalink
allowed to inject types in existing modules
Browse files Browse the repository at this point in the history
added Context.defineModule for mutually referencing type definitions
added Context.getLocalModule() (for MacroType)
  • Loading branch information
ncannasse committed Oct 2, 2013
1 parent 3ebb484 commit 445be7a
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 5 deletions.
18 changes: 18 additions & 0 deletions interp.ml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ type extern_api = {
get_build_fields : unit -> value;
get_pattern_locals : Ast.expr -> Type.t -> (string,Type.tvar * Ast.pos) PMap.t;
define_type : value -> unit;
define_module : string -> value list -> unit;
module_dependency : string -> string -> bool -> unit;
current_module : unit -> module_def;
delayed_macro : int -> (unit -> (unit -> value));
Expand Down Expand Up @@ -2368,6 +2369,10 @@ let macro_lib =
VNull
| _ -> error()
);
"local_module", Fun0 (fun() ->
let m = (get_ctx()).curapi.current_module() in
VString (Ast.s_type_path m.m_path);
);
"local_type", Fun0 (fun() ->
match (get_ctx()).curapi.get_local_type() with
| None -> VNull
Expand Down Expand Up @@ -2409,6 +2414,14 @@ let macro_lib =
(get_ctx()).curapi.define_type v;
VNull
);
"define_module", Fun2 (fun p v ->
match p, v with
| VString path, VArray vl ->
(get_ctx()).curapi.define_module path (Array.to_list vl);
VNull
| _ ->
error()
);
"add_class_path", Fun1 (fun v ->
match v with
| VString cp ->
Expand Down Expand Up @@ -4398,6 +4411,11 @@ let decode_type_def v =
| _ ->
raise Invalid_expr
) in
(* if our package ends with an uppercase letter, then it's the module name *)
let pack,name = (match List.rev pack with
| last :: l when not (is_lower_ident last) -> List.rev l, last
| _ -> pack, name
) in
(pack, name), tdef, pos

(* ---------------------------------------------------------------------- *)
Expand Down
4 changes: 2 additions & 2 deletions main.ml
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ and wait_loop boot_com host port =
else try
if m.m_extra.m_mark <= start_mark then begin
(match m.m_extra.m_kind with
| MFake -> () (* don't get classpath *)
| MFake | MSub -> () (* don't get classpath *)
| MCode -> if not (check_module_path com2 m p) then raise Not_found;
| MMacro when ctx.Typecore.in_macro -> if not (check_module_path com2 m p) then raise Not_found;
| MMacro ->
Expand Down Expand Up @@ -609,7 +609,7 @@ and wait_loop boot_com host port =
a.a_meta <- List.filter (fun (m,_,_) -> m <> Ast.Meta.ValueUsed) a.a_meta
| _ -> ()
) m.m_types;
Typeload.add_module ctx m p;
if m.m_extra.m_kind <> MSub then Typeload.add_module ctx m p;
PMap.iter (Hashtbl.add com2.resources) m.m_extra.m_binded_res;
PMap.iter (fun _ m2 -> add_modules m0 m2) m.m_extra.m_deps);
List.iter (Typer.call_init_macro ctx) m.m_extra.m_macro_calls
Expand Down
13 changes: 13 additions & 0 deletions std/haxe/macro/Context.hx
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,13 @@ class Context {
}
}

/**
Returns the current module path in/on which the macro was called.
**/
public static function getLocalModule() : String {
return new String(load("local_module", 0)());
}

/**
Returns the current type in/on which the macro was called.
Expand Down Expand Up @@ -344,6 +351,12 @@ class Context {
load("define_type", 1)(t);
}

/**
Defines a new module with several `TypeDefinition` `types`.
**/
public static function defineModule( modulePath : String, types : Array<TypeDefinition> ) : Void {
load("define_module", 2)(untyped modulePath.__s,untyped types.__neko());
}

/**
Returns a syntax-level expression corresponding to typed expression `t`.
Expand Down
1 change: 1 addition & 0 deletions type.ml
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ and module_kind =
| MCode
| MMacro
| MFake
| MSub

and dt =
| DTSwitch of texpr * (texpr * dt) list * dt option
Expand Down
37 changes: 34 additions & 3 deletions typer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -3702,9 +3702,40 @@ let make_macro_api ctx p =
);
Interp.define_type = (fun v ->
let m, tdef, pos = (try Interp.decode_type_def v with Interp.Invalid_expr -> Interp.exc (Interp.VString "Invalid type definition")) in
let mdep = Typeload.type_module ctx m ctx.m.curmod.m_extra.m_file [tdef,pos] pos in
mdep.m_extra.m_kind <- MFake;
add_dependency mdep ctx.m.curmod;
let prev = (try Some (Hashtbl.find ctx.g.modules m) with Not_found -> None) in
let mnew = Typeload.type_module ctx m ctx.m.curmod.m_extra.m_file [tdef,pos] pos in
add_dependency mnew ctx.m.curmod;
(* if we defined a type in an existing module, let's move the types here *)
(match prev with
| None ->
mnew.m_extra.m_kind <- MFake;
| Some mold ->
Hashtbl.replace ctx.g.modules mnew.m_path mold;
mold.m_types <- mold.m_types @ mnew.m_types;
mnew.m_extra.m_kind <- MSub;
add_dependency mold mnew;
);
);
Interp.define_module = (fun m types ->
let types = List.map (fun v ->
let _, tdef, pos = (try Interp.decode_type_def v with Interp.Invalid_expr -> Interp.exc (Interp.VString "Invalid type definition")) in
tdef, pos
) types in
let m = Ast.parse_path m in
let pos = (match types with [] -> Ast.null_pos | (_,p) :: _ -> p) in
let prev = (try Some (Hashtbl.find ctx.g.modules m) with Not_found -> None) in
let mnew = Typeload.type_module ctx m ctx.m.curmod.m_extra.m_file types pos in
add_dependency mnew ctx.m.curmod;
(* if we defined a type in an existing module, let's move the types here *)
(match prev with
| None ->
mnew.m_extra.m_kind <- MFake;
| Some mold ->
Hashtbl.replace ctx.g.modules mnew.m_path mold;
mold.m_types <- mold.m_types @ mnew.m_types;
mnew.m_extra.m_kind <- MSub;
add_dependency mold mnew;
);
);
Interp.module_dependency = (fun mpath file ismacro ->
let m = typing_timer ctx (fun() -> Typeload.load_module ctx (parse_path mpath) p) in
Expand Down

0 comments on commit 445be7a

Please sign in to comment.