Skip to content

Commit 7529e5b

Browse files
committed
The tactic swap now takes generalized code position.
Moreover, offsets can bow be absolute (i.e. can be a code-position). In that case, the meaning is "move the code block before the targetted instruction". This work brings some breaking changes: - the variant `swap i1 i2 i3` has been removed. It was a way to give a direct access to the low-level functionality, but its interface is brittle and is not used by any development - a bug has been found in the resolution of negative code position (they were all shifted by one, making impossible to target the last instruction). This now has been fixed.
1 parent ad957d6 commit 7529e5b

File tree

10 files changed

+250
-165
lines changed

10 files changed

+250
-165
lines changed

src/ecCorePrinting.ml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ module type PrinterAPI = sig
2424

2525
(* ------------------------------------------------------------------ *)
2626
val string_of_hcmp : EcFol.hoarecmp -> string
27-
val string_of_cpos1 : EcMatching.Position.codepos1 -> string
2827

2928
(* ------------------------------------------------------------------ *)
3029
type 'a pp = Format.formatter -> 'a -> unit
@@ -63,6 +62,10 @@ module type PrinterAPI = sig
6362
val pp_tyunivar : PPEnv.t -> EcUid.uid pp
6463
val pp_path : path pp
6564

65+
(* ------------------------------------------------------------------ *)
66+
val pp_codepos1 : PPEnv.t -> EcMatching.Position.codepos1 pp
67+
val pp_codeoffset1 : PPEnv.t -> EcMatching.Position.codeoffset1 pp
68+
6669
(* ------------------------------------------------------------------ *)
6770
val pp_typedecl : PPEnv.t -> (path * tydecl ) pp
6871
val pp_opdecl : ?long:bool -> PPEnv.t -> (path * operator ) pp

src/ecHiTacticals.ml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,8 +236,9 @@ and process1_phl (_ : ttenv) (t : phltactic located) (tc : tcenv1) =
236236
with (* PHL Specific low errors *)
237237
| EcLowPhlGoal.InvalidSplit cpos1 ->
238238
tc_error_lazy !!tc (fun fmt ->
239-
Format.fprintf fmt "invalid split index: %s"
240-
(EcPrinting.string_of_cpos1 cpos1))
239+
let ppe = EcPrinting.PPEnv.ofenv (FApi.tc1_env tc) in
240+
Format.fprintf fmt "invalid split index: %a"
241+
(EcPrinting.pp_codepos1 ppe) cpos1)
241242

242243
(* -------------------------------------------------------------------- *)
243244
and process_sub (ttenv : ttenv) tts tc =

src/ecMatching.ml

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,15 @@ module Position = struct
3232

3333
type codepos1 = int * cp_base
3434
type codepos = (codepos1 * int) list * codepos1
35+
type codeoffset1 = [`ByOffset of int | `ByPosition of codepos1]
36+
37+
let shift ~(offset : int) ((o, p) : codepos1) : codepos1 =
38+
(o + offset, p)
39+
40+
let resolve_offset ~(base : codepos1) ~(offset : codeoffset1) : codepos1 =
41+
match offset with
42+
| `ByPosition pos -> pos
43+
| `ByOffset off -> (off + fst base, snd base)
3544
end
3645

3746
(* -------------------------------------------------------------------- *)
@@ -111,20 +120,28 @@ module Zipper = struct
111120
| false -> (s1, ir, s2)
112121
| true -> (s2, ir, s1)
113122

