#include "config.hh" #include "ast.hh" #include "range_checking.hh" #include "type_checking.hh" #include "codegen.hh" #include #include #include #if HAVE_LIBPOPT # include #endif #include "options.hh" #if HAVE_LIBPOPT static struct poptOption info_options[] = { { "version", '\0', POPT_ARG_NONE, &options::version, 0, "Print version of dprog.", 0 }, { "contact", '\0', POPT_ARG_NONE, &options::contact, 0, "Print contact information.", 0 }, { 0 } // sentinel }; static struct poptOption analysis_options[] = { { "strict-decl", 's', POPT_ARG_NONE, &options::strict_decl, 0, "Disable implicit symbol declarations.", 0 }, { "strict-upd-decl", '\0', POPT_ARG_NONE, &options::strict_upd_decl, 0, "Disable implicit symbol declarations of update matrices. " "(This is not done with the --strict-decl option, since usually " "it is not what you want)." , 0 }, { 0 } // sentinel }; static struct poptOption backend_options[] = { { "lang", 'l', POPT_ARG_STRING, &options::language, 0, "Set output language.", "language" }, { 0 } // sentinel }; static struct poptOption main_options[] = { { "verbose", 'v', POPT_ARG_NONE, &options::verbose, 0, "Toggle verbose output.", 0 }, { 0, '\0', POPT_ARG_INCLUDE_TABLE, &info_options, 0, "Information options", 0 }, { 0, '\0', POPT_ARG_INCLUDE_TABLE, &analysis_options, 0, "Analysis options", 0 }, { 0, '\0', POPT_ARG_INCLUDE_TABLE, &backend_options, 0, "Backend options", 0 }, POPT_AUTOHELP { 0 } // sentinel }; #endif // parser extern int yyparse(); ast::DProg *dprog = 0; int main (int argc, const char *argv[]) { #if (HAVE_LIBPOPT != 1) // at this point, no popt means no option parsing! const char *infile = (argc > 1) ? argv[1] : 0; const char *output_name = (argc > 2) ? argv[2] : 0; #else poptContext ctxt = poptGetContext(0, argc, argv, main_options, 0); poptSetOtherOptionHelp(ctxt, "[infile [output name]]"); int opt = poptGetNextOpt(ctxt); if (opt < -1) { std::cerr << poptBadOption(ctxt, POPT_BADOPTION_NOALIAS) << ':' << poptStrerror(opt) << std::endl; return 2; } if (options::version) { std::cout << PACKAGE_STRING << " [" << DATE << " (" << ARCH << ")]\n"; return 0; } if (options::contact) { std::cout << PACKAGE_STRING << "\n\n"; std::cout << "For questions or comments on dprog, contact:\n" << "\tThomas Mailund , \n" << "or\tPeter Mechlenborg \n" << "\n" << "For submitting bug-reports, please use " << '<' << PACKAGE_BUGREPORT << ">\n\n"; return 0; } const char *infile = poptGetArg(ctxt); const char *output_name = poptGetArg(ctxt); const char *extra = poptGetArg(ctxt); if (extra) { std::cerr << "WARNING: " << "Extra ignored options after input and output files." << std::endl; } #endif // HAVE_LIBPOPT // strict_upd_decl implies strict_decl if (options::strict_upd_decl) options::strict_decl = 1; if (!codegen::supported(options::language)) { std::cerr << "Backend language " << options::language << " not supported.\n"; std::cerr << "Supported languages are:\n"; std::vector::const_iterator i; for (i = codegen::supported().begin(); i != codegen::supported().end(); ++i) std::cerr << '\t' << *i << '\n'; std::cerr << std::endl; return 2; } if (infile) { FILE *f = freopen(infile, "r", stdin); if (f == NULL) { std::cerr << "Couldn't open input file `" << infile << "'\n"; return 2; } } try { if (options::verbose) std::cerr << "Parsing input file...\n"; yyparse(); if (!dprog) return 2; // parse error! if (options::verbose) std::cerr << "Analysing program...\n"; range_checking::check(dprog); type_checking::check(dprog); // FIXME: more analysis here if (options::verbose) std::cerr << "Emitting code...\n"; codegen::emit_code(options::language, dprog, output_name); if (options::verbose) std::cerr << "Done.\n"; } catch (ast::Exception *ex) { ex->print_error(std::cerr); delete ex; return 2; } return 0; }