1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
import "cffc.hff";
import "common.hff";
fn prihelp(f *FILE, progname *const u8) void {
fprintf(f, "Usage: %s [OPTION]... [FILE]\n", progname);
fprintf(f, "Compile cffc source code in FILE\n"
"\n"
"Options:\n"
" --help, -h \t\tshow this help message\n"
" --target triple \tset compilation target triple\n"
" - \t\t\tread input from stdin\n"
" -p \t\t\toutput LLVM IR to stdout\n"
" -o path \t\toutput LLVM IR to file path\n");
}
extern fn main(argc int, argv **u8) int {
let triple = #null;
let path *const u8 = #null;
let outfile *FILE = #null;
for let i = 1; i < argc; ++i {
let arg = argv[i];
defmacro nextarg() [
(do let $next = argv[++i];
if $next == #null {
fprintf(stderr, "%s: error: argument expected after `%s'\n", argv[0], arg);
fprintf(stderr, "Try '%s --help' for more information\n", argv[0]);
return 1;
}
$next;);
]
switch {
case streq(arg, "-h") or streq(arg, "--help");
prihelp(stdout, argv[0]);
return 0;
case streq(arg, "-");
path = "/dev/stdin";
case streq(arg, "--target");
triple = nextarg();
case streq(arg, "-p");
outfile = stdout;
case streq(arg, "-o");
let outpath = nextarg();
outfile = fopen(outpath, "wb");
if outfile == #null {
fprintf(stderr, "%s: error: cannot open '%s': %s\n", argv[0], outpath, strerror(errno));
return 1;
}
case *arg == '-';
fprintf(stderr, "%s: error: unknown option '%s'\n", argv[0], arg);
fprintf(stderr, "Try '%s --help' for more information\n", argv[0]);
return 1;
case else
if path {
fprintf(stderr, "%s: error: path was already given\n", argv[0]);
fprintf(stderr, "Try '%s --help' for more information\n", argv[0]);
return 1;
}
path = arg;
}
}
if path == #null {
fprintf(stderr, "%s: error: no input file\n", argv[0]);
fprintf(stderr, "Try '%s --help' for more information\n", argv[0]);
return 1;
}
if outfile == #null {
fprintf(stderr, "%s: error: no output file\n", argv[0]);
fprintf(stderr, "Try '%s --help' for more information\n", argv[0]);
return 1;
}
triple = triple ?? host_target_triple;
let targ = triple2targ(triple);
if targ == #null {
fprintf(stderr, "%s: error: unsupported target triple `%s'\n", argv[0], triple);
return 1;
}
targ_ini(targ);
g_targ.triple = triple;
let p = Parser {};
parser_init(&p, path);
llvm_init(outfile);
let decls = parse(&p);
defer free(decls.#ptr);
if p.error { return 1; }
return 0;
}
|