«Развертывание цикла» обычно означает замену повторения последовательностью действий. Цикл:
for (int i = 0; i < 4; ++i) {
a[i] = b[i] + c[i];
}
развернется в эквивалент:
a[0] = b[0] + c[0];
a[1] = b[1] + c[1];
a[2] = b[2] + c[2];
a[3] = b[3] + c[3];
Мне кажется, что тот, кто цитировался в Википедии, использовал эту фразу в несколько метафорическом смысле. Итак, в этом смысле ...
Ваш образец обычно вызывается внутри интерпретатора, который проходит по дереву узлов AST, который может выглядеть примерно так:
ASSIGN
|
+--+---+
| |
REF MINUS
| |
x +--+---+
| |
VAR PLUS
| |
a +--+--+
| |
VAR CONST
| |
b 3
и функция interpret
будут иметь дополнительные опции:
int interpret(node) {
switch(node) {
case PLUS:
return interpret(child(0))+interpret(child(1));
case MINUS:
return interpret(child(0))-interpret(child(1));
case ASSIGN:
return set(child(0), interpret(child(1));
case VAR:
return fetch(child(0));
case CONST:
return value(child(0));
...
}
}
Если вы проходите AST с помощью этой функции interpet
(фактически выполняющей операции), вы интерпретируете. Но если функция записывает выполняемые действия, а не выполняет их, вы компилируете. В псевдокоде (фактически, псевдокод дважды , поскольку я предполагаю гипотетическую машину стека в качестве цели компиляции):
string compile(node) {
switch(node) {
case PLUS:
return(compile(child(0))) + compile(child(1)) + ADD);
case MINUS:
return(compile(child(0))) + compile(child(1)) + SUB);
case ASSIGN:
return(PUSHA(child(0))) + compile(child(1)) + STORE);
case REF:
return(PUSHA(child(0)));
case VAR:
return(PUSHA(child(0)) + FETCH);
case CONST:
return(PUSHLIT + value(child(0)));
...
}
}
Вызов compile
для этого AST (игнорирование любых опечаток псевдокода ;-) выдаст что-то вроде:
PUSHA x
PUSHA a
FETCH
PUSHA b
FETCH
PUSHLIT 3
ADD
SUB
STORE
FWIW, я бы склонялся к тому, чтобы развернуть AST, а не развернуть переводчика, но не буду критиковать чужую метафору, не читая ее в контексте.