在大学,我们正在为Scheme建立一个Scheme Interpreter。在下面的代码中,您可以看到plus运算符的实现。
#lang racket
(define (EVAL e)
(if (pair? e) ;if its a pair its a function -> call EVALFunctionCall
(EVALFunctionCall e)
(null))) ;null - other cases are not implemented
(define (EVALFunctionCall e)
(if (eq? (car e) '+) ;if its + its addition -> call EVALPlus
(EVALPlus (cdr e))
(null))) ;null - other cases are not implemented
(define (EVALPlus argList)
;for debugging
(display (car argList))(display "\n")
(display (cdr argList))(display "\n")
(display (car (cdr argList)))(display "\n")
(display (cdr (cdr argList)))(display "\n")
(+ (car argList) (cdr argList)))
(EVAL '(+ 1 2))
应评估为3
。但事实并非如此。相反,我得到一个错误。
这是因为(cdr argList)
(我传递给+ -function的第二个参数)不是数字而是一对。我为调试添加的显示打印出来:
1
(2)
2
()
我很确定这是教授在课程中展示的代码(有效)。那我错了什么?我的教授是否有可能使用另一种方案 - 方言'(+ 1 2)
保存(+(1 2))
而不是(+(1(2 null)))
?
答案 0 :(得分:1)
您的代码中有一点错误,请在EVALPlus
程序中尝试此操作:
(+ (car argList) (car (cdr argList)))
请记住cdr
检索下一个列表,而不是下一个元素。获得下一个列表后,我们调用car
来获取它的第一个元素。
答案 1 :(得分:0)
嗯,显而易见的解决方案是:
(define (EVALPlus argList)
(apply + argList))
但是,由于练习是关于实现Scheme解释器,这可能是作弊; - )
那么简单的累积总和如何:
(define (EVALPlus argList)
(cond ((null? argList) 0)
((null? (cdr argList)) (car argList))
(#t (+ (car argList) (EVALPlus (cdr argList))))))
或者,如果您不被允许cond
:
(define (EVALPlus argList)
(if (null? argList) 0
(if (null? (cdr argList)) (car argList)
(+ (car argList) (EVALPlus (cdr argList))))))
一如既往,要注意特殊情况:
(EVAL '(+)) ; no argument
=> 0
(EVAL '(+ 42)) ; only one argument
=> 42
(EVAL '(+ 1 3 5 7 9)) ; n arguments
=> 25
希望它有所帮助。