15 ms·
Dennis Ritchie’s first C compiler (c. 1972)
- RcouF1uZ4gsC 6y agoVery interesting. Does anyone have any idea how the C compiler was bootstrapped. Was it first written in B, or was it written in PDP-11 assembler?
- QuantumG 6y agoFlint knives and bear skins.
- dboreham 6y agoAbacus
- AntiRush 6y agoThe basic sequence was: - Rewrite B compiler in B (generating threaded code) - Extend B to a language Ritchie called NB (new B). This compiler generated PDP assembly There is no version of the NB compiler known to exist. - Continue extending NB until it became the very early versions of C. You can read the longer version of this history here: https://www.bell-labs.com/usr/dmr/www/chist.html https://www.bell-labs.com/usr/dmr/www/chist.html
- 0x003 6y agoI think it was written in B as Ritchie extended B for the PDP-11. By that point the B compiler was written in B https://sci-hub.do/10.1145/155360.155580 https://sci-hub.do/10.1145/155360.155580
- retrac 6y agoIt was written in B. And B was written in B. To trace the bootstrap up into the high level, you have to go further back than the PDP-11. To bootstrap B on the PDP-7 and GE-635 machines he had access too, Ritchie wrote the minimum subset required to compile a compiler in B, in a language known as TMG (in the vein of, and a big influence on, Yacc and similar). This minimal bootstrap was then used to compile a B compiler written in B, and further development was self-hosted. Later, the language would be retargeted to the PDP-11 while on the PDP-7. Various changes, like byte-addressed rather than word-addressed memory, led to it morphing into C after it was moved. There was no clear line between B and C -- the language was self-hosting the whole time as it changed from B into C. Mr. Ritchie wrote a history from his perspective published in 1993. I've mostly just summarized it above. It's available here: https://web.archive.org/web/20150611114355/https://www.bell-labs.com/usr/dmr/www/chist.html https://web.archive.org/web/20150611114355/https://www.bell-...
- systemvoltage 6y agoWhen people say bootstrapping, is this how all computer languages came to be? Or there has been multiple attempts at bootstrapping? What I’m getting at is whether all languages have a single root.
- retrac 6y agoYes, bootstrapping with regard to languages is the trick of getting that first compiler running so you can compile the rest of the compiler. It has been done many times. The first assemblers were written directly in machine language. The first compilers were written in assembly. Many implementations of FORTRAN, ALGOL, COBOL, etc. As late as the 1970s it was not unknown to write a new high level language directly in machine code. Steve Woz's BASIC for the Apple II was "hand-assembled", as he put it. So, taken literally, certainly not. People still do it today as a hobby or educational project. But if we take the question in a looser sense? Yes kind of, at least in the UNIXish world. No one has implemented a serious high level systems language, except in a high level systems language, for a long time now. Rust, for example, was initially implemented in Ocaml. And normally that's what would be called the first Rust bootstrap. But OCaml was implemented in C, probably compiled by Clang or GCC. GCC was written in C and... so on. Often one finds it does lead back to DMR at a PDP-7. On the other hand, I strongly suspect something like IBM's COBOL compiler for their mainframes (still supported and maintained today!) would not have such a heritage.
- userbinator 6y agoPrevious discussion: https://news.ycombinator.com/item?id=14669709 https://news.ycombinator.com/item?id=14669709 https://news.ycombinator.com/item?id=5748672 https://news.ycombinator.com/item?id=5748672
- tirrex 6y agohttps://github.com/mortdeus/legacy-cc/blob/ccbe90a2803e2cc7e177c77cf1d5c19dd13f6d02/last1120c/cvopt.c#L35 https://github.com/mortdeus/legacy-cc/blob/ccbe90a2803e2cc7e... “auto” exists in the initial version.
- volta83 6y agoAnd what does it mean there? (automatic storage duration)
- tirrex 6y agoDo you mean automatic type deduction? Edit : I know it’s also storage specifier but it also does type deduction here, hope I’m not confused with the terminology
- volta83 6y agoIt doesn't do type deduction there. In original C you could declare variables without a type, and these variables with auto have no type. So this "auto" is essentially saying "this variable without a type uses automatic storage". That's a completely different language feature from "deduce the type of this variable".
- nix-zarathustra 6y agoNo, it doesn't do type deduction. Without specifying the type, it assumes a type of int. Everything in C revolves around ints.
- 6y ago
- jb1991 6y agowell, this sure looks wasteful: https://github.com/mortdeus/legacy-cc/blob/master/prestruct/c10.c#L11-L18 https://github.com/mortdeus/legacy-cc/blob/master/prestruct/...
- tyingq 6y agoExplanation: https://news.ycombinator.com/item?id=5748762 https://news.ycombinator.com/item?id=5748762
- lisper 6y agoWhy not just: char waste[however-many-bytes-are-needed]; ?
- TonyTrapp 6y agoCan't say for sure if it's the reason in this particular situation, but that would require dynamic memory allocation, and while it may seem backwards to reserve more memory than potentially needed on old memory-constrained systems, it is a pattern you see very frequently because on those systems, you actually know exactly how much memory you have. As a result, you know exactly how much memory you can "waste". Especially on single-tasking systems, it doesn't matter how much memory you waste, because no other program is affected by it. Or in other words: If you know you are guaranteed to have x KB of memory available and no other program can steal it, and you know that you don't need more than y KB, then why allocate up to y KB dynamically when you can just straight-up allocate y KB statically, which is less work?
- amyjess 6y agoI have to say, the way indentation and brackets were done here looks like it's just inviting subtle bugs. Take this for example: if (peekc) { c = peekc; peekc = 0; } else if (eof) return(0); else c = getchar();
- bawolff 6y agoI dont think it would look that out of place if he was using the ternary operator which is the same thing after all. E.g.: if (peekc) { c = peekc; peekc = 0; } else eof ? return(0) : c = getchar(); The first else clause sill looks weird, but the final part isn't nearly as out of place (well i guess assigning in a ternary would be weird, but in terms of indentation) and its not like we actually changed anything.
- andreareina 6y agoCan't return in a ternary.
- amelius 6y agoCorrect, return is not an expression. But then again, he could if he wanted to, as the language designer ;)
- Maken 6y agoMaybe it was not worth the extra work.
- Koshkin 6y agoWouldn't it be wonderful if we could write a = return b;
- colejohnson66 6y agoWhat would that even do? Return b, but then set b to a right before “deleting” a? That would serve no purpose.
- astroanax 6y agoThe original keywords - https://github.com/mortdeus/legacy-cc/blob/master/last1120c/c00.c#L44 https://github.com/mortdeus/legacy-cc/blob/master/last1120c/... Interestingly, long was commented
- josephg 6y agoIt makes sense long would have needed a comment. It needs a comment because “long” and “double” are terrible names for data types. Long what? Double length what? Those type names could easily have opposite meanings and meant long floating point / double length integer. WORD/DWORD are nearly as bad - calling something a "word" incorrectly implies the data type has something to do with strings. If you don't believe me, ask a non programmer friend what kind of thing an "integer" is in a computer program. Then ask them to guess what kind of thing a "long" is. The only saving grace of these terms is they’re relatively easy to memorise. int_16/int_32/int_64 and float_32/float_64 (or i32/i64/f32/f64/...) are much better names, and I'm relieved that’s the direction most modern languages are taking. (Edit: Oops I thought Microsoft came up with the names WORD / DWORD. Thanks for the correction!)
- zokier 6y ago> Microsoft’s WORD/DWORD are nearly as bad. Don’t call something a “word” if it doesn’t store characters. "Word" as a term has been in the wide use since at least 50s-60s, you can't really blame MS for that https://en.wikipedia.org/wiki/Word_(computer_architecture) https://en.wikipedia.org/wiki/Word_(computer_architecture)
- hakanai 6y agoA 'word' on an x86 is 32-bit, but a WORD is 16 bits. You can _absolutely_ blame Microsoft for using it to mean something that it isn't.
- innocenat 6y agoFloat doesn't make sense either. What is floating? (I know it's floating point, but it's the same as long/double).
- neatze 6y agoIt is surreal feeling when looking at first code, not sure how to explain why it is the case.
- inopinatus 6y agoI felt the same upon seeing an actual Dead Sea Scroll at the Jordan Museum in Amman. The feeling dissipated somewhat when our guide explained that it’s a treasure map
- deleted 6y ago[deleted]
- bumbada 6y agoIt is very interesting how many hardcoded magic numbers it has. No headers and defines because they did not existed yet?. The full compiler is super compressed. Hundreds of lines per file. It would be great if there was an explanation of the general idea of the design somewhere.
- Cthulhu_ 6y agoI'm only seeing a few thousand lines of code, so I think it would fit in someone's head easily enough. Might be the numbers were on paper.
- andi999 6y agoSo do I get this right: this is not the first C compiler (since that one would be written in B) and the first C compiler written in C?
- Jeema101 6y agoThank you for pointing this out. It obviously can't be his first C compiler because it's written in C! :) I'm not even sure it's the first C compiler written in C, though - it just says in the github description "the very first c compiler known to exist in the wild." Regardless, if it's from 1972 it's a very early version.
- mywittyname 6y ago> Thank you for pointing this out. It obviously can't be his first C compiler because it's written in C! :) This isn't obvious to me. I just assumed that the first iteration was compiled by hand to bootstrap a minimum workable version. Then the language would be extended slightly, and that version would be compiled with the compiler v. n-1 until a full-feature compiler is made. It makes sense to write a compiler in a different language, but given the era, I could see hand-compilation still being a thing.
- Blahagun 6y agoIt's not uncommon for a compiler to be partially written in its own language, so therefore this may as well be the first C compiler.
- rightbyte 6y agoThis is gold. I like how the files are named 00 01 10 11 because long filenames are scary. hshsiz 100; hshlen 800; /* 8*hshsiz */ hshtab[800]; These were at file scope. I assume they default to int, but when was the demand for = added?
- wott 6y agoFor those who wonder, the extract comes from https://github.com/mortdeus/legacy-cc/blob/ccbe90a2803e2cc7e177c77cf1d5c19dd13f6d02/last1120c/c00.c https://github.com/mortdeus/legacy-cc/blob/ccbe90a2803e2cc7e... IMO, it is close to Assembly: * you reserve space and possibly set an original value with "hshsiz DB 100" or "paraml DB ?" * assignment is a different business which involves a runtime instruction (MOV) Hence the same difference (no = sign for the first, passive, compile-time operation; an = sign for the second, active, runtime operation) in this proto-C. (Of course, this doesn't answer your question of "when" did the syntax of those 2 operation fuse :-) )
- kps 6y agoLong filenames are scary when your system has a 2.5MB disk.
- dibyendu 6y agoI tried to find the last version that Dennis wrote: my findings are here: https://github.com/dibyendumajumdar/C https://github.com/dibyendumajumdar/C
- bullen 6y agoSo how do you "bootstrap" compile this? I mean without cheating, say on a rebuilt computer after all computers where destroyed?
- flyinghamster 6y agoHand-compile it for the initial bootstrap would be one way to go. That, or write a minimal C in assembler, then make it self-hosting, then expand it into the full implementation. Edit: Elsewhere in-thread, retrac posted a detailed summary of how C developed from B.
- cptnapalm 6y agoFor the hobbyists and the curious using 2.11 BSD, its C compiler is the end of the line for development of the Ritchie C compiler, as far as I know.
- dboreham 6y agoBrings back some memories because this was the first "large" program available to me for study when I was first learning to program, around 1978. Having talked my way into using the local university EE dept's 11/45, I found the source tree was mounted (they had a 90MB CDC "washing machine" drive) and decided to print it out on the 132-col Tally dot-matrix printer. Some minutes into this, the sysadmin bursts into the terminal room, angrily asking "who's running this big print job". I timidly raise my hand. He asks what I'm printing. I tell him the C compiler source code because I want to figure out how it works. He responds "Oh, that's ok then, no problem, let me know if you need more paper loaded or a new ribbon".