#!/usr/bin/env perl

# Note: make sure you edit build.pl.in not build.pl.

unshift @INC, '@srcdir@';
require 'PLinker.pm';
require 'Instructions.pm';
require 'TCOFF.pm';

package main;

use Data::Dumper;
use Fcntl ':mode';
use strict;

my $PREFIX = "@prefix@";
my $SRCDIR = "@srcdir@";

my %build = (
	'main.pl' => 'plinker.pl',
	'dump.pl' => 'tce-dump.pl'
);

my %included;
write_file ('store.pl', compile_store ());
foreach my $in (sort (keys (%build))) {
	my $out = $build{$in};
	# Clear dependencies.
	%included = ();
	# Process input to output.
	write_file ($out, include_file ($in));
	# Make output executable.
	chmod (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH, $out);
}

exit 0;

sub write_file ($$) {
	my ($fn, $data) = @_;
	my $fh;
	open ($fh, '>', $fn) || die $!;
	print $fh $data;
	close ($fh);
	print $fn, ": ", length ($data), " bytes\n";
}

sub compile_store {
	my $store = {};
	Transputer::Instructions::compile (
		$store, "$SRCDIR/../occ21/include/instruct.h"
	);
	Transputer::TCOFF::compile (
		$store, "$SRCDIR/../occ21/include/tcoff.h"
	);
	Transterpreter::Instructions::compile (
		$store, "$SRCDIR/../../runtime/libtvm/"
	);
	return Data::Dumper->new ([$store], ['STORE'])->Dump;
}

sub include_file ($) {
	my $file = shift;
	my $data = "";

	return $data if exists $included{$file};

	$included{$file}++;

	unless (-e $file) {
		$file = "$SRCDIR/$file";
	}

	my $fh;
	open ($fh, $file) || die $!;
	while (my $line = <$fh>) {
		if ($line =~ m/^\s*require '(.*?)'/) {
			my $required = $1;
			$data .= include_file ($required);
		} elsif ($line =~ /^\s*1\s*;\s*/) {
			# ignore
		} else {
			$data .= $line;
		}
	}
	close ($fh);

	return $data;
}
