1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
|
# Leave the first line of this file blank!
# This is a Perl script; the following two lines allow us to avoid
# embedding the path of the perl interpreter in the script.
eval "exec perl -S $0 $*"
if $running_under_some_shell;
#---------------------------------------------------------------------------#
# Copyright (C) 1995 The University of Melbourne.
# This file may only be copied under the terms of the GNU General
# Public License - see the file COPYING in the Mercury distribution.
#---------------------------------------------------------------------------#
# This script converts .mod files to .c files.
sub println {
local ($line) = @_;
if ($line =~ /\n/) {
print "/* oops - line = $line */\n";
}
print "$line\n";
$line_count++;
}
sub printlines {
local ($lines) = @_;
foreach $line (split(/\n/,$lines)) {
do println($line);
}
}
$decl = $code = $init = $special_init = $gnudecl = $gnuinit = "";
$in_module = $in_code = 0;
$init_funcs = "";
$output_init = 0;
unshift(@ARGV, '-') if $#ARGV < $[;
FILE:
while ($ARGV = shift) {
if ($ARGV eq "-s") {
shift;
next FILE;
}
if ($ARGV =~ /^-s/) {
next FILE;
}
open(F, $ARGV) || die "mod2c: can't open input file `$ARGV': $!\n";
LINE:
while (<F>) {
$target = $ARGV;
$target =~ s/\.mod//;
$target =~ s/.*\///;
if ($output_init == 0) {
do println("/*");
do println("INIT mercury_sys_init_$target");
do println("ENDINIT");
do println("*/");
$output_init = 1;
}
if (/^BEGIN_MODULE\((\w+)\)/) {
$module = $1;
$in_module = 1;
next LINE;
}
if (/^BEGIN_CODE/) {
$in_code = 1;
next LINE;
}
if (/^END_MODULE/) {
do printlines($decl);
do println("");
do println("BEGIN_MODULE($module)");
do printlines($special_init);
do printlines($init);
do println("BEGIN_CODE");
do printlines($code);
do println("END_MODULE");
$init_funcs .= "\t$module();\n";
$decl = $code = $init = $special_init = "";
$in_module = $in_code = 0;
next LINE;
}
if (! $in_module) {
chop;
do println("$_");
next LINE;
}
if (! $in_code) {
$special_init .= $_;
next LINE;
}
$save = $_;
s/^[ \t]*//;
($label, $_) = split;
if ($label =~ /^[a-zA-Z0-9_]*:$/)
{
chop $label;
if ($label =~ /^default/ || $label =~ /^otherwise/) {
$code .= $save;
next LINE;
}
#
# A label is considered an entry point if
# - it starts with "do_" (eg. do_fail)
# - it matches <letters and underlines><underline><digits>
# but does NOT start with "aux"
# - it matches the same pattern followed by "_input"
#
# A label is considered a local entry point if
# - it matches <letters and underlines><underline><digits>_l
# but does NOT start with "aux"
#
if ($label =~ /^do_/ ||
($label =~ /^([a-zA-Z0-9_]+)_([0-9]+)$/ && ! ($label =~ /^aux/)) ||
($label =~ /^([a-zA-Z0-9_]+)_([0-9]+)_input$/ && ! ($label =~ /^aux/)))
{
$type = "entry";
}
else {
if ($label =~ /^([a-zA-Z0-9_]+)_([0-9]+)_l$/ && ! ($label =~ /^aux/))
{
$type = "local";
}
else
{
$type = "label";
}
}
$init .= "\tinit_$type($label);\n";
if ($type eq "entry") {
$decl .= "Define_extern_entry($label);\n";
} else {
$decl .= "Declare_$type($label);\n";
}
$code .= "Define_$type($label);\n";
} else {
$code .= $save;
}
}
}
do println("void mercury_sys_init_$target(void); /* suppress gcc warning */");
do println("void mercury_sys_init_$target(void) {");
do printlines($init_funcs);
do println("}");
|