2013-05-22 30 views
1

所以我正在爲我的編程語言類工作一些練習題,其中一個任務是創建一個腳本「MyEval」,它允許您執行簡單的嵌套加法和乘法。 因此,例如程序將能夠做到這一點(MyEval '(1 +(3 *4)))或更深,但不必做減法或超過2個數字和一個操作符。所以不那麼複雜。然而,我的腦海裏炸了,我會喜歡一些指導。 這是我迄今爲止DrRacket中的簡單嵌套評估

#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 任何指導或尖端讚賞,我不知道我的標題有多準確,但如果不恰當,請告訴我。

謝謝!

+2

注意:請不要**使用您的環境的基礎'eval'。如果你這樣做,你誤解了這項任務。 – dyoo

回答

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代替carcadr等。隨着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])) 

雖然有些不喜歡` S和參與, S,我更喜歡那些所有list秒。

+0

太棒了,效果非常好!非常感謝你 – AngelloMaggio