@@ -148,13 +148,36 @@ let rec pp_pattern (Pat (pat_, _bt, _)) =
148148 args)
149149
150150
151+ (* Precedences:
152+ Reference: https://en.cppreference.com/w/c/language/operator_precedence
153+ The number we use are `16 - p` where `p` is the reference in the table.
154+ We do this so bigger numbers are higher precedence.
155+
156+ Highest
157+
158+ 15: . [] -> selectors
159+ 14: ! - ~ & cast unary
160+ 13: * / %
161+ 12: + -
162+ 10: < <= > >=
163+ 9: == !=
164+ 8: &
165+ 7: ^
166+ 6: |
167+ 5: &&
168+ 4: ||
169+ 3: ? : ternary
170+
171+ Lowest
172+ *)
173+
151174let pp
152175 : 'bt 'a .
153- ?atomic : bool -> ?f :('bt term -> Pp. document -> Pp. document ) -> 'bt term -> Pp. document
176+ ?prec : int -> ?f :('bt term -> Pp. document -> Pp. document ) -> 'bt term -> Pp. document
154177 =
155- fun ?(atomic = false ) ?(f = fun _ x -> x) ->
156- let rec aux atomic (IT (it , _ , _ )) =
157- let aux b x = f x (aux b x) in
178+ fun ?(prec = 0 ) ?(f = fun _ x -> x) ->
179+ let rec aux prec (IT (it , _ , _ )) =
180+ let aux prec x = f x (aux prec x) in
158181 (* Without the `lparen` inside `nest 2`, the printed `rparen` is indented by 2 (wrt to
159182 the lparen). I don't quite understand it, but it works. *)
160183 let parens pped =
@@ -163,7 +186,7 @@ let pp
163186 let braces pped =
164187 Pp. group ((nest 2 @@ lbrace ^^ break 0 ^^ pped) ^^ break 0 ^^ rbrace)
165188 in
166- let mparens pped = if atomic then parens pped else Pp. group pped in
189+ let wrap_after tgt doc = if prec > tgt then parens doc else doc in
167190 let break_op x = break 1 ^^ x ^^ space in
168191 let alloc_id i = ! ^ (" @" ^ Z. to_string i) in
169192 match it with
@@ -173,7 +196,7 @@ let pp
173196 | Bits ((sign , n ), v ) ->
174197 let dec =
175198 ! ^ (Z. to_string v)
176- ^^ (match sign with Unsigned -> ! ^ " u" | Signed -> ! ^ " i" )
199+ ^^ (match sign with Unsigned -> ! ^ " ' u" | Signed -> ! ^ " ' i" )
177200 ^^ ! ^ (string_of_int n)
178201 in
179202 if Z. lt v (Z. of_int 16 ) then
@@ -185,89 +208,100 @@ let pp
185208 ^^^ ! ^ " */"
186209 | Q q -> ! ^ (Q. to_string q)
187210 | Pointer { alloc_id = id ; addr } ->
188- braces (alloc_id id ^^ Pp. semi ^^ Pp. space ^^ ! ^ (Z. to_string addr))
211+ braces (alloc_id id ^^ Pp. semi ^^ Pp. space ^^ ! ^ (" 0x " ^ Z. format " %x " addr))
189212 | Alloc_id i -> ! ^ (" @" ^ Z. to_string i)
190213 | Bool true -> ! ^ " true"
191214 | Bool false -> ! ^ " false"
192215 | Unit -> ! ^ " void"
193216 | Default bt -> c_app ! ^ " default" [ BaseTypes. pp bt ]
194- | Null -> ! ^ " null "
217+ | Null -> ! ^ " NULL "
195218 | CType_const ct -> Pp. squotes (Sctypes. pp ct))
196219 | Sym sym -> Sym. pp sym
197220 | Unop (uop , it1 ) ->
221+ let prefix x op p = wrap_after x (! ^ op ^^ aux p it1) in
198222 (match uop with
199- | BW_CLZ_NoSMT -> c_app ! ^ " bw_clz_uf" [ aux false it1 ]
200- | BW_CTZ_NoSMT -> c_app ! ^ " bw_ctz_uf" [ aux false it1 ]
201- | BW_FFS_NoSMT -> c_app ! ^ " bw_ffs_uf" [ aux false it1 ]
202- | BW_FLS_NoSMT -> c_app ! ^ " bw_fls_uf" [ aux false it1 ]
203- | Not -> mparens (! ^ " !" ^^ parens (aux false it1))
204- | Negate -> mparens (! ^ " -" ^^ parens (aux false it1))
205- | BW_Compl -> mparens (! ^ " ~" ^^ parens (aux false it1)))
223+ | BW_CLZ_NoSMT -> c_app ! ^ " bw_clz_uf" [ aux 0 it1 ]
224+ | BW_CTZ_NoSMT -> c_app ! ^ " bw_ctz_uf" [ aux 0 it1 ]
225+ | BW_FFS_NoSMT -> c_app ! ^ " bw_ffs_uf" [ aux 0 it1 ]
226+ | BW_FLS_NoSMT -> c_app ! ^ " bw_fls_uf" [ aux 0 it1 ]
227+ | Not ->
228+ let infix p op l r =
229+ wrap_after p (flow (break 1 ^^ op ^^ space) [ aux p l; aux p r ])
230+ in
231+ (match it1 with
232+ | IT (Binop (EQ, l , r ), _ , _ ) -> infix 9 (! ^ " !" ^^ equals) l r
233+ | IT (Binop (LT, l , r ), _ , _ ) -> infix 10 (rangle () ^^ equals) l r
234+ | IT (Binop (LE, l , r ), _ , _ ) -> infix 10 (rangle () ) l r
235+ | IT (Binop (LTPointer, l , r ), _ , _ ) -> infix 10 (rangle () ^^ equals) l r
236+ | IT (Binop (LEPointer, l , r ), _ , _ ) -> infix 10 (rangle () ) l r
237+ | _ -> prefix 14 " !" 14 )
238+ | Negate -> prefix 14 " -" 14
239+ | BW_Compl -> prefix 14 " ~" 14 )
206240 | Binop (bop , it1 , it2 ) ->
241+ let infix x op l r = wrap_after x (flow (break_op op) [ aux l it1; aux r it2 ]) in
242+ let prefix x = c_app ! ^ x [ aux 0 it1; aux 0 it2 ] in
207243 (match bop with
208- | And ->
209- mparens (flow (break_op (ampersand ^^ ampersand)) [ aux true it1; aux true it2 ])
210- | Or -> mparens (flow (break_op (bar ^^ bar)) [ aux true it1; aux true it2 ])
211- | Implies -> c_app ! ^ " implies" [ aux true it1; aux true it2 ]
212- | Add -> mparens (flow (break_op plus) [ aux true it1; aux true it2 ])
213- | Sub -> mparens (flow (break_op minus) [ aux true it1; aux true it2 ])
214- | Mul -> mparens (flow (break_op star) [ aux true it1; aux true it2 ])
215- | MulNoSMT -> mparens (c_app ! ^ " mul_uf" [ aux true it1; aux true it2 ])
216- | Div -> mparens (flow (break_op slash) [ aux true it1; aux true it2 ])
217- | DivNoSMT -> mparens (c_app ! ^ " div_uf" [ aux true it1; aux true it2 ])
218- | Exp -> c_app ! ^ " power" [ aux true it1; aux true it2 ]
219- | ExpNoSMT -> c_app ! ^ " power_uf" [ aux true it1; aux true it2 ]
220- | Rem -> c_app ! ^ " rem" [ aux true it1; aux true it2 ]
221- | RemNoSMT -> mparens (c_app ! ^ " rem_uf" [ aux true it1; aux true it2 ])
222- | Mod -> c_app ! ^ " mod" [ aux true it1; aux true it2 ]
223- | ModNoSMT -> mparens (c_app ! ^ " mod_uf" [ aux true it1; aux true it2 ])
224- | EQ -> mparens (flow (break_op (equals ^^ equals)) [ aux true it1; aux true it2 ])
225- | LT -> mparens (flow (break_op @@ langle () ) [ aux true it1; aux true it2 ])
226- | LE ->
227- mparens (flow (break_op @@ langle () ^^ equals) [ aux true it1; aux true it2 ])
228- | LTPointer ->
229- mparens (flow (break_op @@ langle () ) [ aux true it1; aux true it2 ])
230- | LEPointer ->
231- mparens (flow (break_op @@ langle () ^^ equals) [ aux true it1; aux true it2 ])
232- | Min -> c_app ! ^ " min" [ aux false it1; aux false it2 ]
233- | Max -> c_app ! ^ " max" [ aux false it1; aux false it2 ]
234- | XORNoSMT -> c_app ! ^ " xor_uf" [ aux false it1; aux false it2 ]
235- | BW_And -> c_app ! ^ " bw_and_uf" [ aux false it1; aux false it2 ]
236- | BWOrNoSMT -> c_app ! ^ " bw_or_uf" [ aux false it1; aux false it2 ]
237- | ShiftLeft -> c_app ! ^ " shift_left" [ aux false it1; aux false it2 ]
238- | ShiftRight -> c_app ! ^ " shift_right" [ aux false it1; aux false it2 ]
239- | SetMember -> c_app ! ^ " member" [ aux false it1; aux false it2 ]
240- | SetUnion -> c_app ! ^ " union" [ aux false it1; aux false it2 ]
241- | SetIntersection -> c_app ! ^ " inter" [ aux false it1; aux false it2 ]
242- | SetDifference -> c_app ! ^ " difference" [ aux false it1; aux false it2 ]
243- | Subset -> c_app ! ^ " subset" [ aux false it1; aux false it2 ])
244+ | And -> infix 5 (ampersand ^^ ampersand) 5 5
245+ | Or -> infix 4 (bar ^^ bar) 4 4
246+ | Implies -> prefix " implies"
247+ | Add -> infix 12 ! ^ " +" 12 12
248+ | Sub -> infix 12 ! ^ " -" 12 13
249+ | Mul -> infix 13 ! ^ " *" 13 13
250+ | MulNoSMT -> prefix " mul_uf"
251+ | Div -> infix 13 slash 14 14
252+ | DivNoSMT -> prefix " div_uf"
253+ | Exp -> prefix " power"
254+ | ExpNoSMT -> prefix " power_uf"
255+ | Rem -> infix 13 ! ^ " %" 14 14
256+ | RemNoSMT -> prefix " rem_uf"
257+ | Mod -> prefix " mod"
258+ | ModNoSMT -> prefix " mod_uf"
259+ | EQ -> infix 9 (equals ^^ equals) 9 9
260+ | LT -> infix 10 (langle () ) 10 10
261+ | LE -> infix 10 (langle () ^^ equals) 10 10
262+ | LTPointer -> infix 10 (langle () ) 10 10
263+ | LEPointer -> infix 10 (langle () ^^ equals) 10 10
264+ | Min -> prefix " min"
265+ | Max -> prefix " max"
266+ | XORNoSMT -> infix 7 ! ^ " ^" 7 7
267+ | BW_And -> infix 8 ampersand 8 8
268+ | BWOrNoSMT -> infix 6 bar 6 6
269+ | ShiftLeft ->
270+ infix 0 (langle () ^^ langle () ) 1 1 (* easier to read with parens *)
271+ | ShiftRight ->
272+ infix 0 (rangle () ^^ rangle () ) 1 1 (* easier to read with parens *)
273+ | SetMember -> prefix " member"
274+ | SetUnion -> prefix " union"
275+ | SetIntersection -> prefix " inter"
276+ | SetDifference -> prefix " difference"
277+ | Subset -> prefix " subset" )
244278 | ITE (o1 , o2 , o3 ) ->
245- parens (flow (break 1 ) [ aux true o1; ! ^ " ?" ; aux true o2; colon; aux true o3 ])
279+ wrap_after 2 (flow (break 1 ) [ aux 3 o1; ! ^ " ?" ; aux 3 o2; colon; aux 3 o3 ])
246280 | EachI ((i1 , (s , _ ), i2 ), t ) ->
247281 Pp. (
248282 group
249283 @@ group (c_app ! ^ " for" [ int i1; Sym. pp s; int i2 ])
250- ^/^ group ((nest 2 @@ lbrace ^^ break 0 ^^ aux false t) ^^ break 0 ^^ rbrace))
251- | NthTuple (n , it2 ) -> mparens (aux true it2 ^^ dot ^^ ! ^ (" member" ^ string_of_int n))
252- | Tuple its -> braces (separate_map (semi ^^ space) (aux false ) its)
284+ ^/^ group ((nest 2 @@ lbrace ^^ break 0 ^^ aux 0 t) ^^ break 0 ^^ rbrace))
285+ | NthTuple (n , it2 ) ->
286+ wrap_after 15 (aux 15 it2 ^^ dot ^^ ! ^ (" member" ^ string_of_int n))
287+ | Tuple its -> braces (separate_map (semi ^^ space) (aux 0 ) its)
253288 | Struct (_tag , members ) ->
254289 lbrace
255290 ^^ hardline
256291 ^^ flow_map
257292 (comma ^^ hardline)
258293 (fun (member , it ) ->
259- Pp. group
260- @@ (Pp. group @@ dot ^^ Id. pp member ^^^ equals)
261- ^^^ align (aux false it))
294+ Pp. group @@ (Pp. group @@ dot ^^ Id. pp member ^^^ equals) ^^^ align (aux 0 it))
262295 members
263296 ^^^ rbrace
264- | StructMember (t , member ) -> prefix 0 0 (aux true t) ( dot ^^ Id. pp member)
297+ | StructMember (t , member ) -> wrap_after 15 (aux 15 t ^^ dot ^^ Id. pp member)
265298 | StructUpdate ((t , member ), v ) ->
266- mparens
267- (aux true t
268- ^^ braces
269- @@ (Pp. group @@ dot ^^ Id. pp member ^^^ equals)
270- ^^^ align (aux true v))
299+ braces
300+ (! ^ " ..."
301+ ^^ aux 0 t
302+ ^^ comma
303+ ^^^ (Pp. group @@ dot ^^ Id. pp member ^^^ equals)
304+ ^^^ align (aux 0 v))
271305 | Record members ->
272306 align
273307 @@ lbrace
@@ -276,79 +310,65 @@ let pp
276310 (fun (member , it ) ->
277311 Pp. group
278312 @@ (Pp. group @@ dot ^^ Id. pp member ^^^ equals)
279- ^^^ align (aux false it))
313+ ^^^ align (aux 0 it))
280314 members
281315 ^^^ rbrace
282- | RecordMember (t , member ) -> prefix 0 0 (aux true t) ( dot ^^ Id. pp member)
316+ | RecordMember (t , member ) -> wrap_after 15 (aux 15 t ^^ dot ^^ Id. pp member)
283317 | RecordUpdate ((t , member ), v ) ->
284- mparens
285- (aux true t
286- ^^ braces
287- @@ (Pp. group @@ dot ^^ Id. pp member ^^^ equals)
288- ^^^ align (aux true v))
289- | Cast (cbt , t ) ->
290- mparens (align @@ parens (BaseTypes. pp cbt) ^^ break 0 ^^ aux true t)
291- | MemberShift (t , tag , member ) ->
292- mparens
293- (c_app (! ^ " member_shift" ^^ angles (Sym. pp tag)) [ aux false t; Id. pp member ])
294- | ArrayShift { base; ct; index } ->
295- mparens
296- (c_app
297- (! ^ " array_shift" ^^ angles (Sctypes. pp ct))
298- [ aux false base; aux false index ])
299- | CopyAllocId { addr; loc } ->
300- mparens (c_app ! ^ " copy_alloc_id" [ aux false addr; aux false loc ])
301- | SizeOf t -> mparens (c_app ! ^ " sizeof" [ Sctypes. pp t ])
302- | OffsetOf (tag , member ) -> mparens (c_app ! ^ " offsetof" [ Sym. pp tag; Id. pp member ])
303- | Aligned t -> mparens (c_app ! ^ " aligned" [ aux false t.t; aux false t.align ])
304- | Representable (rt , t ) ->
305- mparens (c_app (! ^ " repr" ^^ angles (CT. pp rt)) [ aux false t ])
306- | Good (rt , t ) -> mparens (c_app (! ^ " good" ^^ angles (CT. pp rt)) [ aux false t ])
307- | WrapI (ity , t ) ->
308- mparens (c_app (! ^ " wrapI" ^^ angles (CT. pp (Integer ity))) [ aux false t ])
309- | Head o1 -> mparens (c_app ! ^ " hd" [ aux false o1 ])
310- | Tail o1 -> mparens (c_app ! ^ " tl" [ aux false o1 ])
318+ braces
319+ (! ^ " ..."
320+ ^^ aux 0 t
321+ ^^ comma
322+ ^^^ (Pp. group @@ dot ^^ Id. pp member ^^^ equals)
323+ ^^^ align (aux 0 v))
324+ | Cast (cbt , t ) -> wrap_after 14 (align @@ parens (BaseTypes. pp cbt) ^^ aux 14 t)
325+ | MemberShift (t , _tag , member ) ->
326+ wrap_after 14 (ampersand ^^ aux 15 t ^^ (! ^ " -" ^^ rangle () ) ^^ Id. pp member)
327+ | ArrayShift { base; ct = _ct ; index } ->
328+ wrap_after 14 (ampersand ^^ aux 15 base ^^ brackets (aux 0 index))
329+ | CopyAllocId { addr; loc } -> c_app ! ^ " copy_alloc_id" [ aux 0 addr; aux 0 loc ]
330+ | SizeOf t -> c_app ! ^ " sizeof" [ Sctypes. pp t ]
331+ | OffsetOf (tag , member ) -> c_app ! ^ " offsetof" [ Sym. pp tag; Id. pp member ]
332+ | Aligned t -> c_app ! ^ " aligned" [ aux 0 t.t; aux 0 t.align ]
333+ | Representable (rt , t ) -> c_app (! ^ " repr" ^^ angles (CT. pp rt)) [ aux 0 t ]
334+ | Good (rt , t ) -> c_app (! ^ " good" ^^ angles (CT. pp rt)) [ aux 0 t ]
335+ | WrapI (ity , t ) -> c_app (! ^ " wrapI" ^^ angles (CT. pp (Integer ity))) [ aux 0 t ]
336+ | Head o1 -> c_app ! ^ " hd" [ aux 0 o1 ]
337+ | Tail o1 -> c_app ! ^ " tl" [ aux 0 o1 ]
311338 | Nil bt -> ! ^ " nil" ^^ angles (BaseTypes. pp bt)
312- | Cons (t1 , t2 ) -> mparens (aux true t1 ^^ colon ^^ colon ^^ aux true t2)
313- | NthList (n , xs , d ) ->
314- mparens (c_app ! ^ " nth_list" [ aux false n; aux false xs; aux false d ])
339+ | Cons (t1 , t2 ) -> c_app ! ^ " cons" [ aux 0 t1; aux 0 t2 ]
340+ | NthList (n , xs , d ) -> c_app ! ^ " nth_list" [ aux 0 n; aux 0 xs; aux 0 d ]
315341 | ArrayToList (arr , i , len ) ->
316- mparens ( c_app ! ^ " array_to_list" [ aux false arr; aux false i; aux false len ])
317- | MapConst (_bt , t ) -> mparens ( c_app ! ^ " const" [ aux false t ])
318- | MapGet (t1 , t2 ) -> mparens (aux true t1 ^^ brackets (aux false t2))
342+ c_app ! ^ " array_to_list" [ aux 0 arr; aux 0 i; aux 0 len ]
343+ | MapConst (_bt , t ) -> c_app ! ^ " const" [ aux 0 t ]
344+ | MapGet (t1 , t2 ) -> wrap_after 15 (aux 15 t1 ^^ brackets (aux 0 t2))
319345 | MapSet (t1 , t2 , t3 ) ->
320- mparens (aux true t1 ^^ brackets (aux false t2 ^^^ equals ^^^ aux false t3))
321- | MapDef ((s , _ ), t ) -> brackets (Sym. pp s ^^^ ! ^ " -> " ^^^ aux false t)
322- | Apply (name , args ) -> c_app (Sym. pp name) (List. map (aux false ) args)
346+ wrap_after 15 (aux 15 t1 ^^ brackets (aux 0 t2 ^^^ equals ^^^ aux 0 t3))
347+ | MapDef ((s , _ ), t ) -> brackets (Sym. pp s ^^^ ( ! ^ " -" ^^ rangle () ) ^^^ aux 0 t)
348+ | Apply (name , args ) -> c_app (Sym. pp name) (List. map (aux 0 ) args)
323349 | Let ((name , x1 ), x2 ) ->
324- parens
325- (! ^ " let"
326- ^^^ Sym. pp name
327- ^^^ Pp. equals
328- ^^^ aux false x1
329- ^^^ ! ^ " in"
330- ^^^ aux false x2)
350+ parens (! ^ " let" ^^^ Sym. pp name ^^^ Pp. equals ^^^ aux 0 x1 ^^^ ! ^ " in" ^^^ aux 0 x2)
331351 | Match (e , cases ) ->
332352 ! ^ " match"
333- ^^^ aux false e
353+ ^^^ aux 0 e
334354 ^^^ braces
335355 ((* copying from mparens *)
336356 Pp. group
337357 (nest 2
338358 @@ separate_map
339359 (break 0 )
340360 (fun (pattern , body ) ->
341- pp_pattern pattern ^^^ ! ^ " =>" ^^^ braces (aux false body))
361+ pp_pattern pattern ^^^ ! ^ " =>" ^^^ braces (aux 0 body))
342362 cases))
343363 | Constructor (s , args ) ->
344364 Sym. pp s
345365 ^^^ braces
346366 (separate_map
347367 (comma ^^ space)
348- (fun (id , e ) -> Id. pp id ^^ colon ^^^ aux false e)
368+ (fun (id , e ) -> Id. pp id ^^ colon ^^^ aux 0 e)
349369 args)
350370 in
351- fun (it : 'bt term ) -> aux atomic it
371+ fun (it : 'bt term ) -> aux prec it
352372
353373
354374open Cerb_pp_prelude
0 commit comments