123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- ;;; Ported from Scheme 48 1.9. See file COPYING for notices and license.
- ;;;
- ;;; Port Author: Andrew Whatson
- ;;;
- ;;; Original Authors: Richard Kelsey, Jonathan Rees, Martin Gasbichler, Mike Sperber
- ;;;
- ;;; scheme48-1.9.2/scheme/bcomp/schemify.scm
- ;;;
- ;;; schemify
- ;;;
- ;;; This is only used for producing error and warning messages.
- ;;;
- ;;; Flush nodes and generated names in favor of something a little more
- ;;; readable. Eventually, (schemify node env) ought to produce an
- ;;; s-expression that has the same semantics as node, when node is fully
- ;;; expanded.
- (define-module (prescheme bcomp schemify)
- #:use-module (prescheme scheme48)
- #:use-module (prescheme bcomp cenv)
- #:use-module (prescheme bcomp binding)
- #:use-module (prescheme bcomp mtype)
- #:use-module (prescheme bcomp name)
- #:use-module (prescheme bcomp node)
- #:use-module (prescheme bcomp package)
- #:use-module (prescheme bcomp transform)
- #:export (schemify))
- (define (schemify node . maybe-env)
- (if (node? node)
- (schemify-node node
- (if (null? maybe-env)
- #f
- (car maybe-env)))
- (schemify-sexp node)))
- (define schemifiers
- (make-operator-table (lambda (node env)
- (let ((form (node-form node)))
- (if (list? form)
- (let ((op (car form)))
- (cons (cond ((operator? op)
- (operator-name op))
- ((node? op)
- (schemify-node op env))
- (else
- (schemify-sexp op)))
- (schemify-nodes (cdr form) env)))
- form)))))
- ;; We cache the no-env version because that's the one used to generate the
- ;; sources in the debugging info (which takes up a lot of space).
- (define (schemify-node node env)
- (or (and (not env)
- (node-ref node 'schemify))
- (let ((form ((operator-table-ref schemifiers (node-operator-id node))
- node
- env)))
- (if (not env)
- (node-set! node 'schemify form))
- form)))
- (define (schemify-nodes nodes env)
- (map (lambda (node)
- (schemify-node node env))
- nodes))
- (define (define-schemifier name type proc)
- (operator-define! schemifiers name type proc))
- (define-schemifier 'name 'leaf
- (lambda (node env)
- (if env
- (name->qualified (node-form node)
- env)
- (let ((form (node-form node)))
- (if (or #f (node? form))
- (schemify-node form env)
- (desyntaxify form))))))
- ;; Convert an alias (generated name) to S-expression form ("qualified name").
- (define (name->qualified name env)
- (cond ((not (generated? name))
- name)
- ((let ((d0 (lookup env name))
- (d1 (lookup env (generated-name name))))
- (and d0 d1 (same-denotation? d0 d1)))
- (generated-name name)) ;;+++
- (else
- (make-qualified (qualify-parent (generated-parent-name name)
- env)
- (generated-name name)
- (generated-uid name)))))
- ;; As an optimization, we elide intermediate steps in the lookup path
- ;; when possible. E.g.
- ;; #(>> #(>> #(>> define-record-type define-accessors)
- ;; define-accessor)
- ;; record-ref)
- ;; is replaced with
- ;; #(>> define-record-type record-ref)
- (define (qualify-parent name env)
- (let recur ((name name) (env env))
- (if (generated? name)
- (let ((parent (generated-parent-name name)))
- (if (and (environment-stable? env)
- (let ((b1 (generic-lookup env name))
- (b2 (generic-lookup env parent)))
- (and b1
- b2
- (or (same-denotation? b1 b2)
- (and (binding? b1)
- (binding? b2)
- (let ((s1 (binding-static b1))
- (s2 (binding-static b2)))
- (and (transform? s1)
- (transform? s2)
- (eq? (transform-env s1)
- (transform-env s2)))))))))
- (recur parent env) ;;+++
- (make-qualified (recur parent (generated-env name))
- (generated-name name)
- (generated-uid name))))
- name)))
- (define-schemifier 'quote syntax-type
- (lambda (node env)
- (let ((form (node-form node)))
- `(quote ,(cadr form)))))
- (define-schemifier 'call 'internal
- (lambda (node env)
- (map (lambda (node)
- (schemify-node node env))
- (node-form node))))
- ;; We ignore the list of free variables in flat lambdas.
- (define (schemify-lambda node env)
- (let ((form (node-form node)))
- `(lambda ,(schemify-formals (cadr form) env)
- ,(schemify-node (last form) env))))
- (define-schemifier 'lambda syntax-type schemify-lambda)
- (define-schemifier 'flat-lambda syntax-type schemify-lambda)
- (define (schemify-formals formals env)
- (cond ((node? formals)
- (schemify-node formals env))
- ((pair? formals)
- (cons (schemify-node (car formals) env)
- (schemify-formals (cdr formals) env)))
- (else
- (schemify-sexp formals)))) ;; anything besides '() ?
- ;; let-syntax, letrec-syntax...
- (define-schemifier 'letrec syntax-type
- (lambda (node env)
- (let ((form (node-form node)))
- (schemify-letrec 'letrec (cadr form) (caddr form) env))))
- (define-schemifier 'letrec* syntax-type
- (lambda (node env)
- (let ((form (node-form node)))
- (schemify-letrec 'letrec* (cadr form) (caddr form) env))))
- (define-schemifier 'pure-letrec syntax-type
- (lambda (node env)
- (let ((form (node-form node)))
- (schemify-letrec 'letrec (cadr form) (cadddr form) env))))
- (define (schemify-letrec op specs body env)
- `(,op ,(map (lambda (spec)
- (schemify-nodes spec env))
- specs)
- ,(schemify-node body env)))
- (define-schemifier 'loophole syntax-type
- (lambda (node env)
- (let ((form (node-form node)))
- (list 'loophole
- (type->sexp (cadr form) #t)
- (schemify-node (caddr form) env)))))
- (define-schemifier 'lap syntax-type
- (lambda (node env)
- (let ((form (node-form node)))
- `(lap
- ,(cadr form)
- ,(schemify-nodes (caddr form) env)
- . ,(cdddr form)))))
- ;;----------------
- (define (schemify-sexp thing)
- (cond ((name? thing)
- (desyntaxify thing))
- ((pair? thing)
- (let ((x (schemify-sexp (car thing)))
- (y (schemify-sexp (cdr thing))))
- (if (and (eq? x (car thing))
- (eq? y (cdr thing)))
- thing ;;+++
- (cons x y))))
- ((vector? thing)
- (let ((new (make-vector (vector-length thing) #f)))
- (let loop ((i 0) (same? #t))
- (if (>= i (vector-length thing))
- (if same? thing new) ;+++
- (let ((x (schemify-sexp (vector-ref thing i))))
- (vector-set! new i x)
- (loop (+ i 1)
- (and same? (eq? x (vector-ref thing i)))))))))
- (else thing)))
|