let goal_failed msg = raise (Goal_result (Goal_failed msg))
+let depth = ref 0
+let indent fs =
+ let do_indent str =
+ prerr_string "| ";
+ for i = 0 to !depth-1 do prerr_string " " done;
+ prerr_string str;
+ Pervasives.flush Pervasives.stderr
+ in
+ ksprintf do_indent fs
+
let target v =
if v then raise (Goal_result Goal_OK)
let target_all vs = target (List.fold_left (&&) true vs)
let target_exists vs = target (List.fold_left (||) false vs)
-let require f = f ()
+let require name f =
+ indent "require: %s\n" name;
+ incr depth;
+ let r = (try Either (f ()) with exn -> Or exn) in
+ decr depth;
+ match r with
+ | Either x -> x
+ | Or exn -> raise exn
+
+let _enter_goal name = indent "enter goal: %s\n" name
+let _leave_goal name = indent "leave goal: %s\n" name
type period_t = Seconds | Days | Months | Years
let seconds = (1, Seconds)
(** [target_exists [t1; t2; ...]] is the same as writing
[target (t1 || t2 || ...)] *)
-val require : (unit -> unit) -> unit
+val require : string -> (unit -> unit) -> unit
(** [require] {i goal} defines the requirements of this goal, that
is, other goals that have to be met before the rest of the
goal is able to run.
(* Export this so the macros can catch these exceptions. *)
type goal_result_t = Goal_OK | Goal_failed of string
exception Goal_result of goal_result_t
+
+(* Called to print debug message when we enter or leave a goal. *)
+val _enter_goal : string -> unit
+val _leave_goal : string -> unit
(* Define a goal name which the body may use. *)
let goalname = $str:name$ in
+ _enter_goal goalname;
+
(* Source location. *)
let goalloc = $str:goalloc$ in
$body$ ;
_call_onruns ();
_call_onsuccesses ();
+ _leave_goal goalname;
(* Avoid a compiler warning: *)
ignore (goalname); ignore (goalloc)
* ordinary function exit.
*)
| Goal_result Goal_OK ->
+ _leave_goal goalname;
_call_onsuccesses ();
()
| exn ->
+ _leave_goal goalname;
_call_onfails exn;
raise exn
>> in
let () = publish $str:name$ (
function
| [] ->
- Goaljobs.require $lid:gname$
+ Goaljobs.require $str:name$ $lid:gname$
| _ ->
failwith (Printf.sprintf "goal '%s' does not take any arguments"
$str:name$);
let rec rewrite = function
| ExApp (_loc, ExId (_loc1, IdLid (_loc2, name)), right) ->
let gname = "goal_" ^ name in
- ExApp (_loc, ExId (_loc1, IdLid (_loc2, gname)), right)
+ ExApp (_loc, ExId (_loc1, IdLid (_loc2, gname)), right), name
+
| ExApp (_loc, (ExApp _ as expr), right) ->
- ExApp (_loc, rewrite expr, right)
+ let expr, name = rewrite expr in
+ ExApp (_loc, expr, right), name
+
| _ ->
locfail _loc "require (...) expression must contain a call to a goal"
in
- let expr = rewrite expr in
- <:expr< Goaljobs.require (fun () -> $expr$) >>
+ let expr, name = rewrite expr in
+ <:expr< Goaljobs.require $str:name$ (fun () -> $expr$) >>
;;