;; DESUGAR.SCM ;;6.001 PROJECT 3: EXPLICIT-CONTINUATION EVALUATOR ;;DESUGAR ;transform a scheme expression to one with a reduced set of special forms. (define (desugar expr) (cond ((quoted? expr) expr) ((let? expr) (desugar-let expr)) ((let*? expr) (desugar-let* expr)) ((and? expr) (desugar-and expr)) ((assignment? expr) (make-assignment (assignment-variable expr) (desugar (assignment-value expr)))) ((definition? expr) (make-define (definition-variable expr) (desugar (definition-value expr)))) ((begin? expr) (make-begin (map desugar (begin-actions expr)))) ((lambda? expr) (make-lambda (lambda-parameters expr) (map desugar (lambda-body expr)))) ((application? expr) (desugar-application expr)) (else expr))) (define (make-assignment var expr) (list 'set! var expr)) (define (make-define var expr) (list 'define var expr)) (define (make-begin seq) (cons 'begin seq)) ;;DESUGAR-AND ;turn an and into ifs. return false, or the last true value (define (desugar-and expr) (let ((a-exprs (and-exprs expr))) (if (pair? a-exprs) (let ((first-expr (car a-exprs)) (rest-exprs (cdr a-exprs))) (if (pair? rest-exprs) (make-if (desugar first-expr) (desugar (make-and rest-exprs)) #f) (desugar first-expr))) #t))) (define (and? expr) (tagged-list? expr 'and)) (define and-exprs cdr) (define (make-and exprs) (cons 'and exprs)) (define (make-if pred conseq alt) (list 'if pred conseq alt)) ;;DESUGAR-LET (define (desugar-let expr) (let ((names (let-bound-variables expr)) (values (map desugar (let-values expr))) (body (map desugar (let-body expr)))) (make-application (make-lambda names body) values))) (define (let? expr) (tagged-list? expr 'let)) (define (let-bound-variables expr) (map first (second expr))) (define (let-values expr) (map second (second expr))) (define (let-body expr) (cddr expr)) ;differs from lecture--body may be a sequence (define (make-let bindings body) (cons 'let (cons bindings body))) (define (make-application rator rands) (cons rator rands)) ;;DESUGAR-LET* (define (desugar-let* expr) (define (top-level-let*->let lexpr) (let ((binds (let*-bindings lexpr)) (bod (let*-body lexpr))) (if (null? binds) (make-let nil bod) (make-let (list (car binds)) (if (null? (cdr binds)) bod (list (make-let* (cdr binds) bod))))))) (desugar-let (top-level-let*->let expr))) (define (let*? expr) (tagged-list? expr 'let*)) (define (let*-bindings expr) (second expr)) (define (let*-body expr) (cddr expr)) (define (make-let* binds body) (cons 'let* (cons binds body))) ;;DESUGAR-APPLICATION ;desugar each piece of a combination (define (desugar-application expr) (map desugar expr)) ;prevent runaway printer cycles ;(set! *unparser-list-depth-limit* 10) ;(set! *unparser-list-breadth-limit* 20)