cvsuser     01/09/19 18:49:55

  Modified:    .        assemble.pl
  Log:
  Added include processing to assemble.pl  the syntax is:
  include 'file.to.include'
  
  Revision  Changes    Path
  1.31      +57 -25    parrot/assemble.pl
  
  Index: assemble.pl
  ===================================================================
  RCS file: /home/perlcvs/parrot/assemble.pl,v
  retrieving revision 1.30
  retrieving revision 1.31
  diff -u -w -r1.30 -r1.31
  --- assemble.pl       2001/09/19 22:57:15     1.30
  +++ assemble.pl       2001/09/20 01:49:55     1.31
  @@ -7,6 +7,7 @@
   use strict;
   use Getopt::Long;
   use Parrot::Opcode;
  +use Symbol;
   
   my %options;
   GetOptions(\%options,('checksyntax',
  @@ -17,7 +18,7 @@
                      'listing=s'));
   
   if($options{'version'}) {
  -    print $0,'Version $Id: assemble.pl,v 1.30 2001/09/19 22:57:15 thgibbs Exp $ 
',"\n";
  +    print $0,'Version $Id: assemble.pl,v 1.31 2001/09/20 01:49:55 bdwheele Exp $ 
',"\n";
       exit;
   }
   
  @@ -70,37 +71,38 @@
   my $listing="PARROT ASSEMBLY LISTING - ".scalar(localtime)."\n\n";
   
   
  +# read source/include processing
  +my(@program);
  +foreach my $file (@ARGV) {
  +    push(@program,read_source($file));
  +}
   
   
  -# read source and assemble
  +# assemble
   my $pc=0; my $op_pc=0;
   my ($bytecode,%label,%fixup,%constants,@constants);
   my (%local_label, %local_fixup, $last_label);
   my $line=0;
   my %equate=('*'=>sub { return $pc },
            '__DATE__'=>'"'.scalar(localtime).'"',
  -         '__VERSION__'=>'" $Revision: 1.30 $ "',
  +         '__VERSION__'=>'" $Revision: 1.31 $ "',
            '__LINE__' => sub { return $line });
  -while(<>) {
  -    $line++;
  -    chomp;
  -    my $sline=$_;
  -    s/^\s*//;
  -    s/\s*$//;
  -    if(/^\#/ || $_ eq "") {
  +foreach my $l (@program) {
  +    my($file,$line,$pline,$sline)=@$l;
  +    if($pline=~m/^\#/ || $pline eq "") {
        if($options{'listing'}) {
            $listing.=sprintf("%4d %08x %-44s %s\n", $line, $op_pc, '',$sline);
        }
        next;
       }
       my($label,$code);
  -    if(m/^(\S+):\s*(.+)?/) {
  +    if($pline=~m/^(\S+):\s*(.+)?/) {
           ($label,$code)=($1,$2);
        if(defined($label) && $label ne "") {
            if($label=~m/^\$/) {
                # a local label
                if(exists($local_label{$label})) {
  -                 error("local label '$label' already defined in $last_label!");
  +                 error("local label '$label' already defined in 
$last_label!",$file,$line);
                }
                if(exists($local_fixup{$label})) {
                    # backpatch everything with this PC.
  @@ -115,7 +117,7 @@
            } else {
                # a global label
                if(exists($label{$label})) {
  -                 error("'$label' already defined!");
  +                 error("'$label' already defined!",$file,$line);
                }
                if(exists($fixup{$label})) {
                    # backpatch everything with this PC.
  @@ -132,7 +134,7 @@
                if(keys(%local_fixup)) {
                    # oops, some local labels are unresolved
                    error("These local labels were undefined in $last_label: ".
  -                       join(",",sort(keys(%local_fixup))));
  +                       join(",",sort(keys(%local_fixup))),$file,$line);
                }
                $label{$label}=$pc; # store it.
                $last_label=$label;
  @@ -140,11 +142,11 @@
        } 
       } else {
        # here's where we can catch assembler directives!
  -     if(m/^([_a-zA-Z]\w*)\s+equ\s+(.+)$/i) {
  +     if($pline=~m/^([_a-zA-Z]\w*)\s+equ\s+(.+)$/i) {
            my($name,$data)=($1,$2);
            $equate{$name}=$data;
        } else {
  -         $code=$_;
  +         $code=$pline;
        }
       }
       next if(!defined($code));
  @@ -235,17 +237,17 @@
           }
   
           if ($ambiguous) {
  -          error( "Ambiguous operator $old_op matches $opcode and $match_level_2\n" 
);
  +          error("Ambiguous operator $old_op matches $opcode and 
$match_level_2\n",$file,$line);
           }
       
        if ($found_op) {
  -         log_message("substituting $opcode for $old_op" . (scalar(@tests) ? (" ( 
tried " . join(', ', @tests) . ")") : ''));
  +         log_message("substituting $opcode for $old_op" . (scalar(@tests) ? (" ( 
tried " . join(', ', @tests) . ")") : ''),$file,$line);
        } else {
  -         error("No opcode $opcode ( tried " . join(', ', @tests) . ") in <$_>");
  +         error("No opcode $opcode ( tried " . join(', ', @tests) . ") in 
<$pline>",$file,$line);
        }
       }
       if (@args != $opcodes{$opcode}{ARGS}) {
  -      error("Wrong arg count--got ".scalar(@args)." needed 
".$opcodes{$opcode}{ARGS}." in <$_>" );
  +      error("Wrong arg count--got ".scalar(@args)." needed 
".$opcodes{$opcode}{ARGS}." in <$_>" ,$file,$line);
       }
       $bytecode .= pack $pack_type{'i'}, $opcodes{$opcode}{CODE};
       $op_pc=$pc;
  @@ -387,16 +389,20 @@
       close L;
   }
   
  +###############################
  +# Helper Subroutines
  +###############################
  +
   sub error {
  -    my($message)=@_;
  -    print STDERR "Error ($line): $message\n";
  +    my($message,$file,$Line)=@_;
  +    print STDERR "Error ($file:$line): $message\n";
       exit;
   }
   
   sub log_message {
  -    my($message)=@_;
  +    my($message,$file,$line)=@_;
       if($options{'verbose'}) {
  -     print STDERR "INFO ($line): $message\n";
  +     print STDERR "INFO ($file:$line): $message\n";
       }
   }
   
  @@ -413,3 +419,29 @@
       return "[".$constants{$s}."]";
   }
   
  +sub read_source {
  +    my($file,$ofile,$oline)=@_;
  +    my($line)=1;
  +    my(@lines);
  +    my($handle)=gensym;
  +    open($handle,$file) || error("Cannot open $file for input!",$ofile,$oline);
  +    while(<$handle>) {
  +     chomp;
  +     my($sline)=$_;
  +     s/^\s*//;
  +     s/\s*$//;
  +     push(@lines,[$file,$line,$_,$sline]);
  +     if(m/^INCLUDE\s+['"](.+)["']/i) {
  +         my $newfile=$1;
  +         # this is an include directive.
  +         $lines[-1][2]="";
  +         # include the file
  +         push(@lines,[$file,$line,'',"#<<<< Start of $newfile >>>>"]);
  +         push(@lines,read_source($newfile,$file,$line));
  +         push(@lines,[$file,$line,'',"#<<<< End of $newfile >>>>"]);
  +     }
  +     $line++;
  +    }
  +    close($handle);
  +    return @lines;
  +}
  
  
  

Reply via email to