cvsuser     05/03/25 02:39:14

  Modified:    classes  pmc2c2.pl
  Log:
  perl #34564] [PATCH] Cleanup of pmc2c2.pl
  
  Attached is a patch to clean up pmc2c2.pl and (hopefully) make it more
  readable and a little easier to approach. No new features are added
  (yet).
  
  Courtesy of Matt Diephouse <[EMAIL PROTECTED]>
  
  Revision  Changes    Path
  1.27      +199 -203  parrot/classes/pmc2c2.pl
  
  Index: pmc2c2.pl
  ===================================================================
  RCS file: /cvs/public/parrot/classes/pmc2c2.pl,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- pmc2c2.pl 20 Mar 2005 12:47:01 -0000      1.26
  +++ pmc2c2.pl 25 Mar 2005 10:39:14 -0000      1.27
  @@ -1,6 +1,6 @@
   #! perl -w
   # Copyright: 2001-2005 The Perl Foundation.  All Rights Reserved.
  -# $Id: pmc2c2.pl,v 1.26 2005/03/20 12:47:01 bernhard Exp $
  +# $Id: pmc2c2.pl,v 1.27 2005/03/25 10:39:14 leo Exp $
   
   =head1 NAME
   
  @@ -237,6 +237,8 @@
   
   Leopold Toetsch.
   
  +Cleaned up by Matt Diephouse.
  +
   Many thanks to the author of F<pmc2c.pl>, many useful code pieces got
   reused.
   
  @@ -263,39 +265,42 @@
           return $path if -e $path;
       }
   
  -    die "can't find file '$file' in path '",
  -      ( join "', '", @$include ), "'"
  +    die "can't find file '$file' in path '", join("', '", @$include), "'"
           if $die_unless_found;
   
       undef;
   }
   
   sub dump_default {
  -    my $file = "$FindBin::Bin/../vtable.tbl";
  +    my $file    = "$FindBin::Bin/../vtable.tbl";
       my $default = parse_vtable($file);
  -    my $dump;
  -    ($dump = $file) =~ s/\.\w+$/\.dump/;
  +    my $dump    = $file;
  +    $dump =~ s/\.\w+$/\.dump/;
  +    
       print "Writing $dump\n" if $opt{verbose};
  -    open(VTD, ">$dump") or die "Can't write $dump";
  -    my %vt;
  -    $vt{flags} = {};
  -    $vt{pre} = '';
  -    $vt{post} = '';
  +    open VTD, ">", $dump or die "Can't write '$dump'";
  +    
  +    my %vtable = (
  +        flags   => {},
  +        pre     => '',
  +        post    => '',
  +    );
       my %meth_hash;
       my $i = 0;
       foreach my $entry (@$default) {
           $meth_hash{$entry->[1]} = $i++;
  -        push ( @{$vt{methods}},
  -        {
  -            parameters => $entry->[2],
  -            meth =>       $entry->[1],
  -            type =>       $entry->[0],
  -            section =>    $entry->[3],
  -            mmd =>        $entry->[4]
  -        });
  -    }
  -    $vt{'has_method'} = \%meth_hash;
  -    my $Dumper = Data::Dumper->new([\%vt], [qw(class)]);
  +        push @{$vtable{methods}},
  +            {
  +                parameters  => $entry->[2],
  +                meth        => $entry->[1],
  +                type        => $entry->[0],
  +                section     => $entry->[3],
  +                mmd         => $entry->[4]
  +            };
  +    }
  +    $vtable{'has_method'} = \%meth_hash;
  +    
  +    my $Dumper = Data::Dumper->new([\%vtable], ['class']);
       $Dumper->Indent(3);
       print VTD $Dumper->Dump();
       close VTD;
  @@ -303,16 +308,20 @@
   
   sub extract_balanced {
       my $balance = 0;
  -    my $lines = 0;
  +    my $lines   = 0;
  +    
       for(shift) {
           s/^(\s+)//;
           $lines += count_newlines($1);
           /^\{/ or die "bad block open: ".substr($_,0,10),"..."; # }
  -        while(/(\{)|(\})/g) {
  +        
  +        while(/ (\{) | (\}) /gx) {
               if($1) {
                   $balance++;
               } else { # $2
  -                --$balance or return (substr($_, 0, pos, ""),  $_, $lines);
  +                $balance--;
  +                return substr($_, 0, pos, ""), $_, $lines
  +                    if not $balance;
               }
           }
           die "Badly balanced" if $balance;
  @@ -324,130 +333,136 @@
   
       $$c =~ s/^(.*?^\s*)pmclass ([\w]*)//ms;
       my ($pre, $classname) = ($1, $2);
  -    my %has_value = ( does => 1, extends => 1, group => 1, lib => 1 );
  +    
  +    # flags that have values passed with them
  +    my %has_value = map { $_ => 1 } qw(does extends group lib);
   
       my (%flags, $parent_nr);
       # look through the pmc declaration header for flags such as noinit
  -    while ($$c =~ s/^(?:\s*)(\w+)//s) {
  -     if ($has_value{$1}) {
  -         my $what = $1;
  -         if (s/^(?:\s+)(\w+)//s) {
  -                if ($what eq 'extends') {
  -                    $flags{$what}{$1} = ++$parent_nr;
  -                } else {
  -                    $flags{$what}{$1} = 1;
  -                }
  -         }
  -         else {
  -             die "Parser error: no value for '$what'";
  -         }
  -     }
  -     else {
  -         $flags{$1} = 1;
  -     }
  +    while ($$c =~ s/^\s*(\w+)//s) {
  +        my $flag = $1;
  +        if ($has_value{$flag}) {
  +            $$c =~ s/^\s+(\w+)//s
  +                or die "Parser error: no value for '$flag'";
  +            
  +            $flags{$flag}{$1} =
  +                $flag eq 'extends' ? ++$parent_nr : 1;
  +        }
  +        else {
  +            $flags{$flag} = 1;
  +        }
       }
  +    
       # setup some defaults
       if ($classname ne 'default') {
  -     $flags{extends}{default} = 1 unless $flags{extends};
  -     $flags{does}{scalar} = 1 unless $flags{does};
  +        $flags{extends}{default} = 1 unless $flags{extends};
  +        $flags{does}{scalar}     = 1 unless $flags{does};
       }
  -    ($pre, $classname, \%flags);
  +    
  +    return $pre, $classname, \%flags;
   }
   
   sub parse_pmc {
  -  local $_ = shift;
  +    my $code = shift;
   
  -  my $signature_re = qr{
  +    my $signature_re = qr{
       ^
  -    (?:             #blank spaces and comments and spurious semicolons
  +    (?:                 #blank spaces and comments and spurious semicolons
         [;\n\s]*
  -      (?:/\*.*?\*/)?  # C-like comments
  +      (?:/\*.*?\*/)?    # C-like comments
       )*
   
  -    (METHOD\s+)?  #method flag
  -    (\w+\**)      #type
  -    \s+
  -    (\w+)         #method name
  -    \s*
  -    \(([^\(]*)\)  #parameters
  +    (METHOD\s+)?        #method flag
  +    
  +    (\w+\**)            #type
  +      \s+
  +        (\w+)           #method name
  +      \s*
  +        \( ([^\(]*) \)  #parameters
       }sx;
   
  -  my ($pre, $classname, $flags) = parse_flags(\$_);
  -  my $lineno = 1;
  -  $lineno += count_newlines($pre);
  -  my ($classblock, $post, $lines) = extract_balanced($_);
  -  $classblock = substr($classblock, 1,-1); # trim out the { }
  -
  -  my (@methods, %meth_hash, $class_init);
  -
  -  while ($classblock =~ s/($signature_re)//) {
  -     $lineno += count_newlines($1);
  -     my ($flag, $type, $methodname, $parameters) = ($2,$3,$4,$5);
  -     my ($methodblock, $rema, $lines) = extract_balanced($classblock);
  -     $lineno += $lines;
  -     $methodblock = "" if $opt{nobody};
  -     if ($methodname eq 'class_init') {
  -         $class_init =
  -       {   'meth' => $methodname,
  -              'body' => $methodblock,
  -              'line' => $lineno,
  -              'type' => $type,
  -              'parameters' => $parameters,
  -              'loc' => "vtable"
  -          };
  -      }
  -      else {
  -         # name => method idx mapping
  -         $meth_hash{$methodname} = scalar @methods;
  -         push @methods,
  -            { 'meth' => $methodname,
  -              'body' => $methodblock,
  -              'line' => $lineno,
  -              'type' => $type,
  -              'parameters' => $parameters,
  -              'loc' => $flag ? "nci" : "vtable"
  -          };
  -     }
  -     $classblock = $rema;
  -     $lineno += count_newlines($methodblock);
  +    my ($pre, $classname, $flags)     = parse_flags(\$code);
  +    my ($classblock, $post, $lines)   = extract_balanced($code);
  +  
  +    my $lineno  = 1 + count_newlines($pre);
  +    $classblock = substr($classblock, 1,-1); # trim out the { }
  +
  +    my (@methods, %meth_hash, $class_init);
  +
  +    while ($classblock =~ s/($signature_re)//) {
  +        $lineno += count_newlines($1);
  +        my ($flag, $type, $methodname, $parameters) = ($2,$3,$4,$5);
  +        my ($methodblock, $rema, $lines) = extract_balanced($classblock);
  +        $lineno += $lines;
  +        
  +        $methodblock = "" if $opt{nobody};
  +        if ($methodname eq 'class_init') {
  +            $class_init = {
  +                meth        => $methodname,
  +                body         => $methodblock,
  +                line        => $lineno,
  +                type        => $type,
  +                parameters  => $parameters,
  +                loc         => "vtable"
  +            };
  +        }
  +        else {
  +            # name => method idx mapping
  +            $meth_hash{$methodname} = scalar @methods;
  +            push @methods,
  +                {
  +                    meth        => $methodname,
  +                    body        => $methodblock,
  +                    line        => $lineno,
  +                    type        => $type,
  +                    parameters  => $parameters,
  +                    loc         => $flag ? "nci" : "vtable"
  +                };
  +        }
  +        $classblock = $rema;
  +        $lineno += count_newlines($methodblock);
       }
  +    
       if ($class_init) {
           $meth_hash{'class_init'} = scalar @methods;
           push @methods, $class_init;
       }
   
   
  -    return ( $classname, { 'pre'   => $pre,
  -                        'flags' => $flags,
  -                        'methods' => [EMAIL PROTECTED],
  -                        'post' => $post,
  -                        'class' => $classname,
  -                           'has_method' => \%meth_hash
  -                      }
  -           );
  +    return $classname,
  +           {
  +               pre          => $pre,
  +                flags        => $flags,
  +                methods      => [EMAIL PROTECTED],
  +                post         => $post,
  +                class        => $classname,
  +               has_method   => \%meth_hash
  +           };
   }
   
   # make a linear list of class->{parents} array
   sub gen_parent_list {
       my ($include, $this, $all) = @_;
   
  -    my @todo = ($this);
  +    my @todo  = ($this);
       my $class = $all->{$this};
  +    
       while (@todo) {
  -        my $n = shift @todo;
  +        my $n   = shift @todo;
           my $sub = $all->{$n};
           next if $n eq 'default';
  +        
           my %parent_hash = %{$sub->{flags}{extends}};
  -        foreach my $parent (sort {$parent_hash{$a} <=> $parent_hash{$b} }
  -                (keys (%parent_hash) ) ) {
  +        my @parents     = sort { $parent_hash{a} <=> $parent_hash{$b} } keys 
%parent_hash;
  +        for my $parent (@parents) {
               next if exists $class->{has_parent}{$parent};
  -            if (!$all->{$parent}) {
  -                my $pf = lc $parent;
  -                $all->{$parent} = read_dump($include, "$pf.pmc");
  -            }
  +            
  +            $all->{$parent} = read_dump($include, lc("$parent.pmc"))
  +                if not $all->{$parent};
  +            
               $class->{has_parent}{$parent} = { %{$all->{$parent}{has_method} 
}};
  -            push(@todo, $parent);
  -            push(@{ $class->{parents} }, $parent);
  +            push @todo, $parent;
  +            push @{ $class->{parents} }, $parent;
           }
       }
   }
  @@ -455,13 +470,12 @@
   
   sub dump_1_pmc {
       my $file = shift;
  -
       $file =~ s/\.\w+$/.pmc/;
  +    
       print "Reading $file\n" if $opt{verbose};
  -    open F, "<$file" or die "Can't read '$file'";
  -    local $/;
  -    my $contents = <F>;
  -    close F;
  +    open my $fh, "<", $file
  +        or die "Can't read '$file'";
  +    my $contents = do { local $/; <$fh> };
       return parse_pmc($contents);
   }
   
  @@ -500,7 +514,6 @@
   sub add_defaulted {
       my ($class, $vt) = @_;
   
  -    my $i = @{ $class->{methods} };
       foreach my $e ( @{$vt->{methods}} ) {
           my $meth = $e->{meth};
           $class->{super}{$meth} = 'default';
  @@ -508,133 +521,116 @@
   }
   
   sub dump_is_newer {
  -    my $file = shift;
  -
  -    my $pmc;
  -    ($pmc = $file) =~ s/\.\w+$/\.pmc/;
  -    my ($pmc_dt, $dump_dt);
  -    $pmc_dt = (stat($pmc))[9];
  -    $dump_dt = (stat($file))[9];
  +    my $pmc = my $file = shift;
  +    $pmc =~ s/\.\w+$/.pmc/;
  +    
  +    my $pmc_dt  = (stat $pmc)[9];
  +    my $dump_dt = (stat $file)[9];
  +    
       return $dump_dt > $pmc_dt;
   }
   
   sub dump_pmc {
  -    my $include = shift;
  -
  -    my @files = @_;
  -    my %all;
  +    my ($include, @files) = @_;
       # help these dumb 'shells' that are no shells
       @files = glob $files[0] if $files[0] eq '*.pmc';
  -    foreach my $file (@files) {
  -     my ($class, $res) = dump_1_pmc($file);
  +
  +    my %all;
  +    for my $file (@files) {
  +        my ($class, $res) = dump_1_pmc($file);
           $res->{file} = $file;
           $all{$class} = $res;
       }
   
  +    $all{default} = read_dump($include, "classes/default.pmc")
  +        if not $all{default};
  +    
       my $vt = read_dump($include, "vtable.pmc");
  -    if (!$all{default}) {
  -        $all{default} = read_dump($include, "classes/default.pmc");
  -    }
       add_defaulted($all{default}, $vt);
   
       foreach my $name (keys %all) {
  -        my $dump;
           my $file = $all{$name}->{file};
  -        ($dump = $file) =~ s/\.\w+$/\.dump/;
  -        gen_parent_list($include, $name, \%all);
  +        $file =~ s/\.\w+$/\.dump/;
  +        
  +        # XXX write default.dump only once
  +        my $existing = find_file($include, $file);
  +        next if $existing && -e $existing && dump_is_newer($existing);
  +        
           my $class = $all{$name};
  +        gen_parent_list($include, $name, \%all);
           gen_super_meths($class, $vt);
  -        # XXX write default.dump only once
  -        my $existing = find_file($include, $dump);
  -        next if ($existing && -e $existing && dump_is_newer($existing));
  -        my $Dumper = Data::Dumper->new([$class], [qw(class)]);
  +        
  +        my $Dumper = Data::Dumper->new([$class], ['class']);
           $Dumper->Indent(1);
  -        print "Writing $dump\n" if $opt{verbose};
  -        open PMD, ">$dump" or die "Can't write '$dump'";
  -        print PMD $Dumper->Dump;
  -        close PMD;
  +        
  +        print "Writing $file\n" if $opt{verbose};
  +        open my $fh, ">", $file or die "Can't write '$file'";
  +        print $fh $Dumper->Dump;
  +        close $fh;
       }
   }
   
   sub read_dump {
  -    my ( $include, $file ) = @_;
  -
  -    ( my $dump = $file) =~ s/\.\w+$/.dump/;
  -    $dump = find_file($include, $dump, 1);
  -    print "Reading $dump\n" if $opt{verbose};
  -
  -    open D, "<$dump" or die "Can't read '$dump'";
  -    local $/;
  -    my $contents = <D>;
  -    close D;
  +    my ($include, $file) = @_;
  +    
  +    $file =~ s/\.\w+$/.dump/;
  +    $file = find_file($include, $file, 1);
  +    
  +    print "Reading $file\n" if $opt{verbose};
  +    open my $fh, "<", $file or die "Can't read '$file'";
  +    
       my $class;
  -    # $class => { ... };
  -    eval $contents;
  +    eval do { local $/; <$fh> };
       die $@ if $@;
  +    
  +    close $fh;
       $class;
   }
   
   sub print_tree {
       my ($include,$depth, @files) = @_;
   
  -    foreach my $file (@files) {
  -     my $class = read_dump($include, $file);
  -     print "    " x $depth, $class->{class}, "\n";
  -     foreach my $parent (keys %{$class->{flags}{extends}}) {
  -         my $pmc = lc($parent) . '.pmc';
  -         print_tree($include, $depth + 1, $pmc);
  -     }
  +    for my $file (@files) {
  +        my $class = read_dump($include, $file);
  +        
  +        print "    " x $depth, $class->{class}, "\n";
  +        print_tree($include, $depth + 1, lc("$_.pmc"))
  +            for keys %{$class->{flags}{extends}};
       }
   }
   
   sub gen_c {
       my ($include, @files) = @_;
  -
  -    my $library = Parrot::Pmc2c::Library->new
  -      ( \%opt, read_dump($include, "vtable.pmc"),
  -        map { $_, read_dump($include, $_) }
  -            @files );
  -
  -    $library->write_all_files;
  +    my %pmcs = map { $_, read_dump($include, $_) } @files;
  +    
  +    Parrot::Pmc2c::Library
  +        ->new( \%opt, read_dump($include, "vtable.pmc"), %pmcs )
  +        ->write_all_files;
   }
   
   sub main {
  -    my ($default, $dump, $gen_c, $result, $tree, $debug, $verbose, $nobody, 
$nolines, @include, $library);
  -    $result = GetOptions(
  -     "vtable"        => \$default,
  -     "dump"          => \$dump,
  -     "c|gen-c"       => \$gen_c,
  -     "tree"          => \$tree,
  -     "no-body"       => \$nobody,
  -     "no-lines"      => \$nolines,
  -     "debug+"        => \$debug,
  -     "verbose+"      => \$verbose,
  +    my ($default, $dump, $gen_c, $tree, @include);
  +    # initialization to prevent warnings
  +    %opt = map { $_ => 0 } qw(nobody nolines debug verbose);
  +    
  +    my $result = GetOptions(
  +        "vtable"        => \$default,
  +        "dump"          => \$dump,
  +        "c|gen-c"       => \$gen_c,
  +        "tree"          => \$tree,
           "include=s"     => [EMAIL PROTECTED],
  -        "library=s"     => \$library,
  +        "no-body"       => \$opt{nobody},
  +        "no-lines"      => \$opt{nolines},
  +        "debug+"        => \$opt{debug},
  +        "verbose+"      => \$opt{verbose},
  +        "library=s"     => \$opt{library},
       );
  -    $opt{debug} = $debug || 0;
  -    $opt{verbose} = $verbose || 0;
  -    $opt{nobody} = $nobody || 0;
  -    $opt{nolines} = $nolines || 0;
  -    $opt{library} = $library;
       unshift @include, ".", "$FindBin::Bin/..", $FindBin::Bin;
   
  -    $default and do {
  -     dump_default();
  -     exit;
  -    };
  -    $dump and do {
  -     dump_pmc([EMAIL PROTECTED], @ARGV);
  -     exit;
  -    };
  -    $tree and do {
  -     print_tree([EMAIL PROTECTED], 0, @ARGV);
  -     exit;
  -    };
  -    $gen_c and do {
  -     gen_c([EMAIL PROTECTED], @ARGV);
  -     exit;
  -    };
  +    dump_default()                  and exit if $default;
  +    dump_pmc([EMAIL PROTECTED], @ARGV)      and exit if $dump;
  +    print_tree([EMAIL PROTECTED], 0, @ARGV) and exit if $tree;
  +    gen_c([EMAIL PROTECTED], @ARGV)         and exit if $gen_c;
   }
   
   # vim: expandtab shiftwidth=4:
  
  
  

Reply via email to