Skip to content

Reduce equal & compare boilerplate using deriving eq & ord#227

Merged
sim642 merged 7 commits intomasterfrom
ppx-eq-ord
May 18, 2021
Merged

Reduce equal & compare boilerplate using deriving eq & ord#227
sim642 merged 7 commits intomasterfrom
ppx-eq-ord

Conversation

@sim642
Copy link
Copy Markdown
Member

@sim642 sim642 commented May 12, 2021

Issue #31.

I went through the equal and compare definitions and replaced suitable ones with deriving eq and ord.

Some more boilerplate could be removed by moving some CIL-specific implementations that only compare IDs into Deriving.Cil. Right now their comparisons are duplicated all over the place.

@sim642 sim642 added the cleanup Refactoring, clean-up label May 12, 2021
@sim642 sim642 mentioned this pull request May 12, 2021
10 tasks
@michael-schwarz michael-schwarz self-requested a review May 12, 2021 10:40
@sim642
Copy link
Copy Markdown
Member Author

sim642 commented May 12, 2021

Some more boilerplate could be removed by moving some CIL-specific implementations that only compare IDs into Deriving.Cil. Right now their comparisons are duplicated all over the place.

It kind of annoys me how such comparisons are spread around. For example .vid\s+= yields 39 different places where varinfos are checked for equality. It would actually be better organized if all of those just delegated to Basetype.Variables.equal. Similarly with all the other modules we have for CIL types in Basetype (which might be better called CilType or something).

Then one doesn't need to define Deriving.Cil.equal_varinfo etc and make sure Deriving.Cil is opened everywhere. In fact, it could even make Deriving.Cil completely redundant because as seen in #210, we don't actually want the derived to_yojson functions anyway.


I'll pursue this line of refactoring in a separate branch and PR. I think it's reasonable to have common and well-behaved implementations for most Printable functions for these CIL types in a clear place.

@michael-schwarz
Copy link
Copy Markdown
Member

michael-schwarz commented May 17, 2021

let rec compareExp a b =
let order x = match x with
| Const _ -> 0
| Lval _ -> 1
| SizeOf _ -> 2
| SizeOfE _ -> 3
| SizeOfStr _ -> 4
| AlignOf _ -> 5
| AlignOfE _ -> 6
| UnOp _ -> 7
| BinOp _ -> 9
| CastE _ -> 10
| AddrOf _ -> 11
| StartOf _ -> 12
| Question _ -> 13
| AddrOfLabel _ -> 14
| Real _ -> 15
| Imag _ -> 16
in
if a == b || Expcompare.compareExp a b then
0
else if order a <> order b then
(order a) - (order b)

let compare (x1,o1) (x2,o2) =
let tag = function
| `NoOffset -> 0
| `Field _ -> 1
| `Index _ -> 2
| _ -> 3
in
let rec compare a b =
let r = tag a - tag b in
if r <> 0 then r else

These and some other such places seem problematic in light of

 If an ord comparator returns a value outside -1..1 range, the behavior is unspecified.

from https://github.com/ocaml-ppx/ppx_deriving#plugins-eq-and-ord

One should probably patch all such places to return values from [-1,1]?

@sim642
Copy link
Copy Markdown
Member Author

sim642 commented May 17, 2021

One should probably patch all such places to return values from [-1,1]?

I noticed that at some point too, but chose to ignore it, because it worked regardless. And ppx_deriving_ord actually nowhere makes any assumptions about the range, so I don't think it's an issue. But I'll go ahead and wrap those with Stdlib.compare anyway, so this doesn't stay open ended.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cleanup Refactoring, clean-up

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants