(define-datatype expression expression? (lit-exp (value scheme-value?)) (begin-exp (exps (list-of expression?))) (var-exp (id symbol?)) ;;; (assignment-exp ;;; (id symbol?) ;;; (val expression?)) (if-exp (test-exp expression?) (true-exp expression?) (false-exp expression?)) (cond-exp (exps (list-of (list-of expression?)))) (lambda-exp (ids (list-of symbol?)) (bodies (list-of expression?))) (let-exp (ids (list-of symbol?)) (vals (list-of expression?)) (bodies (list-of expression?))) (app-exp (rator expression?) (rands (list-of expression?)))) (define scheme-value? (lambda (v) #t)) (define parse-expression (lambda (datum) (cond [(symbol? datum) (var-exp datum)] [(number? datum) (lit-exp datum)] [(string? datum) (lit-exp datum)] [(boolean? datum) (lit-exp datum)] [(null? datum) (lit-exp datum)] [(pair? datum) (cond [(eqv? (car datum) 'lambda) (lambda-exp (cadr datum) (map parse-expression (cddr datum)))] [(eq? (cadr datum) '+) (app-exp (parse-expression (cadr datum)) (map parse-expression (cons (car datum) (cddr datum))))] [(eq? (cadr datum) '-) 'plus] [(eq? (cadr datum) '*) 'plus] [(eq? (cadr datum) '/) 'plus] [(eqv? (car datum) 'cond) (cond-exp (map (lambda (x) (list (parse-expression (car x)) (parse-expression (cadr x)))) (cdr datum)))] ;;; [(eq? (cadr datum) '=) ;;; (assignment-exp (car datum) ;;; (parse-expression (caddr 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) 'begin) (begin-exp (map parse-expression (cdr datum)))] [(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))] [else (app-exp (parse-expression (car datum)) (map parse-expression (cdr datum)))])] [else (eopl:error 'parse-expression "Invalid concrete syntax ~s" datum)])))