Language Models as Compilers: Simulating Pseudocode Execution Improves Algorithmic Reasoning in Language Models