前段时间我写了自己的 Scheme 元循环解释器,支持特殊形式的=>
语法。cond
本质上,这就是我必须做的:
(define (expand-actions clause)
(let ((exp (sequence->exp (cond-actions clause))))
(if (cond-has-then? clause)
(make-application exp
(if (cond-else-clause? clause)
#t
(list (cond-predicate clause))))
exp)))
当遍历cond
表达式的所有子句(谓词和动作对)时,我展开每个动作并询问=>
子句中是否存在令牌(使用cond-has-then?
)。如果=>
找到,我将子句的动作部分应用于谓词。
这是我的解释器中负责评估表达式的完整代码cond
,主要过程(称为 from eval
)是cond->if
,它将cond
表达式转换为一系列嵌套if
表达式,并处理=>
语法;我希望这对你有帮助:
(define (cond->if exp)
(expand-clauses (cond-clauses exp)))
(define cond-clauses cdr)
(define (cond-has-then? clause)
(eq? (cadr clause) '=>))
(define cond-predicate car)
(define (cond-actions clause)
(if (cond-has-then? clause)
(cddr clause)
(cdr clause)))
(define (cond-else-clause? clause)
(eq? (cond-predicate clause) 'else))
(define (expand-clauses clauses)
(if (null? clauses)
(void)
(let ((first (car clauses))
(rest (cdr clauses)))
(if (cond-else-clause? first)
(if (null? rest)
(expand-actions first)
(error "ELSE clause isn't last -- COND->IF" clauses))
(make-if (cond-predicate first)
(expand-actions first)
(expand-clauses rest))))))
(define (expand-actions clause)
(let ((exp (sequence->exp (cond-actions clause))))
(if (cond-has-then? clause)
(make-application exp
(if (cond-else-clause? clause)
#t
(list (cond-predicate clause))))
exp)))
(define (make-if predicate consequent alternative)
(list 'if predicate consequent alternative))
(define (sequence->exp seq)
(cond ((null? seq) '())
((last-exp? seq) (first-exp seq))
(else (make-begin seq))))
(define (last-exp? seq)
(null? (cdr seq)))
(define first-exp car)
(define (make-application proc . args)
(cond ((null? args) (list proc))
((list? (car args)) (cons proc (car args)))
(else (cons proc args))))
(define (make-begin seq)
(cons 'begin seq))