こんにちは山本です。

皆さんは、難解プログラミング言語をご存知でしょうか?

私は去年にブログのお題を探している時にみつけました。

なので、今回はそれで記事を書こうかと思います。

まあ、メジャーどころの紹介でしかないんですけどね。

そうそう、一応難解プログラミング言語とは何か?です。

  • 難解プログラミング言語

難解プログラミング言語 (なんかいプログラミングげんご)とは、意図的に読解が困難なように設計されたプログラミング言語である。英語では、Esoteric programming language (略してesolangとも)と言われる。

基本的には、実用性を目指したものではなく、冗談プログラミング言語の一種で、いわゆるハッカーの間では、この種のジョークはたしなみとみなされており、難解プログラミング言語に区分されるプログラミング言語はいくつも作られてきた。

wikiからの引用です。

HQ9+

さて、まず最初にご紹介する言語が「HQ9+」です。

恐らく最も簡単に「Hello, world」出せる言語ではないかと思います。

もし、あなたが明日、「Hello, world」出せるよねと言われても、この言語を知っていれば
たやすくその問題を解決できることでしょう。

で、言語の仕様です。

  • H
    Hello, worldを出力
  • Q
    自身のソースを表示する
  • 9
    『99 Bottles of Beer』(アメリカの数え歌で、プログラミングの例題でよく利用される)の歌詞を出力する。
  • +
    アキュムレータをインクリメント(1だけ増やす)する。

この言語において、命令とはこの4つだけです。

つまり、もしあなたがHello, Worldを出そうと思うのであれば

H

これだけです。

実際に使ってみたい方もいると思うので、インタープリタのURLを貼っときます。

インタプリタ

Brainfuck

説明

brainfuckプログラムは、以下の8個の実行可能な命令から成る(他の文字は無視され、読み飛ばされる)。

  • >
    ポインタをインクリメントする。ポインタをptrとすると、C言語の「ptr++;」に相当する。
  • <
    ポインタをデクリメントする。C言語の「ptr–;」に相当。
  • +
    ポインタが指す値をインクリメントする。C言語の「(*ptr)++;」に相当。

  • ポインタが指す値をデクリメントする。C言語の「(*ptr)–;」に相当。
  • .
    ポインタが指す値を出力に書き出す。C言語の「putchar(*ptr);」に相当。
  • ,
    入力から1バイト読み込んで、ポインタが指す先に代入する。C言語の「*ptr=getchar();」に相当。
  • [
    ポインタが指す値が0なら、対応する ] の直後にジャンプする。C言語の「while(*ptr){」に相当。
  • ]
    ポインタが指す値が0でないなら、対応する [ (の直後[1])にジャンプする。C言語の「}」に相当[2]。

Hello World

++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++
..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.

何が何だか、よく分からないですね。

なので、実際に実行してみましょう。

このサイトで実行出来ます。
インタプリタ

どうでしょう、Hello Worldが表示されたかと思います。

こういう、記述になるんですね。

私が始めに考えた、Hello Worldは

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.+++++++++++++++++++++++++++++.+++++++..+++.>++++++++++++++++++++++++++++++++.<------------------------.++++++++++++++++++++++++.+++.------.--------.>+.

このようにループのない、とても冗長なものでした。

確かにループさせれば処理は短くなるんですが、この辺になれていないと、中々そういった処理は書けないものです。

記述がわからない方

わからない人はこちらを御覧ください。

0から9迄を表示する、Brainfuckのコードです。

これは、先ほどのインタプリタでステップ実行などをして頂けると値の動きが分かりやすいのではと思います。

++++[>++++++++++++<-]++++++++++[>.+<-]

ループカウンタを4にセットして、12を4回ループさせ、48までカウントアップをします。
次にループカウンタを10にセットした状態で、先程カウントアップした48をそのまま表示します。

表示されるのはASCIIの48なので数字の「0」になります。

その後に、一つカウントしながら10回ループをします。

49は1となり、50は2となり、9になるまで一文字づつ表示されていきます。

0123456789

低水準言語ぽい挙動ですね。

派生

あと、この言語簡潔な為か派生系が一杯あります。

Ook!

