在EOPL第3章,练习3.28。它要求我构造只包含那些自由变量的闭包,而不是整个环境。但解析后,所有变量都被替换为词法地址,例如:
(lambda (x)
(lambda (y)
(+ x y)))
将成为:
(lambda (x)
(lambda (y)
(+ (var 1 0) (var 0 0))))
第一个数字是深度,第二个数字是位置。
我的问题是:
如何判断变量是否是表达式中的所有变量都无名的变量?
答案 0 :(得分:2)
它们的肋骨数量大于它们在表达式中出现的深度:
(lambda (x)
(lambda (y)
(+ (var 1 0) (var 0 0))))
移除外部后(var 1 0)
的肋骨为1
,其中参考的出现深度为0
,因此(var 1 0)
是免费的:
(lambda (y)
(+ (var 1 0) (var 0 0))
答案 1 :(得分:2)
保留一个计数器,表明您看到一个新闭包的次数,并且有一个环境,您可以将变量绑定到索引和深度。评估正文以便解析符号并执行(list 'var (- framcount var-frame) var-index)
示例:
(lambda (x)
;; evironment count=0, x=(0,0)
(lambda (y)
;; environment count=1, x=(0,0), y=(1,0)
(+ ; + is a global (no match), (glob '+)
x ; x is frame (- 1 0) and index 0 (var 1 0)
y))) ; y is frame (- 1 1) and index 0 (var 0 0)
你也可以保留帧,以便解析器计算它没有找到变量的帧数以及它找到的索引。这样就不需要计数变量了。这可能是更多的方法。
(= count row)