[svn:parrot] r40054 - in branches/ops_pct/compilers/opsc: ops t
bacek at svn.parrot.org
bacek at svn.parrot.org
Mon Jul 13 13:17:07 UTC 2009
Author: bacek
Date: Mon Jul 13 13:17:07 2009
New Revision: 40054
URL: https://trac.parrot.org/parrot/changeset/40054
Log:
[opsc] Borrow code from Ops2pm for parsing ops.num and ops.skip files
Modified:
branches/ops_pct/compilers/opsc/ops/oplib.pm
branches/ops_pct/compilers/opsc/t/04-oplib_parse_ops.t
Modified: branches/ops_pct/compilers/opsc/ops/oplib.pm
==============================================================================
--- branches/ops_pct/compilers/opsc/ops/oplib.pm Mon Jul 13 13:16:32 2009 (r40053)
+++ branches/ops_pct/compilers/opsc/ops/oplib.pm Mon Jul 13 13:17:07 2009 (r40054)
@@ -22,11 +22,52 @@
=over 4
-=item C<@.files>
+=item * C<@.files>
Op files. Mandatory argument of C<BUILD> method.
-=cut
+=item * C<$.max_op_num>
+
+Scalar holding number of highest non-experimental op. Example:
+
+ 'max_op_num' => 1246,
+
+=item * C<%.optable>
+
+Hash holding mapping of opcode names ops to their numbers.
+Example:
+
+ 'optable' => {
+ 'pow_p_p_i' => 650,
+ 'say_s' => 463,
+ 'lsr_p_p_i' => 207,
+ 'lt_s_sc_ic' => 289,
+ # ...
+ 'debug_init' => 429,
+ 'iseq_i_nc_n' => 397,
+ 'eq_addr_sc_s_ic' => 254
+ },
+
+Per F<src/ops/ops.num>, this mapping exists so that we can nail down
+the op numbers for the core opcodes in a particular version of the
+bytecode and provide backward-compatibility for bytecode.
+
+=item * C<%.skiptable>
+
+Reference to a 'seen-hash' of skipped opcodes.
+
+ 'skiptable' => {
+ 'bor_i_ic_ic' => 1,
+ 'xor_i_ic_ic' => 1,
+ 'tanh_n_nc' => 1,
+ # ...
+ },
+
+As F<src/ops/ops.skip> states, these are "... opcodes that could be listed in
+F<[src/ops/]ops.num> but aren't ever to be generated or implemented because
+they are useless and/or silly."
+
+=back
=head1 METHODS
@@ -47,7 +88,13 @@
}
self<files> := @files;
- self<ops> := <>;
+ self<max_op_num> := 0;
+ self<num_file> := %args<num_file> || 'src/ops/ops.num';
+ self<skip_file> := %args<skip_file> || 'src/ops/ops.skip';
+
+ my %optable;
+ self<optable> := %optable;
+ self<ops> := <>;
self;
}
@@ -66,6 +113,12 @@
}
}
+=item C<parse_ops_file>
+
+Parse single ops file. Returns list of parsed ops.
+
+=cut
+
method parse_ops_file($file) {
my $parser := self._get_compiler();
my $buffer := slurp($file);
@@ -75,6 +128,75 @@
$past<ops>;
}
+
+=item C<load_op_map_files>
+
+Load ops.num and ops.skip files.
+
+=cut
+
+method load_op_map_files() {
+ self._load_num_file();
+ self._load_skip_file();
+}
+
+method _load_num_file() {
+## open $op, '<', $num_file
+## or die "Can't open $num_file: $!";
+
+ # slurp isn't very efficient. But extending NQP beyond bare minimum is not in scope.
+ my $buf := slurp(self<num_file>);
+ my @ops := split("\n", $buf);
+
+ my $prev := -1;
+## while (<$op>) {
+ for @ops {
+## chomp;
+## s/#.*$//;
+## s/\s*$//;
+## s/^\s*//;
+## next unless $_;
+ my @parts := split( /\s+/, $_ );
+ my $name := @parts[0];
+ my $number := @parts[1];
+ #say(@parts[0] ~ ' => ' ~@parts[1]);
+ if ((+$number) eq $number) {
+ if ($prev + 1 != $number) {
+ die("hole in ops.num before #$number");
+ }
+ if ( exists(self<optable>, $name) ) {
+ die("duplicate opcode $name and $number");
+ }
+
+ $prev := $number;
+ self<optable>{$name} := $number;
+ if ( $number > self<max_op_num> ) {
+ self<max_op_num> := $number;
+ }
+ }
+ }
+}
+
+method _load_skip_file() {
+## open $op, '<', $skip_file
+## or die "Can't open $skip_file: $!";
+## while (<$op>) {
+## chomp;
+## s/#.*$//;
+## s/\s*$//;
+## s/^\s*//;
+## next unless $_;
+## ($name) = split( /\s+/, $_ );
+## if ( exists $self->{optable}{$name} ) {
+## die "skipped opcode is also in $num_file:$.";
+## }
+## $self->{skiptable}{$name} = 1;
+## }
+## undef $op;
+## return 1;
+}
+
+
method _get_compiler() {
PIR q<
%r = compreg 'Ops'
@@ -89,6 +211,13 @@
self<files>;
}
+method optable() {
+ self<optable>;
+}
+
+method max_op_num() {
+ self<max_op_num>;
+}
# Local Variables:
# mode: perl6
Modified: branches/ops_pct/compilers/opsc/t/04-oplib_parse_ops.t
==============================================================================
--- branches/ops_pct/compilers/opsc/t/04-oplib_parse_ops.t Mon Jul 13 13:16:32 2009 (r40053)
+++ branches/ops_pct/compilers/opsc/t/04-oplib_parse_ops.t Mon Jul 13 13:17:07 2009 (r40054)
@@ -1,16 +1,24 @@
#!../../parrot ../nqp/nqp.pbc
+# Checking for OpLib num and skip files parsing.
+
+# opsc_core contains everything except nqp.pbc
PIR q<
load_bytecode "opsc_core.pbc"
>;
+plan(4);
my @files := qw{
../../src/ops/core.ops
../../src/ops/math.ops
};
-my $lib := Ops::OpLib.new.BUILD(:files(@files));
+my $lib := Ops::OpLib.new.BUILD(
+ :files(@files),
+ :num_file('../../src/ops/ops.num'),
+ :skip_file('../../src/ops/ops.skip'),
+);
$lib.parse_ops();
@@ -18,4 +26,12 @@
# 116 math
ok(+($lib.ops) == 86 + 116, "ops file parsed");
+$lib.load_op_map_files();
+# It's 1258 currently. But testing for exact match isn't nessary.
+ok( $lib.max_op_num > 1200, "ops.num file parsed");
+
+# Check couple random ops.
+ok( $lib.optable<end> == 0, "'end' have code 0");
+ok( $lib.optable<set_args_pc> == 42, "'set_args_pc' have code 42");
+
# vim: expandtab shiftwidth=4 ft=perl6:
More information about the parrot-commits
mailing list