Skip to content
Fetching contributors…
Cannot retrieve contributors at this time
300 lines (272 sloc) 8.14 KB
#! winxed
// Winxed compiler driver.
$include_const 'iglobals.pasm';
$include_const 'libpaths.pasm';
$include_const 'except_types.pasm';
$load 'Getopt/Obj.pbc';
class WinxedDriverOptions : [ 'Getopt', 'Obj']
{
var name;
var options;
var opts;
function WinxedDriverOptions(argv)
{
var options = [
[ 'c', 'Compile to pir' ],
[ 'e=s', 'Evaluate' ],
[ 'o=s', 'Object name' ],
[ 'target=s', 'Set target type' ],
[ 'L=s', 'Add to parrot library search path' ],
[ 'I=s', 'Add to parrot include search path' ],
[ 'X=s', 'Add to parrot dynext search path' ],
[ 'debug', 'Set debug mode' ],
[ 'nowarn', 'No warnings' ],
[ 'noan', 'No code annotations' ],
[ 'help', 'Show this help' ],
[ 'version', 'Show version and exit' ]
];
self.options = options;
for (var o in options)
self.push_string(o[0]);
self.notOptStop(1);
self.name = argv.shift();
self.opts = self.get_options(argv);
}
function getbool(string option)
{
var value = self.opts[option];
return value != null;
}
function getstring(string option)
{
var value = self.opts[option];
string result = null;
if (value != null)
result = value;
return result;
}
function showhelp()
{
say('Usage: ', self.name, ' [options] [program] [args]');
say(' Available options:');
int l= 0;
int i;
var o;
for (o in self.options) {
i= length(o[0]) + 4;
if (i > l) l= i;
}
for (o in self.options) {
string s= o[0];
if (length(s) > 1 && substr(s, 1, 1) != '=')
s= '--' + s;
else
s= '-' + s;
i= l - length(s);
say(' ', s, ' ' * i, '-> ', o[1]);
}
}
}
function path_option(options, string opt, int path_type)
{
string value = options.getstring(opt);
if (value != null) {
var lpaths = getinterp()[IGLOBALS_LIB_PATHS];
var pathlib = lpaths[path_type];
pathlib.push(value);
}
}
function extname[anon](string filename, string ext)
{
// Strip a possible .winxed extension from filename,
// add ext, and return the result.
string newname;
int l = length(filename);
if (l > 7 && substr(filename, -7) == '.winxed')
newname = substr(filename, 0, l - 7) + ext;
else
newname = filename + ext;
return newname;
}
function getcompiler[anon]()
{
var compiler;
try
compiler = load_language('winxed');
catch () { }
if (compiler == null) {
if (__DEBUG__) {
load_bytecode("winxedst2.pbc");
compiler = compreg('winxed');
if (compiler == null)
die("winxed: Cannot load language or stage");
}
else
die("winxed: Cannot load language");
}
return compiler;
}
function process_args [anon] (argv)
{
var optionset = new WinxedDriverOptions(argv);
if (optionset.getbool('version')) {
var compiler = getcompiler();
say(compiler.version_string());
exit(0);
}
int help = optionset.getbool('help');
int compileonly = optionset.getbool('c');
string target = optionset.getstring('target');
string eval = optionset.getstring('e');
string objectname = optionset.getstring('o');
int debug = optionset.getbool('debug');
int nowarn = optionset.getbool('nowarn');
int noan = optionset.getbool('noan');
if (help) {
optionset.showhelp();
exit(0);
}
path_option(optionset, 'L', PARROT_LIB_PATH_LIBRARY);
path_option(optionset, 'I', PARROT_LIB_PATH_INCLUDE);
path_option(optionset, 'X', PARROT_LIB_PATH_DYNEXT);
var compileoptions = {
"debug": debug,
"noan": noan,
"nowarn": nowarn
};
if (compileonly) {
if (target != null)
die("options -c and --target can't be used together");
compileoptions["target"] = "pir";
}
else {
if (target == null)
target = '';
switch (target) {
case '':
case 'run':
break;
case 'pir':
case 'include':
compileonly = true;
compileoptions["target"] = target;
break;
default:
die("Invalid target '" + target + "'");
}
}
if (objectname != null && ! compileonly)
die('-o without -c or --target is not supported yet');
var compiler = getcompiler();
var code;
string outfilename = null;
try [handle_types(__WINXED_ERROR__)] {
if (eval == null) {
if (elements(argv) < 1) {
say("ERROR: No program specified");
optionset.showhelp();
exit(1);
}
string srcfilename = argv[0];
if (compileonly && objectname == null)
outfilename = extname(srcfilename, '.pir');
code = compiler.compile_from_file(srcfilename,
compileoptions:[named, flat]);
}
else {
var output;
var outfile;
if (compileonly) {
if (outfilename == null)
outfilename = objectname;
if (outfilename != null && outfilename != "-") {
outfile = open(outfilename, 'w');
output = outfile;
}
else
output = getstdout();
compileoptions['output'] = output;
}
string expr = 'function main[main](argv){' + eval + ';}';
code = compiler.compile(expr,
compileoptions:[named, flat]);
if (compileonly) {
if (outfile != null)
outfile.close();
exit(0);
}
else
argv.unshift('__EVAL__');
}
}
catch (e) {
var payload = e["payload"];
if (payload != null)
cry(payload.filename, ':', payload.line, ': ', payload.message);
else
cry(e["message"]);
exit(1);
}
if (compileonly) {
if (outfilename == null)
outfilename = objectname;
int create = outfilename != null && outfilename != "-";
var outfile = create ? open(outfilename, 'w') : getstdout();
outfile.print(code);
if (create)
outfile.close();
exit(0);
}
// Program start: look for a sub called 'main'.
// Use get_main if available, else use the old heuristic.
var sub;
try {
for (var load_sub in code.subs_by_tag("load"))
load_sub();
code.mark_initialized("load");
sub = code.main_sub();
}
catch () {
cry("Cannot find main sub");
}
return sub;
}
//**************************************************************
function __PARROT_ENTRY_WINXED_main [main] (argv)
{
var mainsub = process_args(argv);
__ASSERT__(mainsub != null);
int retval = 0;
try [handle_types_except(CONTROL_EXIT)] {
var retvalp = mainsub(argv);
if (retvalp != null)
retval = retvalp;
}
catch (e) {
fail(e);
}
exit(retval);
}
function fail [anon] (exception)
{
var stderr = getstderr();
string message = exception.message;
if (message == null || message == "")
message = "No exception handler and no message";
stderr.print(sprintf("%s\n", [ message ]));
string line_sep = "";
var bts = exception.backtrace_strings();
for (int i = elements(bts) - 1; i >= 0; --i) {
string bt = bts[i];
for (string line in split("\n", bt)) {
if (indexof(line, "__PARROT_ENTRY") >= 0)
continue;
stderr.print(sprintf("%s%s", [ line_sep, line ]));
line_sep = "\n";
}
line_sep = "\nthrown from\n";
}
int exit_code = exception.exit_code;
exit(exit_code != 0 ? exit_code : 1);
}
// End
Jump to Line
Something went wrong with that request. Please try again.