Per ottenere risultati corretti scoping lessicale e chiusure in un interprete, tutto quello che dovete fare è seguire queste regole:
- Nel vostro interprete, le variabili sono sempre guardato in una tabella di ambiente passata dal chiamante/mantenuto come variabile, non un env-stack globale. Cioè,
eval(expression, env) => value
.
- Quando il codice interpretato chiama una funzione, l'ambiente è NOT passato a quella funzione.
apply(function, arguments) => value
.
- Quando viene chiamata una funzione interpretata, l'ambiente in cui viene valutato il corpo è l'ambiente in cui è stata creata la definizione della funzione e non ha assolutamente nulla a che fare con il chiamante. Pertanto, se si dispone di una funzione locale, è una chiusura , ovvero una struttura dati contenente i campi
{function definition, env-at-definition-time}
.
elaborare tale ultimo bit in Python-ish sintassi:
x = 1
return lambda y: x + y
Viene eseguito come se fosse
x = 1
return makeClosure(<AST for "lambda y: x + y">, {"x": x})
dove il secondo dict può essere la corrente-env piuttosto che una struttura dati costruita in quel momento. (D'altra parte, mantenere l'intero env piuttosto che solo le variabili chiuse può causare perdite di memoria.)
fonte
2010-03-05 02:47:56
Si consiglia di leggere * Essentials of Programming Languages * http://www.cs.indiana.edu/eopl/ –