work on type inference some more
[ccc.git] / splc.c
diff --git a/splc.c b/splc.c
index 8d7174c..6e5c5ab 100644 (file)
--- a/splc.c
+++ b/splc.c
@@ -3,8 +3,10 @@
 #include <getopt.h>
 
 #include "ast.h"
+#include "genc.h"
 #include "parse.h"
 #include "scan.h"
+#include "sem.h"
 extern int yylex_destroy(void);
 
 void usage(FILE *out, char *arg0)
@@ -15,30 +17,43 @@ void usage(FILE *out, char *arg0)
                "Compile an spl file. If FILE is not specified stdin is used.\n"
                "\n"
                "Options:\n"
-               "\t-p\tJust parse and pretty print\n"
-               "\t-t\tJust parse and typecheck\n"
-               "\t-c\tparse, typecheck and compile (default)\n"
+               "\t-p\tPretty print the parsed abstract syntax tree\n"
+               "\t-t\tPretty print the typed abstract syntax tree\n"
+               "\t-g LANG\tGenerate LANG code (default: C)\n"
+               "\t       \tSupported languages: C\n"
+               "\t-o FILE\tOutput code to FILE (default: a.suf)\n"
                "\t-h\tShow this help\n"
                , arg0);
 }
 
-enum mode {parse,type,compile};
-
 int main(int argc, char *argv[])
 {
-       int opt;
-       enum mode mode = compile;
+       int opt, r;
+       bool pparse = false, ptype = false;
+       char *cfile = NULL;
+       enum {langc} lang = langc;
+       const char *suffix[] = { [langc] = "c" };
+       struct ast *result = NULL;
+       FILE *cout;
 
-       while ((opt = getopt(argc, argv, "hptc")) != -1) {
+       while ((opt = getopt(argc, argv, "g:ho:tp")) != -1) {
                switch (opt) {
+               case 'g':
+                       if (strcmp(optarg, "c") == 0
+                                       || strcmp(optarg, "C") == 0) {
+                               lang = langc;
+                       } else {
+                               usage(stderr, argv[0]);
+                       }
+                       break;
+               case 'o':
+                       cfile = safe_strdup(optarg);
+                       break;
                case 'p':
-                       mode = parse;
+                       pparse = true;
                        break;
                case 't':
-                       mode = type;
-                       break;
-               case 'c':
-                       mode = compile;
+                       ptype = true;
                        break;
                case 'h':
                        usage(stdout, argv[0]);
@@ -52,19 +67,36 @@ int main(int argc, char *argv[])
                if ((yyin = fopen(argv[optind], "r")) == NULL)
                        pdie("fopen");
 
-       struct ast *result = NULL;
-        int r = yyparse(&result);
+       //Parse
+       r = yyparse(&result);
+       if (yyin != stdin)
+               safe_fclose(yyin);
+       yylex_destroy();
        if (r != 0)
+               return r;
+       if (pparse)
+               ast_print(result, stdout);
+
+       //Typecheck
+       if ((result  = sem(result)) == NULL) {
                return 1;
-       yylex_destroy();
-       if (mode == parse) {
+       }
+       if (ptype)
                ast_print(result, stdout);
-               goto end;
+
+       //Generate code
+       if (cfile == NULL)
+               sprintf(cfile = safe_malloc(10), "a.%s", suffix[lang]);
+       cout = safe_fopen(cfile, "w+");
+       free(cfile);
+       switch(lang) {
+       case langc:
+//             genc(result, cout);
+               break;
+       default:
+               die("unsupported language\n");
        }
-end:
+       safe_fclose(cout);
        ast_free(result);
-       if (yyin == stdin)
-               if (fclose(yyin) == -1)
-                       perror("fclose");
-       return 0;
+       return r;
 }