X-Git-Url: http://git.annexia.org/?p=whenjobs.git;a=blobdiff_plain;f=lib%2Fpa_when.ml;h=00bfd1443999cc612a5cba87af5619e4427edc2b;hp=da51e20015b963c728adc57898eb9fc3f4619094;hb=0c9faf57f9239b0fe1c0b46353d222bb4cf5cd74;hpb=76e68068f22a67c788f14a7c9404db7f7514da49 diff --git a/lib/pa_when.ml b/lib/pa_when.ml index da51e20..00bfd14 100644 --- a/lib/pa_when.ml +++ b/lib/pa_when.ml @@ -75,6 +75,11 @@ let expr_of_loc _loc loc = $`int:stop_line$, $`int:stop_bol$, $`int:stop_off$, $`bool:ghost$) >> +(* Convert 'expr option' to an expression that contains the option inside. *) +let expr_of_option _loc = function + | None -> <:expr< None >> + | Some e -> <:expr< Some $e$ >> + (* "Lift" an expression, turning it from an expression into an OCaml * abstract syntax tree in the output. This is pretty obscure. * http://caml.inria.fr/pub/ml-archives/caml-list/2008/09/591f7c4a8df9295d675a5adcb6802748.en.html @@ -83,12 +88,16 @@ module M = Ast.Meta.Make (Ast.Meta.MetaGhostLoc) let lift_expr = M.Expr.meta_expr (* Handle a top level statement. *) -let rec call_stmt name (_loc, stmt, sh) = - let name = if name <> "" then name else unique_job_name () in - let name = <:expr< $str:name$ >> in +let rec call_stmt name pre post (_loc, stmt, sh) = + let name = + match name with + | None -> let name = unique_job_name () in <:expr< $str:name$ >> + | Some name -> name in + let pre = expr_of_option _loc pre in + let post = expr_of_option _loc post in match stmt with - | `When e -> when_stmt _loc name e sh - | `Every p -> every_stmt _loc name p sh + | `When e -> when_stmt _loc name pre post e sh + | `Every p -> every_stmt _loc name pre post p sh (* Handle a top level "when" statement. * e -> when expression @@ -96,20 +105,20 @@ let rec call_stmt name (_loc, stmt, sh) = * Returns a top level statement (str_item) which when executed just * adds the statement to a global list. *) -and when_stmt _loc name e sh = +and when_stmt _loc name pre post e sh = let loc = expr_of_loc _loc _loc in let e = lift_expr _loc e in <:str_item< open Camlp4.PreCast - Whenfile.add_when_job $loc$ $name$ $e$ $sh$ + Whenfile.add_when_job $loc$ $name$ $pre$ $post$ $e$ $sh$ >> (* Handle a top level "every" statement. *) -and every_stmt _loc name period sh = +and every_stmt _loc name pre post period sh = let loc = expr_of_loc _loc _loc in <:str_item< open Camlp4.PreCast - Whenfile.add_every_job $loc$ $name$ $period$ $sh$ + Whenfile.add_every_job $loc$ $name$ $pre$ $post$ $period$ $sh$ >> let () = @@ -177,26 +186,6 @@ let period_parser = ) | _ -> raise Stream.Failure ) - -(* -(* This hand-written parser looks for "job " before a statement. *) -let optjob = - Gram.Entry.of_parser "optjob" - (fun stream -> - let info, name = - match Stream.npeek 2 stream with - | [ LIDENT "job", info; STRING (_,name), _ ] -> - Stream.junk stream; - Stream.junk stream; - info, name - | (_, info) :: _ -> - (* Job is unnamed so generate a unique internal name. *) - info, unique_job_name () - | _ -> assert false in - let _loc = Gram.token_location info in - <:expr< $str:name$ >> - ) -*) ;; EXTEND Gram @@ -221,6 +210,10 @@ EXTEND Gram | [ e = period_parser -> e ] ]; + (* Pre and post functions. *) + pre: [[ "pre"; f = expr -> f ]]; + post: [[ "post"; f = expr -> f ]]; + (* Top level statements. *) statement: [ [ "when"; e = expr; ":"; sh = expr -> @@ -231,8 +224,12 @@ EXTEND Gram (* "str_item" is a top level statement in an OCaml program. *) str_item: LEVEL "top" [ - [ s = statement -> call_stmt "" s ] - | [ "job"; name = STRING; s = statement -> call_stmt name s ] + [ s = statement -> call_stmt None None None s ] + | [ "job"; name = expr; + pre = OPT pre; + post = OPT post; + s = statement -> + call_stmt (Some name) pre post s ] ]; END