#| Your task is to extend the interpreter below with `cond' and the implement the function `contains-five?' in your interpreter: (define (contains-five? a-lon) (cond [(null? a-lon) #f] [else (cond [(= (car a-lon) 5) #t] [else (contains-five? (cdr a-lon))])])) and test it with these function calls (already translated below). (contains-five? '()) (contains-five? (cons 1 '())) (contains-five? (cons 5 '())) (contains-five? (cons 3 (cons 4 (cons 5 (cons 6 (cons 7 '())))))) Be sure to read over the entire assignment and think about the organization and that data that the program uses before trying to modify the program. NB: if you use set!, you are either doing it wrong or making it more complicated than you have to. Step 1: add boolean values to scheme-val and add tests for booleans to the evaluate test suite Step 2: add conditional expressions to scheme-exp. You may assume that cond expressions always have two clauses and always have an `else' clause as the question in the second clause. NOTE: use `kond' instead of `cond' in your define-struct (to avoid collisions with built in names) Step 3: make some examples of cond expressions and add tests to the evaluator test suite and the subst test suite. Step 4: extend the evaluate and subst functions to handle cond expressions. Step 5: translate the contains-five definition above to a scheme-def. Step 6: test your scheme-def and your evaluator by using the example calls to contains-five? shown above (already translated below). |# #| DATA DEFINITIONS A scheme-exp is either: - (make-num= scheme-exp scheme-exp) - (make-kons scheme-exp scheme-exp) - (make-hd scheme-exp) - (make-tl scheme-exp) - (make-null-test scheme-exp) - (make-app symbol scheme-exp) - symbol - scheme-val A scheme-val is: - number - (cons scheme-val scheme-val) - '() A scheme-def is: - (make-def symbol symbol scheme-exp) A list-of-scheme-defs is either: - empty - (cons scheme-def list-of-scheme-defs) |# (define-struct num= (lhs rhs)) (define-struct kons (hd tl)) (define-struct hd (arg)) (define-struct tl (arg)) (define-struct null-test (arg)) (define-struct app (rator rand)) (define-struct def (name param body)) ;; evaluate : scheme-exp list-of-scheme-defs -> scheme-val (define (evaluate a-se a-losd) (cond [(num=? a-se) (= (evaluate (num=-lhs a-se) a-losd) (evaluate (num=-rhs a-se) a-losd))] [(kons? a-se) (cons (evaluate (kons-hd a-se) a-losd) (evaluate (kons-tl a-se) a-losd))] [(hd? a-se) (car (evaluate (hd-arg a-se) a-losd))] [(tl? a-se) (cdr (evaluate (tl-arg a-se) a-losd))] [(app? a-se) (let ([def (lookup-def (app-rator a-se) a-losd)]) (evaluate (subst (def-param def) (evaluate (app-rand a-se) a-losd) (def-body def)) a-losd))] [(symbol? a-se) (error 'evaluate "free variable")] [(null-test? a-se) (null? (evaluate (null-test-arg a-se) a-losd))] [else ;; scheme-val a-se])) ;; lookup-def : symbol list-of-scheme-defs -> def ;; finds the def for name in a-losd, or calls error if there isn't one (define (lookup-def name a-losd) (cond [(null? a-losd) (error 'lookup-def "not found: ~a" name)] [else (if (eq? name (def-name (car a-losd))) (car a-losd) (lookup-def name (cdr a-losd)))])) ;; subst : number or cons symbol scheme-exp -> scheme-exp ;; substitutes val for var in body (define (subst var val body) (cond [(num=? body) (make-num= (subst var val (num=-lhs body)) (subst var val (num=-rhs body)))] [(kons? body) (make-kons (subst var val (kons-hd body)) (subst var val (kons-tl body)))] [(hd? body) (make-hd (subst var val (hd-arg body)))] [(tl? body) (make-tl (subst var val (tl-arg body)))] [(app? body) (make-app (app-rator body) (subst var val (app-rand body)))] [(symbol? body) (if (eq? var body) val body)] [(null-test? body) (make-null-test (subst var val (null-test-arg body)))] [else ;; scheme-val body])) ;; EXAMPLES AS TESTS (subst 'x 1 2) 2 (subst 'x 1 'x) 1 (subst 'x 1 'y) 'y (subst 'x 1 #t) #t (subst 'x 1 (make-num= 'x 'y)) (make-num= 1 'y) (subst 'x 1 (make-kons 'x 'y)) (make-kons 1 'y) (subst 'x 1 '()) '() (subst 'x 1 (make-hd 'x)) (make-hd 1) (subst 'x 1 (make-tl 'x)) (make-hd 1) (subst 'x 1 (make-tl 'x)) (make-tl 1) (subst 'x 1 (make-app 'f 'x)) (make-app 'f 1) (subst 'x 1 (make-null-test 'x)) (make-null-test 1) (define defs (cons (make-def 'f 'x (make-kons 1 'x)) (cons (make-def 'g 'x (make-kons 3 (make-tl 'x))) (cons (make-def 'h 'x (make-num= 'x 1)) '())))) (lookup-def 'f defs) (make-def 'f 'x (make-kons 1 'x)) (lookup-def 'g defs) (make-def 'g 'x (make-kons 3 (make-tl 'x))) (evaluate 2 defs) 2 (evaluate (make-num= 1 2) defs) #f (evaluate (make-num= 1 1) defs) #t (evaluate (make-kons 1 '()) defs) (cons 1 '()) (evaluate (make-hd (make-kons 1 '())) defs) 1 (evaluate (make-tl (make-kons 1 '())) defs) '() (evaluate (make-null-test (make-kons 1 '())) defs) #f (evaluate (make-null-test '()) defs) #t (evaluate (make-app 'h '1) defs) #t (define cf-test1 (make-app 'contains-five? '())) (define cf-test2 (make-app 'contains-five? (make-kons 1 '()))) (define cf-test3 (make-app 'contains-five? (make-kons 5 '()))) (define cf-test4 (make-app 'contains-five? (make-kons 3 (make-kons 4 (make-kons 5 (make-kons 6 (make-kons 7 '())))))))