123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281 |
- ;;; Part of Scheme 48 1.9. See file COPYING for notices and license.
- ;;;
- ;;; Port Author: Andrew Whatson
- ;;;
- ;;; Original Authors: Richard Kelsey, Mike Sperber
- ;;;
- ;;; scheme48-1.9.2/ps-compiler/prescheme/linking.scm
- ;;;
- ;;; This file has the Pre-Scheme compiler's code for dealing with the
- ;;; Scheme 48's module system.
- (define-module (ps-compiler prescheme linking)
- #:use-module (prescheme scheme48)
- #:use-module (prescheme bcomp binding)
- #:use-module ((prescheme bcomp mtype) #:select (syntax-type usual-variable-type))
- #:use-module ((prescheme bcomp node) #:select (get-operator))
- #:use-module (prescheme bcomp interface)
- #:use-module (prescheme bcomp package)
- #:use-module (prescheme bcomp read-form)
- #:use-module (prescheme bcomp scan-package)
- #:use-module (prescheme bcomp transform)
- #:use-module (prescheme bcomp usual)
- #:use-module (prescheme environment)
- #:use-module (prescheme env stubs)
- #:use-module (prescheme locations)
- #:use-module ((ps-compiler node variable) #:select (make-global-variable))
- #:use-module ((ps-compiler prescheme type) #:select (type/unknown))
- #:use-module (ps-compiler util util)
- #:export (package-specs->packages+exports
- package-source
- define-prescheme!
- prescheme-compiler-env))
- ;; FILES is a list of files that contain structure definitions, including
- ;; a definition for NAME. The files are loaded into a config package
- ;; containing:
- ;; - the procedures and macros for defining structures and interfaces
- ;; - a Pre-Scheme structure (called PRESCHEME)
- ;; - a ps-memory structure
- ;; - a ps-receive structure
- ;; - the STRUCTURE-REFS structure
- ;; We then return:
- ;; 1. a list of the packages required to implement the named structures
- ;; 2. a list of the names exported by the named structures
- ;; 3. a procedure that for looking up names defined in packages in the
- ;; config package (this is used to map user directives to their targets)
- (define (package-specs->packages+exports struct-names files)
- (let ((config (make-very-simple-package 'config (list defpackage)))
- (old-config (config-package)))
- (environment-define! config 'prescheme prescheme)
- (environment-define! config 'ps-memory ps-memory)
- (environment-define! config 'ps-receive ps-receive)
- (environment-define! config 'ps-flonums ps-flonums)
- (environment-define! config 'ps-unsigned-integers ps-unsigned-integers)
- (environment-define! config 'ps-record-types ps-record-types)
- (environment-define! config 'structure-refs structure-refs)
- (environment-define! config ':syntax syntax-type)
- (set-reflective-tower-maker! config (get-reflective-tower-maker old-config))
- (with-fluids (($get-location
- (make-cell get-variable))
- ($note-file-package
- (make-cell (lambda (filename package) (values)))))
- (lambda ()
- (for-each (lambda (file)
- (load file config))
- files)))
- (values (collect-packages (map (lambda (name)
- (environment-ref config name))
- struct-names)
- (lambda (package)
- #t))
- (let ((names '()))
- (for-each (lambda (struct-name)
- (let ((my-names '()))
- (for-each-declaration
- (lambda (name package-name type)
- (set! my-names (cons name my-names)))
- (structure-interface
- (environment-ref config struct-name)))
- (set! names
- (cons (cons struct-name my-names)
- names))))
- struct-names)
- names)
- (make-lookup config))))
- ;; This creates new variables as needed for packages.
- (define (get-variable package name)
- ;;(format #t "Making variable ~S for ~S~%" name package)
- (make-global-variable
- name
- type/unknown))
- ;; Return something that will find the binding of ID in the package belonging
- ;; to the structure PACKAGE-ID in the CONFIG package.
- (define (make-lookup config)
- (lambda (package-id id)
- (let ((binding (package-lookup config package-id)))
- (if (and (binding? binding)
- (location? (binding-place binding))
- (structure? (contents (binding-place binding))))
- (let* ((package (structure-package
- (contents (binding-place binding))))
- (binding (package-lookup package id)))
- (if (binding? binding)
- (binding-place binding)
- #f))
- #f))))
- ;;----------------------------------------------------------------
- ;; Handy packages and package making stuff.
- (define defpackage #f) ;; (structure-ref built-in-structures defpackage))
- (define structure-refs #f) ;; (structure-ref built-in-structures structure-refs))
- (define scheme #f) ;; (structure-ref built-in-structures scheme))
- (define (make-env-for-syntax-promise . structures)
- (make-reflective-tower eval structures 'prescheme-linking))
- (define (make-very-simple-package name opens)
- (make-simple-package opens
- eval
- (make-env-for-syntax-promise scheme)
- name))
- (define (get-reflective-tower-maker p)
- (environment-ref p (string->symbol ".make-reflective-tower.")))
- ;;----------------------------------------------------------------
- ;; The following stuff is used to define the DEFINE-RECORD-TYPE macro.
- ;; We produce a structure that exports EXPAND-DEFINE-RECORD-TYPE. The
- ;; base package then includes that structure in its FOR-SYNTAX package.
- (define defrecord-for-syntax-package
- (make-very-simple-package 'defrecord-for-syntax-package '()))
- (define defrecord-for-syntax-structure
- (make-structure defrecord-for-syntax-package
- (lambda () (export expand-define-record-type))
- 'defrecord-for-syntax-structure))
- (define (define-for-syntax-value id value)
- (let ((loc (make-new-location defrecord-for-syntax-package id)))
- (set-contents! loc value)
- (package-define! defrecord-for-syntax-package
- id
- usual-variable-type
- loc
- #f)))
- ;; (define-for-syntax-value 'expand-define-record-type expand-define-record-type)
- ;;----------------------------------------------------------------
- ;; BASE-PACKAGE contains all of the primitives, syntax, etc. for Pre-Scheme
- (define (prescheme-unbound package name)
- (bug "~S has no binding in package ~S" name package))
- (define base-package
- ;; (let-fluid (structure-ref packages-internal $get-location) prescheme-unbound
- ;; (lambda () ))
- (make-simple-package '()
- eval
- (make-env-for-syntax-promise
- scheme
- defrecord-for-syntax-structure)
- 'base-package))
- ;; Add the operators.
- (for-each (lambda (id)
- (package-define! base-package
- id
- syntax-type
- #f
- (get-operator id syntax-type)))
- '(if begin lambda letrec quote set!
- define define-syntax let-syntax letrec-syntax
- ;; the rest are special for Prescheme
- goto type-case real-external))
- ;; Add the usual macros.
- (for-each (lambda (name)
- (package-define! base-package
- name
- syntax-type
- #f
- (make-transform
- (usual-transform name)
- base-package
- syntax-type
- `(usual-transform ',name)
- name)))
- '(and cond do let let* or quasiquote)) ;; delay
- ;; Plus whatever primitives are wanted.
- (define (define-prescheme! name location static)
- (package-define! base-package
- name
- usual-variable-type
- location
- static))
- ;; Copy over the enumeration macros and the ERRORS enumeration.
- (define (import-syntax! package-id name)
- (let ((config (config-package)))
- (let ((binding (structure-lookup (environment-ref config package-id)
- name
- #t)))
- (package-define! base-package
- name
- syntax-type
- (binding-place binding)
- (binding-static binding)))))
- (import-syntax! 'enumerated 'define-enumeration)
- (import-syntax! 'enumerated 'enum)
- (import-syntax! 'enumerated 'name->enumerand)
- (import-syntax! 'enumerated 'enumerand->name)
- (import-syntax! 'prescheme 'errors)
- (import-syntax! 'prescheme 'define-external-enumeration)
- (import-syntax! 'scheme 'syntax-rules)
- ;; define still more syntax
- (load "prescheme/ps-syntax.scm" base-package)
- (eval '(define-syntax define-record-type expand-define-record-type)
- base-package)
- ;;(eval '(define-syntax define-union-type expand-define-union-type)
- ;; base-package)
- ;;----------------------------------------------------------------
- ;; Make the Pre-Scheme structure and related structures
- (define (get-interface name)
- (environment-ref (config-package)
- name))
- (define prescheme
- (make-structure base-package
- (lambda () (get-interface 'prescheme-interface))
- 'prescheme))
- (define ps-memory
- (make-structure base-package
- (lambda () (get-interface 'ps-memory-interface))
- 'ps-memory))
- (define ps-flonums
- (make-structure base-package
- (lambda () (get-interface 'ps-flonums-interface))
- 'ps-flonums))
- (define ps-unsigned-integers
- (make-structure base-package
- (lambda () (get-interface 'ps-unsigned-integers-interface))
- 'ps-unsigned-integers))
- (define ps-receive
- (make-structure base-package
- (lambda () (get-interface 'ps-receive-interface))
- 'ps-receive))
- (define ps-record-types
- (make-structure base-package
- (lambda () (export (define-record-type :syntax)))
- 'ps-record-types))
- ;; and a handy environment
- (define prescheme-compiler-env
- (package->environment base-package))
|