The main function in ATS is declared as follows:
fun main {n:int | n > 0} (argc: int n, argv: &(@[string][n])): void
= "mainats"
So this function takes an integer argc greater than 0 and a string
array argv of size argc and returns no value. The syntax
argv: &(@[string][n]) indicates that argv is a
call-by-reference argument. If we followed C++ kind of syntax, then
this would be written as something like &argv: @[string][n].
The name "mainats", which is global, can be used in C code to refer to this function. When a program in ATS is compiled that implements the main function in ATS, the following implementation of the main function in C is automatically included in the C code generated by the ATS compiler:
main (int argc, char *argv[]) {
// some initialization code is included here
mainats (argc, argv) ;
return 0 ;
}
As an example, the following ATS program prints out the command line
on the standard output:
implement main (argc, argv) = let
fun loop {n,i:nat | i <= n} // [loop] is tail-recursive
(i: int i, argc: int n, argv: &(@[string][n])): void =
if i < argc then begin
if i > 0 then print (' '); print argv.[i]; loop (i+1, argc, argv)
end // end of [if]
// end of [loop]
in
loop (0, argc, argv); print_newline ()
end // end of [main]
There are also situations where the function mainats may need to be
implemented in C. If this happens, the function main_dummy needs to
be implemented as follows:
implement main_dummy () = ()This allows the compiler to generate proper code for the main function in C.
As an example, we present as follows a typical scenario in GTK+ programming, where the function gtk_init needs to be called to modify the arguments passed from a command line:
// some function implemented in ATS
extern fun main_work {n:pos} (argc: int n, argv: &(@[string][n])): void
= "main_work"
implement main_work (argc, argv) = ( (* some ATS code that does the main work *) )
implement main_dummy () = () // indicating [mainats] being implemented in C
%{$
ats_void_type
mainats (ats_int_type argc, ats_ptr_type argv) {
gtk_init ((int*)&argc, (char ***)&argv) ;
main_work (argc, argv) ;
return ;
} /* end of [mainats] */
%}
The code used for illustration is available here.