バロース B5000
呼び出し側が終了しても処理を続行できる独立したタスクを生成する。このため、子プロセスは親の環境にある変数群にアクセスできないし、呼び出されるプロシージャの引数は全て値渡しでなければならない。
以上のようにバロースの拡張したALGOLには後のAdaなどの言語に見られるマルチプロセッシング機構と同期機構が全て備わっている。また、非同期処理サポートはハードウェアレベルで行われる。
他の可能性としてプロシージャがINLINEを宣言された場合がある。この場合コンパイラはそのプロシージャを呼び出しているプロシージャ内に展開し、プロシージャ呼び出しのオーバヘッドをなくす。
例で示したプログラムは normal 呼び出しである。したがって情報は全てひとつのスタック上に配置される。非同期呼び出しの場合、スタックは複数に分割され、各プロセスは独立して動作しつつ両者のデータを共有できるようになっている。
スタックハードウェアの最適化として D (Display) レジスタがある。Dレジスタは各スタックフレームの開始地点を指す。Dレジスタ群はプロシージャ呼び出しに応じて自動的に更新され、ソフトウェアからはアクセスできない。32本のDレジスタがあり、語彙の入れ子の最大が32レベルとなっているのはここから来ている。
語彙レベル5(D[5])から語彙レベル2(D[2])の広域変数にアクセスする方法を考えてみよう。
B5000は高級言語をサポートするよう設計された。当時、FORTRANとCOBOLが登場したばかりである。FORTRANもCOBOLもソフトウェア技術から見れば不足である。したがってもっと新しい、まだ試されていないALGOL-60が採用された。正確にはALGOLから派生した言語 Elliott ALGOL が採用された。これはアントニー・ホーアが Elliott 503 というマシン用に開発したものである。ALGOLに現実的な入出力命令を追加したもので、強力な文字列操作機能を持っている。ホーアのチューリング賞受賞講演では、これについて論じている。
ALGOL-60は、FORTRANなど他の言語を設計した経験のある専門家たちが設計した。設計にはバッカス・ナウア記法を用い、非常にきれいな文法を持つ言語となっている。多くの言語の先祖でもあり、Pascal、C言語、Simula、Ada、Eiffelなどがそれにあたる。
B5000はしたがって非常に強力な言語に基づいている。他のベンダーはALGOLコンパイラの実装を試みたが、実装できなかったという。しかし、当時学生だったドナルド・クヌースは、夏休み期間中にバロースの以前のマシン上に ALGOL-58 を実装した。ALGOLなどの高級言語はアセンブリ言語と同等の能力がないと思われがちで、ALGOLのシステム記述言語としての潜在能力に気づいていなかった。
バロース B5000は、バロースが1961年にリリースした大型コンピュータの名称。当時バロースは、大型・中型・小型でそれぞれ全く異なるアーキテクチャを採用し、ロバート・S・バートン(英語版)のコンセプトからそれぞれ命令セットを特定の高水準言語向けに最適化するという戦略をとった。大型システムの設計部門はスタックマシン型命令セットを採用し、命令の密度を高めると共にデータワード長を48ビットとした。B5000は ALGOL 60 向けに最適化されており、単純なコンパイラでコンパイル可能とした。後継にはB5500がある。その後、B6500/B6700 やその後継機がリリースされた。なお、中型システムはCOBOLに最適化されており、小型システムはコントロールストアが書き換え可能で命令セットを置換可能とされた。
1880年代に創業したバロースはコンピュータ業界では最古参だったが、1950年代末の同社の主力製品はまだ電気機械式の会計機 Sensimatic などだった。IBM、NCR、UNIVACといったライバル企業は既に大型コンピュータを生産し始めていた。遅れて参入することになったバロースは、当時の最新のアイデアに基づく全く新たな設計を採用するという戦略をとった。B5000のアーキテクチャは長続きしなかったが、それをベースとしてB6500が生まれている。そのアーキテクチャはユニシスの ClearPath Libra ファミリに受け継がれており、B6700からサポートしているMCPというオペレーティングシステムがほぼそのまま動作している。第三の大型システムであるB8500は商業的には成功しなかった。
プロシージャを非同期タスクとして呼び出し、別のスタックを呼び出されたプロシージャの語彙レベルから処理できるように設定して使用する。非同期タスクなのでコルーチンとは異なり、明確なタスク間の制御の受け渡しは存在しない。プロシージャは呼び出した側の環境にアクセスできるので、これは非常に効率的なプロセス間通信機構でもある。複数のタスクが共通の変数群にアクセスできるため、競合状態を避けるための同期が必要である。これはEVENTデータ型で対応でき、プロセスは他のプロセスと協調動作するために何らかのイベントを待つ(WAIT)ことができる。EVENTは相互排他型同期を行う PROCURE と LIBRATE 関数も使うことができる。何らかの理由で子プロセスが終了しても、呼び出し側タスクは処理が続行される。しかし、親プロセスが終了した場合、そこから派生した子プロセスは自動的に終了させられる。
この風潮はC言語が開発されるまで続いた。
バロースのALGOLコンパイラは非常に高速であった。エドガー・ダイクストラはパサデナのB5000の工場で自身の書いたプログラムのコンパイルを行い、その高速さに驚き、即座に何台か大学(アイントホーフェン工科大学)に欲しいと言ったとされる。このコンパイラの高速性にはいくつか理由があるが、最も大きな理由はワンパスコンパイラ(英語版)だったためである。初期のコンピュータはメモリ容量が小さく、ソースコードをメモリ上に全て置くのも難しかった。そのためソースコードをメモリ上に保持せず、何度か読み込む必要があった。バロースのALGOLでは、各変数を使用する前に宣言する必要があった。これにより、ソースコードを1度読み込んだだけでコンパイルを完了させることができた。この概念は理論的にも深い意味があるが、同時にそれによってコンパイルが非常に高速化される。パンチカードからソースコードを読み込むと即座にコンパイルでき、バロースのカードリーダーは業界でも最速だった。
COBOLコンパイラもワンパスコンパイラで、同様に高速だった。パンチカード4000枚のCOBOLプログラムを毎秒1000枚のカードを読み込んでコンパイルできた。全ソースコードを読み込むと、即座にコンパイル済みのプログラムを実行可能だった。