I'd recommend you to get some good C and x86 NASM interpreters, so that you can interpret C code instead of compiling it.davidv1992 wrote:I would suggest against trying to compile C, or even any reasonable subset of C. Because of it's design heritage, C has some major gotchas in the lexing/parsing department (especially around user defined types) that you probably dont want to try your hand on for a first compiler. Besides that, the kind of familiarity one gets with a language when building a compiler for it is quite different than one gets (and needs) for actually building projects in it. You get a really good idea of all the edgecases that a language supports, but won't learn as much on proper design of a larger software project, and good habits around building maintainable code in it, both of which are key for getting into something as complex osdev in the long run.
If you want to become more familiar with C through this project, the best option probably would be to program the compiler itself in C. Do note that this makes your job harder, as you will be missing any object oriented tools that can be very useful, but is perfectly doable. For what language to compile, my suggestion would be to go for something simple. There are various languages designed specifically for teaching compiler construction (for the project I did for university, the goal was to compile SPL, a language defined somewhat during the coarse, see the code.pdf target produced by this repo: https://github.com/davidv1992/SPLCompiler), such languages can also be found in instructional books on the topic of compiler construction, such as A.W. Appel's Modern Compiler Implementation in C or it's variants. It is also an option to construct your own simple language by choosing a number of language features you find interesting.
As for learning assembly during a project like this, a good option is to try to get your compiler to the point where it outputs assembly for an architecture you are interested in. This will teach you a lot about the assembly language for a platform, as well as the broader ecosystem surrounding it.
It's guaranteed that then you will learn C and Assembly (if NASM interpreters exist) as easily as if it was JavaScript, because an interpreter closes the breach between having to configure the right compiler/assembler/toolchain and actually run and debug the code freely enough and immediately so as to make it possible for you to spot and correct bugs fast, on the immediate term, so you become capable of understanding and correcting even complex code in the same way you would inspect a JavaScript or PHP application.
Shipping an OS with pure source code interpreters for C, C++, x86 NASM Assembly (16, 32, 64-bit), would be a key learning tool to trivialize those languages without mutilating their complexity or scope.