support ${..} in :include
This commit is contained in:
parent
001daa62d0
commit
7c6f3e6dd6
|
@ -9,7 +9,7 @@ module Ast = struct
|
||||||
| Special : Loc.t * string -> ('a, _) t
|
| Special : Loc.t * string -> ('a, _) t
|
||||||
| Union : ('a, 'b) t list -> ('a, 'b) t
|
| Union : ('a, 'b) t list -> ('a, 'b) t
|
||||||
| Diff : ('a, 'b) t * ('a, 'b) t -> ('a, 'b) t
|
| Diff : ('a, 'b) t * ('a, 'b) t -> ('a, 'b) t
|
||||||
| Include : string -> ('a, unexpanded) t
|
| Include : String_with_vars.t -> ('a, unexpanded) t
|
||||||
end
|
end
|
||||||
|
|
||||||
type t = (string, Ast.expanded) Ast.t
|
type t = (string, Ast.expanded) Ast.t
|
||||||
|
@ -40,16 +40,16 @@ let eval t ~special_values =
|
||||||
match t with
|
match t with
|
||||||
| Element s -> [s]
|
| Element s -> [s]
|
||||||
| Special (loc, name) ->
|
| Special (loc, name) ->
|
||||||
begin
|
begin
|
||||||
match List.assoc name special_values with
|
match List.assoc name special_values with
|
||||||
| l -> l
|
| l -> l
|
||||||
| exception Not_found -> Loc.fail loc "undefined symbol %s" name;
|
| exception Not_found -> Loc.fail loc "undefined symbol %s" name;
|
||||||
end
|
end
|
||||||
| Union elts -> List.flatten (List.map elts ~f:of_ast)
|
| Union elts -> List.flatten (List.map elts ~f:of_ast)
|
||||||
| Diff (left, right) ->
|
| Diff (left, right) ->
|
||||||
let left = of_ast left in
|
let left = of_ast left in
|
||||||
let right = of_ast right in
|
let right = of_ast right in
|
||||||
List.filter left ~f:(fun acc_elt -> not (List.mem acc_elt ~set:right))
|
List.filter left ~f:(fun acc_elt -> not (List.mem acc_elt ~set:right))
|
||||||
in
|
in
|
||||||
of_ast t
|
of_ast t
|
||||||
|
|
||||||
|
@ -83,15 +83,15 @@ module Unexpanded = struct
|
||||||
match t with
|
match t with
|
||||||
| Element s -> Element s
|
| Element s -> Element s
|
||||||
| Union [Special (_, "include"); Element fn] ->
|
| Union [Special (_, "include"); Element fn] ->
|
||||||
Include (Sexp.Of_sexp.string fn)
|
Include (String_with_vars.t fn)
|
||||||
| Union [Special (loc, "include"); _]
|
| Union [Special (loc, "include"); _]
|
||||||
| Special (loc, "include") ->
|
| Special (loc, "include") ->
|
||||||
Loc.fail loc "(:include expects a single element (do you need to quote the filename?)"
|
Loc.fail loc "(:include expects a single element (do you need to quote the filename?)"
|
||||||
| Special (l, s) -> Special (l, s)
|
| Special (l, s) -> Special (l, s)
|
||||||
| Union l ->
|
| Union l ->
|
||||||
Union (List.map l ~f:map)
|
Union (List.map l ~f:map)
|
||||||
| Diff (l, r) ->
|
| Diff (l, r) ->
|
||||||
Diff (map l, map r)
|
Diff (map l, map r)
|
||||||
in
|
in
|
||||||
parse_general t ~f:(fun x -> x) |> map
|
parse_general t ~f:(fun x -> x) |> map
|
||||||
|
|
||||||
|
@ -99,31 +99,33 @@ module Unexpanded = struct
|
||||||
|
|
||||||
let append = append
|
let append = append
|
||||||
|
|
||||||
let files t =
|
let files t ~f =
|
||||||
let rec loop acc (t : t) =
|
let rec loop acc (t : t) =
|
||||||
let open Ast in
|
let open Ast in
|
||||||
match t with
|
match t with
|
||||||
| Element _
|
| Element _
|
||||||
| Special _ -> acc
|
| Special _ -> acc
|
||||||
| Include fn ->
|
| Include fn ->
|
||||||
String_set.add fn acc
|
String_set.add (f fn) acc
|
||||||
| Union l ->
|
| Union l ->
|
||||||
List.fold_left l ~init:acc ~f:loop
|
List.fold_left l ~init:acc ~f:loop
|
||||||
| Diff (l, r) ->
|
| Diff (l, r) ->
|
||||||
loop (loop acc l) r
|
loop (loop acc l) r
|
||||||
in
|
in
|
||||||
loop String_set.empty t
|
loop String_set.empty t
|
||||||
|
|
||||||
let rec expand (t : t) ~files_contents ~f : (string, Ast.expanded) Ast.t =
|
let rec expand (t : t) ~files_contents ~f : (string, Ast.expanded) Ast.t =
|
||||||
let open Ast in
|
let open Ast in
|
||||||
match t with
|
match t with
|
||||||
| Element s -> Element (f s)
|
| Element s -> Element (f (String_with_vars.t s))
|
||||||
| Special (l, s) -> Special (l, s)
|
| Special (l, s) -> Special (l, s)
|
||||||
| Include fn ->
|
| Include fn ->
|
||||||
parse_general (String_map.find_exn fn files_contents ~string_of_key:(sprintf "%S")
|
parse_general (
|
||||||
~desc:(fun _ -> "<filename to s-expression>")) ~f
|
String_map.find_exn (f fn) files_contents ~string_of_key:(sprintf "%S")
|
||||||
|
~desc:(fun _ -> "<filename to s-expression>")
|
||||||
|
) ~f:(fun s -> f (String_with_vars.t s))
|
||||||
| Union l ->
|
| Union l ->
|
||||||
Union (List.map l ~f:(expand ~files_contents ~f))
|
Union (List.map l ~f:(expand ~files_contents ~f))
|
||||||
| Diff (l, r) ->
|
| Diff (l, r) ->
|
||||||
Diff (expand l ~files_contents ~f, expand r ~files_contents ~f)
|
Diff (expand l ~files_contents ~f, expand r ~files_contents ~f)
|
||||||
end
|
end
|
||||||
|
|
|
@ -23,10 +23,10 @@ module Unexpanded : sig
|
||||||
val append : t -> t -> t
|
val append : t -> t -> t
|
||||||
|
|
||||||
(** List of files needed to expand this set *)
|
(** List of files needed to expand this set *)
|
||||||
val files : t -> String_set.t
|
val files : t -> f:(String_with_vars.t -> string) -> String_set.t
|
||||||
|
|
||||||
(** Expand [t] using with the given file contents. [file_contents] is a map from
|
(** Expand [t] using with the given file contents. [file_contents] is a map from
|
||||||
filenames to their parsed contents. Every [(:include fn)] in [t] is replaced by
|
filenames to their parsed contents. Every [(:include fn)] in [t] is replaced by
|
||||||
[Map.find files_contents fn]. Every element is converted to a string using [f]. *)
|
[Map.find files_contents fn]. Every element is converted to a string using [f]. *)
|
||||||
val expand : t -> files_contents:Sexp.Ast.t String_map.t -> f:(Sexp.Ast.t -> string) -> expanded
|
val expand : t -> files_contents:Sexp.Ast.t String_map.t -> f:(String_with_vars.t -> string) -> expanded
|
||||||
end with type expanded := t
|
end with type expanded := t
|
||||||
|
|
|
@ -902,8 +902,8 @@ end
|
||||||
|
|
||||||
let expand_and_eval_set t ~scope ~dir set ~standard =
|
let expand_and_eval_set t ~scope ~dir set ~standard =
|
||||||
let open Build.O in
|
let open Build.O in
|
||||||
let f sexp = expand_vars t ~scope ~dir (String_with_vars.t sexp) in
|
let f = expand_vars t ~scope ~dir in
|
||||||
match Ordered_set_lang.Unexpanded.files set |> String_set.elements with
|
match Ordered_set_lang.Unexpanded.files set ~f |> String_set.elements with
|
||||||
| [] ->
|
| [] ->
|
||||||
let set = Ordered_set_lang.Unexpanded.expand set ~files_contents:String_map.empty ~f in
|
let set = Ordered_set_lang.Unexpanded.expand set ~files_contents:String_map.empty ~f in
|
||||||
Build.return (Ordered_set_lang.eval_with_standard set ~standard)
|
Build.return (Ordered_set_lang.eval_with_standard set ~standard)
|
||||||
|
|
Loading…
Reference in New Issue