Ook. Ook? > ポインタをインクリメント
Ook? Ook. < ポインタをデクリメント
Ook. Ook. + ポインタの指す値をインクリメント
Ook! Ook! – ポインタの指す値をデクリメント
Ook. Ook! , 入力から1バイトをポインタの指す値に代入
Ook! Ook. . ポインタの指す値をASCII文字として出力
Ook! Ook? [ ポインタの指す値が0なら、対応する「Ook? Ook!」にジャンプ
Ook? Ook! ] ポインタの指す値が非0なら、対応する「Ook! Ook?」にジャンプ

Brainfuckの置き換えですね。

  • Hello World
Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook.
Ook. Ook. Ook. Ook. Ook! Ook? Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook.
Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook! Ook! Ook? Ook! Ook? Ook.
Ook! Ook. Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook.
Ook. Ook. Ook! Ook? Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook?
Ook! Ook! Ook? Ook! Ook? Ook. Ook. Ook. Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook.
Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook! Ook. Ook. Ook. Ook. Ook.
Ook. Ook. Ook! Ook. Ook. Ook? Ook. Ook? Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook.
Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook? Ook. Ook. Ook.
Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook! Ook! Ook? Ook! Ook? Ook. Ook! Ook.
Ook. Ook? Ook. Ook? Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook.
Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook? Ook. Ook. Ook.
Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook.
Ook. Ook? Ook! Ook! Ook? Ook! Ook? Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook.
Ook? Ook. Ook? Ook. Ook? Ook. Ook? Ook. Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook.
Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook.
Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook!
Ook! Ook. Ook. Ook? Ook. Ook? Ook. Ook. Ook! Ook.

インタープリタ

「Ook! Programm-Code」にコードを入れて、Decodeで実行できます。

頭の悪そうなのがとても良いですね。

コミュ障プログラミング言語

Brainfuckを拡張した言語ですね。

  • Hello World
ア…ア…ア…ア…ア…ア…ア…ア…ア…サセン…アア…ア…ア…ア…ア…ア…ア…ア…ア…
アア…ア…ア…ア…ア…ア…ア…ア…ア…ア…ア…ア…アア…ア…ア…ア…ア…ア…アア、アア、
アア、ア、ッス…アア…エット…アア…ア…ア…エット…ア…ア…ア…ア…ア…ア…ア…エット…エット…
ア…ア…ア…エット…アア…ア、エット…ア、ア、ア、ア、ア、ア、ア、ア、ア、ア、ア、ア、エット…アア、ア…ア…
ア…ア…ア…ア…ア…ア…エット…ア、ア、ア、ア、ア、ア、ア、ア、エット…ア…ア…ア…エット…ア、ア、
ア、ア、ア、ア、エット…ア、ア、ア、ア、ア、ア、ア、ア、エット…アア…ア…エット…

オンライン版のインタープリタは残念ながら見つかりませんでした。
なので、公式のインタプリタのリンクを貼っておきます。

ダウンロードしてお試しください。

インタープリタ

Shakespeare

最後に、Shakespeare です。

これは、通常のプログラミング言語では風情がなさすぎる……と考えたかは分かりませんが、ソースがシェイクスピアの演劇に見えるようになっています。

  • Hello World
The Infamous Hello World Program.

Romeo, a young man with a remarkable patience.
Juliet, a likewise young woman of remarkable grace.
Ophelia, a remarkable woman much in dispute with Hamlet.
Hamlet, the flatterer of Andersen Insulting A/S.


                    Act I: Hamlet's insults and flattery.

                    Scene I: The insulting of Romeo.

[Enter Hamlet and Romeo]

Hamlet:
 You lying stupid fatherless big smelly half-witted coward!
 You are as stupid as the difference between a handsome rich brave
 hero and thyself! Speak your mind!

 You are as brave as the sum of your fat little stuffed misused dusty
 old rotten codpiece and a beautiful fair warm peaceful sunny summer's
 day. You are as healthy as the difference between the sum of the
 sweetest reddest rose and my father and yourself! Speak your mind!

 You are as cowardly as the sum of yourself and the difference
 between a big mighty proud kingdom and a horse. Speak your mind.

 Speak your mind!

[Exit Romeo]

                    Scene II: The praising of Juliet.

[Enter Juliet]

