(define-datatype expression expression? (lit-exp (value scheme-value?)) (break-exp (value scheme-value?)) (exit-exp) (var-exp (id symbol?)) (call/cc-exp (receiver expression?)) (app-exp (all-of-it (list-of expression?))) (lambda-exp (args (list-of symbol?)) (bodies (list-of expression?))) (if-exp (test-exp expression?) (true-exp expression?) (false-exp expression?))) (define scheme-value? (lambda (v) #t)) (define parse-expression (lambda (datum) (cond [(symbol? datum) (var-exp datum)] [(number? datum) (lit-exp datum)] [(pair? datum) (cond [(eqv? (car datum) 'if) (if-exp (parse-expression (cadr datum)) (parse-expression (caddr datum)) (parse-expression (cadddr datum)))] [(eqv? (car datum) 'quote) (lit-exp (cadr datum))] [(eqv? (car datum) 'break) (break-exp (parse-expression (cadr datum)))] [(eqv? (car datum) 'exit) (exit-exp)] [(eqv? (car datum) 'call/cc) (call/cc-exp (parse-expression (cadr datum)))] [(eq? (car datum) 'let) (let ([syms (map car (cadr datum))] [vals (map parse-expression (map cadr (cadr datum)))] [bodies (map parse-expression (cddr datum))]) (app-exp (cons (lambda-exp syms bodies) vals)))] [(eqv? (car datum) 'lambda) (lambda-exp (cadr datum) (map parse-expression (cddr datum)))] [else (app-exp (map parse-expression datum))])] [else (eopl:error 'parse-expression "Invalid concrete syntax ~s" datum)])))