(define-datatype expression expression? (label-exp (num number?) (exp expression?)) (goto-exp (num number?)) (lit-exp (value scheme-value?)) (break-exp (exps (list-of expression?))) (exit-exp) (set-exp (id symbol?) (value expression?)) (define-exp (id symbol?) (value expression?)) (let-exp (syms (list-of symbol?)) (vals (list-of expression?)) (bodies (list-of expression?))) (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)] [(boolean? 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) '_label) (label-exp (cadr datum) (parse-expression (caddr datum)))] [(eqv? (car datum) 'goto) (goto-exp (cadr datum))] [(eqv? (car datum) 'quote) (lit-exp (cadr datum))] [(eqv? (car datum) 'begin) (app-exp (list (lambda-exp '() (map parse-expression (cdr datum)))))] [(eqv? (car datum) 'let) (let-exp (map car (cadr datum)) (map parse-expression (map cadr (cadr datum))) (map parse-expression (cddr datum)))] [(eqv? (car datum) 'break) (break-exp (map parse-expression (cdr datum)))] [(eqv? (car datum) 'set!) (set-exp (cadr datum) (parse-expression (caddr datum)))] [(eqv? (car datum) 'define) (define-exp (cadr datum) (parse-expression (caddr datum)))] [(eqv? (car datum) 'exit) (exit-exp)] [(eqv? (car datum) 'call/cc) (call/cc-exp (parse-expression (cadr datum)))] [(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)])))