| None -> filter_map f xs
type whenexpr =
+ | Expr_unit
| Expr_bool of bool
| Expr_str of string
| Expr_int of Big_int.big_int
| Expr_increases of string
| Expr_decreases of string
| Expr_prev of string
+ | Expr_reloaded
(* This internal type is used during conversion of the OCaml AST
* to the whenexpr type.
*)
type whenexpr_int =
+ | IExpr_unit
| IExpr_bool of bool
| IExpr_str of string
| IExpr_int of Big_int.big_int
}
type variable =
+ | T_unit
| T_bool of bool
| T_string of string
| T_int of big_int
| T_float of float
let variable_of_rpc = function
+ | `unit_t -> T_unit
| `bool_t b -> T_bool b
| `string_t s -> T_string s
| `int_t i -> T_int (big_int_of_string i)
| `float_t f -> T_float f
let rpc_of_variable = function
+ | T_unit -> `unit_t
| T_bool b -> `bool_t b
| T_string s -> `string_t s
| T_int i -> `int_t (string_of_big_int i)
expr_of_iexpr _loc (iexpr_of_ast _loc ast)
and iexpr_of_ast _loc = function
+ | ExId (_, IdUid (_, "()")) -> IExpr_unit
| ExId (_, IdUid (_, "True")) -> IExpr_bool true
| ExId (_, IdUid (_, "False")) -> IExpr_bool false
| ExStr (_, str) -> IExpr_str str
invalid_arg (sprintf "%s: invalid expression" (Loc.to_string _loc))
and expr_of_iexpr _loc = function
+ | IExpr_unit -> Expr_unit
| IExpr_bool b -> Expr_bool b
| IExpr_str s -> Expr_str s
| IExpr_int i -> Expr_int i
invalid_arg (sprintf "%s: '%s' operator must be followed by a variable name"
(Loc.to_string _loc) op)
+ | IExpr_app ("reloaded", [IExpr_unit]) ->
+ Expr_reloaded
+
+ | IExpr_app ("reloaded", _) ->
+ invalid_arg (sprintf "%s: you must use 'reloaded ()'" (Loc.to_string _loc))
+
| IExpr_app (op, _) ->
invalid_arg (sprintf "%s: unknown operator in expression: %s"
(Loc.to_string _loc) op)
op (Loc.to_string _loc))
let rec string_of_whenexpr = function
+ | Expr_unit -> "()"
| Expr_bool b -> sprintf "%b" b
| Expr_str s -> sprintf "%S" s
| Expr_int i -> sprintf "%s" (string_of_big_int i)
| Expr_increases v -> sprintf "increases %s" v
| Expr_decreases v -> sprintf "decreases %s" v
| Expr_prev v -> sprintf "prev %s" v
+ | Expr_reloaded -> "reloaded ()"
let string_of_periodexpr = function
| Every_seconds 1 -> "1 second"
| Every_years i -> sprintf "%d years" i
let rec dependencies_of_whenexpr = function
+ | Expr_unit -> []
| Expr_bool _ -> []
| Expr_str _ -> []
| Expr_int _ -> []
| Expr_increases v
| Expr_decreases v
| Expr_prev v -> [v]
+ | Expr_reloaded -> []
let dependencies_of_job = function
| { job_cond = When_job whenexpr } -> dependencies_of_whenexpr whenexpr
| { job_cond = Every_job _ } -> []
-let rec eval_whenexpr job variables = function
+let rec eval_whenexpr job variables onload = function
+ | Expr_unit -> T_unit
| Expr_bool b -> T_bool b
| Expr_str s -> T_string s
| Expr_int i -> T_int i
(try StringMap.find v variables with Not_found -> T_string "")
| Expr_and (e1, e2) ->
- if eval_whenexpr_as_bool job variables e1 &&
- eval_whenexpr_as_bool job variables e2 then
+ if eval_whenexpr_as_bool job variables onload e1 &&
+ eval_whenexpr_as_bool job variables onload e2 then
T_bool true
else
T_bool false
| Expr_or (e1, e2) ->
- if eval_whenexpr_as_bool job variables e1 ||
- eval_whenexpr_as_bool job variables e2 then
+ if eval_whenexpr_as_bool job variables onload e1 ||
+ eval_whenexpr_as_bool job variables onload e2 then
T_bool true
else
T_bool false
| Expr_lt (e1, e2) ->
- let e1 = eval_whenexpr job variables e1
- and e2 = eval_whenexpr job variables e2 in
+ let e1 = eval_whenexpr job variables onload e1
+ and e2 = eval_whenexpr job variables onload e2 in
if compare_values e1 e2 < 0 then
T_bool true
else
T_bool false
| Expr_le (e1, e2) ->
- let e1 = eval_whenexpr job variables e1
- and e2 = eval_whenexpr job variables e2 in
+ let e1 = eval_whenexpr job variables onload e1
+ and e2 = eval_whenexpr job variables onload e2 in
if compare_values e1 e2 <= 0 then
T_bool true
else
T_bool false
| Expr_eq (e1, e2) ->
- let e1 = eval_whenexpr job variables e1
- and e2 = eval_whenexpr job variables e2 in
+ let e1 = eval_whenexpr job variables onload e1
+ and e2 = eval_whenexpr job variables onload e2 in
if compare_values e1 e2 = 0 then
T_bool true
else
T_bool false
| Expr_ge (e1, e2) ->
- let e1 = eval_whenexpr job variables e1
- and e2 = eval_whenexpr job variables e2 in
+ let e1 = eval_whenexpr job variables onload e1
+ and e2 = eval_whenexpr job variables onload e2 in
if compare_values e1 e2 >= 0 then
T_bool true
else
T_bool false
| Expr_gt (e1, e2) ->
- let e1 = eval_whenexpr job variables e1
- and e2 = eval_whenexpr job variables e2 in
+ let e1 = eval_whenexpr job variables onload e1
+ and e2 = eval_whenexpr job variables onload e2 in
if compare_values e1 e2 > 0 then
T_bool true
else
T_bool false
| Expr_not e ->
- if not (eval_whenexpr_as_bool job variables e) then
+ if not (eval_whenexpr_as_bool job variables onload e) then
T_bool true
else
T_bool false
| Expr_add (e1, e2) ->
- let e1 = eval_whenexpr job variables e1
- and e2 = eval_whenexpr job variables e2 in
+ let e1 = eval_whenexpr job variables onload e1
+ and e2 = eval_whenexpr job variables onload e2 in
add_values e1 e2
| Expr_sub (e1, e2) ->
- let e1 = eval_whenexpr job variables e1
- and e2 = eval_whenexpr job variables e2 in
+ let e1 = eval_whenexpr job variables onload e1
+ and e2 = eval_whenexpr job variables onload e2 in
sub_values e1 e2
| Expr_mul (e1, e2) ->
- let e1 = eval_whenexpr job variables e1
- and e2 = eval_whenexpr job variables e2 in
+ let e1 = eval_whenexpr job variables onload e1
+ and e2 = eval_whenexpr job variables onload e2 in
mul_values e1 e2
| Expr_div (e1, e2) ->
- let e1 = eval_whenexpr job variables e1
- and e2 = eval_whenexpr job variables e2 in
+ let e1 = eval_whenexpr job variables onload e1
+ and e2 = eval_whenexpr job variables onload e2 in
div_values e1 e2
| Expr_mod (e1, e2) ->
- let e1 = eval_whenexpr job variables e1
- and e2 = eval_whenexpr job variables e2 in
+ let e1 = eval_whenexpr job variables onload e1
+ and e2 = eval_whenexpr job variables onload e2 in
mod_values e1 e2
| Expr_changes v ->
T_bool false
| Expr_prev v ->
- try StringMap.find v job.job_private.job_prev_variables
- with Not_found -> T_string ""
+ (try StringMap.find v job.job_private.job_prev_variables
+ with Not_found -> T_string "")
+
+ | Expr_reloaded ->
+ T_bool onload
and get_prev_curr_value job variables v =
let prev_value =
prev_value, curr_value
(* Call {!eval_whenexpr} and cast the result to a boolean. *)
-and eval_whenexpr_as_bool job variables expr =
- match eval_whenexpr job variables expr with
+and eval_whenexpr_as_bool job variables onload expr =
+ match eval_whenexpr job variables onload expr with
+ | T_unit -> false
| T_bool r -> r
| T_string s -> s <> ""
| T_int i -> sign_big_int i <> 0
(printable_string_of_variable value2))
and string_of_variable = function
+ | T_unit -> "" (* for string_of_variable, we don't want () here *)
| T_bool b -> string_of_bool b
| T_string s -> s
| T_int i -> string_of_big_int i
| T_float f -> string_of_float f
and printable_string_of_variable = function
+ | T_unit -> "()"
| T_bool b -> string_of_bool b
| T_string s -> sprintf "%S" s
| T_int i -> string_of_big_int i
| T_float f -> string_of_float f
-let job_evaluate job variables =
+let job_evaluate job variables onload =
match job with
| { job_cond = Every_job _ } -> false, job
| { job_cond = When_job whenexpr } ->
- let state = eval_whenexpr_as_bool job variables whenexpr in
+ let state = eval_whenexpr_as_bool job variables onload whenexpr in
(* Because jobs are edge-triggered, we're only interested in the
* case where the evaluation state changes from false -> true.