Hamlet:
 Thou art as sweet as the sum of the sum of Romeo and his horse and his
 black cat! Speak thy mind!

[Exit Juliet]

                    Scene III: The praising of Ophelia.

[Enter Ophelia]

Hamlet:
 Thou art as lovely as the product of a large rural town and my amazing
 bottomless embroidered purse. Speak thy mind!

 Thou art as loving as the product of the bluest clearest sweetest sky
 and the sum of a squirrel and a white horse. Thou art as beautiful as
 the difference between Juliet and thyself. Speak thy mind!

[Exeunt Ophelia and Hamlet]


                    Act II: Behind Hamlet's back.

                    Scene I: Romeo and Juliet's conversation.

[Enter Romeo and Juliet]

Romeo:
 Speak your mind. You are as worried as the sum of yourself and the
 difference between my small smooth hamster and my nose. Speak your
 mind!

Juliet:
 Speak YOUR mind! You are as bad as Hamlet! You are as small as the
 difference between the square of the difference between my little pony
 and your big hairy hound and the cube of your sorry little
 codpiece. Speak your mind!

[Exit Romeo]

                    Scene II: Juliet and Ophelia's conversation.

[Enter Ophelia]

Juliet:
 Thou art as good as the quotient between Romeo and the sum of a small
 furry animal and a leech. Speak your mind!

Ophelia:
 Thou art as disgusting as the quotient between Romeo and twice the
 difference between a mistletoe and an oozing infected blister! Speak
 your mind!

[Exeunt]

とても良い感じです。まあ、全く内容が分かりませんが。。。

仕様をかいつまんで説明すると

  • 変数名はシェイクスピアの劇中に登場する人物の名前でなければいけない。
  • 「幕」(Act) と「場」(Scene) で構成され、GOTOで飛ばせる。
  • 変数を使うには、Enter (登場) コマンドで舞台に上げ、終わったらExit (退場) コマンドで退場させる。

解説を読んでもさっぱり分かりませんね。

まあ、とりあえず実行してみましょう。

調べる限り、オンラインのインタプリタは無いようでした。

と言いますか、インタプリタはmakeしろ!ってことのようです。

なので、ダウンロードして、makeします。

wget http://shakespearelang.sf.net/download/spl-1.2.1.tar.gz
tar xzvf spl-1.2.1.tar.gz
cd spl-1.2.1
make

a001

まあ、makeは大体初回は失敗するものです。

bisonが足りないと、依存問題ですね。

なので、さくっとインストールします。

yum install bison flex

flexも必須らしいので、合わせてインストールします。
そして、再度makeします。

lflってなんだよ!

調べると、flexに含まれるもののようです。

インストールしているんですけどね。。。

まあ、どうせ開発版にはあるんでしょう。

yum install flex-devel

でインストールすると、無事makeが成功しました。

では、コンパイルしてみましょう。

examplesディレクトリにサンプルがあるので、それを使用します。

cd examples
make hello

a003

またか!

えーと、32行目らしいので見てみます。

                    Scene II: The praising of Juliet.

が、問題ない記述に見えます。多分ですが。。。

もう一度、エラーメッセージを見てみます。

../spl/bin/spl2c hello.c

どうやらシェークスピアは、一度Cに置換しているようです。

gcc -O2 -Wall -Wno-unused -I../spl/include -c hello.c
hello.c: In function ‘main’:
hello.c:49: error: duplicate label ‘act_i_scene_i’

そして、Cのコンパイル時にラベルが重複エラーが出ています。

act_i_scene_i

とは、第一幕(Act)の一場(Scene)ということなのでしょう。

その辺は読み解けましたが、それ以上はどうにもならなそうです。

なのでググります。

え~と、コミュニティに情報がありました。
英語ですがないよりましですね。

This is a defect in a regular expression in the lexical parser.

パーサーの、正規表現の欠陥です?ってとこですかね。

I fixed the issue.

同じページに、修正したとの情報もありまして、辿ってみましたが、パッチを当てれば良いというものでもなさそうです。

どうしたものかと考えていたところ、ふと思いつきました。

IとIII、IIIとありますが、ローマ数字ですね。

そして、IIもIIIも駄目となると、同じ文字が続くと駄目なのではないか?

