File: oplist.pm

package info (click to toggle)
moarvm 2020.12%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 18,652 kB
  • sloc: ansic: 268,178; perl: 8,186; python: 1,316; makefile: 768; sh: 287
file content (52 lines) | stat: -rw-r--r-- 1,456 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package oplist;
use strict;
use warnings;
use File::Spec::Functions qw(splitpath updir catpath catdir);
use constant OPLIST => do {
    my ($path, $directory, $filename) = splitpath(__FILE__);
    catpath($path, catdir($directory, (updir()) x 2, qw(src core)), 'oplist');
};

# Parse MoarVM oplist file and stash it in @OPLIST and %OPLIST
sub parse_oplist {
    my ($fh) = @_;
    my @oplist;
    while (<$fh>) {
        # remove comments and skip empty strings
        chomp and s/#.*$//;
        next unless length;
        my ($name, @meta) = split /\s+/;
        my ($attribute, @operands, @adverbs);
        for (@meta) {
            if (m/^[-+.:*]\w$/) {
                $attribute = $_;
            } elsif (m/^:\w+$/) {
                push @adverbs, $_;
            } elsif (m/^([rw])l?\((.+)\)$/) {
                push @operands, $1 => $2;
            } else {
                push @operands, '' => $_;
            }
        }
        push @oplist, [ $name, $attribute, \@operands, \@adverbs ];
    }
    return @oplist;
}

sub import {
    my ($class, $file) = (@_, OPLIST);
    open my $fh, '<', $file or die $!;
    my @oplist = parse_oplist($fh);
    my %oplist = map {
        $_->[0] => { attr => $_->[1], operands => $_->[2], adverbs => $_->[3] }
    } @oplist;
    my ($caller) = caller();
    {
        no strict 'refs';
        *{$caller . '::OPLIST'} = \@oplist;
        *{$caller . '::OPLIST'} = \%oplist;
    }
    close $fh;
}

1;