It's a little goofy that you have to do this so often in IDL, but another strategy for mixing variables and executive commands (.run etc.) is to use the IDL_IDLBridge() object.
oBridge = IDL_IDLBridge()
oBridge->execute, '.compile ' + some_var
The difference between this and CALL_PROCEDURE or CALL_FUNCTION or EXECUTE is that the IDL_IDLBridge instantiates an interactive process, or command line like environment. That means you can include executive commands, and therefore embed a .COMPILE inside of a foreach loop that is iterating over the results of a file search to compile all .PRO files in a directory.
You can also use this to package up multiple .PRO files into a .SAV file. Note that the IDL_IDLBridge is a child process, so you won't get access to whatever it has compiled, but you can use SAVE/RESTORE with a passed variable.