所以我正在试验,并在方案中创建了一种编程语言。我也为它构建了一个解释器,这是下面的大部分代码。
我想重写解释器,以便它构建具有较小环境的闭包,即。在构建闭包时,它使用类似于当前环境的环境,但仅在闭包的函数部分保存作为自由变量的变量。我正在学习内存,但这很令人困惑。
编辑:我现在正在使用与此相当的 Racket ,所以如果那里更容易,你应该给我建议。
(define-struct var (string)) ;; a variable, e.g., (make-var "foo")
(define-struct int (num)) ;; a constant number, e.g., (make-int 17)
(define-struct add (e1 e2)) ;; add two expressions
(define-struct fun (name formal body)) ;; a recursive 1-argument function
(define-struct closure (fun env)) ;; closures (made at run-time)
(define (envlookup env str)
(cond [(null? env) (error "unbound variable during evaluation" str)]
[(equal? (caar env) str) (cdar env)]
[#t (envlookup (cdr env) str)]))
(define (eval-prog p)
(letrec
([f (lambda (env p)
(cond [(var? p) (envlookup env (var-string p))]
[(int? p) p]
[(add? p) (let ([v1 (f env (add-e1 p))]
[v2 (f env (add-e2 p))])
(if (and (int? v1) (int? v2))
(make-int (+ (int-num v1) (int-num v2)))
(error "TTPL addition applied to non-number")))]
[(fun? p) (make-closure p env)]
[(closure? p) p]
[#t (error "bad TTPL expression")]))])
(f () p)))
最佳答案
第一个问题:您的语言中是否有绑定(bind)突变?目前您似乎没有,但也许您正计划添加它。如果你这样做了,那么复制绑定(bind)就会打开一个新的蠕虫 jar ;需要额外的间接性。
回答您的问题:是的,您当然可以这样做,大多数语言实现都可以。这与“空间安全”的属性有关,因此闭包避免保留对本来可以收集的大值的引用。
实现这一点非常简单:您可能希望通过对程序进行一次静态传递来使用其自由变量注释每个表达式。在 Racket 中,我可能会构建一个哈希表,将表达式与其自由变量列表相关联。
对于它的值(value),我可以想象大约七种方式,通过这样做你可能会意外地让你的语言变慢:)。
关于programming-languages - 内存、解释器和闭包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8193401/