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" " -o -:\t\tset output to stdout\n" " -o path:\t\tset output 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[1]); return 0; case streq(arg, "-"); path = "/dev/stdin"; case streq(arg, "--target"); triple = nextarg(); case streq(arg, "-o"); let outpath = nextarg(); outfile = streq(outpath, "-") ? stdout : 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'\n1", 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; } }