2022-02-10 14:24:35 +03:00
|
|
|
(* This file is part of the Catala build system, a specification language for tax and social
|
|
|
|
benefits computation rules. Copyright (C) 2020 Inria, contributor: Emile Rolley
|
|
|
|
<emile.rolley@tuta.io>
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
|
|
in compliance with the License. You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
|
|
is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
|
|
or implied. See the License for the specific language governing permissions and limitations under
|
|
|
|
the License. *)
|
|
|
|
|
2022-02-05 21:22:46 +03:00
|
|
|
module Expr = struct
|
2022-02-24 15:45:16 +03:00
|
|
|
type t = Lit of string | Var of string | Seq of t list
|
2022-02-05 21:22:46 +03:00
|
|
|
|
|
|
|
let rec to_string = function
|
|
|
|
| Lit s -> s
|
|
|
|
| Var s -> "$" ^ s
|
2022-02-08 16:29:12 +03:00
|
|
|
| Seq ls -> List.fold_left (fun acc s -> acc ^ " " ^ to_string s) "" ls
|
2022-02-05 22:51:43 +03:00
|
|
|
|
|
|
|
let list_to_string ?(sep = " ") ls = ls |> List.map to_string |> String.concat sep
|
2022-02-05 21:22:46 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
module Rule = struct
|
|
|
|
type t = { name : string; command : Expr.t; description : Expr.t option }
|
|
|
|
|
|
|
|
let make name ~command ~description = { name; command; description = Option.some description }
|
|
|
|
|
|
|
|
let to_string rule =
|
2022-02-05 22:51:43 +03:00
|
|
|
Printf.sprintf "rule %s\n command =%s\n" rule.name (Expr.to_string rule.command)
|
2022-02-05 21:22:46 +03:00
|
|
|
^ (rule.description
|
2022-02-05 22:51:43 +03:00
|
|
|
|> Option.fold ~some:(fun e -> " description =" ^ Expr.to_string e ^ "\n") ~none:"")
|
|
|
|
end
|
|
|
|
|
|
|
|
module Build = struct
|
|
|
|
type t = {
|
|
|
|
outputs : Expr.t list;
|
|
|
|
rule : string;
|
|
|
|
inputs : Expr.t list option;
|
|
|
|
vars : (string * Expr.t) list;
|
|
|
|
}
|
|
|
|
|
|
|
|
let make ~outputs ~rule = { outputs; rule; inputs = Option.none; vars = [] }
|
|
|
|
|
|
|
|
let make_with_vars ~outputs ~rule ~vars = { outputs; rule; inputs = Option.none; vars }
|
|
|
|
|
|
|
|
let make_with_inputs ~outputs ~rule ~inputs =
|
|
|
|
{ outputs; rule; inputs = Option.some inputs; vars = [] }
|
|
|
|
|
2022-02-14 16:43:38 +03:00
|
|
|
let make_with_vars_and_inputs ~outputs ~rule ~inputs ~vars =
|
|
|
|
{ outputs; rule; inputs = Option.some inputs; vars }
|
|
|
|
|
2022-02-08 14:45:52 +03:00
|
|
|
let empty = make ~outputs:[ Expr.Lit "empty" ] ~rule:"phony"
|
|
|
|
|
2022-02-24 15:45:16 +03:00
|
|
|
let unpath ?(sep = "-") path = Re.Pcre.(substitute ~rex:(regexp "/") ~subst:(fun _ -> sep)) path
|
2022-02-08 14:20:14 +03:00
|
|
|
|
2022-02-05 22:51:43 +03:00
|
|
|
let to_string build =
|
|
|
|
Printf.sprintf "build %s: %s" (Expr.list_to_string build.outputs) build.rule
|
2022-02-08 14:45:52 +03:00
|
|
|
^ (build.inputs |> Option.fold ~some:(fun ls -> " " ^ Expr.list_to_string ls) ~none:"")
|
2022-02-05 22:51:43 +03:00
|
|
|
^ "\n"
|
|
|
|
^ List.fold_left
|
|
|
|
(fun acc (name, exp) -> acc ^ Printf.sprintf " %s = %s\n" name (Expr.to_string exp))
|
|
|
|
"" build.vars
|
2022-02-05 21:22:46 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
module RuleMap : Map.S with type key = String.t = Map.Make (String)
|
|
|
|
|
2022-02-05 22:51:43 +03:00
|
|
|
module BuildMap : Map.S with type key = String.t = Map.Make (String)
|
2022-02-05 21:22:46 +03:00
|
|
|
|
2022-02-05 22:51:43 +03:00
|
|
|
type ninja = { rules : Rule.t RuleMap.t; builds : Build.t BuildMap.t }
|
2022-02-05 21:22:46 +03:00
|
|
|
|
2022-02-05 22:51:43 +03:00
|
|
|
let empty = { rules = RuleMap.empty; builds = BuildMap.empty }
|
2022-02-05 21:22:46 +03:00
|
|
|
|
|
|
|
let write out ninja =
|
2022-02-05 22:51:43 +03:00
|
|
|
let write_for_all iter to_string =
|
|
|
|
iter (fun _name rule -> Printf.fprintf out "%s\n" (to_string rule))
|
|
|
|
in
|
|
|
|
write_for_all RuleMap.iter Rule.to_string ninja.rules;
|
|
|
|
write_for_all BuildMap.iter Build.to_string ninja.builds
|