#| -*-Scheme-*-
-$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/runtime/defstr.scm,v 14.2 1988/06/16 06:26:59 cph Exp $
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/runtime/defstr.scm,v 14.3 1988/10/29 00:12:22 cph Exp $
Copyright (c) 1988 Massachusetts Institute of Technology
that depends on the Common Lisp package system to help generate unique
tags; Scheme has no such way of generating unique symbols.
-* The NAMED option may optionally take an argument, which should be
-the name of a variable. If used, structure instances will be tagged
-with that variable's value. If the structure has a PRINT-PROCEDURE
-(the default) the variable must be defined when the defstruct is
-evaluated.
+* The NAMED option may optionally take an argument, which is normally
+the name of a variable (any expression may be used, but it will be
+evaluated whenever the tag name is needed). If used, structure
+instances will be tagged with that variable's value. The variable
+must be defined when the defstruct is evaluated.
* The TYPE option is restricted to the values VECTOR and LIST.
(parse/options name-and-options '())))
(define (parse/options name options)
+ (if (not (symbol? name))
+ (error "Structure name must be a symbol" name))
+ (if (not (list? options))
+ (error "Structure options must be a list" options))
(let ((conc-name (symbol-append name '-))
(constructor-seen? false)
(keyword-constructor? false)
(boa-constructors '())
(copier-name false)
(predicate-name (symbol-append name '?))
- (print-procedure print-procedure/default)
+ (print-procedure default-value)
(type-seen? false)
(type 'STRUCTURE)
(named-seen? false)
- (tag-name name)
+ (tag-name default-value)
(offset 0)
(include false))
(error "Structure option used with wrong number of arguments"
keyword
arguments)))
+
+ (define (symbol-option default)
+ (parse/option-value symbol? keyword (car arguments) default))
+
(case keyword
((CONC-NAME)
(check-arguments 0 1)
(set! conc-name
(and (not (null? arguments))
- (parse/option-value (car arguments)
- (symbol-append name '-)))))
+ (symbol-option (symbol-append name '-)))))
((KEYWORD-CONSTRUCTOR)
(check-arguments 0 1)
(set! constructor-seen? true)
(set! keyword-constructor? true)
(if (not (null? (cdr arguments)))
(set! constructor-name
- (parse/option-value (car arguments)
- (symbol-append 'make- name)))))
-\f
+ (symbol-option (symbol-append 'make- name)))))
((CONSTRUCTOR)
(check-arguments 0 2)
(cond ((null? arguments)
((null? (cdr arguments))
(set! constructor-seen? true)
(set! constructor-name
- (parse/option-value (car arguments)
- (symbol-append 'make- name))))
+ (symbol-option (symbol-append 'make- name))))
(else
(set! boa-constructors (cons arguments boa-constructors)))))
((COPIER)
(check-arguments 0 1)
(if (not (null? arguments))
- (set! copier-name
- (parse/option-value (car arguments)
- (symbol-append 'copy- name)))))
+ (set! copier-name (symbol-option (symbol-append 'copy- name)))))
+\f
((PREDICATE)
(check-arguments 0 1)
(if (not (null? arguments))
- (set! predicate-name
- (parse/option-value (car arguments)
- (symbol-append name '?)))))
+ (set! predicate-name (symbol-option (symbol-append name '?)))))
((PRINT-PROCEDURE)
(check-arguments 1 1)
(set! print-procedure
- (parse/option-value (car arguments) false)))
+ (parse/option-value (lambda (x) x true)
+ keyword
+ (car arguments)
+ false)))
((NAMED)
(check-arguments 0 1)
(set! named-seen? true)
|#
(else
(error "Unrecognized structure option" keyword)))))
-\f
+
(for-each (lambda (option)
(if (pair? option)
(parse/option (car option) (cdr option))
boa-constructors
copier-name
predicate-name
- (if (eq? print-procedure print-procedure/default)
+ (if (eq? print-procedure default-value)
`(,(absolute 'UNPARSER/STANDARD-METHOD) ',name)
print-procedure)
type
((eq? type 'VECTOR) 'VECTOR)
((eq? type 'LIST) 'LIST)
(else (error "Unsupported structure type" type)))
- (or (not type-seen?) named-seen?)
- tag-name
+ (and (or (not type-seen?) named-seen?)
+ (if (eq? tag-name default-value) 'DEFAULT true))
+ (if (eq? tag-name default-value)
+ name
+ tag-name)
offset
include
'())))
-(define print-procedure/default
+(define default-value
"default")
\f
;;;; Parse Slot-Descriptions
structure
(let ((kernel
(lambda (name default options)
+ (if (not (list? options))
+ (error "Structure slot options must be a list" options))
(let ((type #T)
(read-only? false))
(define (loop options)
(begin
(case (car options)
((TYPE)
- (set! type (parse/option-value (cadr options) true)))
+ (set! type
+ (parse/option-value symbol?
+ (car options)
+ (cadr options)
+ true)))
((READ-ONLY)
(set! read-only?
- (parse/option-value (cadr options) true)))
+ (parse/option-value boolean?
+ (car options)
+ (cadr options)
+ true)))
(else
(error "Unrecognized structure slot option"
(car options))))
(kernel (car slot-description) false '()))
(kernel slot-description false '()))))
-(define (parse/option-value name default)
- (case name
- ((FALSE NIL) #F)
- ((TRUE T) default)
- (else name)))
+(define (parse/option-value predicate keyword option default)
+ (case option
+ ((FALSE NIL)
+ #F)
+ ((TRUE T)
+ default)
+ (else
+ (if (not (or (predicate option)
+ (not option)
+ (eq? option default)))
+ (error "Structure option has incorrect type" keyword option))
+ option)))
\f
;;;; Descriptive Structure
(define (type-definitions structure)
(cond ((not (structure/named? structure))
'())
- ((eq? (structure/tag-name structure) (structure/name structure))
- `((DEFINE ,(structure/name structure)
+ ((eq? (structure/named? structure) 'DEFAULT)
+ `((DEFINE ,(structure/tag-name structure)
',structure)))
(else
`((NAMED-STRUCTURE/SET-TAG-DESCRIPTION!
#| -*-Scheme-*-
-$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/runtime/packag.scm,v 14.4 1988/08/05 20:48:18 cph Exp $
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/runtime/packag.scm,v 14.5 1988/10/29 00:12:38 cph Exp $
Copyright (c) 1988 Massachusetts Institute of Technology
(and child
(loop (cdr path) child))))))
+(define (environment->package environment)
+ (and (not (lexical-unreferenceable? environment package-name-tag))
+ (let ((package (lexical-reference environment package-name-tag)))
+ (and (package? package)
+ (eq? environment (package/environment package))
+ package))))
+
+(define-integrable package-name-tag
+ (string->symbol "#[(package)package-name-tag]"))
+
(define (find-package name)
(let loop ((path name) (package system-global-package))
(if (null? path)
(error "Package already has child of given name" package name))
(let ((child (make-package package name environment)))
(set-package/children! package (cons child (package/children package)))
+ (if (not (environment->package environment))
+ (local-assignment environment package-name-tag child))
child))
(define system-global-package)