]> pd.if.org Git - lice/blob - lice.c
autocommit for files dated 2014-11-17 20:15:26
[lice] / lice.c
1 #include <stdlib.h>
2 #include <stdarg.h>
3 #include <string.h>
4 #include <stdio.h>
5 #include <getopt.h>
6
7 #include "lexer.h"
8 #include "parse.h"
9 #include "gen.h"
10 #include "opt.h"
11
12 bool compile_warning = true;
13
14 static void compile_diagnostic(const char *type, const char *fmt, va_list va) {
15     fprintf(stderr, "%s %s: ", lexer_marker(), type);
16     vfprintf(stderr, fmt, va);
17     fprintf(stderr, "\n");
18 }
19
20 void compile_error(const char *fmt, ...) {
21     va_list  a;
22     va_start(a, fmt);
23     compile_diagnostic("error", fmt, a);
24     va_end(a);
25     exit(EXIT_FAILURE);
26 }
27
28 void compile_warn(const char *fmt, ...) {
29     if (!compile_warning)
30         return;
31
32     va_list a;
33     va_start(a, fmt);
34     compile_diagnostic("warning", fmt, a);
35     va_end(a);
36 }
37
38 void compile_ice(const char *fmt, ...) {
39     va_list a;
40     va_start(a, fmt);
41     compile_diagnostic("internal error", fmt, a);
42     va_end(a);
43
44     /* flush all streams */
45     fflush(NULL);
46     abort();
47 }
48
49 int compile_begin(bool dump) {
50     parse_init();
51
52     list_t *block = parse_run();
53     size_t  index = 0;
54
55     for (list_iterator_t *it = list_iterator(block); !list_iterator_end(it); index++) {
56         printf("# block %zu\n", index);
57         if (!dump) {
58             gen_toplevel(list_iterator_next(it));
59         } else {
60             printf("%s", ast_string(list_iterator_next(it)));
61         }
62     }
63     return true;
64 }
65
66 static bool parse_option(const char *optname, int *cargc, char ***cargv, char **out, int ds, bool split) {
67     int    argc = *cargc;
68     char **argv = *cargv;
69     size_t len  = strlen(optname);
70
71     if (strncmp(argv[0]+ds, optname, len))
72         return false;
73
74     /* it's --optname, check how the parameter is supplied */
75     if (argv[0][ds+len] == '=') {
76         *out = argv[0]+ds+len+1;
77         return true;
78     }
79
80     if (!split || argc < ds) /* no parameter was provided, or only single-arg form accepted */
81         return false;
82
83     /* using --opt param */
84     *out = argv[1];
85     --*cargc;
86     ++*cargv;
87
88     return true;
89 }
90
91 int main(int argc, char **argv) {
92     bool  dumpast  = false;
93     char *standard = NULL;
94
95     while (argc > 1) {
96         ++argv;
97         --argc;
98
99         if (argv[0][0] == '-') {
100             if (parse_option("std", &argc, &argv, &standard, 1, false))
101                 continue;
102         }
103
104         if (!strcmp(*argv, "--dump-ast")) {
105             dumpast = true;
106             continue;
107         }
108
109         fprintf(stderr, "unknown option: %s\n", argv[argc-1]);
110         return EXIT_FAILURE;
111     }
112
113     if (standard) {
114         if      (!strcmp(standard, "licec")) opt_std_set(STANDARD_LICEC);
115         else if (!strcmp(standard, "gnuc"))  opt_std_set(STANDARD_GNUC);
116         else if (!strcmp(standard, "c90"))   opt_std_set(STANDARD_C90);
117         else if (!strcmp(standard, "c99"))   opt_std_set(STANDARD_C99);
118         else if (!strcmp(standard, "c11"))   opt_std_set(STANDARD_C11);
119         else if (!strcmp(standard, "kandr")) opt_std_set(STANDARD_KANDR);
120         else {
121             fprintf(stderr, "unknown standard: %s\n", standard);
122             return EXIT_FAILURE;
123         }
124     }
125
126     return compile_begin(dumpast);
127 }