1#! /usr/bin/perl 2# 3# Copyright 2014, General Dynamics C4 Systems 4# 5# This software may be distributed and modified according to the terms of 6# the GNU General Public License version 2. Note that NO WARRANTY is provided. 7# See "LICENSE_GPLv2.txt" for details. 8# 9# @TAG(GD_GPL) 10# 11 12$literate = 0; 13$literate = 1 if $ARGV[0] eq "-l"; 14 15$prefix = $literate ? "> " : ""; 16 17# read the entire input 18$/ = undef; 19$input = <STDIN>; 20 21# find the module name 22$input =~ /module\s+([A-Z][a-zA-Z0-9._]*)/m or die "no module"; 23$modname = $1; 24 25# find the lists of hs-boot imports and exports 26$input =~ /{-# BOOT-IMPORTS:((\s+#?[A-Z][a-zA-Z0-9._]+(\(.*?\))?(%[a-zA-Z]+)?)*) #-}/ 27 or die "no imports"; 28$imports = $1; 29 30$input =~ /{-# BOOT-EXPORTS:((\s+#?[a-zA-Z][a-zA-Z0-9_']+(\(.*?\))?)*) #-}/ 31 or die "no exports"; 32$exports = $1; 33 34# transform the import list to import statements 35$imports =~ s/\s+/\n${prefix}import /g; 36$imports =~ s/#/{-# SOURCE #-} /g; 37$imports =~ s/%/ as /g; 38 39# create the export list 40$explist = $exports; 41$explist =~ s/\s#\w+//g; 42$explist =~ s/(\w|\))\s/\1, /g; 43 44# print the module & import statements 45print "${prefix}-- this file is automatically generated, do not edit\n"; 46print "${prefix}module $modname($explist) where\n${prefix}import Prelude hiding(Word)\n$imports\n\n"; 47 48$exports =~ s/#//g; 49$exports =~ s/\(.*?\)//g; 50 51# find and print all the type definitions... 52while($exports =~ / ([A-Z][a-zA-Z0-9']*)/g) { 53 $name = $1; 54 55 if (not $literate and 56 $input =~ /^((type|newtype|data|class)\s+([A-Z][a-zA-Z0-9_' ]*=>\s+)?$name\W.*?)^\S/ms) 57 { 58 print "$1"; 59 } elsif ($literate and 60 $input =~ /^(> (type|newtype|data|class)\s+([A-Z][a-zA-Z0-9_' ]*=>\s+)?$name\W.*?)^> \S/ms) 61 { 62 print "$1"; 63 } 64} 65 66# ...and the type signatures 67while($exports =~ / ([a-z][a-zA-Z0-9']*)/g) { 68 $name = $1; 69 70 if (not $literate and $input =~ /^($name\s+::.*?)^\S/ms) { 71 print "$1"; 72 } elsif ($literate and $input =~ /^(> $name\s+::.*?)^> \S/ms) { 73 print "$1"; 74 } 75} 76 77