所以我正在为我的编程语言类解决一些练习问题,其中一个任务就是创建一个脚本“MyEval”,它允许你进行简单的嵌套加法和乘法。
因此,例如程序将能够执行此操作(MyEval '(1 +(3 *4)))
或更深,但无需进行减法或超过2个数字和运算符。所以不那么复杂。然而,我的思绪是炒的,我会喜欢一些指导。
这就是我到目前为止所拥有的
#lang racket
(define ns (make-base-namespace))
(define (MyEval lis)
(cond
[(and ; neither is a list and can be evaluated
(not(list? (car lis)))
(not(list? (caddr lis)))
)
(eval (cons (cadr lis) (list (car lis) (caddr lis)) ) ns)]
[(list? (car lis))
(MyEval (car lis))]
[(list? (caddr lis))
(MyEval (caddr lis))]
) ;end of cond
) ;end of define
但是你们可能会注意到这只会解决最后的内部括号,所以如果我(MyEval '(1 + (1 + 2)))
我得到3而不是4。
任何指导或提示都表示赞赏,我不知道我的标题有多准确,但如果不合适请告诉我。
谢谢!
答案 0 :(得分:5)
通常一个好的计划是首先编写一些单元测试。函数应该返回某些输出的示例。试着考虑边界或角落的情况。例如:
(require rackunit)
(check-equal? (my-eval '(1 + (3 * 4)))
13)
(check-equal? (my-eval '(20 + 20))
40)
(check-equal? (my-eval 1)
1)
当然这些都会在最初失败。但你的目标是让他们通过。
接下来,您不需要使用eval
,也不应该使用eval
。你几乎不想在现实生活中使用eval
。 (另外,实施match
所实现的(某些)是不是你的练习的全部要点?)
最后,除非你有一个禁止它的课程作业,否则我建议使用car
代替cadr
,match
等。使用(define (my-eval x)
(match x
[(list lhs '* rhs) (* (my-eval lhs) (my-eval rhs))]
[(list lhs '+ rhs) (+ (my-eval lhs) (my-eval rhs))]
[(list) (list)]
[_ x]))
,它只是:
match
您还可以对(define (my-eval x)
(match x
[`(,lhs * ,rhs) (* (my-eval lhs) (my-eval rhs))]
[`(,lhs + ,rhs) (+ (my-eval lhs) (my-eval rhs))]
[`() `()]
[_ x]))
模式使用准引用,我通常会发现它更清晰。等价的,就是这样:
`
虽然有些人不喜欢所涉及的,
和list
,但我更喜欢那些{{1}} s。