; Copyright (c) 1993, 1994 Richard Kelsey and Jonathan Rees. See file COPYING. ; Interfaces (define-record-type interface :interface (really-make-interface ref walk clients name) interface? (ref ref-method) (walk walk-method) (clients interface-clients) (name interface-name set-interface-name!)) (define-record-discloser :interface (lambda (int) (list 'interface (interface-name int)))) (define (interface-ref int name) ((ref-method int) name)) (define (for-each-declaration proc int) ((walk-method int) proc)) (define (note-reference-to-interface! int thing) (let ((pop (interface-clients int))) (if pop (add-to-population! thing pop) ;; If it's compound, we really ought to descend into its components ))) ; If name is #f, then the interface is anonymous, so we don't need to ; make a population. (define (make-interface ref walk name) (really-make-interface ref walk (make-population) name)) ; Simple interfaces (export (name type) ...) (define (make-simple-interface name items) (let ((table (make-table name-hash))) (for-each (lambda (item) (if (pair? item) (let ((name (car item)) (type (cadr item))) (if (or (null? name) (pair? name)) ;; Allow ((name1 name2 ...) type) (for-each (lambda (name) (table-set! table name type)) name) (table-set! table name type))) (table-set! table item undeclared-type))) items) (make-table-immutable! table) (really-make-simple-interface table name))) (define (really-make-simple-interface table name) (make-interface (lambda (name) (table-ref table name)) (lambda (proc) (table-walk proc table)) name)) ; Compoune interfaces (define (make-compound-interface name . ints) (let ((int (make-interface (lambda (name) (let loop ((ints ints)) (if (null? ints) #f (or (interface-ref (car ints) name) (loop (cdr ints)))))) (lambda (proc) (for-each (lambda (int) (for-each-declaration proc int)) ints)) name))) (for-each (lambda (i) (note-reference-to-interface! i int)) ints) int)) (define (note-interface-name! int name) (if (and name (not (interface-name int))) (set-interface-name! int name)))