Structural operational semantics is standard technology in theory of programming languages in which execution of a program is described as a series of transitions, each of which yields a valid program.
There are well-known mechanisms for dealing with or avoiding substitution in the execution of a program. Probably the most common one is that of keeping a run-time environment, which correspond to the subtitution we would have made so far, as well as to the run-time stack.
As far as homoiconicity is concerned, there are several options:
In Kleene's number realizability each piece of data is represented by a number. This holds for machines themselves, so we have homoiconicity, as every infinite object (function with infinite domain, a real number, an infinite sequence) is represented by a number, which can be understood as its Goedel code or "source code".
In theory of programming languages there are programming constructs that explicitely yield homoiconicity, for example the
unqoute mechanism in PCF+quote.
The general buzz word you may want to look up is meta programming, see e.g. this random paper.