#lang eopl (require tests/eopl/private/utils) ;; data definitions (define identifier? symbol?) (define-datatype lc-exp lc-exp? (var-exp (var identifier?)) (lambda-exp (bound-var identifier?) (body lc-exp?)) (app-exp (rator lc-exp?) (rand lc-exp?))) ;; parse-expression : Schemeval -> Lcexp ;; page 53 (define parse-expression (lambda (datum) (cond ((symbol? datum) (var-exp datum)) ((pair? datum) (if (eqv? (car datum) 'lambda) (lambda-exp (car (cadr datum)) (parse-expression (caddr datum))) (app-exp (parse-expression (car datum)) (parse-expression (cadr datum))))) (else (report-invalid-concrete-syntax datum))))) (define report-invalid-concrete-syntax (lambda (datum) (eopl:error "invalid concrete syntax ~s" datum))) ;; unit tests (check-equal? (parse-expression 'x) (var-exp 'x)) (check-equal? (parse-expression 'y) (var-exp 'y)) (check-equal? (parse-expression '(lambda (x) (x y))) (lambda-exp 'x (app-exp (var-exp 'x) (var-exp 'y)))) (check-equal? (parse-expression '(lambda (y) (x y))) (lambda-exp 'y (app-exp (var-exp 'x) (var-exp 'y)))) (check-equal? (parse-expression '((lambda (x) x) (x y))) (app-exp (lambda-exp 'x (var-exp 'x)) (app-exp (var-exp 'x) (var-exp 'y)))) (check-equal? (parse-expression '(lambda (y) (lambda (z) (x (y z))))) (lambda-exp 'y (lambda-exp 'z (app-exp (var-exp 'x) (app-exp (var-exp 'y) (var-exp 'z)))))) ;(report-unit-tests-completed 'parse-expression) ;; unparse-lc-exp : Lcexp -> Schemeval ;; page 53 (define unparse-lc-exp (lambda (exp) (cases lc-exp exp (var-exp (var) var) (lambda-exp (bound-var body) (list 'lambda (list bound-var) (unparse-lc-exp body))) (app-exp (rator rand) (list (unparse-lc-exp rator) (unparse-lc-exp rand)))))) ;; unit tests (check-equal? (unparse-lc-exp (var-exp 'x)) 'x) (check-equal? (unparse-lc-exp (var-exp 'y)) 'y) (check-equal? (unparse-lc-exp (lambda-exp 'x (app-exp (var-exp 'x) (var-exp 'y)))) '(lambda (x) (x y))) (check-equal? (unparse-lc-exp (lambda-exp 'y (app-exp (var-exp 'x) (var-exp 'y)))) '(lambda (y) (x y))) (check-equal? (unparse-lc-exp (app-exp (lambda-exp 'x (var-exp 'x)) (app-exp (var-exp 'x) (var-exp 'y)))) '((lambda (x) x) (x y))) (check-equal? (unparse-lc-exp (lambda-exp 'y (lambda-exp 'z (app-exp (var-exp 'x) (app-exp (var-exp 'y) (var-exp 'z)))))) '(lambda (y) (lambda (z) (x (y z))))) ;(report-unit-tests-completed 'unparse-lc-exp) ;; Exercise 2.27 ;; ((lambda (a) (a b)) c) ;; (lambda (x) ;; (lambda (y) ;; ((lambda (x) ;; (x y)) ;; x))) ;; Exercise 2.31 (define-datatype prefix-exp prefix-exp? (const-exp (num integer?)) (diff-exp (operand1 prefix-exp?) (operand2 prefix-exp?))) ;; (diff-exp ;; (diff-exp ;; (const-exp 3) ;; (const-exp 2)) ;; (diff-exp ;; (const-exp 4) ;; (diff-exp ;; (const-exp 12) ;; (const-exp 7))))