#include <getopt.h>
#include "ast.h"
-#include "gen.h"
+#include "genc.h"
#include "parse.h"
#include "scan.h"
#include "type.h"
"Options:\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);
}
int main(int argc, char *argv[])
{
- int opt;
+ 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, "hpt")) != -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':
pparse = true;
break;
if ((yyin = fopen(argv[optind], "r")) == NULL)
pdie("fopen");
- struct ast *result = NULL;
- int r = yyparse(&result);
- if (r != 0)
- return 1;
+ //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 = type(result)) == NULL) {
- r = 1;
- goto end;
+ return 1;
}
if (ptype)
ast_print(result, stdout);
- if (!gen(result)) {
- r = 1;
- 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:
+ r = genc(result, cout);
+ break;
+ default:
+ die("unsupported language\n");
}
+ safe_fclose(cout);
ast_free(result);
-end:
- if (yyin == stdin)
- if (fclose(yyin) == -1)
- perror("fclose");
return r;
}