3
my @*vms := nqp::list('parrot', 'jvm', 'moar');
5
my %documented_ops := find_documented_opcodes();
7
my %ops := hash_of_vms();
9
%ops<jvm> := find_opcodes(
10
:file("src/vm/jvm/QAST/Compiler.nqp"),
11
:keywords(<map_classlib_core_op add_core_op map_jvm_core_op>)
14
%ops<parrot> := find_opcodes(
15
:file("src/vm/parrot/QAST/Operations.nqp"),
16
:keywords(<add_core_op add_core_pirop_mapping>)
19
%ops<moar> := find_opcodes(
20
:file("src/vm/moar/QAST/QASTOperationsMAST.nqp"),
21
:keywords(<add_core_op add_core_moarop_mapping>)
24
# Most backends programmatically add these ops - to keep our cheating simple,
25
# add them to each of the backends manually
26
for <if unless while until repeat_while repeat_until> -> $op_name {
28
%ops{$vm}{$op_name} := 1;
32
# Are ops that are implemented documented? Fail once per opcode
33
my %combined_ops := nqp::hash();
35
for %ops{$vm} -> $op {
36
if !%combined_ops{$op} {
37
%combined_ops{$op} := nqp::list($vm);
39
nqp::push(%combined_ops{$op}, $vm);
44
for %combined_ops -> $opcode {
45
my $vms := nqp::join(";", %combined_ops{$opcode});
46
ok(%documented_ops<any>{$opcode}, "Opcode '$opcode' ($vms) is documented");
49
# Do documented opcodes actually exist? Fail once per vm if not.
51
for %documented_ops{$vm} -> $doc_op {
52
ok(%ops{$vm}{$doc_op}, "documented op '$doc_op' exists in $vm");
56
sub find_opcodes(:$file, :@keywords) {
57
my %ops := nqp::hash();
58
my @lines := nqp::split("\n", nqp::readallfh(nqp::open($file,"r")));
60
next unless $line ~~ / @keywords /;
61
$line := nqp::split("'", $line)[1];
62
next unless nqp::chars($line);
69
my %hash := nqp::hash();
71
%hash{$vm} := nqp::hash();
76
sub find_documented_opcodes() {
77
my %documented_ops := hash_of_vms();
78
%documented_ops<any> := nqp::hash();
80
my @doc_lines := nqp::split("\n", nqp::readallfh(nqp::open("docs/ops.markdown","r")));
81
my @opcode_vms := nqp::list();
82
for @doc_lines -> $line {
83
my $match := $line ~~ /^ '##' \s* <[a..zA..Z0..9_]>+ \s* ('`' .* '`')? /;
86
@opcode_vms := nqp::clone(@*vms);
88
@opcode_vms := nqp::list();
89
if $match[0] ~~ /jvm/ {
90
nqp::push(@opcode_vms,"jvm");
92
if $match[0] ~~ /parrot/ {
93
nqp::push(@opcode_vms,"parrot");
95
if $match[0] ~~ /moar/ {
96
nqp::push(@opcode_vms,"moar");
100
next unless $line ~~ / ^ '* ' .* '(' /;
101
$line := nqp::substr2($line, 3);
102
$line := nqp::split("(", $line)[0];
103
for @opcode_vms -> $vm {
104
%documented_ops{$vm}{$line} := 1 ;
106
%documented_ops<any>{$line} := 1 ;
109
return %documented_ops;