Программа, как легко понять, состоит из выражений (включающих вызовы функций) и операторов (ветвления, циклы и т.п.) Операторы переводятся в машинный код без проблем. Определённая сложность возникает с выражениями.
Рассмотрим выражение A+(B-C)+D*E
Оно безо всяких проблем, и безо всякого искусственного интеллекта, переводится, скажем, в MSIL:
- Код: Выделить всё
A ld A
B ld B
C ld C
- sub
+ add
D ld D
E ld E
* mul
+ add
Слева -- обратная польская запись, справа -- некое подобие MSIL, инструкция ld -- это либо ldloc, либо ldc, в зависимости от сущности аргумента. Видно соответствие ОПЗ и MSIL один к одному.
* Можно даже перевести эту программу с MSIL на ассемблер x86:
- Код: Выделить всё
A push A
B push B
C push C
- pop reg
- sub [sp], reg
+ pop reg
+ add [sp], reg
D push D
E push E
* pop ax
* mul [sp]
* mov [sp], ax
+ pop reg
+ add [sp], reg
Здесь уже одному члену ОПЗ может соответствовать несколько машинных команд. (reg -- любой из регистров x86.) Наконец, можно применить чуть-чуть искусственного интеллекта, и заменить пары push/pop инструкциями mov:
- Код: Выделить всё
A push A
B push B
C- mov reg, C
- sub [sp], reg
+ pop reg
+ add [sp], reg
D push D
E* mov ax, E
* mul [sp]
* mov [sp], ax
+ pop reg
+ add [sp], reg
* Этот код, вполне вероятно, даже будет работать -- почему бы и нет? Но он отвратителен. Единственное его достоинство -- что для его генерации не потребовалось ничего сложнее последовательных текстовых замен в обратной польской записи выражения.
В следующей заметке я рассчитываю предложить придуманные мной методы дальнейшей высокоинтеллектуальной обработки кода, при которой должно получиться что-нибудь более приятное глазу.