TL/1 の変なところ (論理演算)

プログラミング言語 TL/1 の変数や定数は 1 バイト幅の整数であることは以前述べた通りである。 定数のリテラル表記としては数字や文字での表現があるということも説明したが、 $FF と 0 に関しては更に別の表記として TRUE と FALSE と書くことも出来る。 これは名前から推察できる通り真偽値を表現している。 C を始めとして低レベル寄りのプログラミング言語では整数と真偽値は明確には区別されてない場合があり、 TL/1 もまたそうであるということだ。

具体的には TL/1 において比較演算子が成り立つときには TRUE 、すなわち $FF を返し、そうでないときは FALSE 、つまり 0 を返す。 C 等では真値として 1 を返すのでこの違いには留意が必要だろう。

とは言うものの、真値に $FF を使うのは TL/1 特有というわけでもない。 以前に N88-BASIC が真値として -1 を返すことについて紹介した。 ($FF は 1 バイト幅の 2 の補数形式と考えれば -1 と等しい。)

http://saito.hatenablog.jp/entry/2012/12/09/115710

ビットが全て立った値を真値として使うことでビット演算と論理演算の区別しなくてよくなるというのはかつてはよく知られていた性質かもしれない。 区別しなくてよいというのは逆に言えば区別できないというデメリットでもあるのだが。

例として、与えられた値が奇数 (最下位ビットが立っている) であり、なおかつ 100 より大きいことを判定する関数を考えてみよう。

TEST(X)
BEGIN
  RETURN ((X .AND. 1) = 1) .AND. (X>100)
END

左側の AND はビット演算として、右側の AND は論理演算として使っていることになる。

ではここで比較演算子が真偽値として返す値をみっつの言語別に表にまとめてみよう。

C 1 0
N88-BASIC -1 0
TL/1 -1 0

この表だけを見て TL/1 での真偽値は N88-BASIC と同じと言えるかというとそうでもない。

IF 文が真や偽として判断する値がこうなっているからである。

C 0以外 0
N88-BASIC 0以外 0
TL/1 -1 -1以外

TRUE でも FALSE でもない値を C や N88-BASIC では真と判断するが TL/1 では偽として扱われるのである。

// C では 50 は真
int main(void) {
  if(50) printf("TRUE\n");
  else printf("FALSE\n");

  return 0;
}
10 'N88-BASIC では 50 は真
20 IF 50 THEN PRINT "TRUE" ELSE PRINT "FALSE"
% TL/1 では 50 は偽
BEGIN
  IF 50
    THEN WRITE(0: "TRUE", CRLF)
    ELSE WRITE(0: "FALSE", CRLF)
END

数値と真偽値のマッピングにもバリエーションがあるということだ。

最近の言語だと数値以外のオブジェクト、空文字や nil や undefined といったものが真か偽かで混乱したりもしていて、やってることは昔と変わらないどころか混迷を深めているのではないかなんて思ったりもする。

Document ID: 0011bb1aed52137fa8352653a6104527