Very early C compilers and language

FileSizeDate
last1120cdir 
prestructcdir 

Much of this comes from Dennis Ritchie's web page about these early C compilers, and is quoted below with Dennis' permission.
この文章の大半は Dennis Ritchie の early C compilers に関する web ページから持ってきたもので、 Dennis の許可を得て下記に引用しました。

As described in the C History paper, 1972-73 were the truly formative years in the development of the C language: this is when the transition from typeless B to weakly typed C took place, mediated by the (Neanderthal?) NB language, of which no source seems to survive. It was also the period in which Unix was rewritten in C.
C History paper で説明した通り、 1972-73 は本当に C 言語の開発が形作られた年でした: これは、いつ 型のない B から ソースを紛失したと思われる (ネアンデルタール人の?) NB を経て 貧弱な型のある C への移行が発生したを示したものです。 また Unix が C で書き直された時期を示すものでもあります。

Two tapes are present here; the first is labeled "last1120c", the second "prestruct-c". I know from distant memory what these names mean: the first is a saved copy of the compiler preserved just as we were abandoning the PDP-11/20, which did not have multiply or divide instructions, but instead a separate, optional unit that did these operations (and also shifts) by storing the operands into memory locations.
ここで紹介するテープは2つあります; 最初のものは "last1120c" のラベルが張られたもの、 そして2番目は "prestruct-c" のラベルがはられたものです。 これらの名前が意味する遠い記憶を思い出しました: 最初のものは、ちょうど PDP-11/20 (での作業) を 諦めつつあった時のコンパイラのコピーを保存したものです。 これは乗算と除算のインストラクションがありませんが、 その代わりに、メモリ上にオペラントをおいて、 これらの操作 (更にシフト演算) を行なう オプショナルユニットがありました。

The earlier compiler does not know about structures at all: the string "struct" does not appear anywhere. The second tape has a compiler that does implement structures in a way that begins to approach their current meaning. Their declaration syntax seems to use () instead of {}, but . and -> for specifying members of a structure itself and members of a pointed-to structure are both there.
初期のコンパイラは構造体を全く知りませんでした: "struct" の文字列はどこにも登場しません。 2番目のテープは現在の意味に近い方法で構造体を実装したコンパイラです。 その宣言の文法では {} の代わりに () を 使っていたようですが、 構造体自身のメンバを示す . と 構造体のポインタからメンバを示す -> は 既に存在していました。

Neither compiler yet handled the general declaration syntax of today or even K&R I, with its compound declarators like the one in int **ipp; . The compilers have not yet evolved the notion of compounding of type constructors ("array of pointers to functions", for example). These would appear, though, by 5th or 6th edition Unix (say 1975), as described (in Postscript) in the C manual a couple of years after these versions.
コンパイラは int **ipp; といった 複合した宣言子を使う、 今日の一般的な宣言の文法も そして K&R さえも まだ扱うことができませんでした。 コンパイラはまだ タイプ・コンストラクタを組み合わせた表記へ 進化していませんでした。 (例えば、関数へのポインタの配列など) しかしながら、 5th/6th Edition の数年後の (Postscript による) C manual の記述によると、 これは 5th/6th Edition の Unix のものと思われます。

Instead, pointer declarations were written in the style int ip[];. A fossil from this era survives even in modern C, where the notation can be used in declarations of arguments. On the other hand, the later of the two does accept the * notation, even though it doesn't use it. (Evolving compilers written in their own language are careful not take advantage of their own latest features.)
代わりに、 ポインタの宣言は int ip[]; というスタイルで書かれています。 この時代の化石は 引数の宣言に使うことのできる表記として、 現在の C でも生き残っています。 一方、 この2つの後のものは それを使わなくても * の記法を受け付けます。 (それ自身の言語で書かれたコンパイラを発展させる場合は 最新の機能を殺さないように慎重におこなわなければなりません)

It's interesting to note that the earlier compiler has a commented-out preparation for a "long" keyword; the later one takes over its slot for "struct." Implementation of long was a few years away.
初期のコンパイラで "long" というキーワードの前処理を コメントアウトしているところが面白いです; 後のものは "struct" のためにそのスロットを引き継ぎます。 long の実装は数年後のことでした。

Aside from their small size, perhaps the most striking thing about these programs is their primitive construction, particularly the many constants strewn throughout; they are used for names of tokens, for example. This is because the preprocessor didn't exist at the time.
その小さなサイズはさておき、 おそらくこのプログラムの最も目を引くところは その古い構成、特に多くの定数が至るところに散りばめられていることです; 例えば、トークンの名前のために使われています。 これはこの時点ではプリプロセッサが存在していなかったからでしょう。

A second, less noticeable, but astonishing peculiarity is the space allocation: temporary storage is allocated that deliberately overwrites the beginning of the program, smashing its initialization code to save space. The two compilers differ in the details in how they cope with this. In the earlier one, the start is found by naming a function; in the later, the start is simply taken to be 0. This indicates that the first compiler was written before we had a machine with memory mapping, so the origin of the program was not at location 0, whereas by the time of the second, we had a PDP-11 that did provide mapping. (See the Unix History paper). In one of the files (prestruct-c/c10.c) the kludgery is especially evident.
次に、あまり目につかないが驚くべき変わった点はスペースの確保です: 一時的な記憶領域は意図的にプログラムの先頭を上書きするように確保し、 スペースを節約するための最高の初期化コードになっています。 これの対処方法について2つのコンパイラでは詳細が異なります。 古いものは関数の名前により先頭を見つけますが、 新しいものは単純に0としています。 これは、最初のコンパイラはメモリマッピングが できるマシンを手に入れる以前に書かれたものであり、 故にプログラムの先頭は0でないことに対し、 2番目のコンパイラの時にはマッピングができる PDP-11 を手に入れていたことを示しています。 ( Unix History paper 参照) あるファイル (prestruct-c/c10.c) がやっつけ仕事であることが明らかです。

It is possible to get these compilers to recompile themselves, via the use of a user-mode PDP-11 simulator. Such a simulator called Apout is available. The packaged source code for these compilers and a README can be found nearby.
これらのコンパイラを PDP-11 のユーザーモードのシュミレータを使って それ自身で再コンパイルすることは可能です。 Apout と呼ばれるシュミレータが使えます。 これらのコンパイラのパッケージ化されたソースコードと README は ここ にあります。