This patch makes pmc2c.pl emit #line directives to .c files so the
debugger can trace the code back to the editable source. However, I
also have a larger patch that supersedes this one, but it changes
behavior. I just wanted to get this out first in case the later one is
deemed a bad idea.

The later patch implements "PMC inheritance": any unimplemented vtable
op in a .pmc file is inherited from its superclass. The global, and
default, superclass is default.pmc. You can inherit from an existing
PMC by saying "extends PerlArray" (for example) in the flags section
(the place where you'd put "noinit" right now.) pmc2c.pl scans all the
..pmc files on the path to the root to determine the most specific
implementation for each method.

I really just implemented this so that I could muck with the vtable
without modifying perlint.pmc, perlnum.pmc, etc. every time I made a
change, and the existing '= default' is insufficient for that. I also
think that default.pmc probably ought to have an implementation like

  die("Unimplemented vtable method called.");

for almost everything.

If this sounds worthwhile, I'll clean up the code a bit and submit the
patch. In the meantime, here is the patch that just adds the #lines:

--- pmc2c.pl    Wed Jan  2 13:27:47 2002
+++ pmc2c.pl.lineno     Thu Dec 27 23:40:29 2001
@@ -9,14 +9,16 @@ use strict;
 
 sub extract_balanced {
     my $balance = 0;
+    my $lines = 0;
     for(shift) {
-        s/^\s+//;
+        s/^(\s+)//;
+        $lines += count_newlines($1);
         /^\{/ or die "bad block open: ".substr($_,0,10),"..."; # }
         while(/(\{)|(\})/g) {
             if($1) {
                 $balance++;
             } else { # $2
-                --$balance or return (substr($_, 0, pos, ""),  $_);
+                --$balance or return (substr($_, 0, pos, ""),  $_, $lines);
             }
         }
         die "Badly balanced" if $balance;
@@ -49,7 +51,7 @@ while (my $file = shift @ARGV) {
   my $contents = join('', @contents);
   close PMC;
       
-  my $coutput = filter($contents);     # run the filter
+  my $coutput = filter($contents, $file, $cfile);     # run the filter
 
   open (SOURCE, ">$cfile") || die "$0: Could not write file '$cfile'\n";
   print SOURCE $coutput;  
@@ -58,16 +60,26 @@ while (my $file = shift @ARGV) {
 
 my %flags;
 
+sub count_newlines {
+    return scalar(() = $_[0] =~ /\n/g);
+}
+
 sub filter {
-  my $contents = shift;
+  my ($contents, $pmcfile, $cfile) = @_;
+  my $lineno = 1;
     
   $contents =~ s/^([^{]*)pmclass ([\w]*)//s; 
   my ($pre, $classname) = ($1, $2); 
+  $lineno += count_newlines($1);
 
-  $flags{$1}++ while $contents =~ s/^\s*(\w+)//s;
+  while ($contents =~ s/^(\s*)(\w+)//s) {
+      $lineno += count_newlines($1);
+      $flags{$2}++;
+  }
 
-  my ($classblock, $post) = extract_balanced($contents,);
-  $classblock = substr($classblock, 2,-1); # trim out the { }
+  my ($classblock, $post, $lines) = extract_balanced($contents);
+  $lineno += $lines;
+  $classblock = substr($classblock, 1,-1); # trim out the { }
 
   my $signature_re = qr{
     ^
@@ -89,25 +101,30 @@ sub filter {
   my $OUT;
   my %default;
 
-  while ($classblock =~ s/$signature_re//) {
-     my ($type, $methodname, $parameters) = ($1,$2,$3);
+  while ($classblock =~ s/($signature_re)//) {
+     $lineno += count_newlines($1);
+     my ($type, $methodname, $parameters) = ($2,$3,$4);
 
      $parameters = ", $parameters" if $parameters =~ /\w/;
-     if ($classblock =~ s/^\s*= default;?\s*//s) {
+     if ($classblock =~ s/^(\s*= default;?\s*)//s) {
+        $lineno += count_newlines($1);
         $default{$methodname}++;
         push @methods, $methodname;
         next;
      }
      
-     my ($methodblock, $rema) = extract_balanced($classblock);
+     my ($methodblock, $rema, $lines) = extract_balanced($classblock);
+     $lineno += $lines;
   
      $methodblock =~ s/SELF/pmc/g;
      $methodblock =~ s/INTERP/interpreter/g;
     
      $OUT .= "$type Parrot_" . $classname. "_" . "$methodname (struct Parrot_Interp 
*interpreter, PMC* pmc$parameters)";      
+     $OUT .= "\n#line $lineno \"$pmcfile\"\n   ";
      $OUT .= $methodblock;
      $OUT .= "\n\n";
 
+     $lineno += count_newlines($methodblock);
      $classblock = $rema;
      push @methods, $methodname;
      };
@@ -123,13 +140,17 @@ sub filter {
   }
 
   $OUT = <<EOC . $OUT;
+ /* Do not edit - automatically generated from '$pmcfile' by $0 */
 $pre
 
 static STRING* whoami;
 
 EOC
 
+my $initline = 1+count_newlines($OUT)+1;
+
 $OUT .= <<EOC unless exists $flags{noinit};
+#line $initline "$cfile"
 
 void $initname (void) {
 

Reply via email to