(define (implicit-begin exp) (cond ((null? exp) 'undefined) ((null? (cdr exp)) (car exp)) (else (cons 'begin exp)))) (define (cond-expand% args) (cond ((null? args) (error "Invalid-syntax")) ((eq? (caar args) 'else) (implicit-begin (cdar args))) (else (list* 'if (caar args) (implicit-begin (cdar args)) (if (null? (cdr args)) '() (list (cond-expand% (cdr args)))))))) (define (quote-expand args) (define (expand-list lst acc) (cond ((pair? lst) (expand-list (cdr lst) (cons (quote-expand (list (car lst))) acc))) ((null? lst) (cons 'list (reverse acc))) (else (cons 'list* (reverse (cons (quote-expand (list lst)) acc)))))) (if (pair? (car args)) (expand-list (car args) '()) (cons 'quote args))) (define (macroexpand exp) (cond ((not (pair? exp)) exp) ;; syntax ((eq? (car exp) 'quote) (quote-expand (cdr exp))) ((eq? (car exp) 'if) (list* 'if (macroexpand (cadr exp)) (macroexpand (caddr exp)) (if (null? (cadddr exp)) '() (list (macroexpand (cadddr exp)))))) ((eq? (car exp) 'lambda) (list* 'lambda (cadr exp) (map macroexpand (cddr exp)))) ((eq? (car exp) 'set!) (list 'set! (cadr exp) (macroexpand (caddr exp)))) ;; macro ((eq? (car exp) 'cond) (cond-expand% (cdr exp))) ;; procedure (else (map macroexpand exp))))