#include "config.hh"
#include "ast.hh"
#include "range_checking.hh"
#include "type_checking.hh"
#include "codegen.hh"
#include <iostream>
#include <vector>
#include <string>
#if HAVE_LIBPOPT
# include <popt.h>
#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 <thomas@mailund.dk>, <mailund@birc.dk>\n"
<< "or\tPeter Mechlenborg <metch@daimi.au.dk>\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<std::string>::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;
}
syntax highlighted by Code2HTML, v. 0.9.1