You can further cheat and write a short and tidy attribute grammar for a tiny block-structured and well documented dialect like Oberon, and your grammar will be 1:1 translation from production rules straight to assembly language. No optimization, and certainly no intermediate representation. What you're left with is a clone of the first Turbo C without dynamic memory allocation (just static allocation with a strict stack discipline)
Then you can run around and say you're a compiler hacker. That's how I started :-P