Welcome to the Fabulous.AST, an Abstract Syntax Tree (AST) Domain Specific Language (DSL) for F#.
Fabulous.AST uses Fantomas to generate F# code from AST. This means that you can use Fabulous.AST to generate F# code that is formatted according to the Fantomas style guide. It's designed to provide a simple and expressive way to represent code as a tree of nodes. This makes it easier to manipulate and analyze code programmatically.
Let's take a look at an AST example in Fantomas:
open FSharp.Compiler.Text
open Fantomas.Core.SyntaxOak
let implementationSyntaxTree =
Oak(
[],
[ ModuleOrNamespaceNode(
None,
[ BindingNode(
None,
None,
MultipleTextsNode([ SingleTextNode("let", Range.Zero) ], Range.Zero),
false,
None,
None,
Choice1Of2(IdentListNode([ IdentifierOrDot.Ident(SingleTextNode("x", Range.Zero)) ], Range.Zero)),
None,
[],
None,
SingleTextNode("=", Range.Zero),
Expr.Constant(Constant.FromText(SingleTextNode("12", Range.Zero))),
Range.Zero
)
|> ModuleDecl.TopLevelBinding ],
Range.Zero
) ],
Range.Zero
)
open Fantomas.Core
CodeFormatter.FormatOakAsync(implementationSyntaxTree)
|> Async.RunSynchronously
|> printfn "%s"
produces the following code:
let x = 12
Now let's take a look at same example using Fabulous.AST:
open type Fabulous.AST.Ast
let source =
AnonymousModule() {
Value("x", "12")
}
open Fantomas.Core
let oak = Tree.compile source
let res = CodeFormatter.FormatOakAsync(oak) |> Async.RunSynchronously
printfn $"%s{res}"
produces the following code:
let x = 12
You can use an Escape Hatch
to generate code that is not supported by Fabulous.AST yet. For example, the following code:
open type Fabulous.AST.Ast
let source =
AnonymousModule() {
Value("a", "11")
BindingNode(
None,
None,
MultipleTextsNode([ SingleTextNode("let", Range.Zero) ], Range.Zero),
false,
None,
None,
Choice1Of2(IdentListNode([ IdentifierOrDot.Ident(SingleTextNode("x", Range.Zero)) ], Range.Zero)),
None,
List.Empty,
None,
SingleTextNode("=", Range.Zero),
Expr.Constant(Constant.FromText(SingleTextNode("12", Range.Zero))),
Range.Zero
)
}
open Fantomas.Core
let oak = Tree.compile source
let oak = Tree.compile source
let res = CodeFormatter.FormatOakAsync(oak) |> Async.RunSynchronously
printfn $"%s{res}"
produces the following code:
let a = 11
let x = 12
Using Fabulous.AST, you can easily create and manipulate ASTs like this one using F# functions. For example, you can add new nodes to the AST, modify existing nodes, or traverse the AST to perform analysis or transformation tasks.
Fabulous.AST is a powerful tool for anyone who works with code and wants to automate or streamline their development workflow. Whether you're a compiler writer, a code generator, or just someone who wants to write better code faster, Fabulous.AST can help you achieve your goals.
Widget | Description | F# code |
---|---|---|
AnonymousModule | An anonymous module | () |
Namespace | A namespace | namespace ABC |
Module | A module | module ABC |
NestedModule | A module | module ABC = |
Widget | Description | F# code |
---|---|---|
Open | An open directive | open ABC |
OpenType | An open directive | open type ABC.XYZ |
Widget | Description | F# code |
---|---|---|
Value | A let binding | let x = 12 |
Literal | A literal definition | [<Literal>] let x = 12 |
Function | A function definition | let f x = x + 1 |
Widget | Description | F# code |
---|---|---|
Alias | A type definition | type MyInt = int |
Record | A record type | type R = { x: int; y: int } |
Union | A union type | type U = A | B of int |
Class | A class type | type MyClass() = class end |
Struct | A struct type | type MyStruct() = struct end |
Interface | An interface type | type I = interface end |
Widget | Description | F# code |
---|---|---|
If | An if expression | if x = 12 then 1 |
IfElse | An if expression | if x = 12 then 1 else 2 |
Match | A match expression | match x with |
For | A for loop | for i in 1..10 do |
While | A while loop | while x < 10 do |