#!perl -w
use 5.010;
use strict;

binmode STDOUT;

my @ops;

print <<"HEAD";
/* This file is automatically generated by $0.
 * ANY CHANGES WILL BE LOST!
 */
HEAD

say "/* forward decl */";
while(<>) {
    if(/^TXC(\w*) \s* \( (\w+) \)/xms) {
        push @ops, [$2, $1];

        s/\s*\{/;/;
        print;
    }
}

print <<'H';

enum tx_opcode_t {
H

for(my $i = 0; $i < @ops; $i++) {
    say "    TXOP_$ops[$i][0], /* $i */";
}

print <<'H';
    TXOP_last
}; /* enum tx_opcode_t */

static const tx_exec_t tx_opcode[] = {
H

for(my $i = 0; $i < @ops; $i++) {
    say "    TXCODE_$ops[$i][0],";
}

print <<'H';
    NULL
}; /* tx_opcode[] */

static const U8 tx_oparg[] = {
H

for(my $i = 0; $i < @ops; $i++) {
    my $arg_type = $ops[$i][1];
    my $flags;
    if($arg_type) {
        $flags .= "TXCODE" . uc $arg_type;
    }
    else {
        $flags = '0U';
    }

    say "    $flags, /* $ops[$i][0] */";
}

print <<'H';
}; /* tx_oparg[] */

static void
tx_init_ops(pTHX_ HV* const ops) {
H

for(my $i = 0; $i < @ops; $i++) {
    say "    (void)hv_stores(ops, STRINGIFY($ops[$i][0]), newSViv(TXOP_$ops[$i][0]));";
}

print <<'H';
} /* tx_register_ops() */
H