114-
let split_at_cp_base ~after (env : EcEnv.env) (cb : cp_base) (s : stmt) =
123+
type after = [`Yes | `No | `Auto]
124+
125+
let split_at_cp_base ~(after : after) (env : EcEnv.env) (cb : cp_base) (s : stmt) =
115126
match cb with
116127
| `ByPos i -> begin
117-
let i = if i < 0 then List.length s.s_node + i else i in
118-
try List.takedrop (i - if after then 0 else 1) s.s_node
128+
let after =
129+
match after with
130+
| `Auto -> 0 <= i
131+
| `Yes -> true
132+
| `No -> false in
133+
let i = if i < 0 then List.length s.s_node + i + 1 else i in
134+
let i = i - if after then 0 else 1 in
135+
try List.takedrop i s.s_node
119136
with (Invalid_argument _ | Not_found) -> raise InvalidCPos
120137
end
121138

122139
| `ByMatch (i, cm) ->
123140
let (s1, i, s2) = find_by_cp_match env (i, cm) s in
124141

125142
match after with
126-
| false -> (List.rev s1, i :: s2)
127-
| true -> (List.rev_append s1 [i], s2)
143+
| `No -> (List.rev s1, i :: s2)
144+
| _ -> (List.rev_append s1 [i], s2)
128145

129146
let split_at_cpos1 ~after (env : EcEnv.env) ((ipos, cb) : codepos1) s =
130147
let (s1, s2) = split_at_cp_base ~after env cb s in
@@ -147,11 +164,15 @@ module Zipper = struct
147164

148165
in (s1, s2)
149166

150-
let find_by_cpos1 ?(rev = true) (env : EcEnv.env) (cpos1 : codepos1) s =
151-
match split_at_cpos1 ~after:false env cpos1 s with
167+
let find_by_cpos1 ?(rev = true) (env : EcEnv.env) (cpos1 : codepos1) (s : stmt) =
168+
match split_at_cpos1 ~after:`No env cpos1 s with
152169
| (s1, i :: s2) -> ((if rev then List.rev s1 else s1), i, s2)
153170
| _ -> raise InvalidCPos
154171

172+
let offset_of_position (env : EcEnv.env) (cpos : codepos1) (s : stmt) =
173+
let (s, _) = split_at_cpos1 ~after:`No env cpos s in
174+
1 + List.length s
175+
155176
let zipper_at_nm_cpos1 (env : EcEnv.env) ((cp1, sub) : codepos1 * int) s zpr =
156177
let (s1, i, s2) = find_by_cpos1 env cp1 s in
157178

@@ -178,7 +199,7 @@ module Zipper = struct
178199
zipper s1 (i :: s2) zpr
179200

180201
let split_at_cpos1 env cpos1 s =
181-
split_at_cpos1 ~after:true env cpos1 s
202+
split_at_cpos1 ~after:`Auto env cpos1 s
182203

183204
let may_split_at_cpos1 ?(rev = false) env cpos1 s =
184205
ofdfl

src/ecMatching.mli

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,12 @@ module Position : sig
2626
| `ByMatch of int option * cp_match
2727
]
2828

29-
type codepos1 = int * cp_base
30-
type codepos = (codepos1 * int) list * codepos1
29+
type codepos1 = int * cp_base
30+
type codepos = (codepos1 * int) list * codepos1
31+
type codeoffset1 = [`ByOffset of int | `ByPosition of codepos1]
32+
33+
val shift : offset:int -> codepos1 -> codepos1
34+
val resolve_offset : base:codepos1 -> offset:codeoffset1 -> codepos1
3135
end
3236

3337
(* -------------------------------------------------------------------- *)
@@ -60,6 +64,9 @@ module Zipper : sig
6064
(* Split a statement from an optional top-level position (codepos1) *)
6165
val may_split_at_cpos1 : ?rev:bool -> env -> codepos1 option -> stmt -> instr list * instr list
6266

67+
(* Find the absolute offset of a top-level position (codepos1) w.r.t. a given statement *)
68+
val offset_of_position : env -> codepos1 -> stmt -> int
69+
6370
(* [zipper] soft constructor *)
6471
val zipper : instr list -> instr list -> ipath -> zipper
6572

src/ecParser.mly

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2639,6 +2639,10 @@ codepos:
26392639
| nm=rlist0(nm1_codepos, empty) i=codepos1
26402640
{ (List.rev nm, i) }
26412641

2642+
codeoffset1:
2643+
| i=sword { (`ByOffset i :> pcodeoffset1) }
2644+
| AT p=codepos1 { (`ByPosition p :> pcodeoffset1) }
2645+
26422646
o_codepos1:
26432647
| UNDERSCORE { None }
26442648
| i=codepos1 { Some i}
@@ -2691,21 +2695,24 @@ rnd_info:
26912695
| phi=sform d1=sform d2=sform d3=sform d4=sform p=sform?
26922696
{ PMultRndParams ((phi, d1, d2, d3, d4), p) }
26932697

2694-
swap_info:
2695-
| s=side? p=swap_pos { s,p }
2698+
(* ------------------------------------------------------------------------ *)
2699+
(* Code motion *)
2700+
%public phltactic:
2701+
| SWAP info=iplist1(loc(swap_info), COMMA) %prec prec_below_comma
2702+
{ Pswap info }
26962703

2697-
swap_pos:
2698-
| i1=word i2=word i3=word
2699-
{ SKbase (i1, i2, i3) }
2704+
swap_info:
2705+
| s=side? p=swap_position { (s, p) }
27002706

2701-
| p=sword
2702-
{ SKmove p }
2707+
swap_position:
2708+
| offset=codeoffset1
2709+
{ { interval = None; offset; } }
27032710

2704-
| i1=word p=sword
2705-
{ SKmovei (i1, p) }
2711+
| start=codepos1 offset=codeoffset1
2712+
{ { interval = Some (start, None); offset; } }
27062713

2707-
| LBRACKET i1=word DOTDOT i2=word RBRACKET p=sword
2708-
{ SKmoveinter (i1, i2, p) }
2714+
| LBRACKET start=codepos1 DOTDOT end_=codepos1 RBRACKET offset=codeoffset1
2715+
{ { interval = Some (start, Some end_); offset; } }
27092716

27102717
side:
27112718
| LBRACE n=word RBRACE {
@@ -2984,7 +2991,7 @@ interleave_info:
29842991
| s=brace(stmt) { OKstmt(s) }
29852992
| r=sexpr? LEAT f=loc(fident) { OKproc(f, r) }
29862993

2987-
phltactic:
2994+
%public phltactic:
29882995
| PROC
29892996
{ Pfun `Def }
29902997

@@ -3041,9 +3048,6 @@ phltactic:
30413048
| Some _, true ->
30423049
parse_error s.pl_loc (Some "cannot give side and '='") }
30433050

