dcでマクロを記憶する

ドラマ 『レンタルの恋』(2017)
得体のしれないレンタル彼女のナンバーワンを剛力彩芽が演じます。レンタル中とレンタル終了のときのレミの変化が面白いです。

またまたdcです。マクロを使って合計の計算をします。
最初にマクロとして定義したいコマンドを[]でかこってスタックに入れます。

takk@deb8:~$ dc
[+z1<f]
                        |       |
                        |       |
                        |       |
                        |       |
                        |[<z1<f]|
                        +-------+
                          stack

スタックに積まれたマクロは実行時にスタックから消えてしまうため、何度も使うためには、予めsコマンドで任意のレジスタ(ここではfレジスタ)に記憶しておきます。

sf
                        |       |
                        |       |
                        |       |
                        |       |    +-------+
                        |       |    |[<z1<f]|
                        +-------+    +-------+
                          stack        reg f

今回登録したマクロは、スタック内の数の合計を計算するマクロです。
これを使って計算してみましょう。

1 2 3 4 5 6 7 8 9 10 lfxn
55

lfxで、レジスタfに登録されているマクロを実行し、nコマンドでスタックの内容、つまり合計である55を表示しました。
nはpと違いスタックから取り出して表示しますので、取り出した数字はスタックから消えます。

ではマクロの解説です。+コマンドでスタックから値を2つ取り出して、足し算を行い、結果をスタックへ戻します。その後、zコマンドで現在のスタックサイズを数値としてスタックに積みます。
1で、数値1をスタックに積んだら、<fで、スタックの上2つと取り出し、それらの値を比較します。つまり、1と、スタックに積まれている数値を比較します。もし1より大きかったら、再度レジスタfのマクロを実行します。

このマクロのイメージをperlスクリプトにしてみました。関数f()が、レジスタfに登録したマクロに該当します。

     1	push @stack,1;
     2	push @stack,2;
     3	push @stack,3;
     4	push @stack,4;
     5	push @stack,5;
     6	push @stack,6;
     7	push @stack,7;
     8	push @stack,8;
     9	push @stack,9;
    10	push @stack,10;
    11	
    12	f();
    13	
    14	printf "%d\n",pop @stack;
    15	
    16	sub f{
    17		# "+" 
    18		$a=pop @stack;
    19		$b=pop @stack;
    20		$c=$a+$b;
    21		push @stack,$c;
    22	
    23		# "z"
    24		$size=@stack;
    25		push @stack,$size;
    26	
    27		# "1"
    28		push @stack,1;
    29	
    30		# "<f"
    31		$a=pop @stack;
    32		$b=pop @stack;
    33		f() if($a < $b);
    34	}

perlでこんなに長く書いたことが[+z1<f]のやっていることです。

dcコマンドを使いこなす練習をすると、頭の体操になりそうです。

Leave a Reply

Your email address will not be published. Required fields are marked *

CAPTCHA