As part of continuing to grow as a programmer, I decided it was high time I wrote my own toy language compiler. I have completed a working lexer (I really enjoyed that part) and a parser which creates an AST. I can evaluate the generated AST to execute simple expressions like basic math and assignment. It was pretty amazing to get this far and create an interpreter but I really would like to take it to what I see as the final step. After much searching I have found there tends to be only one resolution and that's to output an intermediate language. Some languages are converted to bytecode for a VM and others have the AST passed directly into the compiler back-end like in GCC'S and LLVM's (or is it LLVM IR?) case. One other solution is to output another high-level language like C which would in tern be compiled by a C compiler but seems abysmally complicated. From what I can gather, to create a front-end for GCC I would need to use C or C++ and for LLVM C++ so it doesn't appear I could use my Go front-end but, again, I could be mistaken.
So, I have a few questions I'm hoping someone would be willing to answer for me:
1) What would be the simplest way to produce an executable from the state I'm at? Is it best to attempt to output Go code or some other intermediate language to be compiled by a secondary compiler? Thereby the 'compiler' would in effect be a script which executes a two-stage process: i) language -> intermediate language, ii) intermediate language -> executable?
2) After looking at Go's sources, it seems that the GC generates assembler instructions. Would it not need an external assembler to compile the assembly to binary? What stage(s) am I missing to produce the final executable? Obviously there's the linking stage but there must be more I'm missing.