3044-
| SWAP info=iplist1(loc(swap_info), COMMA) %prec prec_below_comma
3045-
{ Pswap info }
3046-
30473051
| INTERLEAVE info=loc(interleave_info)
30483052
{ Pinterleave info }
30493053

src/ecParsetree.ml

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -503,12 +503,16 @@ type pcodepos1 = int * pcp_base
503503
type pcodepos = (pcodepos1 * int) list * pcodepos1
504504
type pdocodepos1 = pcodepos1 doption option
505505

506+
type pcodeoffset1 = [
507+
| `ByOffset of int
508+
| `ByPosition of pcodepos1
509+
]
510+
506511
(* -------------------------------------------------------------------- *)
507-
type swap_kind =
508-
| SKbase of int * int * int
509-
| SKmove of int
510-
| SKmovei of int * int
511-
| SKmoveinter of int * int * int
512+
type pswap_kind = {
513+
interval : (pcodepos1 * pcodepos1 option) option;
514+
offset : pcodeoffset1;
515+
}
512516

513517
type interleave_info = oside * (int * int) * ((int * int) list) * int
514518

@@ -729,7 +733,7 @@ type phltactic =
729733
| Prmatch of (oside * symbol * pcodepos1)
730734
| Pcond of pcond_info
731735
| Pmatch of matchmode
732-
| Pswap of ((oside * swap_kind) located list)
736+
| Pswap of ((oside * pswap_kind) located list)
733737
| Pcfold of (oside * pcodepos * int option)
734738
| Pinline of inline_info
735739
| Poutline of outline_info

src/ecPrinting.ml

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,33 +1315,6 @@ let string_of_locality = function
13151315
let pp_locality fmt lc =
13161316
Format.fprintf fmt "%s" (odfl "" (string_of_locality lc))
13171317

1318-
(* -------------------------------------------------------------------- *)
1319-
let string_of_cpos1 ((off, cp) : EcMatching.Position.codepos1) =
1320-
let s =
1321-
match cp with
1322-
| `ByPos i ->
1323-
string_of_int i
1324-
1325-
| `ByMatch (i, k) ->
1326-
let s =
1327-
let k =
1328-
match k with
1329-
| `If -> "if"
1330-
| `While -> "while"
1331-
| `Assign _ -> "<-"
1332-
| `Sample -> "<$"
1333-
| `Call -> "<@"
1334-
in Printf.sprintf "^%s" k in
1335-
1336-
match i with
1337-
| None | Some 1 -> s
1338-
| Some i -> Printf.sprintf "%s{%d}" s i
1339-
in
1340-
1341-
if off = 0 then s else
1342-
1343-
Printf.sprintf "%s%s%d" s (if off < 0 then "-" else "+") (abs off)
1344-
13451318
(* -------------------------------------------------------------------- *)
13461319
(* suppose g is a formula consisting of the application of a binary
13471320
operator op with scope onm and precedence opprec to formula
@@ -2138,6 +2111,41 @@ let pp_scvar ppe fmt vs =
21382111

21392112
pp_list "@ " pp_grp fmt vs
21402113

2114+
(* -------------------------------------------------------------------- *)
2115+
let pp_codepos1 (ppe : PPEnv.t) (fmt : Format.formatter) ((off, cp) : EcMatching.Position.codepos1) =
2116+
let s : string =
2117+
match cp with
2118+
| `ByPos i ->
2119+
string_of_int i
2120+
2121+
| `ByMatch (i, k) ->
2122+
let s =
2123+
let k =
2124+
match k with
2125+
| `If -> "if"
2126+
| `While -> "while"
2127+
| `Sample -> "<$"
2128+
| `Call -> "<@"
2129+
| `Assign `LvmNone -> "<-"
2130+
| `Assign (`LvmVar pv) -> Format.asprintf "%a<-" (pp_pv ppe) pv
2131+
in Format.asprintf "^%s" k in
2132+
2133+
match i with
2134+
| None | Some 1 -> s
2135+
| Some i -> Format.asprintf "%s{%d}" s i
2136+
in
2137+
2138+
if off = 0 then
2139+
Format.fprintf fmt "%s" s
2140+
else
2141+
Format.fprintf fmt "%s%s%d" s (if off < 0 then "-" else "+") (abs off)
2142+
2143+
(* -------------------------------------------------------------------- *)
2144+
let pp_codeoffset1 (ppe : PPEnv.t) (fmt : Format.formatter) (offset : EcMatching.Position.codeoffset1) =
2145+
match offset with
2146+
| `ByPosition p -> Format.fprintf fmt "%a" (pp_codepos1 ppe) p
2147+
| `ByOffset o -> Format.fprintf fmt "%d" o
2148+
21412149
(* -------------------------------------------------------------------- *)
21422150
let pp_opdecl_pr (ppe : PPEnv.t) fmt (basename, ts, ty, op) =
21432151
let ppe = PPEnv.add_locals ppe (List.map fst ts) in

0 commit comments

Comments
 (0)