See AST of an mli file - ocaml

I want to be able to see what the AST of a certain module would be so I can write a proper filter against it.
As I right now don't really see how I can 'log' in a filter, for example I try to match and when the match fails I log, I use the Camlp4AstLifter function to translate the module into a tree, which is then printed out on the console, and like that I try to create my match patterns, like so:
camlp4o -filter Camlp4AstLifter -printer o name_of_file.ml
This falls a bit short right now when I would like to take an mli file and use a camlp4 filter to create a default implementation of this mli file.
I cannot use Camlp4AstLifter to see the tree, becuase this command doesn't seem to work with mli's (it shows me the mli again as output) and therefore I'm a bit blind while trying to match.
Anybody got an idea? Or maybe a hint on how to improve my filtering/matching approach (I don't get the feeling I'm doing it right yet, very tedious).
Kasper

Put module type S = <contents of mli file> into ml file and apply the lifter?

The ocaml compilers have some undocumented switches, that are nevertheless shown when doing ocamlc -h (probably thanks to the module Arg), ocamlopt has even more:
-dsource (undocumented)
-dparsetree (undocumented)
-dtypedtree (undocumented)
-drawlambda (undocumented)
-dlambda (undocumented)
-dclambda (undocumented)
...
I found out that -dsource gives a prettyprinting of the source. Your desired option should be there, too.

Related

What is the correct way to read this github's ocaml compiler project with bash scripts involved?

https://github.com/nlsandler/nqcc
At the above link, there is the compiler created by the author of this blog: https://norasandler.com/2017/11/29/Write-a-Compiler.html
I read through the first post and was faced with the problem that I almost always face when looking at a project on Github. Where to start?
I know the syntax for OCaml more or less, so I can read a single OCaml program and sort of understand what it does, but with a project at this level, I don't even know where the files of src/ are being called! You call the nqcc, and then what happens? How do we get to the ml files in src/? I'm having a hard time wrapping my head around this. Could someone guide me in how to navigate a huge project like this effectively?
In general, it involves understanding the build system, but your particular example is pretty easy to understand and is very transparent.
You need to know only two rules:
a binary foo corresponds to file foo.ml;
a module Foo corresponds to file Foo.ml1.
By applying these rules, we can figure out that nqcc.ml is the entry point. It calls the compile function which has the following definition (copied here for the ease of reference)
let compile prog_filename =
let source_lines = File.lines_of prog_filename in
let ast = Enum.reduce (fun line1 line2 -> line1^" "^line2) source_lines
|> Lex.lex
|> Parse.parse
in
Gen.generate prog_filename ast
So it refers to File, Enum, Lex, Parse, and Gen modules. The first two comes from the outside of the project (from the batteries library, which provides an extension to the OCaml standard library). While the last three correspond to lex.ml, parse.ml, and gen.ml files correspondingly.
1)) An optional but useful third rule:
a module Foo has the interface file named foo.mli
The interface file is sort of like a header file and make contain only types, and usually contains documentation.
The stuff in src/ gets compiled to nqcc.byte by setup.ml, which is run by the Makefile. setup.ml knows to do this by looking at the _oasis file, because all it does is call out to an ocaml build framework called OASIS. The nqcc shell script runs $(dirname $0)/nqcc.byte $1, which means "call the executable nqcc.byte in the same directory as this script, with the script's first argument".
How do you do this in general? Well, mostly experience. But starting with the Makefile or other build script is usually a good way to figure out what the main components are and how they hang together.

what's effect of option dsource of ocamlc?

