aboutsummaryrefslogtreecommitdiff
path: root/src/main.cff
blob: 32aedb298b738083fffe0de08d4248efa04a81b1 (plain) (blame)
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
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; }
   return 0;
}