「なぜ、制御構造?」と思われるかもしれませんが、それはADP(Prolog)が持っている制御構造(バックトラック)が独特のものということと、JavaScriptやRubyにありますクロージャが本格的に普及してきて私自身が持っている制御構造に対する考え方(というか感覚)を変える必要があるので記事にしてみます。
制御構造とは
制御構造とはプログラムの流れ、広くはその命令(for文とかif文)を指します。制御構造を有名なものにしたのは、かのダイクストラ氏が提唱した構造化プログラミングがあります。今となっては『構造化プログラミング』という言葉を始めて聞いた人もいらっしゃるかと思いますが、『構造化プログラミング』が提唱された後に、今ではおなじみの制御構造文・選択(if)
・反復(for,while等のループ)
が明確になりました。それまでの言語ではif文やfor文もありましたが充分でなく、本格的なプログラムの記述にはgoto文を使う必要がありました。そのれに加えてgoto文では様々なプログラムの流れを作ることが出来、流れの追いにくいいわゆるスパゲティプログラムというものもありました。私が駆け出しの頃(20年程前)にはよく可読性の悪いプログラムに対して『このスパゲティプログラムが~』という表現を聞いていました。
機械語ではどうしているのか?
なぜ、「機械語の話が出てくるのか?」と思われるかもしれませんが、制御構造の発展の歴史のルーツを探ることと、コンパイラ言語では制御構造が機械語に変換されるのでその仕組みを探るという意味で、続いて機械語の話をします。機械語では初期のプログラミング言語のように比較文(if文)とgoto文のみで制御を行います。今となっては逆に難しいかもしれませんが、for文やwhile文がなくてもif文とgoto文の組み合わせでループを記述することが出来ます。
意外に思われるかもしれませんが、もう一つの制御構造文である関数呼び出し(サブルーチン呼び出し)も機械語にCALL命令という形で存在します。初期のCPUにはCALL命令がないものもあったらしいですが、今われわれが主に使っているパソコンのx86と呼ばれるCPUにもCALL命令があります。さらにx86の先祖をたどりますと、8080というパソコン用の8ビットCPUがありますが、そのCPUにもCALL命令があります(それから先は8008、4004とたどれますがこれらにCALL命令があるかどうかは不明です・・・)。
もちろんCALL命令が関数呼び出しとイコールではありません。CALL命令と関数呼び出しの違いは引数の受け渡しになります。CALL命令には引数の概念がありません。引数の受け渡しはレジスタまたはスタックまたはグローバル変数ということになります。C言語の関数呼び出しが機械語に翻訳されるるとCALL命令に翻訳されますが、その引数はスタックで渡されます。
続いては、公開1周年記念特集記事として『プログラミング言語の制御構造のいろいろ(2)』を書いてみます。