I would like to generate F# code for a .fs file using the abstract syntax tree. I am able to generate a .cs file using the Roslyn API. Here is an example riak.cs file that the unit tests generate based on the riak.proto. I would like to do the same thing in F#. I do not want to create a type provider yet. Does anyone have any examples using FSharp.Compiler.Service, possible with Fantomas?
2 Answers
Fantomas is certainly the right thing to look at here. If you want to generate F# source code, you basically need two things:
Build the AST that represents the source code you want to build. To do that, you need to use the untyped AST from the F# compiler service. The untyped syntax tree page documents how you can process it, but it should be a good starting point for learning about it. The AST of expressions is defined by the SynExpr type.
Once you build the AST, you need to format it. The F# compiler does not include a pretty printer, but this is exactly what Fantomas does in the CodePrinter file, so you should be able to copy this & pass your AST to the formatting implemented there. I think Visual F# PowerTools might actually have a newer version of Fantomas, so check that out first.
This answer is all using untyped AST, which is probably a good fit for working with syntax of the language. There is also typed AST (created after type inference finishes), but that's hard to use and not a good fit here.

- 240,744
- 19
- 378
- 553
-
And this gives you F# source from an untyped AST? I thought you needed a CodeDOM provider of some sort. – Robert Harvey Jul 14 '14 at 17:12
-
@RobertHarvey Yes - Fantomas is a tool that re-formats your F# code and it implements a pretty printer that does this. So, yes, this gives you F# code. CodeDOM is another option, but it generates very ugly code (because it has been designed for C#/VB) – Tomas Petricek Jul 14 '14 at 17:17
-
Fantomas accepts an AST as input, not source? Does it parse source into an AST first, and then re-emit it? – Robert Harvey Jul 14 '14 at 17:18
-
2It accepts source, uses the compiler to build AST and then pretty prints the AST. So a part of it does what the OP needs here. How else could it work? [Regular expressions?](http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags) – Tomas Petricek Jul 14 '14 at 17:21
-
Well, no, I wouldn't use regular expressions. Having an AST is certainly a very cool bonus, but I doubt that's how online code prettifiers work; you're essentially re-implementing a compiler (well, the lexing and parsing part of it, anyway). Visual Studio gets the AST for free, so they might as well use it for their code formatting. – Robert Harvey Jul 14 '14 at 17:23
-
1Having the AST is the only reasonable way to do this... But yes, I suppose it could be written using an ad-hoc set of rules that process a list of lines represented as strings and sometimes get it right :-) – Tomas Petricek Jul 14 '14 at 17:25
I totally agree with Tomas' answer. You need the latter half of Fantomas pipeline. Here is some relevant information.
FSharp.Compiler.Service's AST module consists of relevant ASTs and other utility functions for creating AST nodes, which might be helpful for you.
In Fantomas project, there is
formatAST
function that takes an AST as an input and output a source code string.

- 41,040
- 7
- 92
- 166
-
1Finally had time to follow up with this. My blog post is here: http://blog.ctaggart.com/2014/09/generating-f-code-using-its-ast.html – Cameron Taggart Sep 22 '14 at 05:23