view cbctools/change_OP_to_cbc.pl @ 10:30098d746672

modofied argument
author Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
date Tue, 09 Oct 2018 13:04:47 +0900
parents 6c4ba0dc43e8
children e08e6dca633f
line wrap: on
line source

#!/usr/bin/env perl
use strict;
use warnings;

my $cbc_file = shift or die; # src/core/cbc-interp.cbc

open my $fh, '<',$cbc_file;
my @cbc_lines= <$fh>;
close $fh;

my @rewritec = ();
my $indent = " " x 12;
my $none_left_blanket = 0;

my $i = 0;
for (;$i < scalar(@cbc_lines); $i++){
    push @rewritec,$cbc_lines[$i];
    if ($cbc_lines[$i] =~ /DISPATCH\(NEXT_OP\)/){ # DISPATCHの中身を書き換えるのでそこまで飛ばす
        $i++;
        last;
    }
}

for (;$i < scalar(@cbc_lines); $i++){
    # check OP(.*) {  codes
    if ($cbc_lines[$i] =~ /^\s+OP\((.*)\):/ ){
        my $opcode = $1;
        $none_left_blanket = $cbc_lines[$i] =~ /{/ ? 0 : 1;
        # transrate OP(HOGE) to __code hoge(INTERP *i){
        $cbc_lines[$i]  = $indent. "__code ".$opcode."(INTERP i){\n";
        push @rewritec,$cbc_lines[$i];

        # 次の行に移動
        $i++;

        # この行がOP()だった場合
        #  OP(DEPRECATED_4):
        #  OP(DEPRECATED_5): <- $i
        # このような宣言になっているので$iにgotoするように関数を書き直し
        # $iの部分の関数定義を次ループでするために一行戻して再ループ

        if ($cbc_lines[$i] =~ /^\s+OP\((.*)\):/){
            push @rewritec,"$indent   goto $1(i);\n";
            insert_right_blanket();
            $i--;
            next;
        }

        # 例外だったらかえってこないはずなのでgoto
        if ( $cbc_lines[$i] =~ /MVM_exception_throw_adhoc/ && $cbc_lines[$i+1] =~ /OP\(/){
            push @rewritec, change_i($cbc_lines[$i]);
            insert_right_blanket();
            next;
        }
    }

    # 普通の行は変換してinsertする
    push @rewritec,change_i($cbc_lines[$i]);


   if ($i != scalar(@cbc_lines)-1 && $cbc_lines[$i+1] =~ /OP/ && $none_left_blanket){
        insert_right_blanket();
        $none_left_blanket = 0;
    }
}

map { print; } @rewritec;


sub change_i {
    my $str = shift;
    $str =~ s/cur_op/i->cur_op/g;
    $str =~ s/tc/i->tc/g;
    $str =~ s/cur_callsite/i->cur_callsite/g;
    $str =~ s/NEXT;/NEXT(i);/;
    return $str;
}

sub insert_right_blanket {
    push @rewritec,"$indent}\n";
}