Ang*_*gio 1 lisp scheme racket r5rs
所以我正在为我的编程语言类做一些练习问题,其中一个任务是创建一个脚本"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
Run Code Online (Sandbox Code Playgroud)
但你们可能会注意到这只会解决最后的内部括号,所以如果我这样做,(MyEval '(1 + (1 + 2)))我会得到3,而不是4.任何指导或提示都会受到赞赏,我不知道我的标题有多准确,但如果不是适当的请告诉我.
谢谢!
通常一个好的计划是首先编写一些单元测试.函数应该返回某些输出的示例.试着考虑边界或角落的情况.例如:
(require rackunit)
(check-equal? (my-eval '(1 + (3 * 4)))
13)
(check-equal? (my-eval '(20 + 20))
40)
(check-equal? (my-eval 1)
1)
Run Code Online (Sandbox Code Playgroud)
当然这些都将最初失败.但你的目标是让他们通过.
接下来,您不需要使用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]))
Run Code Online (Sandbox Code Playgroud)
您也可以对match模式使用准引用,我通常会发现它更清晰.等价的,那样:
(define (my-eval x)
(match x
[`(,lhs * ,rhs) (* (my-eval lhs) (my-eval rhs))]
[`(,lhs + ,rhs) (+ (my-eval lhs) (my-eval rhs))]
[`() `()]
[_ x]))
Run Code Online (Sandbox Code Playgroud)
虽然有些人不喜欢`s和,s,但我更喜欢那些lists.