Hi folks, I’m currently reading Shayne Fletcher’s mini-ml, it’s pretty neat.
I’m figuring it out how to pretty print mini-ml with comments.(As the Comments section mentioned in prettier)
I did try to read the the related code from ReScript’s repo, but it may not be that easy for beginner. For example, there’re 1891 loc of the res_comments_table.ml, and 5661 loc of the res_printer.ml.
Mini-ml has collected comments into a list:
let comments () : (string * Ml_location.t) list = List.rev !comment_list
But it sounds a lot like the comments won’t be used anywhere. The idea behind pretty printer is cool, see fpottier’s awesome demo
I was wondering is there any minimal example could help me understand how to pretty print comments within this mini-ml language?
OCamlformat has the exact same problem and it is solved this way:
- Gather comments, easy.
- Gather every locations appearing on the AST (without remembering to what they belong).
This is possible in OCaml thanks to Ast_mapper), which iterates on the AST and allows us to define a function to be called on a specific node. By chance, it iterates over locations too.
- Each comment is associated to a location found in the AST in a Hashtbl.
No two locations match so it must “attach” a comment to the location that makes the most sense. This could be the closest but it also take into account tokens found in the source code to make a decision.
This uses a Non_overlapping_interval_tree and a lot of heuristics.
- To make things harder, there’s 3 of these hashtbls: Comments attached “before”, “after” or “within” a given location.
This allows to place comments near parentheses,
in, etc… more precisely.
- While iterating the AST again for printing, every time we encounter a location, we query the comment associated with it.
After all this, it’s common to find misplaced comments. It’s definitely a challenge.
I hope you don’t need the precise placement of comments that ocamlformat has and can implement a much simpler solution.