7 ms·
I wrote a self-hosting C compiler in 40 days (2015)
- bluetomcat 7y agoOnce you understand the type declaration syntax via the “declarations mirror use” guideline, there is nothing weird in C syntax. Any scary “pointer to function returning pointer to array” declarations are easily disentangled by applying the operators in the correct order around the declared name. People who know that rule tend to put the asterisk next to the name in pointer declarations. The semantics of the language are quite simple if we discard the weird implicit integer promotion and conversion rules. Every operation yields a new value of a certain type, and some expressions are considered lvalues by virtue of designating a modifiable location in memory.
- kazinator 7y agoRui was struggling with implementing it, not understanding and using it. He found that with 15 years of C experience, he didn't understand it well enough to just sit down and implement all of it without studying the spec.
- bluetomcat 7y agoI didn’t mean to devalue the efforts of the author, just wanted to point out that it is relatively straightforward to write a minimal C compiler, and the gotchas are in some small details.
- deleted 7y ago[deleted]
- Koshkin 7y agoBut the art of this is in getting all these details accounted for in a staightforward manner.
- wyldfire 7y agoRui is [one of?] the primary maintainers of lld: the LLVM project's linker. EDIT, oh, he says as much at the bottom: "Since then, I have moved to the LLVM team in Google, and I'm now working on lld, the LLVM linker."
- slacka 7y agoRelated HN discussion for when the 8cc project was first announced: https://news.ycombinator.com/item?id=9125912 https://news.ycombinator.com/item?id=9125912
- dang 7y agoThis article itself was also discussed in 2017: https://news.ycombinator.com/item?id=13914137 https://news.ycombinator.com/item?id=13914137 and 2015: https://news.ycombinator.com/item?id=10731002 https://news.ycombinator.com/item?id=10731002
- pizlonator 7y agoFucking love shit like this. More folks should write compilers. Can't wait to see your next compiler, Rui.
- favorited 7y agoI recognize Rui's name from llvm-dev, so I think they found their next compiler!
- muizelaar 7y agohttps://github.com/rui314/9cc https://github.com/rui314/9cc and https://github.com/rui314/chibicc https://github.com/rui314/chibicc are his next two compilers.
- nineteen999 7y ago> More folks should write compilers It's on my TODO list. After, of course, I finish that x86_32 preemptive multi-tasking kernel I started writing 20 years ago and never finished. Plus the 16-bit CP/M clone for the 68000 that's gathering dust. Or maybe after my half finished Z80 emulator or my half finished Z80-systems-in-Unreal-Engine project, or my mostly-but-not-completely-working VT100 emulator. Sigh. How do people ever finish this stuff?
- newnewpdro 7y agoNot participating in internet forums is a good start, huge time sink.
- nineteen999 7y agoUsually a during work hours activity for me, while stuff is "building", but point taken.
- sitkack 7y agoIf ever I heard a reason to use C++ templates, this is it.
- kazinator 7y ago> The C vararg spec is not well-designed. If you pass all function arguments via the stack, va_start may be implemented pretty easily, but on the modern processor and in modern calling convention, arguments are passed via registers to reduce overhead of function calls. So the assumption of the spec does not match the reality. The original assumption of the pre-ANSI <vararags.h> was that way, since it was just a hack exploiting actual object code behavior in the absence of language spec support. But ANSI C standardized the ... ellipsis, and the old hack became undefined behavior. A function declaration with the ellipsis is not type compatible with one that lacks it. This difference in type means that the compiler can map variadic functions to a different calling convention, such as one that always uses the stack for all the trailing arguments, even if they occur in positions for which the regular convention uses registers. I wouldn't call variadic functions well designed on the whole, but aspect isn't badly designed.
- WalterBright 7y ago> I've almost finished implementing C preprocessor in just one day. It's actually a port from my previous attempt to write a compiler. The preprocessor is fiendishly tricky to write. I wondered how he did it in such a short time :-) I had to scrap mine and reimplement it 3 times. I wish I had had https://www.spinellis.gr/blog/20060626/cpp.algo.pdf https://www.spinellis.gr/blog/20060626/cpp.algo.pdf to work from.
- tandr 7y agoWalter, I think your Zortech compiler was one of the first (if not The First) to introduce register calling convention. I don't remember much, but how did you get around varargs implementation?
- WalterBright 7y agoSimply, varargs functions didn't use the register calling convention. Varargs is rarely used outside of printf, and so isn't worth the effort optimizing. Indeed, the Linux 64 bit ABI for varargs is hopelessly klunky, but it doesn't really matter.
- tandr 7y agoThank you.
- saagarjha 7y ago> Varargs is rarely used outside of printf, and so isn't worth the effort optimizing. open(2) is also called relatively frequently and AFAIK requires varargs if it’s implemented in C.
- im3w1l 7y agoIt's relatively frequent to see it in source code, but those calls are cold code. People aren't calling open(2) millions of times per second in their inner loop.
- 7y ago
- bla3 7y agoThe author has since written a longer book on how to write compilers (albeit in Japanese): https://www.sigbus.info/compilerbook https://www.sigbus.info/compilerbook
- proyb 7y agoDiscovered that book too, still looking for idea how to translate to English.
- rui314 7y agoI will translate it to English myself once it's complete.
- reinhardt1053 7y agoHow to get a notification when the book comes out?
- deleted 7y ago[deleted]
- rui314 7y agoAuthor here. These days I'm writing a new C compiler (https://github.com/rui314/chibicc https://github.com/rui314/chibicc) from scratch again to write a book about compilers. Since I'll be using the new one as a reference implementation for a book, and the book is intended to be for beginners, I put as much effort as I can into improving the readability of the code. In particular, not only the head of the repository but every commit in the repo should be readable, so that readers can easily understand how each feature is implemented. I believe I'm doing a good job keeping it clean so far. (Actually in order to keep the commit history clean, I continue rewriting commit history and doing `git push -f`, but that should be fine because the purpose of publishing the repo is not for co-development but for sharing a reference implementation.) chibicc does not have a C preprocessor, but except that it can compile itself already, so if you are interested, you can take a look.
- walty8 7y ago(Actually in order to keep the commit history clean, I continue rewriting commit history and doing `git push -f`, actually I wonder if you might consider to maintain another clean repository. So there is a raw repository to record every real history, and a clean repositiory to for better reading? Because sometimes the raw history could be interesting too.
- rui314 7y agoI haven't considered that but I think that's hard to do for technical reasons. New commits are made on top of a clean history, so there's no single history of "raw" commits but they are intermingled.
- jokoon 7y agoThere are so many small C compilers, I never know which one to choose, although TinyCC seems to be the best. To me it allows 2 things: * Use C as a fast scripting language. This can be useful for game programming, where you don't want to recompile your engine, but you can't tolerate the sluggishness of interpreted languages. * Use C as a compile target. I would love to build a "pythonic lean C++", without the hard stuff, without template or backward compatibility of C. Just python indenting, strongly typed, maps, set, geometric types, python-like standard functions... I guess that using C as a compile target allows one to avoid the hassle of building a low-level compiler... Not sure though.
- garaetjjte 7y agoTo second point: do you have looked at D?
- jokoon 7y agoD is too high level, is not really pythonic, and the syntax seems to be too distant from C. I just wish C had some nicer things, like a string type, maps, etc. python indentation would also make it readable. D has a lot of difference with C/C++, even if it does things right. C is nice because it's simple and readable. D looks like it's using a lot of new syntax and it looks hard to adapt/learn.