let rec apply_formals env labels ufs dargs =
let s = "[apply_formals]" in
match ufs , dargs with
| [] , [] -> []
| [] , d :: _ ->
Wp_parameters.fatal
"WP.UserDefs: signature mismatch (args) to much args %a"
pp_data d ;
| UF_logic (lv,_) :: ufs_tail , data :: dargs_tail ->
debug "%s : %a binds to %a, ufs_tail:%d, darg_tail:%d"
s !Ast_printer.d_logic_var lv pp_data data
(List.length ufs_tail) (List.length dargs_tail);
term_of_data data :: apply_formals env labels ufs_tail dargs_tail
| UF_logic (lv,_) :: _ , [] ->
Wp_parameters.fatal
"WP.UserDefs: signature mismatch (args) %a have no value"
!Ast_printer.d_logic_var lv;
| UF_closure(_,closure,at) :: ufs_tail , _ ->
let label = Clabels.lookup labels at in
let mem = mem_at env label in
let varg = M.userdef_mem_apply mem closure in
varg :: apply_formals env labels ufs_tail dargs
| UF_references(_,_,_)::_ , [] ->
Wp_parameters.fatal "WP.UserDefs: signature mismatch (refs)"
| UF_references(_,None,refs)::ufs_tail , data::dargs ->
apply_references env labels refs data ufs_tail dargs
| UF_references(_,Some _,refs)::ufs_tail , data::dargs ->
let loc =
match data with
| Value(M.V_pointer(_,loc)) -> loc
| Loc loc -> loc
| _ -> Wp_parameters.fatal "WP.UserDefs: no reference found"
in
let inner_loc = M.inner_loc loc in
debug "%s the location of %a : %a the C loc : %a" s
pp_data data M.pp_loc loc F.pp_term inner_loc;
inner_loc :: apply_references env labels refs data ufs_tail dargs
and apply_references env labels refs data ufs dargs =
match refs with
| [] -> apply_formals env labels ufs dargs
| (_,formal,at) :: refs_tail ->
let loc =
match data with
| Value(M.V_pointer(_,loc)) -> loc
| Loc loc -> loc
| _ -> Wp_parameters.fatal "WP.UserDefs: no reference found"
in
let label = Clabels.lookup labels at in
let mem = mem_at env label in
let value = M.logic_of_value (M.userdef_ref_apply mem formal loc) in
value :: apply_references env labels refs_tail data ufs dargs