Probably, the more common desire is to get flags and arguments from the command line, to change program behavior. For this, you can just use getopt (or with slightly more complexity but a much nicer CLI interface, GNU getopt). These functions do basically everything for you.
For a somewhat silly example:
#include "share/atspre_staload.hats"
%{^
#include <unistd.h>
%}
extern fun getopt{n:int}(argc: int, argv: !argv(n), flags: string): int = "mac#"
val trad = ref<bool>(false)
val color = ref<bool>(false)
val progname = ref<string>("hello4")
fn get_progname{n:int}(argc: int(n), argv: !argv(n)): void =
if argc > 0 then
!progname := argv[0]
implement main0(argc, argv) = (
get_progname(argc, argv);
process_args(argc, argv);
case+ (!trad, !color) of
| (true, true) => println!("\033[31;1mhello world\033[0m")
| (true, false) => println!("hello world")
| (false, true) => println!("\033[31;1mHello, world!\033[0m")
| (false, false) => println!("Hello, modern world!")
) where {
fn usage(): void = (
fprintln!(stderr_ref, "usage: ", !progname, " [-htc]");
exit(1);
)
fun process_args{n:int}(argc: int, argv: !argv(n)): void =
let
val r = getopt(argc, argv, "htc")
in
if r >= 0 then (
ifcase
| r = 'h' => usage()
| r = 't' => (!trad := true; process_args(argc, argv))
| r = 'c' => (!color := true; process_args(argc, argv))
| _ => (println!("fell through with: ", $UNSAFE.cast{char}(r)); usage())
)
end
}
Usage:
$ ./hello4
Hello, modern world!
$ ./hello4 -t
hello world
$ ./hello4 -c
Hello, world! <-- this is red