Why not use WASM to bootstrap your compiler?
Show HN: My C compiler compiled itself
21–30 of 130 posts
Re: Show HN: My C compiler compiled itself
#22nice work. if you want more of a challenge try a compiler compiler that can compile itself... :) i got pretty far with this myself, although it doesn't work for weirdo languages like Python that need an exceptional lexer. i keep meaning to revisit this problem, since the tools in this space are pretty much non-existent or trash quality. https://github.com/semiessessi/cp2
> if you want more of a challenge try a compiler compiler that can compile itself... :) Is that not what OP did?
Re: Show HN: My C compiler compiled itself
#23Earlier quoted context omitted.
> Why isn't that also done by the Makefile? My guess is that some people would rather write Python code than dig into Make’s documentation. That said, ChatGPT is excellent at creating valid make files.
Or just take a few moments to learn the basics about Makefiles. The thing about Makefiles is that simples ones at least are really easy to write, and read. Much simpler and quicker than a cumbersome python script, that will most likely do less with much more boilerplate code (e.g. dependencies), and be much harder to read. Of course, you may hit a point where you stretch your Makefile so much beyond its common capabi…
Re: Show HN: My C compiler compiled itself
#24Why not use WASM to bootstrap your compiler?
Unlike any real machine (and most virtual ones), WASM is impossible to target with a simple single-pass C compiler. The reducible control flow requirement means you have to build a full control-flow graph and do graph algorithms to it before you can start emitting code. So IMO it makes for a bad starting point.
I think that could be done with a single-pass C compiler. In a very trivial (and terrible) case, you could keep a running "line_counter" variable that every statement in the loop is predicated with, which either gets incremented at the end of the loop, or set to an arbitrary value for representing branches.
It would of course be a horrible (but very amusing) mess, and rather enforces your actual point.
Re: Show HN: My C compiler compiled itself
#25Earlier quoted context omitted.
> if you want more of a challenge try a compiler compiler that can compile itself... :) Is that not what OP did?
No (if the parent really meant ‘compiler compiler’ which, I think, would be what yacc/bison is).
Re: Show HN: My C compiler compiled itself
#26Earlier quoted context omitted.
Or just take a few moments to learn the basics about Makefiles. The thing about Makefiles is that simples ones at least are really easy to write, and read. Much simpler and quicker than a cumbersome python script, that will most likely do less with much more boilerplate code (e.g. dependencies), and be much harder to read. Of course, you may hit a point where you stretch your Makefile so much beyond its common capabi…
As someone that learned C# and python before C and C++, to this day I couldn't explain to you how make rules work. Make is so unlike build tools from other languages that it doesn't surprise me someone would rather use python to bootstrap their compiler.
Less even, here is an attempt:
foo.o: foo.c
clang -c -o foo.o foo.c
This builds a file called foo.o, if foo.c is newer than foo.o. Imagine that there is an identical bar.o as well, that builds it from bar.c. fooexec: foo.o bar.o
clang -o fooexec foo.o bar.o
This links together foo.o and bar.o into a file called fooexec, if at least one of foo.o or bar.o is newer (which in turn means that any of its respective dependencies changed; e.g. change bar.c, and bar.o and then fooexec will rebuild).Now type this into the shell:
make fooexec
Congratulations! You have a fully built fooexec. Now change bar.c, type it again, and like magic, you have a rebuilt bar.o and fooexec. foo.o will stay put, it’s up to date!But of course all the .c -> .o rules look the same, so instead of writing a new one for every file, you'd use simple wildcards, and now the whole, entire Makefile is just:
%.o: %.c
clang -c -o $@ $
Do $@ and $It pains me if that is not immediately obvious. And it pains me even more that someone would want to write a boilerplate heavy, complex python program, that rebuilds everything all the time, instead of just learning this very simple concept.Re: Show HN: My C compiler compiled itself
#27> Then run ./build.py. This will use the bootstrapped 30cc-compiler to compile 30cc itself. It then again uses the 30cc-compiled compiler to compile 30cc once again. The final compiler is then stored as ./30cc. Why isn't that also done by the Makefile? The only catch I could see is that you'd need to have it build to different output names, but that seems fine for what it is? --- Also, I'm curious - did you find your…
> Why isn't that also done by the Makefile? My guess is that some people would rather write Python code than dig into Make’s documentation. That said, ChatGPT is excellent at creating valid make files.
Re: Show HN: My C compiler compiled itself
#28Earlier quoted context omitted.
As someone that learned C# and python before C and C++, to this day I couldn't explain to you how make rules work. Make is so unlike build tools from other languages that it doesn't surprise me someone would rather use python to bootstrap their compiler.
It is so trivial, it takes you 10 minutes to learn. Less even, here is an attempt: foo.o: foo.c clang -c -o foo.o foo.c This builds a file called foo.o, if foo.c is newer than foo.o. Imagine that there is an identical bar.o as well, that builds it from bar.c. fooexec: foo.o bar.o clang -o fooexec foo.o bar.o This links together foo.o and bar.o into a file called fooexec, if at least one of foo.o or bar.o is newer (wh…
It also has “phony” targets that aren’t files. The canonical example of this is “clean” which basically just does something like rm -rf *.o fooexec
This is what the JavaScript tooling people have been chasing for the past 15 years and can’t seem to grasp. Someone actually did build a make-based JS build system I believe but it never got popular because it wasn’t written in JavaScript.
Re: Show HN: My C compiler compiled itself
#29Earlier quoted context omitted.
As someone that learned C# and python before C and C++, to this day I couldn't explain to you how make rules work. Make is so unlike build tools from other languages that it doesn't surprise me someone would rather use python to bootstrap their compiler.
It is so trivial, it takes you 10 minutes to learn. Less even, here is an attempt: foo.o: foo.c clang -c -o foo.o foo.c This builds a file called foo.o, if foo.c is newer than foo.o. Imagine that there is an identical bar.o as well, that builds it from bar.c. fooexec: foo.o bar.o clang -o fooexec foo.o bar.o This links together foo.o and bar.o into a file called fooexec, if at least one of foo.o or bar.o is newer (wh…
So, either you need to manually keep references to which .h files you include in your Makefiles up to date, or start worrying about M / MM / MG / MP, and of course you'd like those to be re-run when you change your files, and suddenly your Makefile is an awful lot less simple.
This is the main reason I stopped teaching Makefiles in intro to C courses -- students often lost entire afternoons to forgetting this stuff, and failing to realise their mistake. It really shouldn't be any person's job to keep this up to date, when the computer knows it.
Re: Show HN: My C compiler compiled itself
#30Earlier quoted context omitted.
No (if the parent really meant ‘compiler compiler’ which, I think, would be what yacc/bison is).
Ah, thanks. My brain actually did not see that second "compiler" when reading, now it makes sense.