### ----------------------------------------------------
### -- MoarVM::Bytecode
### -- Licenses: Artistic-2.0
### -- Authors: Elizabeth Mattijsen
### -- File: makeOPS.raku
### ----------------------------------------------------
#!/usr/bin/env raku

# This script reads MoarVM's ops file, and generates the necessary
# data structures in the lib/MoarVM/Ops.rakumod file, leaving any
# additional code in there untouched

# always use highest version of Raku
use v6.*;

my $generator = $*PROGRAM-NAME;
my $generated = DateTime.now.gist.subst(/\.\d+/,'');
my $start     = '#- start of generated part of Ops ';
my $idpos     = $start.chars;
my $idchars   = 3;
my $end       = '#- end of generated part of Ops ';

# slurp the whole file and set up writing to it
my $filename = "lib/MoarVM/Ops.rakumod";
my @lines = $filename.IO.lines;
$*OUT = $filename.IO.open(:w);

my @ops;
my %ops;
for $*EXECUTABLE.parent(3).add("nqp/MoarVM/src/core/oplist").lines {
    if $_ && !.starts-with("#") {
        my @parts = .words;
        my $op = @parts.shift;
        @ops.push: $op;
        %ops{$op} := @parts.join(" ");
    }
}

# for all the lines in the source that don't need special handling
while @lines {
    my $line := @lines.shift;

    # nothing to do yet
    unless $line.starts-with($start) {
        say $line;
        next;
    }

    say "$start ---------------------------------------------";
    say "#- Generated on $generated by $generator";
    say "#- PLEASE DON'T CHANGE ANYTHING BELOW THIS LINE";

    # skip the old version of the code
    while @lines {
        last if @lines.shift.starts-with($end);
    }

    # Add the new version
    say 'my constant @ops =';
    say "  '$_'," for @ops;
    say ";";
    say "";
    say 'my constant %ops =';
    say "  '$_', '%ops{$_}'," for @ops;
    say ";";

    # we're done for this role
    say "#- PLEASE DON'T CHANGE ANYTHING ABOVE THIS LINE";
    say "$end -----------------------------------------------";
}

# close the file properly
$*OUT.close;

# vim: expandtab sw=4


