我正在尝试学习方案并尝试在方案中实现 let* 的解释器。这是语法:
<s6> -> <expr>
| <define>
<expr> -> NUMBER | IDENT | <if> | <let> | <letstar> | <lambda> | <application>
<define> -> ( define IDENT <expr> )
<if> -> ( if <expr> <expr> <expr> )
<let> -> ( let ( <var_binding_list> ) <expr> )
<letstar> -> ( let* ( <var_binding_list> ) <expr> )
<lambda> -> ( lambda ( <formal_list> ) <expr> )
<application> -> ( <operator> <operand_list> )
<operator> -> <built_in_operator> | <lambda> | IDENT
<built_in_operator> -> + | * | - | /
<operand_list> -> <expr> <operand_list> | empty
<var_binding_list> -> ( IDENT <expr> ) <var_binding_list> | ( IDENT <expr> )
<formal_list> -> IDENT <formal_list> | IDENT
我之前已经学会了如何实现 let ,这里是:
(define let-stmt? (lambda (e)
(and (list? e) (equal? (car e) 'let) (= (length e) 3))))
(define get-value (lambda (var env)
(cond
((null? env) (error "s6-interpret: unbound variable -->" var))
((equal? (caar env) var) (cdar env))
(else (get-value var (cdr env))))))
(define s6-interpret (lambda (e env) //thanks to GoZooner
(cond
((number? e) e)
((symbol? e) (get-value e env))
((not (list? e)) (error "s6-interpret: cannot evaluate -->" e))
((let-stmt? e)
(let ((names (map car (cadr e)))
(inits (map cadr (cadr e))))
(let ((vals (map (lambda (init) (s6-interpret init env)) inits)))
(let ((new-env (append (map cons names vals) env)))
(s6-interpret (caddr e) new-env)))))
如何修改 let 的解释器以便我可以为 let* 编写解释器?任何人都可以帮忙吗?
谢谢