Index: KNOWN_ISSUES
===================================================================
RCS file: /cvs/public/parrot/KNOWN_ISSUES,v
retrieving revision 1.8
diff -u -r1.8 KNOWN_ISSUES
--- KNOWN_ISSUES	4 Feb 2003 10:24:45 -0000	1.8
+++ KNOWN_ISSUES	8 Aug 2003 16:09:11 -0000
@@ -42,7 +42,6 @@
 
 Utilities
 
-- assemble.pl rolls its own packfile packing
 - lib/Parrot/PackFile.pm does it's own packing & unpacking, which is
   not capable of reading the dir_format=1 PBC format. Non native floats
   are also not implemented.
Index: MANIFEST
===================================================================
RCS file: /cvs/public/parrot/MANIFEST,v
retrieving revision 1.394
diff -u -r1.394 MANIFEST
--- MANIFEST	8 Aug 2003 10:06:28 -0000	1.394
+++ MANIFEST	8 Aug 2003 16:09:12 -0000
@@ -13,7 +13,6 @@
 RESPONSIBLE_PARTIES                               [main]doc
 TODO                                              [main]doc
 VERSION                                           [main]doc
-assemble.pl                                       [devel]
 bit.ops                                           []
 build_nativecall.pl                               []
 byteorder.c                                       []
@@ -153,7 +152,6 @@
 debug.c                                           []
 debug.ops                                         []
 disassemble.c                                     []
-disassemble.pl                                    [devel]
 docs/debug.pod                                    [devel]doc
 docs/debugger.pod                                 [main]doc
 docs/dev/byteorder.dev                            [main]doc
