simon       01/09/14 02:07:25

  Modified:    .        assemble.pl
  Log:
          * uses Getopt::Long for options.  -c is now --checksyntax.  I wasn't
  sure how to keep compatible (patches welcome!)
          * options include:
                  --help
                  --version
                  --verbose
                  --output=file
                  --listing=file
                  --checksyntax
          * produces verbose listing of what the assembler saw :)  Only one
  nitpick with it:  unknown symbols are given as 0xffffffff,
  unfortunately, this includes symbols which may be defined later in the
  file (i.e. forward jumps).
  
  Courtesy of: Brian Wheeler <[EMAIL PROTECTED]>
  
  Revision  Changes    Path
  1.16      +97 -10    parrot/assemble.pl
  
  Index: assemble.pl
  ===================================================================
  RCS file: /home/perlcvs/parrot/assemble.pl,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -w -r1.15 -r1.16
  --- assemble.pl       2001/09/14 08:46:03     1.15
  +++ assemble.pl       2001/09/14 09:07:24     1.16
  @@ -5,13 +5,43 @@
   # Brian Wheeler ([EMAIL PROTECTED])
   
   use strict;
  +use Getopt::Long;
   
  -my $opt_c;
  -if (@ARGV and $ARGV[0] eq "-c") {
  -    shift @ARGV;
  -    $opt_c = 1;
  +my %options;
  +GetOptions(\%options,('checksyntax',
  +                   'help',
  +                   'version',
  +                   'verbose',
  +                   'output=s',
  +                   'listing=s'));
  +
  +if($options{'version'}) {
  +    print $0,'Version $Id: assemble.pl,v 1.16 2001/09/14 09:07:24 simon Exp $ 
',"\n";
  +    exit;
  +}
  +
  +if($options{'help'}) {
  +    print "$0 - Parrot Assembler
  +Options:
  +   --checksyntax        Check assembler syntax only, no output
  +   --help               This text
  +   --listing            Dump assembly listing to file
  +   --output             File to dump bytecode into
  +   --verbose            Show what's going on
  +   --version            Show assembler version
  +";
  +    exit;
  +}
  +
  +if(exists($options{'output'}) && $options{'output'} eq "") {
  +    print STDERR "You must provide a file with --output flag!\n";
  +    exit;
   }
   
  +if(exists($options{'listing'}) && $options{'listing'} eq "") {
  +    print STDERR "You must provide a file with --listing flag!\n";
  +    exit;
  +}
   
   # define data types
   my(%pack_type)=('i'=>'l','n'=>'d');
  @@ -52,6 +82,9 @@
   }
   close OPCODES;
   
  +my $listing="PARROT ASSEMBLY LISTING - ".scalar(localtime)."\n\n";
  +
  +
   
   # read source and assemble
   my $pc=0; my $op_pc=0;
  @@ -60,9 +93,15 @@
   while(<>) {
       $line++;
       chomp;
  +    my $sline=$_;
       s/^\s*//;
       s/\s*$//;
  -    next if(/^\#/ || $_ eq "");
  +    if(/^\#/ || $_ eq "") {
  +     if($options{'listing'}) {
  +         $listing.=sprintf("%4d %08x %-44s %s\n", $line, $op_pc, '',$sline);
  +     }
  +     next;
  +    }
       if(m/^((\S+):)?\s*(.+)?/) {
           my($label,$code)=($2,$3);
           if(defined($label) && $label ne "") {
  @@ -119,6 +158,7 @@
            my($found_op)=0;
            foreach my $op (grep($_=~/^$opcode/,keys(%opcodes))) {
                if($op eq $test) {
  +                 log_message("substituting $op for $opcode");
                    $opcode=$op;
                    $found_op=1;
                    last;
  @@ -159,8 +199,17 @@
               }
               $bytecode .= pack $type, $args[$_];
           }
  +     if($options{'listing'}) {
  +         # add line to listing.
  +         my $odata;
  +         foreach (unpack('l*',substr($bytecode,$op_pc))) {
  +             $odata.=sprintf("%08x ",$_);
  +         }
  +         $listing.=sprintf("%4d %08x %-44s %s\n", $line, $op_pc, $odata,$sline);
  +     }
       }
   }
  +$listing.="\n" if($options{'listing'});
   
   my $output;
   
  @@ -170,7 +219,14 @@
   $output=pack($pack_type{i},0x13155a1);
   
   
  -# FIXUP
  +# FIXUP (also, dump listing symbols)
  +if($options{'listing'}) {
  +    $listing.="DEFINED SYMBOLS:\n";
  +    foreach (sort(keys(%label))) {
  +     $listing.=sprintf("\t%08x   %s\n",$label{$_},$_);
  +    }
  +}
  +
   if(keys(%fixup)) {
       print STDERR "SQUAWK!  These symbols were referenced but not
   defined:\n";
  @@ -181,7 +237,11 @@
           }
           print STDERR "\n";
       }
  -    exit;
  +    $listing.="\nUNDEFINED SYMBOLS:\n";
  +    foreach (sort(keys(%fixup))) {
  +     $listing.="\t$_\n";
  +    }
  +    exit;  # some day, unresolved symbols won't be an error!
   } else {
       # dump empty header
       $output.=pack($pack_type{i},0);
  @@ -193,7 +253,11 @@
       # Then spit out how many constants there are, so we can allocate
       $const .= pack($pack_type{i}, scalar @constants);
   
  +    if($options{'listing'}) {
  +     $listing.="\nSTRING CONSTANTS\n";
  +    }
       # Now emit each constant
  +    my $counter=0;
       for (@constants) {
           $const .= pack($pack_type{i},0) x 3; # Flags, encoding, type
           $const .= pack($pack_type{i},length($_)); # Strlen followed by that many 
bytes.
  @@ -202,6 +266,9 @@
           if($pad) {
               $const .= "\0" x ($sizeof{i}-(length($_) % $sizeof{i})); # Padding;
          }
  +     $listing.=sprintf("\t%04x %08x [[%s]]\n",$counter,length($_),$_) 
  +         if($options{'listing'});
  +     $counter++;
       }
   
       $output.=pack($pack_type{i},length($const));
  @@ -214,14 +281,34 @@
   ## BYTECODE
   $output.=$bytecode;
   
  -if(!$opt_c) {
  +if(!$options{'checksyntax'}) {
  +    if($options{'output'} ne "") {
  +     open O,">$options{'output'}" || die $!;
  +     print O $output;
  +     close O;
  +    } else {
       print $output;
   }
  +}
  +
  +
  +if($options{'listing'}) {
  +    open L,">$options{'listing'}" || die $!;
  +    print L $listing;
  +    close L;
  +}
   
   sub error {
       my($message)=@_;
       print STDERR "Error ($line): $message\n";
       exit;
  +}
  +
  +sub log_message {
  +    my($message)=@_;
  +    if($options{'verbose'}) {
  +     print STDERR "INFO ($line): $message\n";
  +    }
   }
   
   
  
  
  

Reply via email to