From: Richard W.M. Jones Date: Tue, 21 Feb 2012 17:13:32 +0000 (+0000) Subject: Remove Whenutils.no_job_private and refactor prev-related code. X-Git-Tag: 0.0.1~9 X-Git-Url: http://git.annexia.org/?p=whenjobs.git;a=commitdiff_plain;h=df2cdcfdc29af0080b9b3eace17325d2a1d83e72;hp=2701d3a832514ee94d110dfbd4f46f2ab6d9637e Remove Whenutils.no_job_private and refactor prev-related code. --- diff --git a/lib/whenfile.ml b/lib/whenfile.ml index 8fdca1e..89a09b0 100644 --- a/lib/whenfile.ml +++ b/lib/whenfile.ml @@ -27,15 +27,11 @@ let init () = jobs := [] let add_when_job _loc name e sh = let e = expr_of_ast _loc e in - let job = { job_loc = _loc; job_name = name; - job_cond = When_job e; job_script = sh; - job_private = no_job_private } in + let job = make_when_job _loc name e sh in jobs := job :: !jobs let add_every_job _loc name e sh = - let job = { job_loc = _loc; job_name = name; - job_cond = Every_job e; job_script = sh; - job_private = no_job_private } in + let job = make_every_job _loc name e sh in jobs := job :: !jobs let get_jobs () = diff --git a/lib/whenutils.ml b/lib/whenutils.ml index fd066b4..e43dcf6 100644 --- a/lib/whenutils.ml +++ b/lib/whenutils.ml @@ -133,18 +133,19 @@ type job_private = { (* The result of the previous evaluation. This is used for * implementing edge-triggering, since we only trigger the job to run * when the state changes from false -> true. + * + * [None] means there has been no previous evaluation. *) - job_prev_eval_state : bool; + job_prev_eval_state : bool option; (* When the job {i ran} last time, we take a copy of the variables. * This allows us to implement the 'changes' operator. + * + * [None] means there has been no previous run. *) - job_prev_variables : variables; + job_prev_variables : variables option; } -let no_job_private = - { job_prev_eval_state = false; job_prev_variables = StringMap.empty } - type job_cond = | When_job of whenexpr | Every_job of periodexpr @@ -157,6 +158,18 @@ type job = { job_private : job_private; } +let make_when_job _loc name e sh = + { job_loc = _loc; job_name = name; + job_cond = When_job e; job_script = sh; + job_private = { job_prev_eval_state = None; + job_prev_variables = None } } + +let make_every_job _loc name e sh = + { job_loc = _loc; job_name = name; + job_cond = Every_job e; job_script = sh; + job_private = { job_prev_eval_state = None; + job_prev_variables = None } } + let rec expr_of_ast _loc ast = expr_of_iexpr _loc (iexpr_of_ast _loc ast) @@ -371,7 +384,7 @@ let rec eval_whenexpr job variables onload = function | Expr_float f -> T_float f | Expr_var v -> - (try StringMap.find v variables with Not_found -> T_string "") + get_variable variables v | Expr_and (e1, e2) -> if eval_whenexpr_as_bool job variables onload e1 && @@ -480,21 +493,27 @@ let rec eval_whenexpr job variables onload = function T_bool false | Expr_prev v -> - (try StringMap.find v job.job_private.job_prev_variables - with Not_found -> T_string "") + get_prev_variable job v | Expr_reloaded -> T_bool onload and get_prev_curr_value job variables v = - let prev_value = - try StringMap.find v job.job_private.job_prev_variables - with Not_found -> T_string "" in - let curr_value = - try StringMap.find v variables - with Not_found -> T_string "" in + let prev_value = get_prev_variable job v in + let curr_value = get_variable variables v in prev_value, curr_value +and get_variable variables v = + try StringMap.find v variables with Not_found -> T_string "" + +and get_prev_variable job v = + match job.job_private.job_prev_variables with + | None -> + (* Job has never run. XXX Should do better here. *) + T_string "" + | Some prev_variables -> + get_variable prev_variables v + (* Call {!eval_whenexpr} and cast the result to a boolean. *) and eval_whenexpr_as_bool job variables onload expr = match eval_whenexpr job variables onload expr with @@ -605,16 +624,18 @@ let job_evaluate job variables onload = * case where the evaluation state changes from false -> true. *) match job.job_private.job_prev_eval_state, state with - | false, false - | true, true - | true, false -> - let jobp = { job.job_private with job_prev_eval_state = state } in + | None, false + | Some false, false + | Some true, true + | Some true, false -> + let jobp = { job.job_private with job_prev_eval_state = Some state } in let job = { job with job_private = jobp } in false, job - | false, true -> - let jobp = { job_prev_eval_state = true; - job_prev_variables = variables } in + | None, true + | Some false, true -> + let jobp = { job_prev_eval_state = Some true; + job_prev_variables = Some variables } in let job = { job with job_private = jobp } in true, job diff --git a/lib/whenutils.mli b/lib/whenutils.mli index 13bc68c..4d5ccc7 100644 --- a/lib/whenutils.mli +++ b/lib/whenutils.mli @@ -183,9 +183,6 @@ type variables = variable StringMap.t type job_private (** Private state associated with a job, used for evaluation. *) -val no_job_private : job_private -(* XXX any use of no_job_private is wrong XXX *) - type job_cond = | When_job of whenexpr (** when ... : << >> *) | Every_job of periodexpr (** every ... : << >> *) @@ -197,7 +194,15 @@ type job = { job_script : shell_script; job_private : job_private; } -(** A job. *) +(** A job. Note that because of the [job_private] field, these cannot + be constructed directly. Use {!make_when_job} or {!make_every_job} + to construct one. *) + +val make_when_job : Camlp4.PreCast.Loc.t -> string -> whenexpr -> shell_script -> job +(** Make a when-statement job. *) + +val make_every_job : Camlp4.PreCast.Loc.t -> string -> periodexpr -> shell_script -> job +(** Make an every-statement job. *) val expr_of_ast : Camlp4.PreCast.Ast.Loc.t -> Camlp4.PreCast.Ast.expr -> whenexpr (** Convert OCaml AST to an expression. Since OCaml ASTs are much