I don't know the effect of option dsource of ocamlc.the -h option tell me it's undocumented
I know the use of dparsetree and dtypedtree,it can show me the ast
I try to use the option dsource,to a file test.ml,It seems to return me the source code,without the null line and the comment,and at bottom tell me the waring of the source code.
Is it the effect of option dsource?Thanks!
-dsource pretty-prints the AST using the OCaml syntax after desugarring syntax extensions such as camlp4 and ppx.
It's mostly used to debug ppxs. The content is exactly the same as -dparsetree (except in source form, instead of AST).
I just spent a few minutes grepping the OCaml compiler sources, and here is what I found.
The -dsource command-line flag sets the dump_source field to true in the Clflags module.
This setting in turn causes the compiler to do something like this in driver/compile.ml when compiling an implementation (.ml) file.
if !Clflags.dump_source then
fprintf ppf "%a#." Pprintast.structure ast
In other words, it pretty-prints the code part of the AST in a form that looks like source code.
Things look similar for an interface (.mli) file, except that it prints out the signature rather than the code.
Since OCaml has a rather flexible front-end, I would guess this is helpful to see the final result of any syntactic transformations that have been applied to the code. (But I might be wrong, I'm not an OCaml compiler hacker.)
I suggest you start looking at the code in driver/compile.ml if you want to figure out more.

How to find documentation in Core.Std?

Where is the documentation for functions, symbols under Core.Std ?
Or, is there any conventional way to look up ocaml documentation rather than guessing in utop REPL ?
E.g. I know if open Core.Std, then the function String.split will be imported. But it's hard to find out what's the function parameter etc.
Also, Ocaml don't have source code links to it's documentation like Haskell does, I guess.
The current best solution is looking at: https://ocaml.janestreet.com/ocaml-core/111.28.00/doc/core_kernel/#Core_string
Merlin is able to perform documentation lookup and jump to the definition. In Emacs, I'm assuming, that you're using Emacs, the documentation lookup is not bound by default to any key, so I bound it to C-c C-d. Add the following to your emacs configuration file:
(define-key merlin-mode-map (kbd "C-c C-d") 'merlin-document)
(define-key merlin-mode-map (kbd "C-c d") 'merlin-destruct)
The lookup function will jump directly to the mli file. This is my favorite way of reading the documentation. Unfortunately, due to a bug, Janestreet stopped to ship the mli file, so the feature is somewhat broken with the core. As a workaround, you can install source code with
opam source core_kernel
And then create a .merlin file, and point it to the sources:
S <path-to-sources>
Usually, it would be something like this
S ../core_kernel.113.33.00/src
Note, you should point merlin directly to the source subfolder.
It is also worth noting, that Merlin has intellisence like completion, that helps a lot, and you can hit F1 when you choose an entry from a completion list, and a window with documentation will pop up.
And finally, the link to the documentation, that you're referencing is very outdated. Here is the link to the latest documentation.

How to exclude test paths from cppcheck analysis?

I try to run a cppcheck analysis over my code, which has the following file structure:
/code/module_1/src/a.cpp
/code/module_1/src/b.cpp
/code/module_1/test/c.cpp
/code/module_2/src/d.cpp
/code/module_2/src/e.cpp
/code/module_3/test/f.cpp
I'd like to run an analysis excluding all test code. Is this possible with a command like "cppcheck -itest"? It doesn't work for me, although I think it should, according to the docs:
...Directory name is matched to all parts of the path.
I'm using version 1.69. I know I could mention all test directories separately (which does work, I checked), but the number of modules is too high to do this for many analyses reasonably.
Is this possible?
I installed Cppcheck to do some tests and it seems the -i implementation is a bit bonkers. However, I managed to achieve what you want.
Solution: use -itest\ instead of -itest (this was in Windows; maybe Linux needs -itest/)
Rationale: in my tests, -itest worked only if there was a .\test\ directory, in which case even .\a\test\a.cpp was excluded. With -itest\, however, such exclusion took place regardless of the presence of .\test\ directory.
This seems like a bug which the developers ought to weed out, but, in the meantime, you can succeed using the above workaround.
This is a late response to an old question, but perhaps this will help other latecomers like myself.
Disclaimer: This answer is for Windows.
It seems as if v1.79 has remedied the OP's issue. The following command line syntax has worked for me:
cppcheck -itest code
In this example, "-itest" weeds out any occurrence of the "test" directory, as originally (and correctly) assumed by the OP. In addition, the code folder is found next to the cppcheck.exe. This will be the root of the recursive source-code scan.
I'd use something like:
cppcheck /code/module_1/src /code/module_2/src /code/module_3/src

Reload option values in boost::program_options from new source

I'm just starting to dig into boost::program_options for the first time. I like it quite a bit. However, what I'm trying to accomplish with it doesn't seem to be something its designers have accounted for.
I want to use boost::program_options to parse both command line options as well as config files. So far so good. Additionally, though, I would like to be able to check for updated settings (say from a new config file) that could override the previously parsed settings in my variables_map.
Granted, I could do a separate parse and try to merge the two maps. Perhaps that's what I'll end up doing. I'm just wondering, though, if anyone has done anything like this before and has come up with a slick solution.