#!/usr/bin/perl

use Cwd;
use Config;
use FindBin;
use File::Copy;
use File::Basename;

if (!@ARGV) {
    die "Usage: $0 [ source[.p6] | -e oneliner ]\n";
}

my $ghc_version = ghc_version();
my $base = cwd();
if (!-e "src/Main.hs") {
    $base = "$FindBin::Bin/..";
    if (!-e "$base/src/Main.hs") {
	die "$0: This script must be invoked in the Pugs source tree directory."
    }
}

$ENV{PATH} .= $Config{path_sep} . $base;

my $out = 'a';
if (@ARGV and -e $ARGV[0]) {
    $out = basename($ARGV[0]);
    $out =~ s{\..*}{};
}
$out .= ($^O eq 'MSWin32') ? ".exe" : ".out";

unlink "dump.ast";

system("pugs", -C => @ARGV);
exit 1 unless -e "dump.ast";

copy ("$base/src/Main.hs" => "$base/src/MainCC.hs");

open FH, '>>', "$base/src/MainCC.hs";
open AST, "dump.ast" or die $!;
print FH "\nmainCC = runAST \$ ";
print FH <AST>;
close AST;
close FH;

unlink "dump.ast";

my @ghc_flags = (
    "-L$base", "-L$base/src", "-L$base/src/pcre",
    "-I$base", "-I$base/src", "-I$base/src/pcre",
    "-i$base", "-i$base/src", "-i$base/src/pcre",
    qw(-static -Wall -fno-warn-missing-signatures -fno-warn-name-shadowing),
);

if ($ghc_version ge '6.4') {
    push @ghc_flags, qw(-fno-warn-deprecations -fno-warn-orphans);
}

if ($Config{_exe} ne '.exe') {
    push @ghc_flags, "$base/src/pcre/pcre$Config{_o}";
}

system("ghc", "-v0", "-o", $out, "--make", "-main-is", "mainCC", @ghc_flags, "$base/src/MainCC.hs");
unlink "$base/src/MainCC.hs";
print "Generated output: $out\n";

sub ghc_version {
    my $ghcver = `ghc --version`;
    ($ghcver =~ /Glasgow.*\bversion\s*(\S+)/s) or die << '.';
*** Cannot find a runnable 'ghc' from path.
*** Please install GHC from http://haskell.org/ghc/.
.
    return $1;
}
