home *** CD-ROM | disk | FTP | other *** search
- ;;; QQUOTE.S 01-14-89 11:34 AM by John Armstrong
-
- ;; Expands QUASIQUOTE/UNQUOTE/UNQUOTE according to Rev^3 Report specs.
- ;;
- ;; This file can be included as is in XSCHEME.INI, or can be incorporated
- ;; into MACROS.S, with expander functions anywhere and macros after
- ;; after definition of COMPILER-SYNTAX
-
- ;;; EXPANDER-FUNCTIONS: compilable under the core XSCHEME, can be evaluated
- ;;; independently of MACRO system
-
- (define APPEND-ME-SYM (gensym)) ;; must be a gensym to avoid capture in
- ;; certain (pathological) situations
-
- (define QQ-EXPANDER
- (lambda (l)
- (letrec
- (
- (qq-lev 0) ; always >= 0
- (QQ-CAR-CDR
- (lambda (exp)
- (let ((qq-car (qq (car exp)))
- (qq-cdr (qq (cdr exp))))
- (if (and (pair? qq-car)
- (eq? (car qq-car) append-me-sym))
- (list 'append (cdr qq-car) qq-cdr)
- (list 'cons qq-car qq-cdr)))))
- (QQ
- (lambda (exp)
- (cond ((symbol? exp)
- (list 'quote exp))
- ((vector? exp)
- (list 'list->vector (qq (vector->list exp))))
- ((atom? exp) ; nil, number or boolean
- exp)
- ((eq? (car exp) 'quasiquote)
- (set! qq-lev (1+ qq-lev))
- (let ((qq-val
- (if (= qq-lev 1) ; min val after inc
- ; --> outermost level
- (qq (cadr exp))
- (qq-car-cdr exp))))
- (set! qq-lev (-1+ qq-lev))
- qq-val))
- ((or (eq? (car exp) 'unquote)
- (eq? (car exp) 'unquote-splicing))
- (set! qq-lev (-1+ qq-lev))
- (let ((qq-val
- (if (= qq-lev 0) ; min val
- ; --> outermost level
- (if (eq? (car exp) 'unquote-splicing)
- (cons append-me-sym
- (%expand-macros (cadr exp)))
- (%expand-macros (cadr exp)))
- (qq-car-cdr exp))))
- (set! qq-lev (1+ qq-lev))
- qq-val))
- (else
- (qq-car-cdr exp)))))
- )
- (let ((expansion (qq l)))
- (if check-qq-expansion-flag
- (check-qq-expansion expansion)) ; error on failure
- expansion))))
-
- (define CHECK-QQ-EXPANSION
- (lambda (exp)
- (cond ((vector? exp)
- (check-qq-expansion (vector->list exp)))
- ((atom? exp)
- #f)
- (else
- (if (eq? (car exp) append-me-sym)
- (error "UNQUOTE-SPLICING in unspliceable position"
- (list 'unquote-splicing (cdr exp)))
- (or (check-qq-expansion (car exp))
- (check-qq-expansion (cdr exp))))))))
-
- (define CHECK-QQ-EXPANSION-FLAG #t) ; do checking
-
- (define UNQ-EXPANDER
- (lambda (l) (error "UNQUOTE outside QUASIQUOTE" l)))
-
- (define UNQ-SPL-EXPANDER
- (lambda (l) (error "UNQUOTE SPLICING outside QUASIQUOTE" l)))
-
- ;;; MACROS: must be evaluated with MACRO system in place
-
- (compiler-syntax QUASIQUOTE qq-expander)
- (compiler-syntax UNQUOTE unq-expander)
- (compiler-syntax UNQUOTE-SPLICING unq-spl-expander)
-
- ;;; END
-
-