Iより大きく、同じ文字が続かない最小の数字は何かと考えるとIVがあります。

「Scene II: The praising of Juliet.」を「Scene IV: The praising of Juliet.」としてみて、再度コンパイルします。

a004

エラーの位置が変わりました。

42行目は「Scene III: The praising of Ophelia.」でした。

どうやら、この方法で回避出来そうですね。

正直どうかと思う方法ですが、どうにかでも回避しないと記事が書けないのでこのまま続けます。

The Infamous Hello World Program.

Romeo, a young man with a remarkable patience.
Juliet, a likewise young woman of remarkable grace.
Ophelia, a remarkable woman much in dispute with Hamlet.
Hamlet, the flatterer of Andersen Insulting A/S.


                    Act I: Hamlet's insults and flattery.

                    Scene I: The insulting of Romeo.

[Enter Hamlet and Romeo]

Hamlet:
 You lying stupid fatherless big smelly half-witted coward!
 You are as stupid as the difference between a handsome rich brave
 hero and thyself! Speak your mind!

 You are as brave as the sum of your fat little stuffed misused dusty
 old rotten codpiece and a beautiful fair warm peaceful sunny summer's
 day. You are as healthy as the difference between the sum of the
 sweetest reddest rose and my father and yourself! Speak your mind!

 You are as cowardly as the sum of yourself and the difference
 between a big mighty proud kingdom and a horse. Speak your mind.

 Speak your mind!

[Exit Romeo]

                    Scene IV: The praising of Juliet.

[Enter Juliet]

Hamlet:
 Thou art as sweet as the sum of the sum of Romeo and his horse and his
 black cat! Speak thy mind!

[Exit Juliet]

                    Scene V: The praising of Ophelia.

[Enter Ophelia]

Hamlet:
 Thou art as lovely as the product of a large rural town and my amazing
 bottomless embroidered purse. Speak thy mind!

 Thou art as loving as the product of the bluest clearest sweetest sky
 and the sum of a squirrel and a white horse. Thou art as beautiful as
 the difference between Juliet and thyself. Speak thy mind!

[Exeunt Ophelia and Hamlet]


                    Act IV: Behind Hamlet's back.

                    Scene I: Romeo and Juliet's conversation.

[Enter Romeo and Juliet]

Romeo:
 Speak your mind. You are as worried as the sum of yourself and the
 difference between my small smooth hamster and my nose. Speak your
 mind!

Juliet:
 Speak YOUR mind! You are as bad as Hamlet! You are as small as the
 difference between the square of the difference between my little pony
 and your big hairy hound and the cube of your sorry little
 codpiece. Speak your mind!

[Exit Romeo]

                    Scene IV: Juliet and Ophelia's conversation.

[Enter Ophelia]

Juliet:
 Thou art as good as the quotient between Romeo and the sum of a small
 furry animal and a leech. Speak your mind!

Ophelia:
 Thou art as disgusting as the quotient between Romeo and twice the
 difference between a mistletoe and an oozing infected blister! Speak
 your mind!

[Exeunt]

と、先ほどのルールでソースを書き換え、実行!

a005

ようやく、Hello Worldが表示されました。

解説

ソースの内容については、解説している日本語サイトがありましたのでリンクを貼っておきます。

http://kara.ifdef.jp/program/spl/spl04.html

流石に、これを説明するのは大変そうなので。。。。

まとめ

それ程、数は多くありませんが興味深い言語を紹介させて頂きました。

どれも、馬鹿馬鹿しくて非常に良いのですが、その中でも私はShakespeareが良かったです。

無駄に冗長なところや、可読性がある意味高いあたり素晴らしい言語ですね。

願わくば、ちゃんと動くコンパイラをご用意頂きたいものです。

さて、今回紹介した以外にも色々と言語は存在します。

wWvのみで表現する、Grass。
スペース、タブ、改行のみの、Whitespace。
画像でプログラミングする、Piet。

そして、恐らく最も難解であろう言語のMalbolge。

まあ、今回の記事にそれらを含めなかったのは、解説が難しいのと、一回分の記事の長さを満たしたなんですが。。。

もしかしたら、機会があったら、それらの記事を書くかもしれません。
(多分無いと思いますが)

では、また次回。