* of let statements.
*)
let generate_let_goal _loc (r : rec_flag) (lets : binding) =
+ let autopublish = ref [] in
+
(* lets might be a single binding, or multiple bindings using BiAnd
* ('let .. and'). Rewrite each individual goal in the list.
*)
if params = [] then
locfail _loc "goal must have some parameters; you probably want to put '()' here";
+ (* Is it a "zero-parameters" automatically published goal? What
+ * this really means is it has exactly one unit parameter.
+ *)
+ (match params with
+ | [ _, PaId (_, IdUid (_, "()")) ] ->
+ autopublish := name :: !autopublish
+ | _ -> ()
+ );
+
(* Put a try-clause around the body. *)
let body = <:expr< try $body$ with Goal_result Goal_OK -> () >> in
let lets = rewrite lets in
(* let [rec] ... and ... in () *)
- Ast.StVal (_loc, r, lets)
+ let stmts = Ast.StVal (_loc, r, lets) in
+
+ (* Auto-published goals. *)
+ List.fold_left (
+ fun stmt name ->
+ let publish_name =
+ let gname = "goal_" ^ name in
+ <:str_item<
+ let () = publish $str:name$ (
+ function
+ | [] ->
+ Goaljobs.require ($lid:gname$ ())
+ | _ ->
+ failwith (Printf.sprintf "goal '%s' does not take any arguments"
+ $str:name$);
+ )
+ >> in
+ StSem (_loc, stmt, publish_name)
+ ) stmts !autopublish
(* Rewrite 'require (name args...)' as 'require (goal_name args)'.
* 'expr' is a function call.