Chapter 29. Automatic Code Generation

Table of Contents
Generating a datcon-function
Generating a datcontag-function
Generating a fprint-function

In practice, one often encounters a need to write boilerplate code or code that tends to follow certain clearly recognizable patterns. It is commonly seen that meta-programming (of various forms) is employed to automatically generate such code, thus not only increasing programming productivity but also potentially eliminating bugs that would otherwise be introduced due to manual code construction.

In the following presentation, I am to show that the ATS compiler can be directed to generate the code for certain functions on values of a declared datatype. Following is the datatype used for illustration:

// datatype expr = | Int of int | Var of string | Add of (expr, expr) | Sub of (expr, expr) | Mul of (expr, expr) | Div of (expr, expr) | Ifgtz of (expr, expr, expr) // if expr > 0 then ... else ... | Ifgtez of (expr, expr, expr) // if expr >= 0 then ... else ... //

which is for some kind of abstract syntax trees representing arithmetic expressions.

Generating a datcon-function

Given a datatype, its datcon-function is the one that takes a value of the datatype and then returns a string representing the name of the (outmost) constructor in the construction of the value. We can use the following directive to indicate (to the ATS compiler) that the datcon-function for the datatype expr needs to be generated:

#codegen2("datcon", expr)

By default, the name of the generated function is datcon_expr_. If a different name is needed, it can be supplied as the third argument of the #codegen2-directive. For instance, the following directive indicates that the generated function is of the given name my_datcon_expr:

#codegen2("datcon", expr, my_datcon_expr)

Assume that a file of the name expr.dats contains the following directive (as a toplevel declaration):

#codegen2("datcon", expr)

and the definition for expr is accessible at the point where the codegen2-directive is declared. By executing the following command-line:


patsopt --codegen-2 -d expr.dats

we can see some output of ATS code that implements datcon_expr_:

(* ****** ****** *) // implement {}(*tmp*) datcon_expr_ (arg0) = ( case+ arg0 of | Int _ => "Int" | Var _ => "Var" | Add _ => "Add" | Sub _ => "Sub" | Mul _ => "Mul" | Div _ => "Div" | Ifgtz _ => "Ifgtz" | Ifgtez _ => "Ifgtez" ) // (* ****** ****** *)

If the output needs to be stored in a file of the name fprint_expr.hats, we can issue the following command-line:


patsopt -o fprint_expr.hats --codegen-2 -d expr.dats

Note that the funtion template datcon_expr_ is required to be declared somewhere in order for the generated code to be compiled properly:

fun{} datcon_expr_ : (expr) -> string // a function template

Please find on-line the entirety of this presented example plus a Makefile (for illustrating the code generation process).