这是一项常见的基本任务,因此了解适当的方法是很好的。 C ++中的类似程序可能如下所示(ref):
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
for (int i = 0; i < argc; ++i)
cout << argv[i] << "\n";
return 0;
}
在此示例中,我们将在命令行上打印出每个参数。因此运行像./main.exe asdf 1234 bob
这样的编程会给出:
./main.exe
asdf
1234
bob
答案 0 :(得分:3)
这与C中的相同类型的程序非常相似,但有一些与约束和线性类型相关的差异。设置后约束很简单:
(*
Run patscc -o hello hello.dats
*)
#include "share/atspre_staload.hats"
implement main0{n}
(argc, argv): void = {
fun echoArgs{i:nat | i < n}
(ii: int(i), argv: !argv(n)): void = {
val () = println!("arg ", ii, " is ", argv[ii])
val () = if ii + 1 < argc then echoArgs(ii + 1, argv)
}
val () = echoArgs(0, argv)
}
由于我们需要访问argv
的内容,我们必须通过提供线性相关类型!argv(n)
来更改其viewtype的视图; corresponds中的!
linear logic表示在函数调用后该类型的值仍然可用; (n
)只表示argv
是一个大小为n
的字符串数组。我们必须保证数组中的索引i
小于数组的大小n
。
答案 1 :(得分:1)
这是一种基于组合器的风格:
#include "share/atspre_staload.hats"
#include "share/atspre_staload_libats_ML.hats"
implement
main0(argc, argv) = let
//
val args = listize_argc_argv(argc, argv)
//
in
list0_foreach(args, lam(arg) => println!(arg))
end // end of [main0]
答案 2 :(得分:1)
可能更常见的是从命令行获取标志和参数,以改变程序行为。为此,您可以使用getopt(或稍微复杂但更好的CLI接口,GNU getopt)。这些功能基本上适合你。
有点愚蠢的例子:
#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
}
用法:
$ ./hello4
Hello, modern world!
$ ./hello4 -t
hello world
$ ./hello4 -c
Hello, world! <-- this is red