てくの電卓
戻る
NAME
    perl2icl.pl - perlプログラムのソースを ICLプログラムのソースに翻訳する

SYNOPSIS
    perl2icl.pl [オプション] perlソースファイル [ICLソースファイル]

    ICLソースファイルが与えられないときには、標準出力に出力します。エラー
    メッセージなど漢字コードは Shift_JIS です。Windows での使用を想定して
    いますが、他のシステムでも動作はします。なお、改行コードは LF です。

OPTIONS
    --line: 1コマンド1行モードで出力する
    (Ver.1.0以前のシミュレータは1コマンド1行モードでないと動作しない)

    --version: ファイルのバージョンを出力する

VERSION
    1.2.1

DESCRIPTION
    「てくの電卓」で実用的なプログラムを作成しようとするときには、どうしても
    変数=メモリをたくさん使用することになってしまいます。ところが、「てくの
    電卓」では、変数名ではなくメモリ番号でしかアクセスができないため記述性の
    悪いプログラムとなってしまいます。特に、変数をメモリ番号に割当てる際、
    上書きがおこらないようにメモリ番号を管理することは、なかなか骨がおれる
    ことです。

    perl2icl.pl は、perl のプログラムソースから、ICL のソースを作成する翻訳
    プログラムです。少しでも、ICL の幼稚性を補う目的で作成しました。かなり
    元プログラムの記述法に制限がありますが、「てくの電卓」利用者の皆様の
    お役に立てることを願っています。

    変数からメモリ番号への割当て
    perl2icl.pl は、変数からメモリへの割当てを行います。この際、{} で囲ま
    れた範囲内で、my 宣言された変数は、他の領域における同じ名前の変数と区別
    してメモリに割当てます。また、my 宣言されていない変数や、main 領域で my
    宣言された変数は、グローバルな変数として割当てを行います。

    for ループ
    for(式;$var<=$vmax;$var++){...} のように定義された for ループを ICL の
    FOR ループに変換します。ただし制限があります。条件部は $var<$vmax の
    ように「<=」以外の関係演算子を使用しているものや、$var-- のように、
    状態更新部が $var++ ではないものはエラーとなります。また、条件部に論理
    演算子を使用することもできません。これは、ICL の FOR 構文が原始的である
    ことの反映です。これ以外形式の for ループは、次に述べる while を利用して
    うまく表現してください。

    while ループ
    while を、ICL の WHILE に翻訳します。この際、条件式を書換えて、ICL の
    WHILE 構文の幼稚性を補います。ただし、論理演算子はやはり、使用できま
    せん。

    ユーザ定義関数の参照
    ICL のユーザ定義関数は、式の途中では使用できません。つまり、

    5 * ( 4 + 3 FN[1] ) = STM[2]

    のように使用することができません。このような式があると、エラーでは
    なく、FN[1] の前に「=」を挿入して計算をしてしまいます。これは、ICL
    の問題点のひとつです。このため、perl2icl.pl は、

            $a = 5*(4 + fun(3))

    のような式があると、

            3 FN[1] STM[1]
            5 * ( 4 + M[1] ) = STM[2]

    のように、式を分割します。

    ユーザ定義関数の定義
    次のようなユーザ関数定義は、

            sub fun {
                    my ($a,$b) = @_;
                    $a * $b;
            }

    次のように翻訳します。

            DEFN[1]
            STM[10]
            RY STM[11]
            M[10] * M[11] =
            FEND

    のように翻訳します。ここで、定義部の第1行目は、() 付きの my 宣言
    を用いて、@_ からの代入とすることが必要です。my $a = shift; の
    ような融通は利きません。

EXAMPLES
    (1) 組込み関数
     [perl]
            use POSIX;
            my $x = 0.5;
            my $y = 0.5;
            print pow($x,$y),"\n";
            print sin($x),"\n";
            print cos($x),"\n";
            print log($x),"\n";
            print log10($x),"\n";
     [ICL]
            0.5 STM[0]
            0.5 STM[1]
            M[0] pow M[1] = HALT
            M[0] sin = HALT
            M[0] cos = HALT
            M[0] ln = HALT
            M[0] log = HALT

    (2) while, ユーザ定義関数
     [perl]
            my $limit = 1e-10;
            my $x1 = 0;
            my $x2 = 1;
            my $y1 = fun($x1);
            my $y2 = fun($x2);
            if ($y1*$y2 > 0) {
                    print "No solution\n";
                    exit;
            }
            my ($x3,$y3);
            my $e = ($x2 - $x1);
            while($e > $limit) {
                    $x3 = ($x2 + $x1)*0.5;
                    $y3 = fun($x3);
                    if ($y3*$y1 > 0) {
                            $x1 = $x3;
                            $y1 = $y3;
                    } else {
                            $x2 = $x3;
                            $y2 = $y3;
                    }
                    $e = ($x2 - $x1);
            }
            print $x3,"\n";
            exit;
            sub fun {
                    my ($x) = @_;
                    exp(-$x) - 0.5;
            }
    [ICL]
            1e-10 STM[0]
            0 STM[1]
            1 STM[2]
            M[1] FN[0] STM[3]
            M[2] FN[0] STM[4]
            M[3] * M[4] = STM[8]
            0
            IF(X<M[8])
            HALT
            EXIT
            ENDIF
            ( M[2] - M[1] ) STM[7]
            M[7]
            WHILE(X>M[0])
            ( M[2] + M[1] ) * 0.5 = STM[5]
            M[5] FN[0] STM[6]
            M[6] * M[3] = STM[9]
            0
            IF(X<M[9])
            M[5] STM[1]
            M[6] STM[3]
            ELSE
            M[5] STM[2]
            M[6] STM[4]
            ENDIF
            ( M[2] - M[1] ) STM[7]
            M[7]
            WEND
            M[5] = HALT
            EXIT
            DEFN[0]
            STM[10] 
            ( -1 * M[10] ) exp - 0.5 =
            FEND

BUGS
    foreach, do-while, until, break, last などの構文とコマンドが使用
    できません

    文字列を扱うことができません

    論理演算子 が使用できません

    その他、ここでは記述していない多くの制限があります

AUTHOR
    和泉サイバーネット株式会社 info@izumi-si.co.jp
戻る
Izumi Cyber Networks Inc.