#include "mcg.h" #include #include static const char* tracechars = NULL; FILE* outputfile = NULL; FILE* dominance_dot_file = NULL; FILE* cfg_dot_file = NULL; bool tracing(char k) { if (k == '!') return true; if (!tracechars) return false; return index(tracechars, k); } void tracef(char k, const char* fmt, ...) { va_list ap; if (tracing(k)) { va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); } } static bool find_procedures_cb(struct symbol* symbol, void* user) { if (symbol->proc) procedure_compile(symbol->proc); return false; } int main(int argc, char* const argv[]) { const char* inputfilename = NULL; const char* outputfilename = NULL; FILE* output; program_name = argv[0]; opterr = 1; for (;;) { int c = getopt(argc, argv, "-d:D:C:o:"); if (c == -1) break; switch (c) { case 'C': cfg_dot_file = fopen(optarg, "w"); if (!cfg_dot_file) fatal("couldn't open output file '%s': %s", optarg, strerror(errno)); fprintf(cfg_dot_file, "digraph {\n"); break; case 'D': dominance_dot_file = fopen(optarg, "w"); if (!dominance_dot_file) fatal("couldn't open output file '%s': %s", optarg, strerror(errno)); fprintf(dominance_dot_file, "digraph {\n"); break; case 'd': tracechars = optarg; break; case 'o': if (outputfilename) fatal("already specified an output file"); outputfilename = optarg; break; case 1: if (inputfilename) fatal("unexpected argument '%s'", optarg); inputfilename = optarg; } } symbol_init(); if (!EM_open((char*) inputfilename)) fatal("couldn't open input '%s': %s", inputfilename ? inputfilename : "", EM_error); if (outputfilename) { outputfile = fopen(outputfilename, "w"); if (!outputfile) fatal("couldn't open output '%s': %s", outputfilename, strerror(errno)); } else outputfile = stdout; fprintf(outputfile, ".sect .text\n.sect .rom\n.sect .data\n.sect .bss\n"); /* Reads in the EM, outputs the data sections, parses any code and * generates IR trees. */ parse_em(); /* For every procedure, go ahead and do the compilation proper. We do this * now so that we know that all the data has been read correctly and our * symbol table is complete (we may need to refer to it). */ symbol_walk(find_procedures_cb, NULL); if (outputfilename) fclose(outputfile); EM_close(); if (cfg_dot_file) { fprintf(cfg_dot_file, "}\n"); fclose(cfg_dot_file); } if (dominance_dot_file) { fprintf(dominance_dot_file, "}\n"); fclose(dominance_dot_file); } return 0; } /* vim: set sw=4 ts=4 expandtab : */