work on type inference some more
[ccc.git] / splc.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <getopt.h>
4
5 #include "ast.h"
6 #include "genc.h"
7 #include "parse.h"
8 #include "scan.h"
9 #include "sem.h"
10 extern int yylex_destroy(void);
11
12 void usage(FILE *out, char *arg0)
13 {
14 fprintf(out,
15 "Usage: %s [OPTS] [FILE]\n"
16 "\n"
17 "Compile an spl file. If FILE is not specified stdin is used.\n"
18 "\n"
19 "Options:\n"
20 "\t-p\tPretty print the parsed abstract syntax tree\n"
21 "\t-t\tPretty print the typed abstract syntax tree\n"
22 "\t-g LANG\tGenerate LANG code (default: C)\n"
23 "\t \tSupported languages: C\n"
24 "\t-o FILE\tOutput code to FILE (default: a.suf)\n"
25 "\t-h\tShow this help\n"
26 , arg0);
27 }
28
29 int main(int argc, char *argv[])
30 {
31 int opt, r;
32 bool pparse = false, ptype = false;
33 char *cfile = NULL;
34 enum {langc} lang = langc;
35 const char *suffix[] = { [langc] = "c" };
36 struct ast *result = NULL;
37 FILE *cout;
38
39 while ((opt = getopt(argc, argv, "g:ho:tp")) != -1) {
40 switch (opt) {
41 case 'g':
42 if (strcmp(optarg, "c") == 0
43 || strcmp(optarg, "C") == 0) {
44 lang = langc;
45 } else {
46 usage(stderr, argv[0]);
47 }
48 break;
49 case 'o':
50 cfile = safe_strdup(optarg);
51 break;
52 case 'p':
53 pparse = true;
54 break;
55 case 't':
56 ptype = true;
57 break;
58 case 'h':
59 usage(stdout, argv[0]);
60 return 0;
61 default:
62 usage(stderr, argv[0]);
63 return 1;
64 }
65 }
66 if (optind + 1 == argc && strcmp(argv[optind], "-") != 0)
67 if ((yyin = fopen(argv[optind], "r")) == NULL)
68 pdie("fopen");
69
70 //Parse
71 r = yyparse(&result);
72 if (yyin != stdin)
73 safe_fclose(yyin);
74 yylex_destroy();
75 if (r != 0)
76 return r;
77 if (pparse)
78 ast_print(result, stdout);
79
80 //Typecheck
81 if ((result = sem(result)) == NULL) {
82 return 1;
83 }
84 if (ptype)
85 ast_print(result, stdout);
86
87 //Generate code
88 if (cfile == NULL)
89 sprintf(cfile = safe_malloc(10), "a.%s", suffix[lang]);
90 cout = safe_fopen(cfile, "w+");
91 free(cfile);
92 switch(lang) {
93 case langc:
94 // genc(result, cout);
95 break;
96 default:
97 die("unsupported language\n");
98 }
99 safe_fclose(cout);
100 ast_free(result);
101 return r;
102 }