因此,我正在为我的编程语言类处理一些实践问题,其中一个任务是创建一个脚本“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。
任何指导或提示都是值得赞赏的,我不知道我的标题有多准确,但如果不合适,请让我知道。
谢谢您!

最佳答案

通常一个好的计划是先编写一些单元测试函数应该为某些输出返回什么的示例试着想想边界或者角落的情况例如:

(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而不是carcadr
(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]))

虽然有些人不喜欢其中的matchs和`s,但比起所有的,s,我更喜欢那些。

关于lisp - DrRacket中的简单嵌套评估,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16689618/

10-09 10:05