Index: assemble.pl
===================================================================
RCS file: assemble.pl
diff -N assemble.pl
--- assemble.pl	27 Jul 2003 21:03:06 -0000	1.103
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,1175 +0,0 @@
-#!/usr/bin/perl -w
-
-=head1 Parrot Assembler
-
-The Parrot Assembler's job is to take .pasm (Parrot Assembly) files and assemble
-them into Parrot bytecode. Plenty of references for Parrot assembly syntax
-already exist, so we won't go into details there. The assembler does its job
-by reading a .pasm file, extracting numeric and string constants from it, and
-reassembling the bits into bytecode.
-
-The first pass goes through and expands constants, macros, and local labels.
-Syntax is described later on, in the 'Macro' section. The next pass goes through
-and collects the numeric and string constants along with the definition points
-and PCs of labels.
-
-If you would like to view the text after the macro expansion pass, use the C<-E>
-flag. This flag simply tells the assembler to quit after the C<Macro> class
-does it thing.
-
-The final pass replaces label occurrences with the appropriate PC offset and
-accumulates the (finally completely numeric) bytecode onto the output string.
-The XS portion takes the constants and bytecode, generates a header, tacks the
-constants and bytecode on, and finally prints out the string.
-
-=head2 Macro
-
-The Parrot assembler's macro layer has now been more-or-less defined, with one
-or two additions to come. The addition of the '.' preface will hopefully make
-things easier to parse, inasmuch as everything within an assembler file that
-needs to be expanded or processed by the macro engine will have a period ('.')
-prepended to it.
-
-The macro layer implements constants, macros, and local labels. Including files
-will be done later on, but this handles most of the basic needs we have for
-macros.
-
-To create a macro, the syntax is slightly different.
-
-  .macro swap (A,B,TEMP) # . marks the directive
-    set .TEMP,.A         # . marks the special variable.
-    set .A,.B
-    set .B,.TEMP
-  .endm                  # And . marks the end of the macro.
-
-Macros support labels that are local to a given macro expansion, and the syntax
-looks something like this:
-
-  .macro SpinForever (Count)
-    .local $LOOP: dec .COUNT # ".local $LOOP" defines a local label.
-                  branch .$LOOP # Jump to said label.
-  .endm
-
-Include this macro as many times as you like, and the branch statement should
-do the right thing every time. To use a global label, just as you usually do.
-
-Constants are new, and the syntax looks like:
-
-  .constant PerlHash 6 # Again, . marks the directive
-
-  new P0, .PerlHash # . marks the special variable for expansion.
-
-Several constants are predefined in the Macro class, but are not generated
-dynamically as they should be, at least not yet.
-
-  .constant Array 0
-  .constant PerlUndef 1
-  ...
-
-This should be generated from include/parrot/pmc.h, but my plans are to add a
-'.include' directive so we can '.include <constants.pmc>', and let pmc2c build
-the .pmc file at the same time as it builds pmc.h.
-
-When the Assembler class is separated out, tests can use the Assembler class to
-accept a simple array of instructions and generate bytecode directly from that.
-This should eliminate the intermediary .pasm file and speed things up.
-
-=head2 Keyed access
-
- We now support the following (tested) code:
-
-  new P0, .PerlHash    # (See the discussion of macros above)
-  set S0, "one"
-  set P0[S0],1
-  set I0,P0[S0]
-  print I0
-  print "\n"
-  end
-
-=head1 COPYRIGHT
-
-Copyright (C) 2001-2003 The Perl Foundation.  All Rights Reserved.
-
-=cut
-
-#
-# XXX Feel free to move this to an appropriate file when the necessary features
-# XXX have been added, and features -will- need to be added.
-#
-
-
-BEGIN {
-  package Syntax;
-
-  use strict;
-
-  use vars qw(@ISA @EXPORT_OK $str_re $label_re $reg_re $num_re
-              $bin_re $dec_re $hex_re $flt_re);
-  require Exporter;
-  @ISA = 'Exporter';
-  @EXPORT_OK = qw($str_re $label_re $reg_re $num_re
-                  $bin_re $dec_re $hex_re $flt_re);
-
-  $reg_re = qr([INPS]\d+);
-  $bin_re = qr([-+]?0[bB][01]+);
-  $dec_re = qr([-+]?\d+);
-  $hex_re = qr([-+]?0[xX][0-9a-fA-F]+);
-  $flt_re = qr{[-+]?\d+ (?:(?:\.\d+(?:[eE][-+]?\d+)?)
-                            | (?:[Ee][+-]?\d+))}x;
-  $str_re = qr{" (?: \\. | (?>[^\\"]+) )* " |
-               ' (?: \\. | (?>[^\\']+) )* '
-              }x;
-  $label_re = qr([a-zA-Z_][a-zA-Z0-9_]*);
-  $num_re   = qr([-+]?\d+(\.\d+([eE][-+]?\d+)?)?);
-
-  # until this gets broken out into a file Syntax.pm we need to cheat:
-  $INC{"Syntax.pm"} = $0;
-  # Otherwise use Syntax; will attempt to require 'Syntax.pm', which will fail
-}
-
-package Macro;
-
-use Syntax qw($label_re $num_re $str_re $reg_re);
-use FindBin;
-use lib "$FindBin::Bin/lib";
-use Parrot::PMC qw(%pmc_types);
-
-=head2 Macro class
-
-=over 4
-
-=item new
-
-Create a new Macro instance. Simply take the argument list and treat it as a
-list of files to concatenate and process. Files are taken in the order that
-they appear in the argument list.
-
-=cut
-
-sub new {
-  my $class = shift;
-  my $self = { cur_contents => '' };
-  #
-  # Read the files, strip leading and trailing whitespace, and put the lines
-  # into an array in $self->{cur_contents}.
-  #
-  for(@_) {
-    open FILE,"< $_" or
-      die "Couldn't open '$_' for reading: $!\n";
-    while(<FILE>) {
-      chomp;
-      s/(^\s+|\s+$)//g;
-      push @{$self->{cur_contents}},$_;
-    }
-    close FILE;
-  }
-
-  #
-  #
-  bless $self,$class;
-  @{$self->{constants}}{keys %pmc_types} = values %pmc_types;
-  $self;
-}
-
-=item _expand_macro
-
-Take a macro name and argument list, and expand the macro inline.
-Also, if the macro has embedded labels, expand these labels to local labels,
-and make certain that they're unique on a per-expansion basis. We do this with
-the C<$self->{macros}{$macro_name}{gensym}> value.
-
-=cut
-
-sub _expand_macro {
-  my ($self,$macro_name,$macro_args) = @_;
-  my %args;
-  my @temp = @{$self->{macros}{$macro_name}{contents}};
-
-  @[EMAIL PROTECTED]>{macros}{$macro_name}{arguments}}} = @$macro_args;
-  $self->{macros}{$macro_name}{gensym}++;
-
-  for(@temp) {
-    s{\.local\s+\$($label_re):}
-     {local__${macro_name}__${1}__$self->{macros}{$macro_name}{gensym}:}gxo;
-
-    s{\.\$($label_re)}
-     {local__${macro_name}__${1}__$self->{macros}{$macro_name}{gensym}}gxo;
-    s{\.($label_re)}
-     {exists $self->{constants}{$1} ? $self->{constants}{$1} : ".$1"}gexo;
-    s{\.($label_re)}
-     {exists $args{$1} ? $args{$1} : ".$1"}gexo;
-  }
-  @temp;
-}
-
-=item preprocess
-
-Preprocesses constants, macros, include statements, and eventually conditional
-compilation.
-
-  .constant name {register}
-  .constant name {signed_integer}
-  .constant name {signed_float}
-  .constant name {"string constant"}
-  .constant name {'string constant'}
-
-are removed from the array. Given the line:
-
-  '.constant HelloWorld "Hello, World!"'
-
-one can expand HelloWorld via:
-
-  'print .HelloWorld' # Note the period to indicate a thing to expand.
-
-Some predefined constants exist for your convenience, namely:
-
-  .Array
-  .PerlHash
-  .PerlArray
-
-and the other PMC types.
-(This should be generated from include/parrot/pmc.h, but isn't at the moment.)
-
-The contents of external files can be included by use of the C<.include>
-macro:
-
-  .include "{filename}"
-
-The contents of the included file are inserted at the point where the
-C<.include> macro occurs. This means that code like this:
-
-  print "Hello "
-  .include "foo.pasm"
-  end
-
-where F<foo.pasm> contains:
-
-  print "World \n"
-
-becomes:
-
-  print "Hello "
-  print "World \n"
-  end
-
-Attempting to include a non-existent file is a non-fatal error.
-
-  .macro name ({arguments?})
-  ...
-  .endm
-
-Optional arguments are simply identifiers separated by commas. These
-arguments are matched to instances inside the macro named '.foo'. A
-simple example follows:
-
-  .macro inc3 (A,BLAM)
-    inc .A # Mark the argument to expand with a '.'.
-    inc .A
-    inc .A
-    print .BLAM
-  .endm
-
-  .inc3(I0) # Expands to the obvious ('inc I0\n') x 3
-
-=cut
-
-sub preprocess {
-  my $self = shift;
-  my $line = 0;
-  my $in_macro;
-
-  my @[EMAIL PROTECTED]>{cur_contents}};
-  while(scalar(@todo)) {
-    $_=shift(@todo);
-    $line++;
-
-    #
-    # Macros aren't recursive, so shuffle them into $self->{macros}.
-    #
-    if($in_macro) {
-      if(/^\.endm/) {
-        $in_macro = undef;
-      }
-      else {
-        push @{$self->{macros}{$in_macro}{contents}},$_;
-      }
-      next;
-    }
-
-    if(/^\.constant \s+
-        ($label_re) \s+
-        ($reg_re)/xo) { # .constant {name} {register}
-      $self->{constants}{$1} = $2;
-    }
-    elsif(/^\.constant \s+
-        ($label_re) \s+
-        ($num_re)/xo) { # .constant {name} {number}
-      $self->{constants}{$1} = $2;
-    }
-    elsif(/^\.constant \s+
-          ($label_re)  \s+
-          ($str_re)/xo) { # .constant {name} {string}
-      $self->{constants}{$1} = $2;
-    }
-    elsif(/^\.include \s+
-           "([^"]+)"
-          /x) {                                # .include "{file}"
-      if(-e $1) {
-        open FOO,"< $1";
-        my @include;
-        while(<FOO>) {
-          chomp;
-          s/(^\s+|\s+$)//g;    # Need to strip leading & trailing whitespace
-          push(@include,$_);
-        }
-        unshift(@todo,@include);
-        close FOO;
-      }
-      else {
-        print STDERR "Couldn't open '$1' for inclusion at line $line: $!.\n";
-      }
-    }
-    elsif(/^\.macro    \s+
-           ($label_re) \s*
-           \(([^)]*)\)
-         /xo) {            # .{name} (...
-      if($in_macro) {
-        push @{$self->{contents}},$_;
-        print STDERR
-          "Macro '$1' defined within macro '$in_macro' at line $line.\n";
-      }
-      else {
-        $in_macro = $1;
-        my @arguments = split /,/,$2;
-        s/(^\s+|\s+$)//g for @arguments;
-        $self->{macros}{$in_macro}{arguments} = [EMAIL PROTECTED];
-      }
-    }
-#
-# XXX Need a definition of how a local label in global scope should work
-#
-#    elsif(/^\.local\s+\$(\w+)/) {
-#      s{^\.local\s+\$(\w+)}
-#       {"global.$1.$self->{global}{gensym}"}gex;
-#      push @{$self->{contents}},$_;
-#    }
-    elsif(/^\.endm/) {
-      $in_macro = undef;
-      push @{$self->{contents}},$_;
-      print STDERR "Macro termination outside macro at line $line.\n";
-    }
-#
-# XXX Need a definition of how a local label in global scope should work
-#
-#    elsif(/\.\$(\w+)/) {
-#      s{\.\$(\w+)}
-#       {global.$1.$self->{global}{gensym}}gx;
-#      push @{$self->{contents}},$_;
-#    }
-    elsif(/\.($label_re) \s*
-           \(([^)]*)\)/xo) {                    # .{name} (...
-      if(defined $self->{macros}{$1}) {
-        my $macro_name = $1;
-        my $arguments = $2;
-        $arguments =~ s{\.(\w+)}
-                       {defined $self->{constants}{$1} ?
-                          $self->{constants}{$1} : ".$1"}egx;
-        my @arguments = split /,/,$arguments;
-        s/(^\s+|\s+$)//g for @arguments;
-        push @{$self->{contents}},
-             $self->_expand_macro($macro_name,[EMAIL PROTECTED]);
-      }
-      else {
-        push @{$self->{contents}},$_;
-        print STDERR "Couldn't find macro '.$1' at line $line.\n";
-      }
-    }
-    elsif(/\.($label_re)/o) {                         # .{name}
-      if(defined $self->{constants}{$1}) {
-        push @{$self->{contents}},$_;
-        $self->{contents}[-1] =~ s/\.($label_re)/$self->{constants}{$1}/g;
-      }
-      else {
-        push @{$self->{contents}},$_;
-        #
-        # XXX If this should be reenabled, how do we best determine what
-        # XXX a valid constant is?
-        #
-#        print STDERR "Couldn't find constant '.$1' at line $line\n";
-      }
-    }
-    else {
-      push @{$self->{contents}},$_;
-    }
-  }
-}
-
-=item contents
-
-Access the C<$self->{contents}> internal array, where the post-processed data
-is stored.
-
-=back
-
-=cut
-
-sub contents {
-  my $self = shift;
-  return $self->{contents};
-}
-
-1;
-
-package Assembler;
-
-use Syntax qw($str_re $label_re $reg_re $bin_re $dec_re $hex_re $flt_re);
-
-use POSIX; # Needed for strtol()
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-use Parrot::Types; # For pack_op()
-use Parrot::OpLib::core;
-use Parrot::Config;
-use Digest::Perl::MD5 qw(md5_hex);
-
-=head2 Assembler class
-
-=over 4
-
-=item new
-
-Create a new Assembler instance.
-
-  To compile a list of files:
-    $compiler = Assembler->new(-files=>[qw(foo.pasm bar.pasm)]);
-
-  To compile an array of instructions:
-    $compiler = Assembler->new(-contents=>['set S0,"foo"','print S0','end']);
-
-=cut
-
-sub new {
-  my $class = shift;
-  my %args = @_;
-  my $self = {
-    contents          => [ ],
-    num_constants     => 0,
-    ordered_constants => [ ],
-    bytecode          => '',
-  };
-  if(exists $args{-files}) {
-    $self->{files} = $args{-files};
-  }
-  elsif(exists $args{-contents}) {
-    for(@{$args{-contents}}) {
-      _annotate_contents($self,$_);
-    }
-  }
-  bless _init($self),$class;
-}
-
-=item _annotate_contents
-
-Process the array C<$self->{contents}>, and make the appropriate annotations
-in the array. For instance, it slightly munges global and local labels to make
-sure the statements fall where they should. Also, annotates the array into an
-AoA of [$statement,$lineno]. A later pass changes $lineno to $pc, once the
-arguments have been appropriately analyzed.
-
-=cut
-
-sub _annotate_contents {
-  my ($self,$line) = @_;
-
-  $self->{pc}++;
-  return if $line=~/^\s*$/ or $line=~/^\s*#/; # Filter out the comments and blank lines
-  $line=~s/^\s+//;           # Remove leading whitespace
-  # Doing it this way chews infinite CPU on 5.005_03. I suspect 5.6.1
-  # introduces some cunning optimisation in the regexp engine to avoid
-  # backtracking through the brackets with the multiple levels of *s
-  #
-  # $line=~s/^((?:[^'"]+|$str_re)*)#.*$/$1/; # Remove trailing comments
-  #
-  # This is 5.005_03 friendly:
-  if ($line=~ /^(?:[^'"]+|$str_re)#/g) {
-    # pos will point to the character after the #
-    substr ($line, (pos $line) - 1) = '';
-  }
-  $line=~s/\s+\z//;           # Remove trailing whitespace
-  #
-  # Accumulate lines that only have labels until an instruction is found.
-  # XXX This could fail if a label occurs at the end of a file.
-  #
-  if(@{$self->{contents}} and
-     $self->{contents}[-1][0] =~ /:$/) {
-    $self->{contents}[-1][0] .= $line;
-  }
-  else {
-    push @{$self->{contents}},[$line,$self->{pc}];
-  }
-}
-
-=item _init
-
-Process files of assembly code, should they have been passed in. Also,
-regardless of the input to C<new()>, take the arrays of operators and load
-them into a form appropriate to parsing.
-
-=cut
-
-sub _init {
-  my $self = shift;
-
-  for(@$Parrot::OpLib::core::ops) {
-    my $argtype = join '_',@{$_->{ARGS}}[1..$#{$_->{ARGS}}];
-    $self->{fullops}->{$_->{NAME}.($argtype &&"_$argtype") } = $_->{CODE};
-  }
-
-  if(defined $self->{files}) {
-    for my $file (@{$self->{files}}) {
-      open FILE,"< $file" or
-        die "Couldn't read from '$file': $!";
-      while(<FILE>) {
-        _annotate_contents($self,$_);
-      }
-      close FILE;
-    }
-  }
-  $self;
-}
-
-=item _collect_labels
-
-Collect labels, remove their definition, and save the appropriate line numbers.
-Local labels aren't given special treatment yet.
-
-=cut
-
-sub _collect_labels {
-  my $self = shift;
-
-  #
-  # Collect label definition points first
-  #
-  for(@{$self->{contents}}) {
-    while($_->[0] =~ s/^(\$?$label_re)\s*:\s*,?//o) {
-      my $label = $1;
-      if($label=~/^\$/) {
-        push @{$self->{local_labels}{$1}},$_->[1]; # Local label
-      }
-      else {
-        die("Label $1 already exists") if($self->{global_labels}{$1});
-        $self->{global_labels}{$1} = $_->[1]; # Global label
-      }
-    }
-  }
-}
-
-=item _generate_bytecode
-
-Start out by walking the C<$self->{contents}> array. On the first pass, make
-sure that the operation requested exists. If it doesn't, yell on STDERR.
-If it does, replace the text version of the operator with its numeric index,
-and pack it into C<$self->{bytecode}>.
-
-The inner loop walks through the arguments nested within the C<$op> arrayref,
-determining what type the argument is (C<$_->[0]>), and packing in the
-appropriate code. Note that labels are precalculated, and constants have been
-packed into the appropriate areas.
-
-=cut
-
-sub _generate_bytecode {
-  my $self = shift;
-
-  for my $op (@{$self->{contents}}) {
-    if(defined $self->{fullops}{$op->[0][0]}) {
-      $op->[0][0] = $self->{fullops}{$op->[0][0]};
-
-      $self->{bytecode} .= pack_op($op->[0][0]);
-
-      for(@{$op->[0]}) {
-        next unless ref($_) eq 'ARRAY'; # XXX Probably should loop smarter than this
-        if ($_->[0] =~ /^[ispn]$/) {      # Register
-          $_->[1] =~ /(\d+)/;
-          $self->{bytecode} .= pack_op($1);
-        }
-        elsif ($_->[0] =~ /^([snpk])c$/) { # String/Num/PMC/Key constant
-          $self->{bytecode} .= pack_op($_->[1]);
-        }
-        elsif ($_->[0] eq "ic") {          # Integer constant
-          $self->{bytecode} .= pack_op($_->[1]);
-        }
-        #
-        # Not sure if this is actually used...
-        #
-        elsif ($_->[0] eq "r") {
-          my %r_types = ("I" => 0, "N"=>1, "S"=>2, "P"=>3);
-          $_->[1]=~/([PSNI])(\d+)/i;
-          $self->{bytecode} .= pack_op($r_types{uc $1} >> 6 + $2);
-        }
-      }
-    }
-    else {
-      print STDERR "Couldn't find operator '$op->[0][0]' on line $op->[1].\n";
-    }
-  }
-}
-
-=item adjust_labels
-
-This works primarily on C<$self->{global_labels}>, computing offsets and getting
-things ready for the final shift. Since the values of C<$self->{global_labels}>
-correspond to line numbers, we replace the line numbers with program counter
-indices.
-
-The next pass walks the C<$self->{contents}> array, replacing the label names
-with the difference between the current PC and the label PC. Label names are
-preserved in the previous pass, which makes this possible.
-
-=cut
-
-sub _adjust_labels {
-  my $self = shift;
-
-  for(keys %{$self->{global_labels}}) { # XXX This probably can be moved
-    $self->{global_labels}{$_} =        # XXX elsewhere.
-      $self->{line_to_pc}{$self->{global_labels}{$_}};
-  }
-
-  for my $line (@{$self->{contents}}) {
-    my $cur_pc = $self->{line_to_pc}{$line->[1]};
-    for(@{$line->[0]}) {
-      next unless ref($_) eq 'ARRAY'; # XXX Probably should loop smarter than this
-      next unless $_->[0] eq 'label';
-      $_->[0] = 'ic'; # Now is an integer constant.
-      $_->[1] = $self->{global_labels}{$_->[1]} - $cur_pc;
-    }
-  }
-}
-
-=item _string_constant
-
-Unescape special characters in the constant and add them to not one but two
-data structures. C<$self->{constants}{s}> is for fast lookup when time comes
-to substitute constants for their indices, and C<$self->{ordered_constants}>
-keeps track of constants in order of occurrence, so they can be packed
-directly into the binary format.
-
-=cut
-
-sub _string_constant {
-  my ($self,$constant) = @_;
-  local $_=substr($constant,0,1);
-  $constant =~ s/\$/\\\$/g;
-  $constant = $_ . eval("qq$constant") . $_;
-  warn "Constant: $@ " if $@;
-
-  my $value = substr($constant,1,length($constant)-2);
-  unless(defined $self->{constants}{s}{$value}) {
-    $self->{constants}{s}{$value} = $self->{num_constants}++;
-    push @{$self->{ordered_constants}},['S',$value];
-  }
-  return ['sc',$self->{constants}{s}{$value}];
-}
-
-=item _numeric_constant
-
-Take the numeric constant and place it into both C<$self->{constants}{n}> and
-C<$self->{ordered_constants}>. The first hash lets us do fast lookup when time
-comes to replace a constant with its value. The second array maintains the
-various constants in order of first occurrence, and is ready to pack into
-the bytecode.
-
-=cut
-
-sub _numeric_constant {
-  my ($self,$constant) = @_;
-
-  unless(defined $self->{constants}{n}{$constant}) {
-    $self->{constants}{n}{$constant} = $self->{num_constants}++;
-    push @{$self->{ordered_constants}},['N',$constant];
-  }
-  return ['nc',$self->{constants}{n}{$constant}];
-}
-
-=item _key_constant
-
-Build a key constant and place it into both C<$self->{constants}{n}> and
-C<$self->{ordered_constants}>. The first hash lets us do fast lookup when time
-comes to replace a constant with its value. The second array maintains the
-various constants in order of first occurrence, and is ready to pack into
-the bytecode.
-
-=cut
-
-sub _key_constant {
-  my ($self,$constant) = @_;
-
-  $constant .= ";";
-
-  my @keys;
-
-  while ($constant)
-  {
-    if ($constant =~ s/^($bin_re);//) {
-      my $val = $1; $val =~ s/0b//;
-      push(@keys, 1, (strtol($val,2))[0]);
-    }
-    elsif ($constant =~ s/^($hex_re);//) {
-      my $val = $1; $val =~ s/0x//;
-      push(@keys, 1, (strtol($val,16))[0]);
-    }
-    elsif ($constant =~ s/^($dec_re);//) {
-      push(@keys, 1, 0+$1);
-    }
-    elsif ($constant =~ s/^($flt_re);//) {
-      push(@keys, 2, $self->_numeric_constant($1)->[1]);
-    }
-    elsif ($constant =~ s/^($str_re);//) {
-      push(@keys, 4, $self->_string_constant($1)->[1]);
-    }
-    elsif ($constant =~ s/^($reg_re);//) {
-      my $type = lc(substr($1,0,1));
-      $type =~ tr/inps/0123/;
-      push(@keys, 7 + $type, substr($1,1));
-    }
-    else {
-      print STDERR "Couldn't parse key '$constant'.\n";
-      last;
-    }
-  }
-
-  $constant = join(";", @keys);
-
-  unless(defined $self->{constants}{k}{$constant}) {
-    $self->{constants}{k}{$constant} = $self->{num_constants}++;
-    push @{$self->{ordered_constants}},['K',$constant];
-  }
-  return ['kc',$self->{constants}{k}{$constant}];
-}
-
-=item constant_table
-
-Constant table returns a hash with the length in bytes of the constant table
-and the constant table packed.
-
-=cut
-
-sub constant_table {
-    my $self = shift;
-    
-    # XXX Some perls < 5.8.0 recognize the 'D' pack format, but it's
-    # a regular double, not a long double.  This is a problem.  
-    # Of course, the packfile format currently only supports 8 and 12 byte
-    # floats anyway.  This hack prevents the creation of size
-    # mismatches and invalid types.  Once packfile generation et al are
-    # really fixed, this can go away, which is why it's here, and not 
-    # elsewhere.
-    my $numpackformat = $PConfig{packtype_n};
-    my $numpacksize   = $PConfig{numvalsize};
-    if ($numpackformat eq "D" and (
-           not (defined $^V and $^V ge v5.8.0) or
-           ($numpacksize != 8 or $numpacksize != 12))) 
-    {
-        $numpackformat = 'd';
-        $numpacksize   = length pack 'd', 1;        
-    } 
-        
-    
-    # $constl = the length in bytes of the constant table
-    my ($constl, $wordsize);
-    my $const = "";
-
-    $constl = $wordsize = $PConfig{'opcode_t_size'};
-    my $packtype = $PConfig{'packtype_op'};
-
-    for(@{$self->{constants}}) {
-        # if it's a string constant.
-        if ($_->[0] eq 'S') {
-            # Length of the string in bytes.
-            my $slen = length($_->[1]);
-            # The number of bytes to fill in the last opcode_t holding the string constant.
-            my $fill = ($slen % $wordsize) ? $wordsize - $slen % $wordsize : 0;
-            # Length of the whole constant.
-            $constl += 6 * $wordsize + $slen + $fill;
-            # Constant type, S
-            $const .= pack($packtype,0x73);
-            # The size of the Parrot string.
-            $const .= pack($packtype, 3 * $wordsize + $slen + $fill + $wordsize);
-            # Flags
-            $const .= pack($packtype,0x0);
-            # Encoding
-            $const .= pack($packtype,0x0);
-            # Type
-            $const .= pack($packtype,0x0);
-            # Length of string alone in bytes
-            $const .= pack($packtype,$slen);
-            # The string it self.
-            $const .= $_->[1] . "\0" x $fill;
-        }
-        # if it's a float constant.
-        elsif ($_->[0] eq 'N') {
-            # The size of the whole constant.
-            $constl += 2 * $wordsize + $numpacksize;
-            # Constant type, N
-            $const .= pack($packtype,0x6e);
-            # Sizeof the Parrot floatval.
-            $const .= pack($packtype,$numpacksize);
-            # The number if self.
-            $const .= pack($numpackformat,$_->[1]);
-        }
-        # if it's a key constant.
-        elsif ($_->[0] eq 'K') {
-            my @values = split(/;/, $_->[1]);
-            my $values = @values;
-            # The size of the whole constant;
-            $constl += 3 * $wordsize + $values * $wordsize;
-            # Constant type, K
-            $const .= pack($packtype,0x6b);
-            # Size of the packed key.
-            $const .= pack($packtype,$wordsize + $values * $wordsize);
-            # Number of key components
-            $const .= pack($packtype,$values / 2);
-            # The key atoms themselves as type and value pairs.
-            for(@values) {
-                $const .= pack($packtype,$_);
-            }
-        }
-    }
-
-    return ('table' => $const,
-            'length' => $constl,
-            'floattype' => ($numpacksize == 12) ? 0x01 : 0x00);
-}
-
-=item output_bytecode
-
-Returns a string with the Packfile.
-
-First process the constants and generate the constant table to be able to make
-the packfile header, then return all.
-
-=cut
-
-sub _fingerprint {
-  my $fingerprint = md5_hex join "\n", map {
-    join '_', $_->{NAME}, @{$_->{ARGS}}
-  } @$Parrot::OpLib::core::ops;
-  my @arr = ();
-  for my $i (0..9) {
-    push @arr, hex substr ($fingerprint, $i*2, 2);
-  }
-  return @arr;
-}
-
-sub output_bytecode {
-    my $self = shift;
-    my $wordsize;
-
-    $wordsize = $PConfig{'opcode_t_size'};
-    my $packtype = $PConfig{'packtype_op'};
-
-    my %const_table = constant_table($self);
-
-    my $byteorder = (substr($PConfig{'byteorder'},0,1) == 1) ? 0 : 1;
-    my $major = $PConfig{MAJOR};
-    # during devel, we check PATCH too
-    my $minor = $PConfig{MINOR} | $PConfig{PATCH};
-
-      
-    my $packfile_header = {
-        wordsize    => $wordsize, # unsigned char wordsize
-        byteorder   => $byteorder, # unsigned char byteorder
-        major       => $major, # unsigned char major
-        minor       => $minor, # unsigned char minor
-
-        flags       => 0x00, # unsigned char flags
-        floattype   => $const_table{'floattype'}, # unsigned char floattype
-        pad         => [ _fingerprint ],
-
-        magic       => 0x0131_55a1, # opcode_t magic
-        opcodetype  => 0x5045_524c, # opcode_t opcodetype
-        fixup_ss    => 0x0000_0000, # opcode_t fixup_ss
-        const_ss    => $const_table{'length'}, # opcode_t const_ss
-        bytecode_ss => $self->{num_constants}, # opcode_t bytecode_ss
-    };
-
-    my $packfile_string = "CCCCCC".("C"x10).$packtype x5;
-
-    return pack($packfile_string,
-        $packfile_header->{wordsize},    # C
-        $packfile_header->{byteorder},   # C
-        $packfile_header->{major},       # C
-        $packfile_header->{minor},       # C
-        $packfile_header->{flags},       # C
-        $packfile_header->{floattype},   # C
-        @{$packfile_header->{pad}},      # "C" x 10
-        $packfile_header->{magic},
-        $packfile_header->{opcodetype},
-        $packfile_header->{fixup_ss},
-        $packfile_header->{const_ss},
-        $packfile_header->{bytecode_ss}) .
-        $const_table{'table'} .
-        pack ($packtype,length($self->{bytecode})) .
-        $self->{bytecode};
-}
-
-=item to_bytecode
-
-Take the content array ref and turn it into a ragged AoAoA of operations with
-attached processed arguments. This is the core of the assembler.
-
-  The transformation looks roughly like this:
-
-  [ [ 'if I0,BLAH', 3],
-    [ 'set P1[S5],P0["foo"]', 5],
-    [ 'BLAH: end', 6],
-  ]
-
-  into:
-
-  [ [ [ 'if_i_ic',
-        ['i','I0'],
-        ['label','BLAH'], # Leave the name here so we can resolve backward refs.
-      ],
-      3, # Line number
-    ],
-    [ [ 'set_p_s_p_sc',
-        ['p','P1'],
-        ['s','S5'],
-        ['p','P0'],
-        ['sc',0],    # String constant number 0
-      ]
-      5,
-    ],
-    [ [ 'end',
-      ],
-      6,
-  ]
-
-The first pass collects labels, so we can resolve forward label references
-(That is, labels used before they're defined). References to labels aren't yet
-expanded.
-
-The second pass takes the arguments in each line (C<$_->[0]>) and breaks them
-into their components. It does this by passing each line through a loop of REs
-to break lines into each argument type. The individual REs break down the
-arguments into an array ref C<[$type,$argument]>. Constants are collected and
-replaced with indices, and the number of arguments is counted and added to the
-internal PC tracking.
-
-The third pass takes labels and replaces them with the PC offset to the actual
-instruction, and generates bytecode. It returns the bytecode, and we're done.
-
-=back
-
-=cut
-
-sub to_bytecode {
-  my $self = shift;
-
-  my $pc = 0;
-
-  $self->_collect_labels(); # Collect labels in a separate pass
-
-  for(@{$self->{contents}}) {
-    #
-    # Collect the operator
-    #
-    my $temp = $_->[0];
-    my $suffixes = '';
-    $temp=~s/^(\w+)\s*//;
-    $_->[0] = [$1];
-
-    while($temp ne '') {
-      $temp=~s/^\s*(,\s*)?//;
-      if($temp=~s/^#.*//) {
-        # Skip flying comments.
-      }
-      elsif($temp=~s/^($reg_re)//o) {
-        my $reg_idx = substr($1,1);
-        unless($reg_idx >= 0 and $reg_idx <= 31) {
-          print STDERR "Caught out-of-bounds register $1 at line $_->[1].\n";
-          last;
-        }
-        $suffixes .= "_".lc(substr($1,0,1));
-        push @{$_->[0]}, [lc(substr($1,0,1)),$1];
-      }
-      elsif($temp=~s/^\[(P\d+)\]//) { # P1[P0]
-        my $reg_idx = substr($1,1);
-        unless($reg_idx >= 0 and $reg_idx <= 31) {
-          print STDERR "Caught out-of-bounds register $1 at line $_->[1].\n";
-          last;
-        }
-        $suffixes .= "_k";
-        push @{$_->[0]}, ['p',$1];
-      }
-      elsif($temp=~s/^\[(I\d+)\]//) { # P2[I1]
-        my $reg_idx = substr($1,1);
-        unless($reg_idx >= 0 and $reg_idx <= 31) {
-          print STDERR "Caught out-of-bounds register $1 at line $_->[1].\n";
-          last;
-        }
-        $suffixes .= "_ki";
-        push @{$_->[0]}, ['i',$1];
-      }
-      elsif($temp=~s/^\[($bin_re)\]//o) { # P3[0b11101]
-        my $val = $1;$val=~s/0b//;
-        $suffixes .= "_kic";
-        push @{$_->[0]}, ['ic',(strtol($val,2))[0]];
-      }
-      elsif($temp=~s/^\[($hex_re)\]//) { # P7[0x1234]
-        $suffixes .= "_kic";
-        push @{$_->[0]}, ['ic',(strtol($1,16))[0]];
-      }
-      elsif($temp=~s/^\[($dec_re)\]//) { # P14[3]
-        $suffixes .= "_kic";
-        push @{$_->[0]}, ['ic',0+$1];
-      }
-      elsif($temp=~s/^\[([^]]+)\]//) { # P18[3;2]
-        $suffixes .= "_kc";
-        push @{$_->[0]}, $self->_key_constant($1);
-      }
-      elsif($temp=~s/^($flt_re)//) {
-        $suffixes .= "_nc";
-        push @{$_->[0]}, $self->_numeric_constant($1);
-      }
-      elsif($temp=~s/^($bin_re)//o) {     # 0b1101
-        my $val = $1;$val=~s/0b//;
-        $suffixes .= "_ic";
-        push @{$_->[0]}, ['ic',(strtol($val,2))[0]];
-      }
-      elsif($temp=~s/^($hex_re)//o) {     # 0x12aF
-        $suffixes .= "_ic";
-        push @{$_->[0]}, ['ic',(strtol($1,16))[0]];
-      }
-      elsif($temp=~s/^($dec_re)//o) {     # -32
-        $suffixes .= "_ic";
-        push @{$_->[0]}, ['ic',0+$1];
-      }
-      elsif($temp=~s/^($str_re)//o) {     # "Hello World"
-        $suffixes .= "_sc";
-        push @{$_->[0]}, $self->_string_constant($1);
-      }
-      elsif($temp=~s/^($label_re)//o) {
-        unless(defined $self->{global_labels}{$1}) {
-          print STDERR "Couldn't find global label '$1' at line $_->[1].\n";
-          last;
-        }
-        $suffixes .= "_ic";
-        push @{$_->[0]}, ['label',$1];
-      }
-      else {
-        print STDERR "Couldn't parse argument '$temp' at line $_->[1].\n";
-        last;
-      }
-    }
-    $_->[0][0] .= $suffixes
-      unless $_->[0][0] =~ /\Q$suffixes\E$/;
-#      unless defined $self->{fullops}{$_->[0][0]};
-    $self->{line_to_pc}{$_->[1]}=$pc;
-    $pc += scalar @{$_->[0]};
-  }
-  $self->_adjust_labels(); # XXX It's possible that these passes could be
-  $self->_generate_bytecode(); # XXX merged, but I'm not going to worry about
-                               # XXX it right now.
-
-  return output_bytecode({
-    bytecode  => $self->{bytecode},
-    constants => $self->{ordered_constants},
-    num_constants => $self->{num_constants}
-  });
-}
-
-
-package main;
-
-use strict;
-
-my %args;
-my @files;
-
-process_args(\%args,[EMAIL PROTECTED]);
-
-my $macro = Macro->new(@files);
-
-#
-# Run the files through the preprocessor, and if -E flag encountered,
-# stop right there.
-#
-$macro->preprocess();
-if(exists $args{-E}) {
-  print join "\n",@{$macro->contents()};
-  print "\n";
-  exit;
-}
-
-#
-# Compile the files, and handle the output.
-#
-my $compiler = Assembler->new('-contents' => $macro->contents());
-my $bytecode = $compiler->to_bytecode();
-
-exit if exists $args{-c};
-if(exists $args{-o}) {
-  open FILE,">$args{-o}"
-    or die "Could not write to '$args{-o}': $!";
-  binmode FILE;
-  print FILE $bytecode;
-  close FILE;
-}
-else {
-  binmode STDOUT;
-  print $bytecode;
-}
-
-exit;
-
-#------------------------------------------------------------------------------
-
-=over 4
-
-=item process_args
-
-Process the argument list and return the list of arguments and files to
-process. Only legal and sane arguments and files should get past this point.
-
-=back
-
-=cut
-
-sub process_args {
-  my ($args,$files) = @_;
-
-  while (my $arg = shift @ARGV) {
-    if($arg =~ /^-(c|-checksyntax)$/) { $args->{-c} = 1; }
-    elsif($arg =~ /^-E$/)             { $args->{-E} = 1; }
-    elsif($arg =~ /^-(o|-output)$/)   { $args->{-o} = shift @ARGV; }
-    elsif($arg =~ /^-(h|-help)$/)     { Usage(); exit 0; }
-    elsif($arg =~ /^-./)              { Fail("Invalid option '$arg'\n"); }
-    else                              { push @$files,$arg; }
-  }
-  Fail("No files to process.\n") unless(@$files);
-  Fail("File '$_' does not exist.\n") for grep { not (-e or /^-$/) } @$files;
-}
-
-sub Fail {
-    print STDERR @_;
-    Usage();
-    exit 1;
-}
-
-sub Usage {
-  print <<"  _EOF_";
-
-usage: $0 [options] file [file...]
-
-    -E              Preprocess input files and terminate processing
-    -h,--help       Print this message
-    -o,--output     Write file
-    -c,--checksyntax Check syntax only, do not generate bytecode
-
-  _EOF_
-}
Index: disassemble.pl
===================================================================
RCS file: disassemble.pl
diff -N disassemble.pl
--- disassemble.pl	27 Jul 2003 21:03:06 -0000	1.24
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,330 +0,0 @@
-#! /usr/bin/perl -w
-#
-# disassemble.pl
-#
-# Turn a parrot bytecode file into text.
-#
-# Copyright (C) 2001-2003 The Perl Foundation.  All rights reserved.
-# This program is free software. It is subject to the same license
-# as the Parrot interpreter.
-#
-# $Id: disassemble.pl,v 1.24 2003/07/27 21:03:06 chromatic Exp $
-#
-
-use strict;
-use FindBin;
-use lib "$FindBin::Bin/lib";
-use Parrot::Config;
-
-use Parrot::OpLib::core;
-use Parrot::Op;
-
-use Parrot::Types;
-use Parrot::PackFile;
-use Parrot::PackFile::ConstTable;
-use Parrot::String;
-use Parrot::Key;
-
-use Data::Dumper;
-$Data::Dumper::Useqq  = 1;
-$Data::Dumper::Terse  = 1;
-$Data::Dumper::Indent = 0;
-
-use Getopt::Std;
-
-my %opts;
-
-getopts('x', \%opts);
-
-#
-# GLOBAL VARIABLES:
-#
-
-my @opcodes = @$Parrot::OpLib::core::ops;
-
-#my $opcode_fingerprint = Parrot::Opcode::fingerprint();
-
-
-#
-# dump_const_table()
-#
-
-sub dump_const_table {
-    my ($pf) = @_;
-
-    #
-    # Check for the opcode table fingerprint:
-    #
-    # TODO: This is a really poor way to do this. Consider having a 'properties' table
-    # as part of the file format. Then we can have whatever properties we want. Probably
-    # these can be pairs of IVs as indexes into the constants table. Then we can have
-    # a 'fingerprint' property if we want.
-    #
-
-    my $count = $pf->const_table->const_count;
-
-=no
-    if ($count < 1) {
-	warn "Disassembling without opcode table fingerprint (no constants)!";
-	return;
-    }
-
-    my $type = $pf->const_table->constant(0)->type;
-    if ($type ne Parrot::PackFile::Constant->type_code('PFC_STRING')) {
-        $type = Parrot::PackFile::Constant->type_name($type);
-        warn "Disassembling without opcode table fingerprint (first constant isn't a string; type = '$type')!";
-    }
-
-    my $ref = ref $pf->const_table->constant(0)->value;
-    if ($ref ne 'Parrot::String') {
-        warn "Cannot disassemble (malformed string as first constant; type = '$ref'!";
-    }
-
-    my $data = ref $pf->const_table->constant(0)->value->data;
-    if ($data ne $opcode_fingerprint) {
-        warn "Cannot disassemble (differing opcode table; data = '$data')!";
-    }
-=cut
-
-    #
-    # Dump the constant table:
-    #
-
-    print "#\n";
-    print "# Constant  Type          Data\n";
-    print "# --------  ------------  ------------------------------\n";
-
-    my $constant_num = 0;
-
-    foreach ($pf->const_table->constants) {
-      my $value;
-      my $type  = Parrot::PackFile::Constant->type_name($_->type + 0);
-
-      if ($type eq 'PFC_STRING') {
-        $value = Dumper($_->value->data);
-      } elsif ($type eq 'PFC_KEY') {
-        $value = $_->value->dump($pf->const_table);
-      } else {
-        $value = Dumper($_->value);
-      }
-
-      printf("# %8ld  %-12s  %-30s\n", $constant_num, $type, $value);
-
-      $constant_num++;
-    }
-
-    print "#\n";
-}
-
-
-#
-# disassemble_byte_code()
-#
-
-my %rtype_map = (
-  "i" => "I",
-  "n" => "N",
-  "p" => "P",
-  "s" => "S",
-  "k" => "K",
-  "ki" => "KI",
-
-  "ic" => "i",
-  "nc" => "n",
-  "pc" => "p",
-  "sc" => "s",
-  "kc" => "k",
-  "kic" => "ki",
-);
-
-sub disassemble_byte_code {
-    my ($pf) = @_;
-
-    my $cursor = 0;
-
-    my $offset=0;
-    my $bytecode = defined $pf->byte_code ? $pf->byte_code : '';
-    my $length = length($bytecode);
-
-    my $label_counter = 0;
-
-    my %pasm;
-
-    #
-    # Scan the byte code, storing the disasembled ops and linking
-    # branch destinations to autogenerated labels.
-    #
-
-    while ($offset < $length) {
-	my $op_start = $offset;
-	my $op_code = shift_op($bytecode);
-	$offset += sizeof("op");
-
-        if (!defined $op_code) {
-            warn "$0: Unable to get next opcode at offset $op_start!\n";
-            last;
-        }
-
-        if (!defined $opcodes[$op_code]) {
-            warn "$0: Unrecognized opcode '$op_code' at offset $op_start!\n";
-            next;
-        }
-
-        if (exists $pasm{$op_start}) {
-            $pasm{$op_start} = [ $pasm{$op_start}[0], [ $op_code ], $opcodes[$op_code]{NAME}, [ ] ];
-        } else {
-            $pasm{$op_start} = [ undef,               [ $op_code ], $opcodes[$op_code]{NAME}, [ ] ];
-        }
-
-	my $arg_count = $opcodes[$op_code]->size - 1;
-	my @args = ();
-
-	foreach (1 .. $arg_count) {
-	    my $type        = $rtype_map{$opcodes[$op_code]->arg_type($_)};
-	    my $unpack_size = sizeof($type);
-
-	    if (($offset + $unpack_size) > $length) {
-	        warn "$0: Premature end of bytecode in argument.\n";
-	        last;
-            }
-
-	    my $arg = shift_arg($type, $bytecode);
-
-            push @{$pasm{$op_start}[1]}, $arg;
-
-	    $offset += $unpack_size;
-
-	    if($type =~ m/^[INPS]$/) { # Register
-		push @{$pasm{$op_start}[3]}, $type . $arg;
-	    } elsif($type eq "D") { # destination address
-                my $dest = $op_start + sizeof('op') * $arg;
-                if (!exists $pasm{$dest}) {
-                    $pasm{$dest}    = [ "L" . $label_counter++, [ ], undef, [ ] ];
-                } elsif (!defined $pasm{$dest}[0]) {
-                    $pasm{$dest}[0] = "L" . $label_counter++;
-                }
-		push @{$pasm{$op_start}[3]}, $pasm{$dest}[0];
-	    } elsif($type eq "K") { # key
-		push @{$pasm{$op_start}[3]}, sprintf("[P$arg]");
-	    } elsif($type eq "KI") { # integer key
-		push @{$pasm{$op_start}[3]}, sprintf("[I$arg]");
-	    } elsif($type eq "n") { # number constant
-		push @{$pasm{$op_start}[3]}, sprintf("[nc:$arg]");
-	    } elsif($type eq "s") { # string constant
-		push @{$pasm{$op_start}[3]}, sprintf("[sc:$arg]");
-	    } elsif($type eq "k") { # key constant
-		push @{$pasm{$op_start}[3]}, sprintf("[kc:$arg]");
-	    } elsif($type eq "ki") { # integer key constant
-		push @{$pasm{$op_start}[3]}, sprintf("[$arg]");
-	    } else { # constant
-		push @{$pasm{$op_start}[3]}, $arg;
-	    }
-	}
-    }
-
-    #
-    # Print out the code:
-    #
-
-    printf "# WORD     BYTE         BYTE CODE                                         LABEL   OPERATION        ARGUMENTS\n";
-    printf "# -------- ----------   ------------------------------------------------  ------  ---------------  --------------------\n";
-
-    foreach my $pc (sort { $a <=> $b } keys %pasm) {
-        my ($label, $code, $op_name, $args) = @{$pasm{$pc}};
-        $label = defined $label ? "$label:" : '';
-        my $words;
-
-        if ($opts{x}) {
-          $words = join('  ', map { sprintf "%08x", $_ } @$code);
-        } else {
-          $words = join('  ', map { sprintf "%08d", $_ } @$code);
-        }
-
-        my @print_args = ($pc / 4, $pc, $words, $label, $op_name);
-
-        if ($opts{x}) {
-	  printf "  %08x [%08x]:  %-48s  %-6s  %-15s  ", @print_args;
-        } else {
-	  printf "  %08d [%08d]:  %-48s  %-6s  %-15s  ", @print_args;
-        }
-
-	print join(", ", @$args), "\n";
-    }
-}
-
-
-#
-# disassemble_file()
-#
-
-sub disassemble_file {
-    my ($file_name) = @_;
-
-    my $pf = Parrot::PackFile->new;
-    $pf->unpack_file($file_name);
-
-    printf "#\n";
-    printf "# Disassembly of Parrot Byte Code from '%s'\n", $_;
-    printf "#\n";
-    printf "# Segments:\n";
-    printf "#\n";
-    printf "#   * Wordsize:     %8d bytes (%d)\n", sizeof('byte'), $pf->wordsize;
-    printf "#   * Byteorder:    %8d bytes (%d)\n", sizeof('byte'), $pf->byteorder;
-    printf "#   * Major:        %8d bytes (%d)\n", sizeof('byte'), $pf->major;
-    printf "#   * Minor:        %8d bytes (%d)\n", sizeof('byte'), $pf->minor;
-    printf "#   * Flags:        %8d bytes (%d)\n", sizeof('byte'), $pf->flags;
-    printf "#   * FloatType:    %8d bytes (%d)\n", sizeof('byte'), $pf->floattype;
-    printf "#   * Fingerprint:  %8d bytes (". "0x%02x," x9 . "0x%02x)\n", length($pf->pad),
-        unpack("C10", $pf->pad);
-    printf "#   * Magic Number: %8d bytes (0x%08x)\n", sizeof('op'), $pf->magic;
-    printf "#   * Opcode Type:  %8d bytes (0x%08x)\n", sizeof('op'), $pf->opcodetype;
-    printf "#   * Fixup Table:  %8d bytes\n", $pf->fixup_table->packed_size;
-    printf "#   * Const Table:  %8d bytes\n", $pf->const_table->packed_size;
-    printf "#   * Byte Code:    %8d bytes (%d opcode_ts)\n", length($pf->byte_code), length($pf->byte_code) / sizeof('op');
-
-    dump_const_table($pf);
-    disassemble_byte_code($pf);
-
-    undef $pf;
-
-    return;
-}
-
-
-#
-# MAIN PROGRAM:
-#
-
[EMAIL PROTECTED] = qw(-) unless @ARGV;
-
-foreach (@ARGV) {
-    disassemble_file($_)
-}
-
-exit 0;
-
-__END__
-
-=head1 NAME
-
-disassemble.pl - disassemble the byte code from Parrot Pack Files
-
-=head1 SYNOPSIS
-
-  perl disassemble.pl FILE
-
-=head1 DESCRIPTION
-
-Disassembles the Parrot Pack Files listed on the command line, or
-from standard input if no file is named.
-
-=head1 COPYRIGHT
-
-Copyright (C) 2001-2003 The Perl Foundation. All Rights Reserved.
-
-=head1 LICENSE
-
-This program is free software. It is subject to the same license
-as the Parrot interpreter.
-
-=cut
Index: packfile.c
===================================================================
RCS file: /cvs/public/parrot/packfile.c,v
retrieving revision 1.92
diff -u -r1.92 packfile.c
--- packfile.c	28 Jul 2003 22:10:29 -0000	1.92
+++ packfile.c	8 Aug 2003 16:09:14 -0000
@@ -536,52 +536,10 @@
 
     header->dir_format = PackFile_fetch_op(self, &cursor);
 
-    /* old compat mode for assemble.pl */
     if (header->dir_format == 0) {
-
-        /*
-         * Unpack the Constant Table Segment:
-         */
-        header->const_ss = PackFile_fetch_op(self, &cursor);
-        self->const_table->base.op_count = header->const_ss /
-            sizeof(opcode_t);
-        if (!PackFile_check_segment_size(header->const_ss,
-                    "constant")) {
-            return 0;
-        }
-
-        if (!PackFile_ConstTable_unpack(interpreter,
-                    (struct PackFile_Segment *)self->const_table,
-                    cursor)) {
-            PIO_eprintf(NULL,
-                    "PackFile_unpack: Error reading constant table segment!\n");
-            return 0;
-        }
-
-        /* Segment size is in bytes => ops */
-        cursor += header->const_ss/sizeof(opcode_t);
-
-        /*
-         * Unpack the Byte Code Segment:
-         * PackFile new did generate already a default code segment
-         */
-
-        header->bytecode_ss = PackFile_fetch_op(self, &cursor);
-
-        if (!PackFile_check_segment_size(header->bytecode_ss,
-                    "bytecode")) {
-            return 0;
-        }
-        else if (header->bytecode_ss == 0) {
-            /* Must have at least one instruction */
-            PIO_eprintf(NULL,
-                "Packfile_unpack: No bytecode present in bytecode segment.\n");
-            return 0;
-        }
-        self->cur_cs->base.size = header->bytecode_ss / sizeof(opcode_t);
-        cursor = default_unpack(interpreter,
-                (struct PackFile_Segment *) self->cur_cs, cursor);
-
+        PIO_eprintf(NULL,
+                    "PackFile_unpack: Dir format 0 no longer supported!\n");
+        return 0;
     }
     else {
         /* new format use directory */
Index: config/gen/makefiles/jako.in
===================================================================
RCS file: /cvs/public/parrot/config/gen/makefiles/jako.in,v
retrieving revision 1.11
diff -u -r1.11 jako.in
--- config/gen/makefiles/jako.in	8 Jul 2003 21:42:16 -0000	1.11
+++ config/gen/makefiles/jako.in	8 Aug 2003 16:09:14 -0000
@@ -9,8 +9,8 @@
 
 DIR=languages/jako
 TOOL_DIR=../..
-ASM=$(PERL) -I ../../lib ../../assemble.pl
 IMCC=../imcc/imcc${exe}
+ASM=$(IMCC) -a --output-pbc 
 JAKOC=$(PERL) -I lib jakoc
 INTERP=../../${test_prog}
 
Index: config/gen/makefiles/miniperl.in
===================================================================
RCS file: /cvs/public/parrot/config/gen/makefiles/miniperl.in,v
retrieving revision 1.3
diff -u -r1.3 miniperl.in
--- config/gen/makefiles/miniperl.in	30 May 2003 17:17:02 -0000	1.3
+++ config/gen/makefiles/miniperl.in	8 Aug 2003 16:09:14 -0000
@@ -7,7 +7,8 @@
 PERL=${perl}
 DIR=languages/miniperl
 TOOL_DIR=../..
-ASM=$(PERL) -I ../../lib ../../assemble.pl
+IMCC=../imcc/imcc${exe}
+ASM=$(IMCC) -a --output-pbc 
 MINIPERLC=$(PERL) miniperlc
 INTERP=./${test_prog}
 
Index: config/gen/makefiles/perl6.in
===================================================================
RCS file: /cvs/public/parrot/config/gen/makefiles/perl6.in,v
retrieving revision 1.8
diff -u -r1.8 perl6.in
--- config/gen/makefiles/perl6.in	30 May 2003 17:17:02 -0000	1.8
+++ config/gen/makefiles/perl6.in	8 Aug 2003 16:09:14 -0000
@@ -5,7 +5,7 @@
 myperl=$(PERL) -I../../lib
 compile=$(myperl) prd-perl6.pl --batch --imc
 imcc=..${slash}imcc${slash}imcc
-asm=$(PERL) ..${slash}..${slash}assemble.pl
+asm=$(imcc) -a --output-pbc
 
 all: imcc perl6-config
 
Index: config/gen/makefiles/root.in
===================================================================
RCS file: /cvs/public/parrot/config/gen/makefiles/root.in,v
retrieving revision 1.99
diff -u -r1.99 root.in
--- config/gen/makefiles/root.in	8 Aug 2003 08:15:27 -0000	1.99
+++ config/gen/makefiles/root.in	8 Aug 2003 16:09:14 -0000
@@ -161,7 +161,6 @@
 # Make directory; do not die if dir exists.
 MKDIR = $(PERL) -e ${PQ}-d or mkdir $$_,0777 or die foreach @ARGV${PQ}
 
-
 ###############################################################################
 #
 # BUILD TARGET CONFIGURATIONS:
@@ -328,7 +327,7 @@
 #
 ###############################################################################
 
-examples/assembly/mops.pbc : examples/assembly/mops.pasm assemble.pl
+examples/assembly/mops.pbc : examples/assembly/mops.pasm
 	cd examples && cd assembly && $(MAKE) mops.pbc PERL=$(PERL) && cd .. && cd ..
 
 examples/assembly/mops.c : examples/assembly/mops.pbc pbc2c.pl
@@ -337,7 +336,7 @@
 examples/assembly/mops${exe} : examples/assembly/mops$(O) $(LIBPARROT)
 	$(LINK) $(LINKFLAGS) ${ld_out}examples/assembly/mops${exe} examples/assembly/mops$(O) $(LIBPARROT) $(C_LIBS)
 
-examples/assembly/life.pbc : examples/assembly/life.pasm assemble.pl
+examples/assembly/life.pbc : examples/assembly/life.pasm
 	cd examples && cd assembly && $(MAKE) life.pbc PERL=$(PERL) && cd .. && cd ..
 
 examples/assembly/life.c : examples/assembly/life.pbc pbc2c.pl
@@ -583,7 +582,7 @@
 	$(PERL) t/harness $(EXTRA_TEST_ARGS) -b $(TEST_PROG_ARGS) quick
 
 # Common prep for all test targets
-test_prep : $(LIBPARROT) $(IMCC_PROG) assemble.pl
+test_prep : $(LIBPARROT) $(IMCC_PROG)
 
 test_dummy :
 	$(PERL) t/harness $(EXTRA_TEST_ARGS) $(TEST_PROG_ARGS)
Index: docs/intro.pod
===================================================================
RCS file: /cvs/public/parrot/docs/intro.pod,v
retrieving revision 1.15
diff -u -r1.15 intro.pod
--- docs/intro.pod	27 Jul 2003 17:57:04 -0000	1.15
+++ docs/intro.pod	8 Aug 2003 16:09:14 -0000
@@ -319,15 +319,22 @@
 some time. This is only because Parrot doesn't currently have a "sleep"
 op; we'll see how to implement one later on.
 
-How do we run this? First, we need to assemble this into Parrot
-bytecode, with the F<assemble.pl> provided. So, copy the assembler to a
+How do we run this? Copy the assembler to a
 file F<showtime.pasm>, and inside your Parrot directory, run:
 
-      perl assemble.pl showtime.pasm > showtime.pbc
+      parrot showtime.pasm
 
+This will assemble and run the code in F<showtime.pasm>. You can also
+create an assembled bytecode from the assembler by running:
+
+      parrot showtime.pasm -o showtime.pbc
 
 (C<.pbc> is the file extension for Parrot bytecode.)
 
+To run this bytecode type
+
+      parrot showtime.pbc
+
 =head2 Finding a Fibonacci number
 
 The Fibonacci series is defined like this: take two numbers, 1 and 1.
@@ -405,8 +412,7 @@
 F<languages/jako> subdirectory:
 
   % languages/jako/jakoc fib.jako > fib.pasm
-  % perl assemble.pl fib.pasm > fib.pbc
-  % ./parrot fib.pbc
+  % ./parrot fib.pasm
  The first 20 fibonacci numbers are:
  1
  1
Index: docs/running.pod
===================================================================
RCS file: /cvs/public/parrot/docs/running.pod,v
retrieving revision 1.14
diff -u -r1.14 running.pod
--- docs/running.pod	27 Jul 2003 23:51:35 -0000	1.14
+++ docs/running.pod	8 Aug 2003 16:09:14 -0000
@@ -48,18 +48,6 @@
 C<parrot> also has several debugging and tracing flags; see the
 usage description (generated by C<parrot -h>) for details.
 
-=item C<assemble.pl>
-
-Converts a Parrot assembly file to Parrot bytecode.
-
-  perl assemble.pl foo.pasm > foo.pbc
-
-Usage information: C<assemble.pl -h>. Detailed documentation on the
-underlying module can be read with C<perldoc -F lib/Parrot/Assembler.pm>.
-
-This Perl-based assembler has become obsolete and may be removed at some
-point in the future. 
-
 =item C<optimizer.pl>
 
 Performs some basic optimizations on Parrot assembly files. Use it by running
Index: examples/assembly/Makefile
===================================================================
RCS file: /cvs/public/parrot/examples/assembly/Makefile,v
retrieving revision 1.4
diff -u -r1.4 Makefile
--- examples/assembly/Makefile	30 May 2003 17:17:06 -0000	1.4
+++ examples/assembly/Makefile	8 Aug 2003 16:09:15 -0000
@@ -9,4 +9,4 @@
 	rm -f *.pbc mops.c mops.o mops
 
 .pasm.pbc:
-	$(PERL) -I../../lib ../../assemble.pl -o $@ $<
+	../../parrot -o $@ $<
Index: examples/assembly/uniq.pasm
===================================================================
RCS file: /cvs/public/parrot/examples/assembly/uniq.pasm,v
retrieving revision 1.3
diff -u -r1.3 uniq.pasm
--- examples/assembly/uniq.pasm	17 Jul 2003 20:10:54 -0000	1.3
+++ examples/assembly/uniq.pasm	8 Aug 2003 16:09:15 -0000
@@ -1,7 +1,7 @@
 # $Id: uniq.pasm,v 1.3 2003/07/17 20:10:54 scog Exp $
 # uniq - Remove duplicate lines from a sorted file
 #
-#   % ./assemble.pl uniq.pasm -o uniq.pbc
+#   % ./parrot uniq.pasm -o uniq.pbc
 #   % ./parrot uniq.pbc data.txt
 #   % ./parrot uniq.pbc -c data.txt
 #
Index: languages/BASIC/interpreter/basic.pl
===================================================================
RCS file: /cvs/public/parrot/languages/BASIC/interpreter/basic.pl,v
retrieving revision 1.1
diff -u -r1.1 basic.pl
--- languages/BASIC/interpreter/basic.pl	9 Mar 2003 23:08:58 -0000	1.1
+++ languages/BASIC/interpreter/basic.pl	8 Aug 2003 16:09:16 -0000
@@ -102,5 +102,5 @@
 close(T);
 
 unlink "basic.pbc";
-system("perl -I../../../lib ../../../assemble.pl -o basic.pbc merged_basic.pasm");
+system("../../../parrot -o basic.pbc merged_basic.pasm");
 system("../../../parrot basic.pbc");
Index: languages/cola/README
===================================================================
RCS file: /cvs/public/parrot/languages/cola/README,v
retrieving revision 1.15
diff -u -r1.15 README
--- languages/cola/README	24 Jun 2003 23:53:29 -0000	1.15
+++ languages/cola/README	8 Aug 2003 16:09:17 -0000
@@ -180,10 +180,7 @@
 
         parrot a.pbc
 
-  You can also see the Parrot assembly in "a.pasm" which should be compilable
-  with the reference assembler:
-
-        assemble.pl a.pasm > a.pbc
+  You can also see the Parrot assembly in "a.pasm".
 
   Currently colac is a short Perl pre-processor that includes
   classes for any import statements (using System;)
Index: languages/imcc/main.c
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/main.c,v
retrieving revision 1.38
diff -u -r1.38 main.c
--- languages/imcc/main.c	8 Aug 2003 08:44:24 -0000	1.38
+++ languages/imcc/main.c	8 Aug 2003 16:09:17 -0000
@@ -75,6 +75,7 @@
     "    -v --verbose\n"
     "    -E --pre-process-only\n"
     "    -o --output=FILE\n"
+    "       --output-pbc\n"
     "    -O --optimize[=LEVEL]\n"
     "    -a --pasm\n"
     "    -c --pbc\n"
@@ -108,6 +109,7 @@
 #define OPT_GC_DEBUG     128
 #define OPT_DESTROY_FLAG 129
 #define OPT_HELP_DEBUG   130
+#define OPT_PBC_OUTPUT   131
 static struct longopt_opt_decl options[] = {
     { '.', '.', 0, { "--wait" } },
     { 'E', 'E', 0, { "--pre-precess-only" } },
@@ -127,6 +129,7 @@
     { 'h', 'h', 0, { "--help" } },
     { 'j', 'j', 0, { "--jit" } },
     { 'o', 'o', OPTION_required_FLAG, { "--output" } },
+    { '\0', OPT_PBC_OUTPUT, 0, { "--output-pbc" } },
     { 'p', 'p', 0, { "--profile" } },
     { 'r', 'r', 0, { "--run-pbc" } },
     { 't', 't', 0, { "--trace" } },
@@ -228,6 +231,12 @@
             case 'o':
                 run_pbc = 0;
                 output = str_dup(opt.opt_arg);
+                break;
+
+            case OPT_PBC_OUTPUT:
+                run_pbc = 0;
+                write_pbc = 1;
+                if (!output) output = str_dup("-");
                 break;
 
             case 'O':
Index: languages/imcc/docs/macros.pod
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/docs/macros.pod,v
retrieving revision 1.4
diff -u -r1.4 macros.pod
--- languages/imcc/docs/macros.pod	7 Jul 2003 21:56:21 -0000	1.4
+++ languages/imcc/docs/macros.pod	8 Aug 2003 16:09:17 -0000
@@ -12,7 +12,7 @@
 for the original F<assemble.pl> macro layer. There for the the macro
 expansion at the moment only works in assembly mode, except for the
 B<.include "file"> feature.  Furthermore this documentation is in
-large parts copied literally from there.
+large parts copied literally from there. 
 
 The addition of the '.' preface will hopefully make things easier to
 parse, inasmuch as everything within an assembler file that needs to
Index: languages/imcc/docs/operation.pod
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/docs/operation.pod,v
retrieving revision 1.4
diff -u -r1.4 operation.pod
--- languages/imcc/docs/operation.pod	7 Jul 2003 21:56:21 -0000	1.4
+++ languages/imcc/docs/operation.pod	8 Aug 2003 16:09:17 -0000
@@ -255,9 +255,8 @@
 
 =head1 Code generation
 
-Imcc either generates PASM output ready to get assembled by
-F<assemble.pl> or else directly generates a PBC file for running with 
-parrot.
+Imcc either generates PASM or else directly generates a PBC file for 
+running with parrot.
 
 =head1 Running code
 
Index: languages/imcc/docs/parsing.pod
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/docs/parsing.pod,v
retrieving revision 1.8
diff -u -r1.8 parsing.pod
--- languages/imcc/docs/parsing.pod	2 Aug 2003 08:53:51 -0000	1.8
+++ languages/imcc/docs/parsing.pod	8 Aug 2003 16:09:17 -0000
@@ -107,7 +107,7 @@
 This allows for global constant folding beyond subroutine scope.
 
 Local labels in different I<compilation units> with the same name are
-allowed, though running the generated PASM through F<assemble.pl>
+allowed, though assembling the generated PASM 
 doesn't work. Running this code inside imcc is ok.
 This will probably change so that local labels are mangled to be unique.
 
Index: languages/imcc/docs/running.pod
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/docs/running.pod,v
retrieving revision 1.10
diff -u -r1.10 running.pod
--- languages/imcc/docs/running.pod	9 Jul 2003 12:40:18 -0000	1.10
+++ languages/imcc/docs/running.pod	8 Aug 2003 16:09:17 -0000
@@ -64,12 +64,17 @@
 
 =item -h, --help
 
-=item -o outputfile
+=item -o outputfile, --output=outputfile
 
 Act like assembler. Don't run code, unless B<-r> is given too. If the
 outputfile ends with B<.pbc>, a PBC file is written. If it ends with
 B<.pasm>, a PASM output is generated, even from PASM input. This can be
 handy to check various optimizations, including B<-Op>.
+
+=item --output-pbc
+
+Act like assembler, but always output a bytecode even though the outputfile
+does not end in B<.pbc>
 
 =item -r, --run-pbc
 
Index: languages/parrot_compiler/Makefile
===================================================================
RCS file: /cvs/public/parrot/languages/parrot_compiler/Makefile,v
retrieving revision 1.4
diff -u -r1.4 Makefile
--- languages/parrot_compiler/Makefile	30 May 2003 17:17:12 -0000	1.4
+++ languages/parrot_compiler/Makefile	8 Aug 2003 16:09:17 -0000
@@ -3,7 +3,7 @@
 all :
 	$(PERL) "-MFile::Copy=cp" -e "cp q|parrot.pasm|, q|pc.pasm|"
 	$(PERL) gentable.pl pc.pasm
-	$(PERL) ../../assemble.pl -o pc.pbc pc.pasm
+	../../parrot -o pc.pbc pc.pasm
 
 clean :
 	rm -f core
Index: languages/perl6/perl6
===================================================================
RCS file: /cvs/public/parrot/languages/perl6/perl6,v
retrieving revision 1.32
diff -u -r1.32 perl6
--- languages/perl6/perl6	5 Jul 2003 09:49:02 -0000	1.32
+++ languages/perl6/perl6	8 Aug 2003 16:09:17 -0000
@@ -1042,7 +1042,6 @@
 - Check for core files, and optionally get backtrace
 - clean up source file
 - more use of Parrot::Config
-- use assemble.pl's classes directly
 - filter warnings/diagnostics ...
   -Wofile -W/frompat/../topat/ (grep expr)
 
Index: languages/perl6/doc/debugging.pod
===================================================================
RCS file: /cvs/public/parrot/languages/perl6/doc/debugging.pod,v
retrieving revision 1.1
diff -u -r1.1 debugging.pod
--- languages/perl6/doc/debugging.pod	27 Sep 2002 02:18:50 -0000	1.1
+++ languages/perl6/doc/debugging.pod	8 Aug 2003 16:09:17 -0000
@@ -21,7 +21,7 @@
 You should see the individual compilation steps and finally the output
 of above program.
 
-If that fails, there are currently 4 steps that might be the culprit:
+If that fails, there are currently 3 steps that might be the culprit:
 
 =over 4
 
@@ -29,8 +29,6 @@
 
 =item imcc -- the intermediate compiler
 
-=item assemble.pl -- PASM assembler
-
 =item parrot -- the parrot interpreter
 
 =back
@@ -126,12 +124,13 @@
 runs all tests through B<imcc>. This will probably be the default run option
 for the next future.
 
-=head2 assemble.pl
+=head2 assembling the pasm
 
 The next step is running above parrot assembly file through the
-assembler, which generates PBC (parrot byte code).
+assembler (which is again imcc running in a diffrent mode) to generate
+PBC (parrot byte code).
 
-	perl ../../assemble.pl -o ok.pbc __eval__.pasm
+	../imcc/imcc -o ok.pbc __eval__.pasm
 
 This generates the binary file F<ok.pbc>, if the assembler worked.
 
Index: languages/regex/test.pl
===================================================================
RCS file: /cvs/public/parrot/languages/regex/test.pl,v
retrieving revision 1.12
diff -u -r1.12 test.pl
--- languages/regex/test.pl	30 May 2003 17:17:21 -0000	1.12
+++ languages/regex/test.pl	8 Aug 2003 16:09:18 -0000
@@ -187,9 +187,9 @@
 
 sub generate_pbc {
     my ($pasm, $pbc) = @_;
-    my $status = system("perl $FindBin::Bin/../../assemble.pl -o $pbc $pasm");
+    my $status = system("$FindBin::Bin/../../parrot -o $pbc $pasm");
     if (! defined($status) || $status) {
-        die "assemble.pl failed: $!";
+        die "assemble failed: $!";
     }
 }
 
Index: lib/Parrot/Test.pm
===================================================================
RCS file: /cvs/public/parrot/lib/Parrot/Test.pm,v
retrieving revision 1.42
diff -u -r1.42 Test.pm
--- lib/Parrot/Test.pm	27 Jul 2003 17:49:05 -0000	1.42
+++ lib/Parrot/Test.pm	8 Aug 2003 16:09:18 -0000
@@ -106,12 +106,6 @@
       binmode ASSEMBLY;
       print ASSEMBLY $assembly;
       close ASSEMBLY;
-      unless($ENV{IMCC}) {
-        my $cmd = "$PConfig{perl} ${directory}assemble.pl -o $by_f $as_f";
-        my $exit_code = _run_command($cmd);
-        $Builder->diag("'$cmd' failed with exit code $exit_code") if $exit_code;
-      }
-
   }
 }
 

Reply via email to