after optimization, we need to convert it to the form that can run on machine. There are two ways for that,
either convert it to machine native code, which is faster but is complex.
or create virtual machine (hypothetical cpu) where the code runs (similar to java language)
runtime which provide runtime supports running the program. for example, garbage collector etc. For fully compiled language, runtime is inserted directly to the executable. And for language runs in interpreter or vm, then runtime lives there.
shortcuts to designing compilers
single pass compilers. does not have pipeline of stages in compilation. It produces the output code at the parsing stage only.
tree walk interpreters. going through the AST and executing the node. good for designing simple languages.
transpiler or source to source compiler. it compiles the source language to another language which already has compiler tools. For example, writing a frontend (transpiler) for a custom language that converts that to C language which already has compiler toolchain.